Как мне добавить автозаполнение в свой режим коминтов в Emacs?
Я пишу режим коминтов для устаревшего инструмента командной строки. Я хотел бы добавить к нему базовое автозаполнение.
Предположим, у меня есть следующий список ключевых слов, используемых инструментом:
(defconst my-keywords '("export" "extract" "display"))
Как добавить автозаполнение в мой режим, основываясь на этом списке?
Что я нашел до сих пор: я знаю, что есть примеры этого в shell.el или в comint.el, но мне не удалось понять код достаточно хорошо, чтобы ответить на этот основной вопрос. Однако я понял, что могу составить список регулярных выражений из моих ключевых слов, например так:
(regexp-opt my-keywords)
;; output:
"\\(?:display\\|ex\\(?:\\(?:por\\|trac\\)t\\)\\)"
Кроме этого, я понял, что могу использовать pcomplete, или компанию, или и то и другое - на самом деле я в порядке с любым решением, но как мне это сделать?
2 ответа
Благодаря ergoemacs я нашел первое решение:
- Определите функцию завершения, которая возвращает список формы
(start end my-keywords . nil)
, с начальным и конечным разделением объекта для завершения в точке. Я добавил твик, чтобы учесть подсказку программы, для первого ключевого слова. - Добавьте эту функцию к функциям завершения в точке в определении режима;
- Добавьте ярлык вкладки к завершению в точке, в карте режима.
(defconst my-keywords '("export" "extract" "display"))
;; 1 - custom completion function
(defun my-completion-at-point ()
"This is the function to be used for the hook `completion-at-point-functions'."
(interactive)
(let* (
(bds (bounds-of-thing-at-point 'symbol))
(start (max (car bds) (comint-line-beginning-position)))
(end (cdr bds)))
(list start end xyz-keywords . nil )))
;; 2 - adding it to my-completion-at-point
(define-derived-mode my-comint-mode comint-mode "My comint mode"
;; your code....
(add-hook 'completion-at-point-functions 'my-completion-at-point nil 'local))
;; 3 - add a tab shortcut in the map of the mode
(defvar my-mode-map
(let ((map (nconc (make-sparse-keymap) comint-mode-map)))
;; your code...
(define-key map "\t" 'completion-at-point)
map))
Comint также называет настраиваемым comint-dynamic-complete-functions
от его comint-completion-at-point
функция. Производные режимы часто добавляют функции к этому хуку (см. shell-dynamic-complete-functions
), например
(defconst my-keywords '("export" "extract" "display"))
(defun my-comint-dynamic-completion-function ()
(when-let* ((bds (bounds-of-thing-at-point 'symbol))
(beg (car bds))
(end (cdr bds)))
(when (> end beg)
(list beg end my-keywords :annotation-function (lambda (_) "my-keywords")))))
(define-derived-mode my-comint-mode comint-mode "my mode"
(add-hook 'comint-dynamic-complete-functions
#'my-comint-dynamic-completion-function nil 'local)
(make-local-variable 'company-backends)
(cl-pushnew 'company-capf company-backends))
Добавлением company-capf
на ваш company-backends
Вы также получите поддержку компании после завершения функции в точке (см. elisp-completion-at-point
например, дополнительные специфические для компании символы для отображения справки / местоположения / и т. д. завершения кандидатов).