Как указать пользовательское лицо с font-lock-defaults?

11

Если я определяю ключевые слова блокировки шрифта, используя существующие грани, я могу выделить строку «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)))

Это подчеркивает правильно:

фу выделено правильно

Однако, если я определю свое лицо:

(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)))

Подсветка не применяется:

без выделения

Как я могу использовать font-lock-defaultsлицо, которое я определил сам?

Уилфред Хьюз
источник

Ответы:

8

Взгляните на C-hvзначение font-lock-type-faceзначения просто символ font-lock-type-face. Теперь посмотрим на C-hvстоимость my-mode-foo-face. о нет! ты не можешь! Это не переменная!

Вам нужна переменная для доступа к вашему лицу. Объявление foo-faceлица не объявляет foo-faceпеременную.

Добавьте (defvar my-mode-foo-face 'my-mode-foo-face)после определения лица, а затем font-lock может использовать ваш my-mode-foo-facevar для доступа к my-mode-foo-faceлицу. Смущаюсь я знаю.


Изменить: кажется, что лучшее решение, основанное на том, что font-lock.el говорит:

;; 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.

Это может быть решением Уилфреда двойных кавычек лица в ключевых словах.

Джордон Биондо
источник
3
Ага, значит, он ожидает переменную. (cons "foo" ''my-mode-foo-face))тоже работает, но я не уверен, что идиоматично.
Уилфред Хьюз
1
Хм, мой ответ, кажется, устарелое решение проблемы, основанное на том, что я читаюfont-lock.el
Джордон Биондо
3
На самом деле это ожидание выражения, которое оно будет оценивать. Таким образом, вы также можете добавить немного логики.
Дмитрий