4

编辑 Bash 脚本 我想将文件名分配给变量。

例如 inputfile=foo.txt

与标准。如果不先在“=”之后插入空格,我将无法完成文件名。

有什么解决办法吗?

4

2 回答 2

3

首先,comint-dynamic-complete从 Emacs 24.1 开始就已经过时了。替换函数为completion-at-point

现在,如果您开始查看在completion-at-pointshell 脚本缓冲区中实际执行的操作,您最终还是会遇到 comint。特别是,该函数comint--match-partial-filename看起来很有希望解释您描述的行为。

如果我没看错的话,这里的问题是“=”被认为是文件名的有效部分,至少在类似 POSIX 的系统上(参见变量comint-file-name-chars)。因此,完成机制正在尝试完成它显然找不到的文件名“inputfile = / ...”。

如果您从不在文件名中使用“=”(或者您很少使用它,以至于工作完成超过其他缺点),您可能需要考虑(setq comint-file-name-chars "[]~/A-Za-z0-9+@:_.$#%,{}-")在 shell 脚本模式挂钩中执行类似操作(如果您在 POSIX 系统上;在 Windows 上看起来会略有不同)。

希望有帮助。

于 2016-11-25T08:36:53.773 回答
2

您可以使用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)
于 2016-11-24T13:03:44.040 回答