如何让我的 shell 函数利用 zsh 中现有的自动完成功能?

Mur*_*iar 9 zsh autocomplete

我在 my.zshrc中定义了几个 shell 函数,它们可以节省打字时间并允许与屏幕集成。例如:

function s()
{
     screen -t "$1" ssh "$@"
}
Run Code Online (Sandbox Code Playgroud)

但是,当我使用这些 shell 函数时,我无法利用 zsh 的内置命令完成功能。(在 SSH 的情况下,根据 known_hosts 和 ssh_config 自动完成主机名)。挂钩到我为其创建包装器的命令的现有完成机制的首选方法是什么?

编辑:

感谢 Gilles 在下面的回答。使用 compdef 似乎是做到这一点的方法,但有趣的是,它似乎并没有统一地工作。在这种情况下,我有以下设置:

function s()
{
    screen -t "$1" ssh "$@"
}

function m()
{
    screen -t "man.$1" man "$1"
}

compdef $_comps[man] m
compdef $_comps[ssh] s
Run Code Online (Sandbox Code Playgroud)

我的包装函数“m”的完成按预期工作,但是我的函数“s”的完成没有;它没有尝试完成主机名,而是通过在我点击“选项卡”时向我提供文件列表来回退到默认自动完成。处理 SSH 完成的方式是否有些奇怪,这意味着我需要进一步做些什么?

Gil*_*il' 9

要请求命令一样,已经知道完成系统的另一个命令完成后,您可以使用compdef my_command=known_command的形式compdef

compdef s=ssh
compdef {cxterm,uxterm,xterm-color}=xterm
Run Code Online (Sandbox Code Playgroud)

在幕后,这基本上相当于_comps[s]=$_comps[ssh].

一些完成命令适用于一系列函数并读取命令行的第一个字以确定要完成哪个特定命令。例如,命令sshscpsftp和几个都是由函数完成_ssh。在这种情况下,您需要告诉完成函数您的函数是什么样的“服务”(默认情况下,服务是可执行文件的名称,这里是您的函数名称)。

_s () {
  local service=ssh
  _ssh "$@"
}
compdef _s s
Run Code Online (Sandbox Code Playgroud)