clojure-emacs / cider

The Clojure Interactive Development Environment that Rocks for Emacs
https://cider.mx
GNU General Public License v3.0
3.54k stars 646 forks source link

Introduce `custom-face-1`/`custom-face-2` facility #3646

Open vemv opened 5 months ago

vemv commented 5 months ago

Context

DSLs and libraries with special semantics aren't uncommon in the Clojure world.

Users of those may want some extra highlighting rules, with different faces, that apply to just those DSLs.

Those extra faces allow to:

CIDER by default gives a relatively small palette of faces to be possibly applied, so stuff either won't get any particular font-locking, or the applied font-locking will overlap with Clojure font-locking (e.g. N different things all use font-lock-variable-name-face), hindering the desired distinction.

Changes

Introduce two new faces and two customizable 'categorizers' that when set, decide whether a given symbol should use one of the custom faces.

Example

The user would simply use something like:

(setq cider-custom-symbol-categorizer-1 (lambda (sym meta)
                                          (member (nrepl-dict-get meta "ns")
                                                  '("com.rpl.ramaspecter"))))

(setq cider-custom-symbol-categorizer-2 (lambda (sym meta)
                                          (member sym
                                                  '("<<sources"
                                                    "<<if"
                                                    "<<subsource"
                                                    "<<cond"
                                                    "<<ramaop"
                                                    "<<ramafn"
                                                    "or>"
                                                    "and>"
                                                    "else>"
                                                    "case>"
                                                    "<<shadowif"))))

And then one's theme can be customized to use the produced faces:

(custom-theme-set-faces
 'my-theme
 `(cider-custom-face-1 ((t (:foreground "blue"))))
 `(cider-custom-face-2 ((t (:foreground "red")))))

Status

Generally ready and functional, except for the addition of a user manual + changelog entry.

I also plan to provide a little more metadata from cider-nrepl (in an efficient manner).

Tweaks welcome.

Cheers - V

bbatsov commented 5 months ago

I'll need some specific use-cases to be able to evaluate the usefulness of this proposal as DSLs come in many flavors and I don't see immediately how a couple of extra faces will make a big difference for them.

Might also be useful to have this as some generic mechanism - e.g. some macro that will define a matching face, instead of hardcoding some faces. Admittedly this will make theming a more manual process, but I doubt that will be a big deal for most people.

vemv commented 5 months ago

As for examples:

Might also be useful to have this as some generic mechanism - e.g. some macro that will define a matching face, instead of hardcoding some faces. Admittedly this will make theming a more manual process, but I doubt that will be a big deal for most people.

I could use some pseudo-code to fully grasp the idea.

bbatsov commented 5 months ago

Something like:

(cider-define-font-locking-category 'category-name 
                                          (lambda (sym meta)
                                          (member (nrepl-dict-get meta "ns")
                                                  '("com.rpl.ramaspecter"))))

And this would create some face based on category-name. Or we can specify the face explicitly. Probably this should also take some face specification. And that's what I said that theming becomes a bit tricky - you'd need to have face overrides only after some faces have been created, but that's not that big of deal IMO.

vemv commented 5 months ago

Can give that a shot - would seem nice as I wasn't sure of how many 'slots' we should offer.

I take it that we'd go ahead with that?

bbatsov commented 5 months ago

Yeah, if it's flexible I'm OK with it.