zsh:命令名和文件名的单独补全

Bro*_*ack 5 command-line zsh terminal autocomplete

我不希望文件名选项卡完成优先考虑文件名的开头。例如,给定文件名 red_blue.txt 和 blue_red.txt,我不希望 vim redtab优先考虑 red_blue.txt

这可以通过使用:

zstyle ':completion:*' matcher-list 'm:{a-zA-Z}={A-Za-z} l:|=* r:|=*'
Run Code Online (Sandbox Code Playgroud)

但是,此行为也适用于我不想要的命令名称的制表符完成。例如,键入 nittab查找命令“nitrogen”也将匹配诸如 mkinitcpio、xinit、compinit 和其他各种命令。

对于命令,我希望完成使用:

zstyle ':completion:*' matcher-list 'm:{a-zA-Z}={A-Za-z}'
Run Code Online (Sandbox Code Playgroud)

如何让 zsh 选项卡完成以不同的方式处理命令名和文件名?

Gil*_*il' 2

一般来说,您需要细化zstyle调用,使其不适用于所有完成,而仅适用于文件完成。对于普通完成,上下文说明符的语法是。:completion:WIDGET:COMPLETER:COMMAND:ARGUMENT:TAG

  • WIDGET仅由一些特殊的小部件设置,保留通用 ( *)。
  • COMPLETER用于complete正常完成,并且可以为任务(例如自动更正)设置其他值。
  • COMMAND通常是其参数正在完成的命令的名称。更准确地说,是后面的那个词compdef。一些复杂的命令会在完成子命令时更改它。对于 shell 语法中的特殊位置,它是破折号之间的上下文名称,例如命令中第一个单词的-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}'
Run Code Online (Sandbox Code Playgroud)