Emacs 31: гид по встроенному markdown-ts-mode
Полный разбор встроенного markdown-ts-mode в Emacs 31: установка, настройка, фичи tree-sitter и практические советы.
Введение: Markdown встречает Tree-sitter
Если вы давно работаете в Emacs и пишете Markdown — будь то документация, README, статьи или заметки — вы наверняка сталкивались с markdown-mode из MELPA. Это добротный, зрелый инструмент. Но Emacs 31 меняет правила игры.
Emacs 31 поставляется с markdown-ts-mode прямо из коробки — и этот режим появился из предложения разработчика Рахула М. Хулиато, который отправил идею и первую версию кода в список emacs-devel ещё в начале 2025 года. Это не сольный проект: Стефан Маркс присоединился позже и стал соавтором режима, отвечая за большую часть того, что делает его удобным сегодня.
Среди ключевых нововведений Emacs 31 — упрощённая настройка tree-sitter с автоматической установкой грамматик, новый встроенный markdown-ts-mode с живой подсветкой синтаксиса внутри блоков кода и рендерингом инлайн-изображений, а также рендеринг LSP-документации через markdown-ts-mode в Eglot.
В этом руководстве мы разберём всё по порядку: что такое markdown-ts-mode, как его настроить, что он умеет и где у него пока есть шероховатости.
Что такое markdown-ts-mode и зачем он нужен
Tree-sitter — это инкрементальная библиотека парсинга, позволяющая редактору строить точное синтаксическое дерево файла в реальном времени. Это принципиально отличается от старого подхода с регулярными выражениями.
Раньше использование tree-sitter требовало ручной конфигурации: нужно было настраивать treesit-language-source-alist, скачивать грамматики, компилировать их и переключать режимы на ts-варианты. В Emacs 31 большая часть этой боли ушла.
Этот релиз продолжает тренд, при котором ядро Emacs поглощает функциональность, ранее требовавшую внешних пакетов, постепенно снижая сложность конфигурации как для новых, так и для опытных пользователей.
markdown-ts-mode — это мажорный режим для редактирования Markdown, построенный поверх tree-sitter. В отличие от старого markdown-mode, он использует два парсера одновременно:
Markdown использует две грамматики: основную и отдельную для инлайн-парсинга. Это позволяет точно разбирать как структуру документа (заголовки, списки, блоки кода), так и инлайн-разметку (жирный, курсив, ссылки) — независимо друг от друга.
Сравнение: markdown-mode vs markdown-ts-mode
| Характеристика | markdown-mode (MELPA) | markdown-ts-mode (встроен) |
|---|---|---|
| Источник | MELPA (внешний пакет) | GNU Emacs 31 (встроен) |
| Парсинг | Регулярные выражения | Tree-sitter |
| Подсветка блоков кода | Частичная | Живая, в языке блока |
| Инлайн-изображения | Нет | Да |
| LSP через Eglot | Ограниченно | Нативно |
| Поддержка тем (modus-themes) | Есть | Добавляется |
| Статус в Emacs 31 | Устарел для новых функций | Рекомендован |
Новый
markdown-ts-mode— это не замена с паритетом функций, а другой фундамент. Он берёт лучшее из tree-sitter и делает Markdown первоклассным гражданином Emacs.
Установка и первый запуск
Главное правило, которое нужно усвоить сразу:
Нет никакой необходимости скачивать или добавлять этот пакет в менеджер пакетов. Старый MELPA-репозиторий откажется устанавливаться начиная с Emacs 31 и очень беден по функциям — если вы его используете, вы не используете новый встроенный markdown-ts-mode.
Шаг 1: Проверка tree-sitter
Прежде всего убедитесь, что ваш Emacs собран с поддержкой tree-sitter:
M-: (featurep 'treesit) RET
Должно вернуть t. Также убедитесь, что у вас есть инструменты для компиляции грамматик — make, gcc и другие. Tree-sitter требует пакета tree-sitter-cli в вашем дистрибутиве, его можно проверить командой tree-sitter --version.
Шаг 2: Базовая конфигурация init.el
Добавьте в ваш init.el:
(autoload 'markdown-ts-mode "markdown-ts-mode" nil t)
(dolist (re '("\\.md\\'" "\\.mdx\\'" "\\.markdown\\'"))
(add-to-list 'auto-mode-alist (cons re 'markdown-ts-mode)))
(with-eval-after-load 'markdown-ts-mode
(require 'markdown-ts-mode-x))
После этого оба файла — основной режим и библиотека markdown-ts-mode-x с дополнительными возможностями — будут загружены, и вы сможете открывать Markdown-файлы в новом режиме.
Шаг 3: Тестирование без изменения конфигурации
Если хотите попробовать, не трогая рабочий конфиг:
Сохраните конфигурацию выше в файл, например testing.el, и запустите Emacs командой emacs -Q --load 'testing.el'. Вы получите чистую сессию Emacs с настроенным тестовым окружением.
Шаг 4: Установка грамматик
При первом открытии .md-файла Emacs может сообщить, что грамматика не найдена.
Это означает, что Emacs не нашёл грамматику для markdown в системе (по умолчанию — в ~/.emacs.d/tree-sitter/). Emacs предложит установить её, то есть скачать и скомпилировать из репозитория, уже указанного в исходном коде markdown-ts-mode. Нужно согласиться — Emacs клонирует репозиторий грамматики, скомпилирует её и перейдёт к второй грамматике.
В Emacs 31 появилась переменная treesit-auto-install-grammar. Установите её в 'always, чтобы грамматики ставились автоматически без запроса:
(setq treesit-auto-install-grammar 'always)
Для корректной работы markdown-ts-mode протестирован со следующими версиями грамматик: tree-sitter-markdown v0.4.1 и tree-sitter-markdown-inline v0.4.1.
flowchart TD
A[Открываем .md файл] --> B{Грамматика установлена?}
B -- Нет --> C[Emacs предлагает установить]
C --> D[Клонирование + компиляция grammars]
D --> E[Установка markdown-inline]
E --> F[markdown-ts-mode активен]
B -- Да --> F
F --> G[Подсветка синтаксиса]
F --> H[Инлайн-изображения]
F --> I[Подсветка внутри блоков кода]
Возможности markdown-ts-mode
Подсветка синтаксиса через tree-sitter
Основа режима — точная синтаксическая подсветка, основанная на реальном дереве разбора, а не на регулярных выражениях. Это означает корректное поведение даже в сложных и вложенных конструкциях.
Режимы языков для блоков кода определяются из таблицы markdown-ts-code-block-modes и эвристики, добавляющей -ts-mode и -mode к имени языка. Если режим вашего языка не распознаётся корректно, добавьте его в markdown-ts-code-block-modes. Мажорный режим каждого языка активируется один раз на буфер markdown-ts-mode во временном буфере для извлечения настроек font-lock и tree-sitter.
То есть блок ```python в вашем Markdown будет подсвечиваться как настоящий Python — со всеми правилами подсветки этого языка.
Поддержка инлайн-изображений
Это одна из самых заметных новинок. Изображения, указанные в Markdown-синтаксисе (), теперь могут отображаться прямо в буфере — без дополнительных плагинов.
Интеграция с Eglot (LSP)
Eglot теперь рендерит LSP-документацию через markdown-ts-mode — это значит, что всплывающие подсказки и документация к функциям, приходящие с языкового сервера в формате Markdown, будут корректно подсвечены и отформатированы.
Работа с блоками кода
Блоки кода с указанием языка должны подсвечиваться в режиме этого языка; отступы внутри блока кода должны работать согласно правилам этого режима; то же касается и заполнения текста (fill) внутри блока кода.
В файле .md с таким содержимым:
```python
def hello():
print("Hello, world!")
```
markdown-ts-mode применит подсветку Python-синтаксиса прямо внутри блока — включая ключевые слова, строки и функции.
Поддержка тем (Modus Themes)
Разрабатывается поддержка markdown-ts-mode faces в темах — в первую очередь в modus-themes. Emacs 31 поставляется с восемью доступными цветовыми схемами, включая варианты для людей с дейтеранопией и тританопией.
Известные ограничения и подводные камни
Ни один инструмент не идеален, особенно в первом релизе. Важно понимать текущие ограничения.
Отсутствие LSP «из коробки»
Eglot не поможет вам подготовить систему к LSP-работе — он воспользуется тем, что уже есть. Автоопределения и автоконфигурации нет. Нет никаких подсказок пользователю, поэтому нужно читать документацию, чтобы знать об этом.
Грамматики не идут в комплекте
Поддержка tree-sitter не включает грамматики. Они, как правило, отсутствуют в репозиториях дистрибутива, поэтому пользователям приходится самостоятельно находить грамматику и компилировать её. Emacs даже не даёт хорошей рекомендации, где их взять.
В Emacs 31 эта ситуация улучшена за счёт авто-предложения установки при первом запуске режима — но базовые инструменты (gcc, make) всё равно должны быть на машине.
Требования к версии libtree-sitter
Старые рантаймы дистрибутивов, например версия 0.22, не поддерживаются, поскольку некорректно обрабатывают несмежные диапазоны парсера. Поддерживаемые комбинации: Emacs 29/30 с libtree-sitter 0.25.x, и Emacs 31 со снимками разработки с libtree-sitter 0.25.x или 0.26.x.
Двунаправленный текст
Текст с разметкой может потребовать дополнительного переноса строки перед двунаправленным текстом для корректного отображения. Это ограничение движка отображения Emacs.
markdown-ts-mode из MELPA раньше — удалите его. Нет никакой необходимости скачивать или добавлять этот пакет в менеджер пакетов. Старый (уже заархивированный) репозиторий MELPA откажется устанавливаться на Emacs 31 и выше и очень беден по функциям.Альтернатива: md-ts-mode для Emacs 29+
Если вы ещё не перешли на Emacs 31, но хотите попробовать схожую функциональность:
Пакет md-ts-mode основан на markdown-ts-mode из GNU Emacs 31, изначально написанном Рахулом Мартимом Хулиато. Это мажорный режим для редактирования Markdown на основе tree-sitter, совместимый с Emacs 29, 30 и 31.
Установка грамматик для него:
M-x treesit-install-language-grammar RET markdown RET
M-x treesit-install-language-grammar RET markdown-inline RET
На Emacs 31 он также отдаёт предпочтение md-ts-mode над встроенным markdown-ts-mode.
Заключение
markdown-ts-mode в Emacs 31 — это не просто ещё один режим для Markdown. Это сигнал о направлении развития редактора: tree-sitter становится стандартом, а не экспериментом. От улучшенной поддержки языков до повышения удобства использования и производительности — tree-sitter в Emacs продолжает развиваться впечатляющими темпами.
Что мы имеем в итоге:
- Встроен — не нужно ничего ставить из MELPA
- Точная подсветка — синтаксическое дерево вместо regex
- Подсветка внутри блоков кода — Python как Python, Rust как Rust
- Инлайн-изображения — прямо в буфере
- LSP-документация — через Eglot, красиво
- Активное развитие — сообщество продолжает улучшать режим
Если вы присматривались к Emacs, но откладывали из-за сложности настройки, Emacs 31 движется в правильном направлении. Больше функций работает из коробки, а улучшения в системе завершения делают ванильный Emacs более современным без необходимости использовать фреймворки вроде Doom или Spacemacs.
- Установите Emacs 31 (или проверьте снапшот)
- Убедитесь, что есть
gcc,make,tree-sitter-cli - Добавьте конфигурацию
markdown-ts-modeвinit.el - Откройте любой
.mdфайл и согласитесь с установкой грамматик - Наслаждайтесь живой подсветкой Python/Rust/JS прямо в блоках кода