如何修复company-mode中可执行文件的自动补全问题?
Eshell中company-mode补全丢失
./前缀导致命令执行错误的解决方法 问题描述
近期使用启用了company-mode的Doom Emacs,在Eshell中自动补全当前目录下的可执行文件时(输入./progr后按回车),补全后的命令会丢失./前缀,变成program而非预期的./program。执行该命令时出现错误提示:Wrong type argument: sequencep, 771。
原因分析
这是由于company-mode的Eshell补全后端(company-eshell)在处理相对路径前缀时存在逻辑问题,它会自动剥离掉./这类相对路径标识,导致Eshell无法识别这是当前目录下的可执行文件,转而在系统PATH中查找,最终找不到命令触发错误。
修复方法
方法1:自定义company-eshell的补全处理逻辑
在Doom Emacs配置文件(~/.doom.d/config.el)中添加以下代码,修改补全候选项处理逻辑,保留./前缀:(advice-add 'company-eshell--candidates :filter-return (lambda (candidates) (let ((prefix (company-grab-symbol))) (if (string-prefix-p "./" prefix) (mapcar (lambda (c) (concat "./" c)) candidates) candidates))))方法2:临时禁用Eshell中的company-mode
如果不需要在Eshell中使用company-mode,可直接关闭:(add-hook 'eshell-mode-hook (lambda () (company-mode -1)))方法3:使用Eshell原生补全替代company-mode
修改Eshell的TAB按键绑定,使用原生补全而非company-mode:(add-hook 'eshell-mode-hook (lambda () (define-key eshell-mode-map (kbd "<tab>") 'eshell-pcomplete)))
栈追踪信息
开启toggle-debug-on-error后得到的错误栈:
error("%s: command not found" "program") eshell-find-interpreter("program" nil nil) eshell-external-command("program" nil) eshell-plain-command("program" nil) eshell-named-command("program") eval((eshell-named-command '"program")) eshell-do-eval((eshell-named-command '"program") nil) eshell-do-eval((prog1 (eshell-named-command '"program") (mapc #'funcall eshell-this-command-hook)) nil) (condition-case err (eshell-do-eval '(prog1 (eshell-named-command '"program") (mapc #'funcall eshell-this-command-hook)) nil) ((debug error) (mapc #'funcall eshell-this-command-hook) (eshell-errorn (error-message-string err)) (eshell-close-handles 1))) eval((condition-case err (eshell-do-eval '(prog1 (eshell-named-command '"program") (mapc #'funcall eshell-this-command-hook)) nil) ((debug error) (mapc #'funcall eshell-this-command-hook) (eshell-errorn (error-message-string err)) (eshell-close-handles 1)))) eshell-do-eval((condition-case err (eshell-do-eval '(prog1 (eshell-named-command '"program") (mapc #'funcall eshell-this-command-hook)) nil) ((debug error) (mapc #'funcall eshell-this-command-hook) (eshell-errorn (error-message-string err)) (eshell-close-handles 1))) nil) #f(compiled-function () #<bytecode -0x13dc3821b05c18d2>)() funcall(#f(compiled-function () #<bytecode -0x13dc3821b05c18d2>)) (let ((eshell-this-command-hook '(ignore))) (funcall '#f(compiled-function () #<bytecode -0x13dc3821b05c18d2>))) eval((let ((eshell-this-command-hook '(ignore))) (funcall '#f(compiled-function () #<bytecode -0x13dc3821b05c18d2>)))) eshell-do-eval((let ((eshell-this-command-hook '(ignore))) (condition-case err (eshell-do-eval '(prog1 (eshell-named-command '"program") (mapc #'funcall eshell-this-command-hook)) nil) ((debug error) (mapc #'funcall eshell-this-command-hook) (eshell-errorn (error-message-string err)) (eshell-close-handles 1)))) nil) eshell-do-eval((progn (let ((eshell-this-command-hook '(ignore))) (condition-case err (eshell-do-eval '(prog1 (eshell-named-command ...) (mapc ... eshell-this-command-hook)) nil) ((debug error) (mapc #'funcall eshell-this-command-hook) (eshell-errorn (error-message-string err)) (eshell-close-handles 1))))) nil) (catch 'top-level (eshell-do-eval '(progn (let ((eshell-this-command-hook '...)) (condition-case err (eshell-do-eval '... nil) ((debug error) (mapc ... eshell-this-command-hook) (eshell-errorn ...) (eshell-close-handles 1))))) nil)) eval((catch 'top-level (eshell-do-eval '(progn (let ((eshell-this-command-hook ...)) (condition-case err (eshell-do-eval ... nil) (... ... ... ...)))) nil))) eshell-do-eval((catch 'top-level (eshell-do-eval '(progn (let ((eshell-this-command-hook ...)) (condition-case err (eshell-do-eval ... nil) (... ... ... ...)))) nil)) nil) eshell-do-eval((progn 'nil (catch 'top-level (eshell-do-eval '(progn (let (...) (condition-case err ... ...))) nil)) (run-hooks 'eshell-post-command-hook)) nil) #f(compiled-function () #<bytecode -0x13dc3821b05c18d2>)() funcall(#f(compiled-function () #<bytecode -0x13dc3821b05c18d2>)) (let ((eshell-current-handles '[nil (t . 1) (t . 1)]) (eshell-current-subjob-p 'nil)) (funcall '#f(compiled-function () #<bytecode -0x13dc3821b05c18d2>))) eval((let ((eshell-current-handles '[nil (t . 1) (t . 1)]) (eshell-current-subjob-p 'nil)) (funcall '#f(compiled-function () #<bytecode -0x13dc3821b05c18d2>)))) eshell-do-eval((let ((eshell-current-handles '[nil (t . 1) (t . 1)]) eshell-current-subjob-p) (progn 'nil (catch 'top-level (eshell-do-eval '(progn (let ... ...)) nil)) (run-hooks 'eshell-post-command-hook)))) eshell-resume-eval() eshell-eval-command((let ((eshell-current-handles '[nil (t . 1) (t . 1)]) eshell-current-subjob-p) (progn 'nil (catch 'top-level (eshell-do-eval '(progn (let ... ...)) nil)) (run-hooks 'eshell-post-command-hook))) "program") eshell-send-input(nil) funcall-interactively(eshell-send-input nil) command-execute(eshell-send-input)
内容的提问来源于Stack Exchange,提问作者Crowl
相关产品推荐
相关产品推荐

