A beginner's guide to extending Emacs
Краткий путь от Spacemacs к своему конфигу: как за 200 строк Elisp добавить автодополнение ref-ов в reStructuredText
Проблема: в Sphinx-доке сотни .. _code_example: и я не помню ни одного. Нужно M-. → список → выбрал → вставил.
0. Emacs готов быть поломан
- Всё документировано, встроенный
C-h f/C-h vпокажет исходники. advice-add,define-derived-mode,completion-at-point-functions— ядерные кнопки; нажал — получил power.
1. Берём нужные куски
rst-modeуже есть.completion-at-pointуже умеет списки.- Осталось написать backend, который возвращает список всех
.. _xxx:из*.rstпроекта.
2. Одна функция — один пулл
(defun rst-collect-refs ()
"Возвращает alist (ref . file) для всех *.rst ниже `project-root'."
(let ((refs nil))
(projectile-map-project-files
(lambda (f)
(when (string-suffix-p ".rst" f)
(with-temp-buffer
(insert-file-contents f)
(while (re-search-forward "^\\.\\. _\\([^:]+\\):" nil t)
(push (cons (match-string-no-properties 1) f) refs))))))
refs))
3. Подсовываем в CAPF
(defun rst-ref-capf ()
(when (looking-back ":ref:`\\([^`]*\\)?" (line-beginning-position))
(let ((refs (rst-collect-refs))
(beg (match-beginning 1)))
(list beg (point)
(mapcar #'car refs)
:annotation-function
(lambda (s) (format " (%s)" (cdr (assoc s refs))))))))
(add-hook 'rst-mode-hook
(lambda ()
(add-hook 'completion-at-point-functions
#'rst-ref-capf nil t)))
4. Украшательства (по желанию)
company-mode+company-capf→ всплывающее меню.marginalia→ красивые аннотации.which-key→ подсказки команд.
5. Итого
20 минут, 40 строк «моего» кода, 160 строк boilerplate.
Emacs живёт 40 лет, но всё ещё позволяет за вечер сделать IDE под себя.
Комментарии (13)
- В Emacs всё — вызов функции: даже нажатие клавиши вызывает elisp-функцию, которую можно переопределить.
- Встроенные
describe,apropos,infoи пакетhelpfulпозволяют быстро понять, «что под капотом», и начать не только конфигурировать, но и расширять редактор. - Пользователи активно интегрируют LLM: через gptel просят Claude 4.1 отвечать в org-файл, версионируют диалоги и думают над собственным chat-mode.
- Doom/Spacemacs дают «готовое мнение» для переходящих с Vim, но рано или поздно приходится дорабатывать конфиг самостоятельно.
- Главный совет: не бояться экспериментировать — в Emacs конфигурация и полноценное программирование различаются только глубиной погружения.
I Prefer RST to Markdown (2024)
- Markdown = лёгкая обёртка HTML, rST = промежуточное дерево документа.
- В Markdown картинка:
→ прямое преобразование в<img>. - В rST:
.. image:: img.jpg :alt: alt→ регистрируется обработчик, возвращает объект-узел, который потом рендерится нужным бэкендом. - rST расширяем: добавил
.. figure::, подключил обработчик — готово. - Можно трансформировать дерево до вывода: перенос решений упражнений в конец книги, генерация ссылок, разные стили для HTML, PDF, EPUB.
- Пример:
.. exercise:: Fizzbuzzи.. solution::собираются в одном месте, но при сборке перемещаются вsolutionlist, связываются ссылками, в EPUB открываются всплывающими сносками, в LaTeX — через answers.
Комментарии (81)
- RST мощнее и расширяемее, но синтаксис вызывает отторжение и сложен для новичков.
- Markdown читается и пишется проще, поэтому стал де-факто стандартом, но не хватает возможностей для больших документов.
- MyST, Asciidoc, Djot и Typst предлагают компромисс между простотой и функциональностью, но пока уступают Markdown в распространённости инструментов.
- Парсеры RST доступны в основном на Python, а у Markdown — «каждый реализует свой диалект».
- Для книг и сложной документации RST + Sphinx выигрывают за счёт автогенерации HTML/PDF/EPUB, глоссариев и индексов.