emacs + comint-dynamic-complete-filename 在'='之后
emacs + comint-dynamic-complete-filename after '='
正在编辑 Bash 脚本我想将文件名分配给变量。
例如输入文件=foo.txt
与标准。设置 如果不先在“=”之后插入 space,我无法完成文件名。
有什么解决办法吗?
你可以使用 bash-completion
假设你不在 windows。它只需要稍作修改即可在 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)
首先,comint-dynamic-complete
从 Emacs 24.1 开始就已经过时了。替换函数为completion-at-point
.
现在,如果您开始查看 completion-at-point
在 shell 脚本缓冲区中实际执行的操作,无论如何您最终都会进入 comint。特别是,函数 comint--match-partial-filename
看起来很有希望解释您所描述的行为。
如果我没看错的话,这里的问题是“=”被认为是文件名的有效部分,至少在类似 POSIX 的系统上是这样(参见变量 comint-file-name-chars
)。因此,完成机制正在尝试完成它显然找不到的文件名 "inputfile=/..."。
如果您从不在文件名中使用“=”(或者您很少使用它以致工作完成超过其他缺点),您可能需要考虑在 shell 脚本模式挂钩(如果您在 POSIX 系统上;在 Windows 上它看起来会略有不同)。
希望对您有所帮助。
正在编辑 Bash 脚本我想将文件名分配给变量。
例如输入文件=foo.txt
与标准。设置 如果不先在“=”之后插入 space,我无法完成文件名。
有什么解决办法吗?
你可以使用 bash-completion
假设你不在 windows。它只需要稍作修改即可在 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)
首先,comint-dynamic-complete
从 Emacs 24.1 开始就已经过时了。替换函数为completion-at-point
.
现在,如果您开始查看 completion-at-point
在 shell 脚本缓冲区中实际执行的操作,无论如何您最终都会进入 comint。特别是,函数 comint--match-partial-filename
看起来很有希望解释您所描述的行为。
如果我没看错的话,这里的问题是“=”被认为是文件名的有效部分,至少在类似 POSIX 的系统上是这样(参见变量 comint-file-name-chars
)。因此,完成机制正在尝试完成它显然找不到的文件名 "inputfile=/..."。
如果您从不在文件名中使用“=”(或者您很少使用它以致工作完成超过其他缺点),您可能需要考虑在 shell 脚本模式挂钩(如果您在 POSIX 系统上;在 Windows 上它看起来会略有不同)。
希望对您有所帮助。