11

If I define font lock keywords using existing faces, I can highlight the string 'foo'.

(defconst my-mode-font-lock-keywords
  (list
   (cons "foo" 'font-lock-type-face)))

(define-derived-mode my-mode fundamental-mode "My mode"
  "A demo mode."
  (set (make-local-variable 'font-lock-defaults) '(my-mode-font-lock-keywords)))

This highlights correctly:

foo highlighted correctly

However, if I define my own face:

(defface my-mode-foo-face
  '((t :inherit font-lock-preprocessor-face))
  "Face for highlighting 'foo'.")

(defconst my-mode-font-lock-keywords
  (list
   (cons "foo" 'my-mode-foo-face)))

(define-derived-mode my-mode fundamental-mode "My mode"
  "A demo mode."
  (set (make-local-variable 'font-lock-defaults) '(my-mode-font-lock-keywords)))

No highlighting is applied:

no highlighting

How can I use font-lock-defaults with a face I've defined myself?

8

Take a look at the C-hv value of font-lock-type-face the value is just the symbol font-lock-type-face. Now look at the C-hv value of my-mode-foo-face. Oh no! you can't! It's not a variable!

You need a variable to access your face. Declaring the foo-face face does not declare the foo-face variable.

Add (defvar my-mode-foo-face 'my-mode-foo-face) after the face definition and then font-lock can use your my-mode-foo-face var to access the my-mode-foo-face face. Confusing I know.


Edit: there seems to be a better solution based on what font-lock.el says:

;; Originally these variable values were face names such as `bold' etc.
;; Now we create our own faces, but we keep these variables for compatibility
;; and they give users another mechanism for changing face appearance.
;; We now allow a FACENAME in `font-lock-keywords' to be any expression that
;; returns a face.  So the easiest thing is to continue using these variables,
;; rather than sometimes evalling FACENAME and sometimes not.  sm.

;; Note that in new code, in the vast majority of cases there is no
;; need to create variables that specify face names.  Simply using
;; faces directly is enough.  Font-lock is not a template to be
;; followed in this area.

That may be Wilfred's solution of double quoting the face in the keywords.

  • 3
    Aha, so it's expecting a variable. (cons "foo" ''my-mode-foo-face)) also works, but I'm not sure which is idiomatic. – Wilfred Hughes Nov 15 '14 at 20:10
  • 1
    Hmm, my answer seems to be the antiquated solution for the problem based on what I'm reading in font-lock.el – Jordon Biondo Nov 15 '14 at 20:22
  • 3
    It's expecting an expression, actually, which it will evaluate. So you can also put some logic in there. – Dmitry Nov 15 '14 at 20:27

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.