38.8 Разработка основных режимов с помощью tree-sitter

В этом разделе приведены общие рекомендации по разработке интеграции tree-sitter для основного режима.

Основной режим, поддерживающий функции tree-sitter, должен примерно следовать этой схеме:

(define-derived-mode woomy-mode prog-mode "Woomy"
  "Режим для языка программирования Woomy."
  (when (treesit-ready-p 'woomy)
    (setq-local treesit-variables ...)
    ...
    (treesit-major-mode-setup)))

treesit-ready-p автоматически выводит предупреждение, если не выполнены условия для включения tree-sitter.

Если основной режим tree-sitter имеет общую настройку с его «нативным» аналогом, можно создать «базовый режим», который содержит общую настройку, как здесь:

(define-derived-mode woomy--base-mode prog-mode "Woomy"
  "Внутренний режим для языка программирования Woomy."
  (common-setup)
  ...)

(define-derived-mode woomy-mode woomy--base-mode "Woomy"
  "Режим для языка программирования Woomy."
  (native-setup)
  ...)

(define-derived-mode woomy-ts-mode woomy--base-mode "Woomy"
  "Режим для языка программирования Woomy."
  (when (treesit-ready-p 'woomy)
    (setq-local treesit-variables ...)
    ...
    (treesit-major-mode-setup)))
Функция: treesit-ready-p language &optional quiet

Эта функция проверяет условия для активации tree-sitter. Она проверяет, был ли Emacs собран с tree-sitter, не слишком ли велик размер буфера для обработки tree-sitter, и доступна ли грамматика для language в системе (см. Грамматика языка Tree-sitter).

Эта функция выводит предупреждение, если tree-sitter не может быть активирован. Если quiet равно message, предупреждение преобразуется в сообщение; если quiet равно t, не выводится ни предупреждение, ни сообщение.

Если все необходимые условия выполнены, эта функция возвращает не-nil; в противном случае возвращает nil.

Функция: treesit-major-mode-setup

Эта функция активирует некоторые функции tree-sitter для основного режима.

В настоящее время она настраивает следующие функции:

  • Если treesit-font-lock-settings (см. Подсветка шрифта на основе парсера) не равно nil, она настраивает фортификацию шрифта.
  • Если treesit-simple-indent-rules или treesit-indent-function (см. Отступы на основе парсера) не равно nil, она настраивает отступы.
  • Если treesit-defun-type-regexp не равно nil, она настраивает функции навигации для beginning-of-defun и end-of-defun.
  • Если treesit-defun-name-function не равно nil, она настраивает функции add-log, используемые add-log-current-defun.
  • Если treesit-simple-imenu-settings (см. Imenu) не равно nil, она настраивает Imenu.
  • Если treesit-outline-predicate (см. Минорный режим Outline) не равно nil, она настраивает минорный режим Outline.
  • Если sexp и/или sentence определены в treesit-thing-settings (см. Пользовательские «Вещи» и навигация), она включает команды навигации, которые перемещаются, соответственно, по sexp и предложениям, определяя такие переменные, как forward-sexp-function и forward-sentence-function.

Для получения дополнительной информации об этих встроенных функциях tree-sitter см. Подсветка шрифта на основе парсера, см. Отступы на основе парсера и см. Перемещение по сбалансированным выражениям.

Для поддержки смешивания нескольких языков в основном режиме см. Парсинг текста на нескольких языках.

Помимо beginning-of-defun и end-of-defun, Emacs предоставляет несколько дополнительных функций для работы с defun: treesit-defun-at-point возвращает узел defun в текущей позиции, а treesit-defun-name возвращает имя узла defun.

Функция: treesit-defun-at-point

Эта функция возвращает узел defun в текущей позиции или nil, если он не найден. Она учитывает treesit-defun-tactic: если его значение равно top-level, эта функция возвращает верхнеуровневый defun, а если его значение равно nested, она возвращает ближайший окружающий defun.

Эта функция требует treesit-defun-type-regexp для работы. Если он равен nil, эта функция просто возвращает nil.

Функция: treesit-defun-name node

Эта функция возвращает имя defun для node. Она возвращает nil, если для node нет имени defun, или если node не является узлом defun, или если node равно nil.

В зависимости от языка и основного режима, имена defun могут быть именами функции, класса, структуры и т. д.

Если treesit-defun-name-function равен nil, эта функция всегда возвращает nil.

Переменная: treesit-defun-name-function

Если не равно nil, значение этой переменной должно быть функцией, которая вызывается с узлом в качестве аргумента и возвращает имя defun этого узла. Функция должна иметь ту же семантику, что и treesit-defun-name: если узел не является узлом defun, или узел является узлом defun, но не имеет имени, или узел равен nil, она должна вернуть nil.