Command-Line

zsh:命令名和文件名的單獨完成

  • April 15, 2018

我不希望文件名選項卡完成優先考慮文件名的開頭。例如,給定文件名 red_blue.txt 和 blue_red.txt,我不希望 vim redtab優先考慮 red_blue.txt

這可以通過使用來完成:

zstyle ':completion:*' matcher-list 'm:{a-zA-Z}={A-Za-z} l:|=* r:|=*'

但是,此行為也適用於命令名稱的製表符完成,這是我不想要的。例如,鍵入 nittab查找命令“nitrogen”也將匹配 mkinitcpio、xinit、compinit 和其他各種命令。

對於命令,我希望使用完成:

zstyle ':completion:*' matcher-list 'm:{a-zA-Z}={A-Za-z}'

如何讓 zsh 選項卡完成以不同方式處理命令名和文件名?

一般來說,您需要細化zstyle呼叫,使其不適用於所有完成,而僅適用於文件完成。對於普通完成,上下文說明符的語法是.:completion:*WIDGET*:*COMPLETER*:*COMMAND*:*ARGUMENT*:*TAG*

  • *WIDGET*僅由一些特殊的小元件設置,保持通用(*)。
  • *COMPLETER*用於complete正常完成,並且可以為任務(例如自動更正)設置其他值。
  • *COMMAND*通常是正在完成其參數的命令的名稱。更準確地說,是後面的詞compdef。一些複雜的命令在完成子命令時會改變它。對於 shell 語法中的特殊位置,它是dash 之間的上下文名稱,例如-parametera 之後$-command-命令中的第一個單詞。
  • *ARGUMENT*通常類似於argument-3第三個非選項參數或選項option--foo-1的參數--foo
  • *TAG*由一些完成函式在內部使用,通常但不總是傳統的標記名稱之一。

zstyle聲明中,更具體的聲明優先於不太具體的聲明。

  • 帶有更多冒號 ( :) 的聲明比帶有更少冒號的聲明更具體。

  • 對於相同數量的列,如果每個以冒號分隔的部分至少與另一個中的相應部分一樣具體,則聲明至少與另一個聲明一樣具體。對於每個部分:

    • *比其他任何東西都更具體。
    • 任何帶有萬用字元的東西都比沒有萬用字元的簡單字元串更具體。

因此,一般來說,要對命令名稱進行例外處理,只需添加另一個zstyle專門針對命令的聲明。

但是,有一個轉折:matcher-list是全域應用的,而不是在完成的上下文中。在您的情況下,只要您只想要一個匹配器,您就可以使用它matcher

zstyle ':completion:*' matcher 'm:{a-zA-Z}={A-Za-z} l:|=* r:|=*'
zstyle ':completion:*:*:-command-:*' matcher 'm:{a-zA-Z}={A-Za-z}'

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