emacs + comint-dynamic-complete-filename после '='

Редактирование скрипта Bash Я хочу назначить имя файла для переменной.

Например, inputfile=foo.txt

Со стандартным Настройки Я не могу завершить имя файла без предварительной вставки пробела после '='.

Есть ли какое-то решение этого?

2 ответа

Решение

Прежде всего, comint-dynamic-complete устарела с Emacs 24.1. Функция замены completion-at-point,

Теперь, если вы начинаете смотреть на то, что completion-at-point на самом деле делает это в буфере сценария оболочки, в конечном итоге вы все равно окажетесь в comint. В частности, функция comint--match-partial-filename выглядит многообещающе для объяснения поведения, которое вы описали.

Если я правильно прочитал, проблема в том, что "=" считается допустимой частью имени файла, по крайней мере, в POSIX-подобных системах (см. Переменную comint-file-name-chars). Итак, механизм завершения пытается завершить имя файла "inputfile=/...", которое он, очевидно, не может найти.

Если вы никогда не используете "=" в своих именах файлов (или используете его так редко, что рабочее завершение перевешивает другие недостатки), вы можете рассмотреть возможность сделать что-то вроде (setq comint-file-name-chars "[]~/A-Za-z0-9+@:_.$#%,{}-") в хуке режима сценария оболочки (если вы работаете в системе POSIX; в Windows это будет выглядеть немного иначе).

Надеюсь, это поможет.

Ты можешь использовать bash-completion при условии, что вы не на окнах. Требуется лишь небольшая модификация для работы в sh-mode поскольку он использует функцию comint для определения текущего кандидата на завершение.

Мне это нравится, потому что, помимо завершения имен файлов, он также даст вам все приятные завершения readline, такие как переключатели командной строки и т. Д. Вот пример установки с использованием company, но вы могли бы удалить вещи компании, так как все, что вам действительно нужно, это добавить модифицированную функцию завершения в точке.

;; required packages: company bash-completion
(eval-when-compile
  (require cl-lib))

;; locally redefine comint-line-beginning-position so bash-completion
;; can work in sh-mode
(defun sh-bash-completion ()
  (cl-letf (((symbol-function 'comint-line-beginning-position)
             #'(lambda ()
                 (save-excursion
                   (sh-beginning-of-command)
                   (point)))))
    (let ((syntax (syntax-ppss)))
      (and (not (or (nth 3 syntax)
                    (nth 4 syntax)))
           (bash-completion-dynamic-complete)))))

;; put this in your sh-mode hook
(defun sh-completion-setup ()
  ;; add capf function
  (add-hook 'completion-at-point-functions
            'sh-bash-completion nil 'local)
  (company-mode)
  (make-local-variable 'company-backends)
  ;; use company completion-at-point
  (delq 'company-capf company-backends)
  (cl-pushnew 'company-capf company-backends)
  (setq-local company-transformers
              '(company-sort-by-backend-importance)))

(add-hook 'sh-mode-hook 'sh-completion-setup)
Другие вопросы по тегам