![禁用 gem 命令的 zsh“智能”自动补全,但保留普通路径补全](https://linux22.com/image/198346/%E7%A6%81%E7%94%A8%20gem%20%E5%91%BD%E4%BB%A4%E7%9A%84%20zsh%E2%80%9C%E6%99%BA%E8%83%BD%E2%80%9D%E8%87%AA%E5%8A%A8%E8%A1%A5%E5%85%A8%EF%BC%8C%E4%BD%86%E4%BF%9D%E7%95%99%E6%99%AE%E9%80%9A%E8%B7%AF%E5%BE%84%E8%A1%A5%E5%85%A8.png)
我的 Mac 运行 macOS 12.0.1,并尝试从 切换bash
到zsh
.当我尝试发出类似以下命令时:
gem install pg -v 1.2.3 -- --with-pg_config=/opt/homebrew/opt/libpq/bin/pg_config
如果我能达到
gem install pg -v 1.2.3 -- --with-pg_config=
然后点击TAB
,我没有完成;我只是从终端窗口标题中看到,在ruby
和之间来回颠簸zsh
;大约三秒钟(和三次敲击)后,我恢复了光标。
从一个适时的情况来看,ctrl-C
它似乎调用了一个 shell 函数_gem
,定义在/usr/share/zsh/5.8/functions/_gem
.
我认为zsh
在这里尝试做一些聪明的事情,但无论它是什么,它都不起作用,我不需要它,而且我不关心为什么它在我的特定用例或这个特定系统上不起作用(自制软件、RVM,等等)。我只想要普通的文件/目录完成。
有没有办法禁用这个特定的zsh
功能,而无需将其删除/usr/share/zsh
(无论如何,它可能会在下一个操作系统更新时被放回)?
答案1
compinit
假设您正在使用“新”(1990 年代)完成系统,即在您的.zshrc
(或者在 zsh 配置框架中,如果您使用的是)有一个调用,您可以通过两种方式覆盖标准完成:
- 您可以
_gem
通过将同名函数放置在$fpath
.该目录必须在$fpath
调用之前存在compinit
。 - 您可以致电
compdef
覆盖compinit
已设置的内容。这需要在调用 后完成compinit
。
因此,要在之后完成文件名gem
,请在调用后运行以下命令compinit
:
compdef _files gem
但是,您不需要采取如此严厉的措施。即使 zsh 认为上下文需要其他内容,也有方法可以完成文件。
概念上最简单但不是最方便的方法是暂时更改上下文。例如,键入;l
,填写文件名,然后删除;l
。或者Home 0
End,填写文件名,Home Del End.
你可以绑定_bash_complete-word
以 结尾的键绑定/
,例如^X/
.然后按^X/
任意位置即可完成文件名。在你的情况下,只有当你在 后面放置一个空格--with-pg_config
而不是等号时,这才有效,因为这个小部件不被视为=
分隔符。
您也许可以利用_most_recent_file
,默认绑定^Xm
。无论上下文如何,这都会完成最新的文件名。在你的情况下,只有当你在 后面放置一个空格--with-pg_config
而不是等号时,这才有效,因为这个小部件不被视为=
分隔符。例如:--with-pg_config /o
^Xm
/h
^Xm
/o
^Xm
/*pq
^Xm
…
_complete_files () {
if [[ $PREFIX == [-0-9A-Z_a-z]##=* ]]; then
IPREFIX+=${PREFIX%%\=*}=
PREFIX=${PREFIX#*=}
fi
_main_complete _files
}
zle -C _complete_files complete-word _complete_files
bindkey '\e^F' _complete_files
然后您可以按Ctrl+Alt+F任意位置来完成文件名。无论上下文如何,此函数都会完成当前的 shell 单词,但它会忽略像 之类的前缀--option=
。