24.7.2 Подсветка на основе поиска

Переменная, которая непосредственно управляет подсветкой на основе поиска, — это font-lock-keywords, которая обычно задается через элемент keywords в font-lock-defaults.

Переменная: font-lock-keywords

Значение этой переменной — это список ключевых слов для подсветки. Lisp-программы не должны устанавливать эту переменную напрямую. Обычно значение автоматически устанавливается режимом Font Lock с использованием элемента keywords в font-lock-defaults. Значение также можно изменить с помощью функций font-lock-add-keywords и font-lock-remove-keywords (см. Настройка подсветки на основе поиска).

Каждый элемент font-lock-keywords определяет, как находить определенные фрагменты текста и как их подсвечивать. Режим Font Lock обрабатывает элементы font-lock-keywords один за другим, и для каждого элемента находит и обрабатывает все совпадения. Обычно, если часть текста уже была подсвечена, это нельзя переопределить последующим совпадением в том же тексте; но вы можете задать другое поведение с помощью элемента override в subexp-highlighter.

Каждый элемент font-lock-keywords должен иметь одну из следующих форм:

regexp

Подсвечивать все совпадения для regexp, используя font-lock-keyword-face. Например,

;; Подсвечивать вхождения слова ‘foo’
;; с использованием font-lock-keyword-face.
"\\<foo\\>"

Будьте осторожны при составлении этих регулярных выражений; плохо написанный шаблон может сильно замедлить работу! Функция regexp-opt (см. Функции для регулярных выражений) полезна для вычисления оптимальных регулярных выражений для сопоставления с несколькими ключевыми словами.

function

Находить текст путем вызова function и подсвечивать найденные совпадения с использованием font-lock-keyword-face.

Когда function вызывается, она получает один аргумент — предел поиска; она должна начинать поиск с точки и не искать за пределами этого предела. Она должна возвращать не nil в случае успеха и устанавливать данные совпадения так, чтобы они описывали найденное совпадение. Возврат nil означает неудачу поиска.

Подсветка будет вызывать function повторно с тем же пределом и с точкой, где остановился предыдущий вызов, до тех пор, пока function не завершится неудачей. При неудаче function не обязана сбрасывать точку каким-либо определенным образом.

(matcher . subexp)

В таком элементе matcher — это либо регулярное выражение, либо функция, как описано выше. CDR, subexp, указывает, какое подвыражение matcher должно быть подсвечено (вместо всего текста, который совпал с matcher).

;; Подсвечивать ‘bar’ в каждом вхождении ‘fubar’,
;; используя font-lock-keyword-face.
("fu\\(bar\\)" . 1)
(matcher . facespec)

В таком элементе facespec — это выражение, значение которого задает лицо для подсветки. В простейшем случае facespec — это Lisp-переменная (символ), значение которой является именем лица.

;; Подсвечивать вхождения ‘fubar’,
;; используя лицо, которое является значением fubar-face.
("fubar" . fubar-face)

Однако facespec может также вычисляться в список следующей формы:

(subexp
(face face prop1 val1 prop2 val2…))

чтобы задать лицо face и различные дополнительные текстовые свойства для установки на текст, который совпадает. Если вы это делаете, не забудьте добавить имена других текстовых свойств, которые вы устанавливаете таким образом, в значение font-lock-extra-managed-props, чтобы эти свойства также очищались, когда они больше не нужны. В качестве альтернативы вы можете установить переменную font-lock-unfontify-region-function в функцию, которая очищает эти свойства. См. Другие переменные Font Lock.

(matcher . subexp-highlighter)

В таком элементе subexp-highlighter — это список, который определяет, как подсвечивать совпадения, найденные matcher. Он имеет форму:

(subexp facespec [override [laxmatch]])

CAR, subexp, — это целое число, указывающее, какое подвыражение совпадения подсвечивать (0 означает весь совпавший текст). Второй подылемент, facespec, — это выражение, значение которого задает лицо, как описано выше.

Последние два значения в subexp-highlighter, override и laxmatch, являются необязательными флагами. Если override равен t, этот элемент может переопределять существующую подсветку, выполненную предыдущими элементами font-lock-keywords. Если он равен keep, то каждый символ подсвечивается, только если он еще не был подсвечен каким-либо другим элементом. Если он равен prepend, лицо, заданное facespec, добавляется в начало свойства font-lock-face. Если он равен append, лицо добавляется в конец свойства font-lock-face.

