Hacker News Digest

12 сентября 2025 г. в 15:32 • blog.tjll.net • ⭐ 113 • 💬 13

OriginalHN

#emacs#elisp#sphinx#restructuredtext#projectile#company-mode#marginalia#which-key

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 под себя.