Zsh

禁用gem命令的zsh“智能”自動補全,但保持普通路徑補全

  • November 12, 2021

我在執行 macOS 12.0.1 並嘗試bashzsh. 當我嘗試發出類似以下命令的內容時:

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=

和 hit TAB,我沒有完成;我只是從終端視窗標題中得到似乎在 and 之間來回顛簸的ruby東西zsh;大約三秒鐘(和三下)後,我的游標又回來了。

從一個恰當的時機ctrl-C來看,它似乎呼叫了一個 shell 函式_gem,定義在/usr/share/zsh/5.8/functions/_gem.

我假設zsh正在嘗試在這裡做一些聰明的事情,但無論它是什麼,它都不起作用,我不需要它,而且我不在乎為什麼它在我的特定案例或這個特定係統上不起作用(自製軟體、RVM 等等)。我只想要普通的文件/目錄完成。

有沒有辦法禁用這個特定的zsh功能,而不是把它撕掉/usr/share/zsh(它可能會被下一次作業系統更新放回去)?

假設您使用的是“新”(1990 年代)補全系統,即compinit在您的.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=

引用自:https://unix.stackexchange.com/questions/677280