Как работает форма 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 не сами списки.

Другие вопросы по тегам