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)