Как мне добавить автозаполнение в свой режим коминтов в Emacs? - PullRequest
2 голосов
/ 01 июля 2019

Я пишу режим коминтов для устаревшего инструмента командной строки.Я хотел бы добавить к нему базовое автозаполнение.

Предположим, у меня есть следующий список ключевых слов, используемых инструментом:

(defconst my-keywords '("export" "extract" "display"))

Как добавить автозаполнение в мойрежим, основанный на этом списке?


Что я нашел до сих пор: Я знаю, что есть примеры этого в shell.el или в comint.el, но мне не удалосьчтобы понять код достаточно хорошо, чтобы ответить на этот основной вопрос.Однако я понял, что могу составить список регулярных выражений из моих ключевых слов, например:

(regexp-opt my-keywords)
;; output:
"\\(?:display\\|ex\\(?:\\(?:por\\|trac\\)t\\)\\)"

Кроме этого, я понял, что могу использовать pcomplete, или компанию, или оба - янормально с любым решением на самом деле, но как мне это сделать?

Ответы [ 2 ]

1 голос
/ 02 июля 2019

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 для примера дополнительных специфических для компании символов для обозначения помощи / местоположения / и т. д. кандидатов на прохождение).

1 голос
/ 01 июля 2019

Благодаря ergoemacs Я нашел первое решение:

  1. Определить функцию завершения, которая возвращает список в форме (start end my-keywords . nil), с start и end , ограничивающими сущность для завершения в точке. Я добавил твик, чтобы учесть подсказку программы для первого ключевого слова.
  2. Добавьте эту функцию к функциям завершения в точке в определении режима;
  3. Добавить ярлык вкладки для завершения в точке, в карте режимов.
(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))

...