Emacs 29 поставляется с tree-sitter, библиотекой для редакторов, позволяющей динамически анализировать исходный код. Tree-sitter значительно упрощает для редакторов и IDE точную подсветку синтаксиса и включает более сложные функции, такие как поддержка рефакторинга. В этой статье объясняется, как настроить его в Emacs на примере C++. C++ служит здесь хорошим примером, потому что он связан с парой общих проблем.

Emacs 29 поставляется с библиотекой tree-sitter, но для ее работы вам по-прежнему нужны файлы определения грамматики для используемых вами языков. Emacs предоставляет функцию treesit-install-language-grammar для их автоматической установки, но вам нужно указать, где их найти в переменной treesit-language-source-alist. Добавьте это в свой init.el:

(setq treesit-language-source-alist
      '((cpp "https://github.com/tree-sitter/tree-sitter-cpp")
        (c "https://github.com/tree-sitter/tree-sitter-c")))

Вы можете найти грамматики для других языков и добавить их сюда. Я включил C, потому что c++-mode происходит от c-mode. Вероятно, вам нужно сделать то же самое для других C-подобных языков.

Затем установите все библиотеки грамматики, которые еще не установлены:

(dolist (lang treesit-language-source-alist)
  (unless (treesit-language-available-p (car lang))
    (treesit-install-language-grammar (car lang))))

Версия c++-mode для дерева называется c++-ts-mode=, и по умолчанию она будет искать tree-sitter-c++ (не только имя библиотеки грамматики, но и определенный в ней символ). Вам нужно сопоставить c++ с правильным именем:

(setq treesit-load-name-override-list
   '((c++ "libtree-sitter-cpp")))

Основные режимы просмотра дерева не установлены по умолчанию, поэтому нам нужно попросить Emacs использовать c++-ts-mode вместо c++-mode при редактировании исходного кода C++:

(add-to-list 'major-mode-remap-alist '(c-mode . c-ts-mode))
(add-to-list 'major-mode-remap-alist '(c++-mode . c++-ts-mode))
(add-to-list 'major-mode-remap-alist
             '(c-or-c++-mode . c-or-c++-ts-mode)))

Перезапустите Emacs и загрузите файл C++, и Tree-sitter должен быть включен. Попробуйте treesit-explore-mode или treesit-inspect-mode!