Как работает форма progn в font-lock-Keywords?
Следующий код будет визуально заменять "hello world" на "HW", передавая прогностическую форму для ключевых слов блокировки шрифтов.
(font-lock-add-keywords
nil '(("\\(hello world\\)"
(0 (progn (put-text-property (match-beginning 1) (match-end 1)
'display "HW")
nil)))))
Я смотрю в C-h v font-lock-keywords
чтобы увидеть, является ли это документированной функцией блокировки шрифтов. Элемент "Привет, мир", похоже, имеет такую форму:
(MATCHER HIGHLIGHT ...)
что означало бы, что (0 ...)
выделен, и док говорит
HIGHLIGHT should be either MATCH-HIGHLIGHT or MATCH-ANCHORED.
а также
MATCH-HIGHLIGHT should be of the form:
(SUBEXP FACENAME [OVERRIDE [LAXMATCH]])
Так что я догадался, 0 был SUBEXP и (progn ...)
был FACENAME. Но если (progn ..)
были бы допустимым FACENAME, следующий код работал бы, но это не работает.
;; (MATCHER . FACENAME)
(font-lock-add-keywords
nil '(("goodbye lenin"
. (progn (put-text-property (match-beginning 1) (match-end 1)
'display "GL")
nil))))
Это подводит меня к вопросу о том, как работает первый код и опирается ли он на недокументированную функцию.
Обновление:
Примечание: более простой способ визуальной замены без ошибок блокировки шрифта
(font-lock-add-keywords
nil '(("my llama"
(0 (progn (put-text-property (match-beginning 0) (match-end 0)
'display "ML")
nil)))))
2 ответа
Это работает - но ваш MATCHER
не правильно - результат матча не сохраняется. Это, например, не работает:
(font-lock-add-keywords
nil '(("goodbye lenin"
(0 (progn (put-text-property (match-beginning 1) (match-end 1)
'display "GL")
nil)))))
в то время как это делает:
(font-lock-add-keywords
nil '(("\\(goodbye lenin\\)"
. (progn (put-text-property (match-beginning 1) (match-end 1)
'display "GL")
nil))))
В документации сказано:FACENAME
это выражение, значением которого является имя лица для использования. Вместо лица, FACENAME
можно оценить список свойств формы (face FACE PROP1 VAL1 PROP2 VAL2 ...)
в этом случае все перечисленные свойства текста будут установлены, а не просто FACE
".
Здесь FACENAME
выражение (progn
) оценивает nil
таким образом, никакие свойства или грани не устанавливаются - единственный эффект, который вызван put-text-property
,
Одна проблема с ("goodbye lenin" . (progn (put-text-property
(match-beginning 1) (match-end 1) 'display "GL") nil))
в том, что это просто еще один способ написать: ("goodbye lenin" progn (put-text-property
(match-beginning 1) (match-end 1) 'display "GL") nil)
и эти эквивалентности могут привести к неоднозначности, поэтому в этом случае вы получаете ошибки.
Итак, форма (MATCHER . HIGHLIGHT)
, (match . FACENAME)
и такие должны использоваться только тогда, когда HIGHLIGHT
а также FACENAME
не сами списки.