Если laxmatch не равен nil, это означает, что не должно быть ошибки, если в matcher нет подвыражения с номером subexp. Очевидно, подсветка подвыражения с номером subexp не произойдет. Однако подсветка других подвыражений (и других регулярных выражений) продолжится. Если laxmatch равен nil, а указанное подвыражение отсутствует, то сигнализируется ошибка, которая прекращает подсветку на основе поиска.

Вот несколько примеров элементов такого вида и того, что они делают:

;; Подсвечивать вхождения либо ‘foo’, либо ‘bar’, используя
;; foo-bar-face, даже если они уже были подсвечены.
;; foo-bar-face должна быть переменной, значением которой является лицо.
("foo\\|bar" 0 foo-bar-face t)

;; Подсвечивать первое подвыражение в каждом совпадении,
;; которое находит функция fubar-match,
;; используя лицо, которое является значением fubar-face.
(fubar-match 1 fubar-face)
(matcher . anchored-highlighter)

В таком элементе anchored-highlighter определяет, как подсвечивать текст, следующий за совпадением, найденным matcher. Таким образом, совпадение, найденное matcher, действует как якорь для дальнейших поисков, задаваемых anchored-highlighter. anchored-highlighter — это список следующей формы:

(anchored-matcher pre-form post-form subexp-highlighters…)

Здесь anchored-matcher, как и matcher, является либо регулярным выражением, либо функцией. После того как найдено совпадение для matcher, точка находится в конце совпадения. Теперь Font Lock вычисляет форму pre-form. Затем он ищет совпадения для anchored-matcher и использует subexp-highlighters для их подсветки. subexp-highlighter описан выше. Наконец, Font Lock вычисляет post-form.

Формы pre-form и post-form могут использоваться для инициализации перед использованием anchored-matcher и очистки после него. Обычно pre-form используется для перемещения точки в некоторую позицию относительно совпадения matcher перед началом работы с anchored-matcher. post-form может использоваться для перемещения обратно перед возобновлением работы с matcher.

После того как Font Lock вычисляет pre-form, он не ищет anchored-matcher за пределами конца строки. Однако если pre-form возвращает позицию в буфере, которая больше, чем позиция точки после вычисления pre-form, то вместо этого возвращенная pre-form позиция используется как предел поиска. Как правило, не рекомендуется возвращать позицию, большую, чем конец строки; иными словами, поиск anchored-matcher не должен выходить за пределы строк.

Например,

;; Подсвечивать вхождения слова ‘item’, следующие
;; за вхождением слова ‘anchor’ (в той же строке),
;; используя лицо item-face.
("\\<anchor\\>" "\\<item\\>" nil nil (0 item-face))

Здесь pre-form и post-form равны nil. Поэтому поиск ‘item’ начинается с конца совпадения ‘anchor’, а поиск последующих вхождений ‘anchor’ возобновляется с того места, где завершился поиск ‘item’.

(matcher highlighters…)

Такой элемент задает несколько списков highlighter для одного matcher. Список highlighter может иметь тип subexp-highlighter или anchored-highlighter, как описано выше.

Например,

;; Подсвечивать вхождения слова ‘anchor’ с использованием
;; лица anchor-face, а последующие вхождения слова
;; ‘item’ (в той же строке) с использованием лица item-face.
("\\<anchor\\>" (0 anchor-face)
                ("\\<item\\>" nil nil (0 item-face)))
(eval . form)

Здесь form — это выражение, которое вычисляется при первом использовании этого значения font-lock-keywords в буфере. Его значение должно иметь одну из форм, описанных в этой таблице.

Предупреждение: Не проектируйте элемент font-lock-keywords для сопоставления с текстом, который выходит за пределы строк; это работает ненадежно. Подробнее см. Конструкции Font Lock для многострочного текста.

Вы можете использовать case-fold в font-lock-defaults для задания значения font-lock-keywords-case-fold-search, которое определяет, должна ли подсветка на основе поиска быть регистронезависимой.

Переменная: font-lock-keywords-case-fold-search

Не nil означает, что сопоставление с регулярными выражениями для font-lock-keywords должно быть регистронезависимым.