reddit / emacs

Why do I keep getting notified that a face I've define is void?

bhrgunatha · 2022-01-27 07:13
I want to add a facility to an existing major mode so that *some* of the keywords that the mode defines have a different face applied. (defface my-keyword-override-face '((t :inherit font-lock-keyword-face :slant italic :underline t)) "WTF face") That mode already define the special case keyword regex and applies the `font-lock-warning-face` and I want to replace that with my face: (,special-case-keywords-regexp . ,my-keyword-override-face) Literally all I've done is define a face and change `font-lock-warning-face` with my new face. It fails with a message i the message biffer saying: Error during redisplay: (jit-lock-function 1) signaled (void-variable my-keyword-override-face) That's coming from font-lock. In the lisp buffer that defines a major mode where I added the face (defface my-keyword-override-face '((t :inherit font-lock-keyword-face :slant italic :underline t)) "WTF face") I place my cursor at the end of the *defface* and `M-x eval-print-last-sexp` and beneath it in the buffer I see. my-keyword-override-face The 'defface' is at location 4120 in the buffer and directly after that I have (add-text-properties 4120 4127 `(face ,my-keyword-override-face)) Place my cursor after that sexp and `M-x eval-print-last-sexp`again. I'm thrown into a lisp debugger Debugger entered--Lisp error: (void-variable my-keyword-override-face) (list 'face my-keyword-override-face) (add-text-properties 4120 4127 (list 'face my-keyword-override-face)) (progn (add-text-properties 4120 4127 (list 'face my-keyword-override-face))) elisp--eval-last-sexp(t) eval-last-sexp(t) eval-print-last-sexp(nil) funcall-interactively(eval-print-last-sexp nil) command-execute(eval-print-last-sexp) Can someone please help me understand what I'm dong wrong and how I should be replacing a modes face with one that I've defined.
7890yuiop · 2022-01-27 07:41
You've defined a face, not a variable. The code you've changed would have been referring to a variable, the value of which was a face. What you *probably* want to do instead is to set the value of that original variable to point to your face, and leave the code alone.
deaddyfreddy · 2022-01-27 07:41
use `:inherit` maybe?
bhrgunatha · 2022-01-27 08:04
> You've defined a face, not a variable. Thanks. Very frustrating as all the web searches and code examples I looked at imply that the *face* is what is you need to use, not a variable with the value of the face's symbol. I know it's on me, but you'd think the documentation **somewhere** would tell you they need to be variables and not the face itself. > What you probably want to do instead is to set the value of that original variable to point to your face, and leave the code alone. Yep, `font-lock.el' itself has: (defvar font-lock-warning-face 'font-lock-warning-face "Face name to use for things that should stand out.") So adding (defvar my-keyword-override-face 'my-keyword-override-face) works as desired.
7890yuiop · 2022-01-27 08:32
It's not that you *need* a variable to use a face; it's just that the code you're basing everything on is doing that (which makes things more customisable). You could also write code which specifies a face directly, rather than evaluating a variable.
bhrgunatha · 2022-01-27 09:38
Yes, I see that now, thanks for your help. What's confusing for example is that the docs for `add-text-properties` say (add-text-properties start end properties &optional object) Add properties to the text from START to END. (add-text-properties (point) (1+ (point)) '(face error)) And while I see that it's using the symbol `'error`, it isn't clear to me why that symbol doesn't refer to a face - similar to how symbols can refer to defuns.
7890yuiop · 2022-01-27 10:30
It does refer to a face. You were doing *this* though: (add-text-properties 4120 4127 `(face ,my-keyword-override-face)) Where you are *evaluating* `my-keyword-override-face` to get its value as a variable (which should, in this context, be a face). You could do as shown in the doc, which would refer to the `my-keyword-override-face` face: (add-text-properties 4120 4127 '(face my-keyword-override-face))
bhrgunatha · 2022-01-27 10:42
OK that's much clearer - thanks for explaining it to me, I appreciate it.
7890yuiop · 2022-01-27 10:43
Note also that it's not so common to define face names ending in `-face`, as that's somewhat redundant. Conventionally (albeit not reliably), when there is a variable named `FOO-face` the default value will be a face named `FOO`. E.g.: dired-ignored-face is a variable defined in ‘dired.el’. Its value is ‘dired-ignored’
00-11 · 2022-01-27 17:32
Lots of us have *void faces* these days. Maybe it's Covid. ;-)