I'm trying to learn about font locking in my own custom major modes. I can get things working fine for the most part, keywords highlighted,
regexp-opt matching strings, using capture groups within a regexp to highlight just the capture group, etc.
But I've noticed that some of the faces that I have tried (such as
dired-directory) do not work in font lock expressions, even though other faces such as
font-lock-keyword-face work fine in the same slot.
Reading the manual says that face variables should be faces that have a value property that evaluates to the face name. Sure enough, when I eval
font-lock-keyword-face, the value is the same as the face name. But when I eval
dired-directory face, its value is
So it looks like the value
nil is the proximal cause of the problem, and the answer to my question (kind of). But it's not really a good answer.
(1) Why doesn't the
dired-directory face that I see listed with
list-faces-display have a value the same as the face name?
(2) How can any mode use the face, if the font lock implementation requires that the face name symbol evaluates to the face name, when
dired-directory face does not?
Here is a link in SX that touches on the same subject, but it mentions that the solution might be obsolete.
Here is my code line that motivated the problem.
( ,(regexp-opt ct-mode-nset-keywords ) . font-lock-keyword-face)
font-lock-keyword-face (with no quote) works. (2) Using
dired-directory (with no quote) fails. (3) Thanks to @theldoria, using
'dired-directory (with quote) works.
Here is what the manual says:
22.6.7 Faces for Font Lock
Font Lock mode can highlight using any face, but Emacs defines several faces specifically for Font Lock to use to highlight text. These Font Lock faces are listed below. They can also be used by major modes for syntactic highlighting outside of Font Lock mode (see Major Mode Conventions).
Each of these symbols is both a face name, and a variable whose default value is the symbol itself. Thus, the default value of font-lock-comment-face is font-lock-comment-face.
Thank you to everyone who responded -- I have a working syntax to use going forward. And sorry for the confusion using
dired-directory as my example - it is both a face and a separate variable holding a directory (or nil). It would have been better for me to use
dired-flagged or some other face from
list-faces-display, which trigger a
void variable error instead of nil.
But now I'm wondering if the face-symbol-with-variable-value model is somehow old or obsolete, even if it is in the manual. Font lock apparently requires that variable value one way or another (eg with a 'quoted-face-name), but other faces in the
list-faces-display do not have that value property (eg. dired-flagged, avy-lead-face, etc).
font-lock-keywordsas it's just confusing people when they're using a face name that is no variable and get the syntax wrong...
(font-lock-add-keywords nil '(("^[ \t]*\\([^ \t\n]+\\)[ \t]+\\([[:alpha:]][^ \t\n]*\\)" (1 'font-lock-keyword-face) (2 'dired-directory)))).