Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

All top-level def forms should have consistent font-lock #578

Open
j-cr opened this issue Nov 6, 2020 · 4 comments
Open

All top-level def forms should have consistent font-lock #578

j-cr opened this issue Nov 6, 2020 · 4 comments

Comments

@j-cr
Copy link
Contributor

j-cr commented Nov 6, 2020

Some thoughts on syntax highlighting.

(def foo 42) ; font-lock-variable-name-face
(defn bar [x] x) ; font-lock-function-name-face

I think variable-name-face should be used for foo in (let [foo 42] ...), but not for foo in (def foo 42). Top-level definitions should use the same face, whether its a function or a 'variable'. It seems more logical, since if I want to make both "foo" and "bar" use the same bold and highly visible face (since both are top-level defs), then e.g. in my c code I get local variables and function arguments highlighted with the same face.

I guess the correct hierarchy would be: top-level-definition-face -> (function-face, var-face[1]). It would be nice to have a separate space for def-like keywords as well (so a user could highlight "defn", but not "do" or "let").

[1]: technically defn also creates a var; what's the best short name for a top-level definition that is not a function? Do we actually need/want this distinction at all? I don't really see how it's useful.

@bbatsov
Copy link
Member

bbatsov commented Nov 13, 2020

I've tried to align the font-locking in clojure-mode to that in lisp-mode and elisp-mode. Obviously there are some differences between a Lisp-1 and Lisp-2, but I think we won't gain much by changing the fock-locking for definitions. None of the existing Lisp modes for Emacs try to font-lock locals, so I didn't bother to so as well.

@j-cr
Copy link
Contributor Author

j-cr commented Nov 13, 2020

I don't care that much about highlighting locals too. My main point's that logically all top-level definitions are kinda on the same level of "importance", so should be highlighted similarly, whether it's defined with a def or defn (or other def-like forms).

But setting font-lock-variable-name-face (currently used for (def x ...) definitions) to be the same as function-name face (i.e. bold and bright) also makes local variables in other languages bold and bright (local variables in other lang modes use the same face: font-lock-variable-name-face).

Anyways, feel free to close as you see fit, as it's not a feature request per se but more of "what's your thoughts on this" type ticket; or maybe leave open to gather more opinions.

@yuhan0
Copy link
Contributor

yuhan0 commented Nov 27, 2020

For what it's worth, I do exactly this special highlighting of all def... forms on my local fork of clojure-mode, and I find it helps greatly with visual parsing of code.
image

This was done with a custom clojure-definition-face that is applied equally to all def.. forms, without distinguishing between def / deftype / defn.
I do realise it's not for everyone and doesn't align well with other Emacs modes as pointed out above, just posting since there's interest.

(defface clojure-definition-face
  `((t :height 1.4 :bold t
       :inherit highlight))
  "Face used to font-lock Clojure definitions")

The font lock keyword:

      ;; Definitions (any form that starts with def except for "default")
      (,(concat "(\\(?:" clojure--sym-regexp "/\\)?"
                (rx (group "def"
                           (? (or (: (not (any "a ")) (* (not (any " "))))
                                  (: "a"
                                   (? (or (: (not (any "u ")) (* (not (any " "))))
                                          (: "u"
                                           (? (or (: (not (any "l ")) (* (not (any " "))))
                                                  (: "l"
                                                   (? (: (not (any "t ")) (* (not (any " "))))))))))))))
                           word-end))
                clojure--whitespace-regexp
                clojure--type-or-metadata-regexp
                "\\(:*" clojure--sym-regexp "\\)?")
       (1 font-lock-keyword-face)
       (2 'clojure-definition-face nil t))

@jpe90
Copy link

jpe90 commented Jan 4, 2022

@yuhan0 Would it be possible to share your local fork? That special highlighting looks great, but it looks you're using definitions of clojure--whitespace-regexp and clojure--type-or-metadata-regexp that aren't shown if I understand correctly

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants