使用 shell 功能自动完成

使用 shell 功能自动完成

功能zshcn

function cn() {
    nmcli device wifi connect "$1" --ask
}

foo如果您键入,将提示输入密码并连接到网络

cn foo

但它不会自动完成foo,就像您完整编写 nmcli 命令时一样。如何自动完成网络名称?

我正在使用 zsh 5.7.1。

答案1

在这种特定情况下,最简单的方法是:将其设置为别名。这是可能的,因为您可以将其放在--ask网络名称之前。默认情况下,Zsh 在完成完成之前扩展别名。

alias cn='nmcli device wifi connect --ask'

如果您使用函数,则需要向 zsh 传授该函数的参数:为 指定一个完成函数cn,该函数可能是也可能不是自定义函数,具体取决于它要执行的操作。 (我假设您正在使用“新的完成系统”,即您的compinit. .zshrc

这里的函数是另一个命令的简单包装。那么看看这个命令的参数是如何完成的。

% echo $_comps[nmcli]
_networkmanager

对于大多数命令,完成函数的名称是前面带有下划线的命令名称,但对于nmcli,在最近的 zsh 版本中,它是一个不同的名称。 (可能是_nmcli在您的系统上。)接下来,查看源代码看看这个函数是如何工作的。看如何查找 zsh 补全定义了解更多信息。

您不需要了解所有内容(祝您好运:完成系统很复杂!),但对于大多数命令来说,弄清楚特定子命令或选项是如何完成的相当容易。在 zsh ≥5.5 中,它是函数_nm_device_wifi_connect这又调用_nm_device_wifi_ssids。在 zsh ≤5.4 中,我认为_nmcli不支持这种特定的命令行语法(语法nmcli不断变化,因此当 zsh 发布版本时,其nmcli完成代码往往已经过时)。

当 zsh ≥5.5 时,可以_nm_device_wifi_ssids关联cn.然而,有一个问题:如果你cn在没有完成的情况下第一次完成nmcli,zsh将不知道在哪里找到_nm_device_wifi_ssids,因为完成函数是按需加载的,并且这种机制只知道如何找到主函数_networkmanager,而不知道如何找到辅助函数,例如_nm_XXX.看我可以在另一个 ZSH 完成文件中使用辅助函数吗覆盖并重用 zsh 中的现有函数了解如何解决这个问题。

这里zsh 5.5功能的代码很简单,而zsh 5.4反正没有对应的功能。因此,最简单的解决方案是将 zsh 5.5 代码的相关部分复制到新函数中。

function _cn {
    compadd -- ${(f)"$(_call_program nmcli nmcli -t -f ssid device wifi list)"}
}
compdef `_cn` cn

相关内容