Подсветка шрифта на основе парсера
Помимо простой синтаксической подсветки шрифта и подсветки шрифта на основе регулярных выражений, Emacs также предоставляет полноценную синтаксическую подсветку шрифта с помощью парсера. В настоящее время Emacs использует для этой цели библиотеку tree-sitter (см. Разбор исходного кода программ).
Подсветка шрифта на основе парсера и другие механизмы подсветки шрифта не исключают друг друга. По умолчанию, если она включена, подсветка шрифта на основе парсера выполняется первой, заменяя синтаксическую подсветку шрифта, за ней следует подсветка шрифта на основе регулярных выражений.
Хотя подсветка шрифта на основе парсера не использует те же переменные настройки, что и подсветка шрифта на основе регулярных выражений, в ней применяются похожие схемы настройки. Аналогом font-lock-keywords для tree-sitter является treesit-font-lock-settings.
В целом подсветка шрифта tree-sitter работает следующим образом:
- Lisp-программа (обычно часть основного режима) задаёт запрос, состоящий из шаблонов, каждому из которых соответствует имя захвата.
- Библиотека tree-sitter находит в дереве разбора узлы, соответствующие этим шаблонам, помечает узлы соответствующими именами захвата и возвращает их Lisp-программе.
- Lisp-программа использует возвращённые узлы, чтобы выделить соответствующие каждому узлу фрагменты текста буфера, используя помеченные имена захвата узлов для определения нужной подсветки шрифта. Например, узел с пометкой
font-lock-keywordбудет выделен шрифтомfont-lock-keyword.
Дополнительные сведения о запросах, шаблонах и именах захвата см. в разделе Сопоставление шаблонов с узлами Tree-sitter.
Чтобы настроить подсветку шрифта tree-sitter, основной режим должен сначала задать treesit-font-lock-settings с помощью результата treesit-font-lock-rules, а затем вызвать treesit-major-mode-setup.
- Функция: treesit-font-lock-rules &rest query-specs
-
Эта функция используется для задания
treesit-font-lock-settings. Она компилирует запросы и выполняет другую постобработку, а затем выводит значение, принимаемое функциейtreesit-font-lock-settings. Пример:(treesit-font-lock-rules :language 'javascript :feature 'constant :override t '((true) @font-lock-constant-face (false) @font-lock-constant-face) :language 'html :feature 'script "(script_element) @font-lock-builtin-face")
Функция принимает последовательность query-spec, где каждый query-spec — это query, которому предшествуют одна или несколько пар keyword/value. Каждый query — это запрос tree-sitter в строковой, s-выраженной или скомпилированной форме.
Для каждого query предшествующие ему пары keyword/value добавляют метаинформацию. Ключевое слово
:languageзадаёт язык query. Ключевое слово:featureзадаёт имя функции query. Пользователи могут управлять тем, какие функции включены, с помощьюtreesit-font-lock-levelиtreesit-font-lock-feature-list(описаны ниже). Эти два ключевых слова обязательны (за некоторыми исключениями).Другие ключевые слова необязательны:
Ключевое слово Значение Описание :overridenilЕсли у области уже есть шрифт, отбросить новый шрифт tВсегда применять новый шрифт appendДобавить новый шрифт к существующим prependДобавить новый шрифт перед существующими keepЗаполнить области, у которых нет шрифта :reversedtВключить query, если feature отсутствует в списке функций. :default-languagelanguage Все запросы query после этого ключевого слова будут по умолчанию использовать language. Lisp-программы помечают шаблоны в query именами захвата (именами, начинающимися с
@), и tree-sitter возвращает найденные узлы с теми же именами захвата. Для подсветки шрифта имена захвата в query должны быть именами шрифтов, напримерfont-lock-keyword-face. Захваченный узел будет выделен этим шрифтом.Именем захвата также может быть имя функции — в этом случае функция вызывается с 4 аргументами: node и override, start и end, где node — сам узел, override — свойство
:overrideправила, захватившего этот узел, а start и end ограничивают область, которую эта функция должна подсветить. (Если функция должна учитывать аргумент override, она может использоватьtreesit-fontify-with-override.)Помимо указанных 4 аргументов, эта функция должна принимать дополнительные аргументы как необязательные, чтобы обеспечить расширяемость в будущем.
Если имя захвата одновременно является именем шрифта и именем функции, приоритет имеет шрифт. Если имя захвата не является ни именем шрифта, ни именем функции, оно игнорируется.
Иногда для поддержки разных версий одной и той же грамматики полезно условно включать некоторые необязательные запросы query или выбирать первый допустимый запрос из списка. В этом могут пригодиться такие функции, как
treesit-query-with-optionalиtreesit-query-with-fallback.
- Переменная: treesit-font-lock-feature-list
-
Это список списков символов функций. Каждый элемент списка — это список, представляющий уровень оформления. Пользовательская настройка
treesit-font-lock-levelопределяет, какие уровни активированы.Каждый элемент списка имеет вид
(feature …), где каждый feature соответствует значению:featureзапроса, заданного вtreesit-font-lock-rules. Удаление символа функции из этого списка отключает соответствующий запрос при подсветке шрифта.К распространённым именам функций для многих языков программирования относятся
definition,type,assignment,builtin,constant,keyword,string-interpolation,comment,doc,string,operator,preprocessor,escape-sequenceиkey. Основные режимы могут разбивать эти общие функции на более мелкие или дополнять их.Некоторые из этих функций требуют пояснения:
definitionвыделяет определяемый элемент, например имя функции в определении функции, имя структуры в определении структуры или имя переменной в определении переменной;assignmentвыделяет элемент, которому присваивается значение, например переменную или поле в операторе присваивания;keyвыделяет ключи в парах ключ-значение, например ключи в объекте JSON или словаре Python;docвыделяет строки документации или комментарии документации.Например, значение этой переменной может быть таким:
((comment string doc) ; level 1 (function-name keyword type builtin constant) ; level 2 (variable-name string-interpolation key)) ; level 3
Основные режимы должны задавать эту переменную перед вызовом
treesit-major-mode-setup.Чтобы эта переменная вступила в силу, Lisp-программа должна вызвать
treesit-font-lock-recompute-features(которая соответствующим образом сбрасываетtreesit-font-lock-settings) илиtreesit-major-mode-setup(которая вызываетtreesit-font-lock-recompute-features).
- Переменная: treesit-font-lock-settings
-
Список настроек подсветки шрифта на основе tree-sitter. Точный формат каждой отдельной настройки считается внутренней деталью реализации. Для задания этой переменной всегда следует использовать
treesit-font-lock-rules.Хотя объект настройки является непрозрачным, Emacs предоставляет функции доступа к запросу, функции, флагу включения и флагу переопределения настройки:
treesit-font-lock-setting-query,treesit-font-lock-setting-feature,treesit-font-lock-setting-enable,treesit-font-lock-setting-override,treesit-font-lock-setting-reversed.
Основные режимы для нескольких языков должны предоставлять функции диапазонов в treesit-range-functions, и Emacs будет задавать соответствующие диапазоны перед подсветкой области (см. Разбор текста на нескольких языках).
Copyright © 1990-1996, 1998-2026 Free Software Foundation, Inc.
Licensed under the GNU GPL license.
https://www.gnu.org/software/emacs/manual/html_node/elisp/Parser_002dbased-Font-Lock.html