zsh:完成'command1',与'command2 ARG相同`

zsh:完成'command1',与'command2 ARG相同`,zsh,zsh-completion,Zsh,Zsh Completion,给出两个命令: command1-已经为其设置了完成项 commmand2-这是一个包装函数,它最终调用command1 ARG 如何使command2以与command1 ARG1相同的方式完成,而无需为command1编写自定义完成 下面是一个例子: alias command1="git ls-files" command2() { echo "I'm a wrapper for git ls-files" >&2 git

给出两个命令:

  • command1
    -已经为其设置了完成项
  • commmand2
    -这是一个包装函数,它最终调用
    command1 ARG
如何使
command2
以与
command1 ARG1
相同的方式完成,而无需为
command1
编写自定义完成

下面是一个例子:

alias command1="git ls-files"

command2() {
  echo "I'm a wrapper for git ls-files" >&2
  git ls-files $@
}
可以执行
compdef command2=command1
——但这将使
command2
以与
git
相同的方式完成,而不是像
git ls文件那样完成

Edit:我正在寻找一个广泛而通用的解决方案,该解决方案还可以与不定义独立完成函数(如git)的命令一起使用。 对于这些,您可以按照马龙·里切特的建议进行操作。

这里有一个更好的例子:

alias command1="kubectl get pod"

command2() {
  echo "I'm a wrapper for kubectl get pod" >&2
  kubectl get pod $@
}

执行此操作以查找需要调用的函数的名称:

%git ls files^Xh#也就是说,按Ctrl-X,然后按H。
上下文中的标记:completion::complete:git ls files::
参数rest选项(_参数_git-ls-files _git)
上下文中的标记:completion::complete:git ls files:参数rest:
全局文件(_文件_参数_git-ls-files _git)
上下文中的标记:completion::complete:git::
参数rest(_arguments\u git)
如您所见,它是
\u git-ls-files

然后,丢弃前导的
并将剩余部分用作
compdef
$service
参数:

compdef\u git command2=git ls文件
现在它可以正常工作了:

%command2^Xh
上下文中的标记:completion::complete:command2::
参数rest选项(_参数_git-ls-files _git)
上下文中的标记:completion::complete:command2:参数rest:
全局文件(_文件_参数_git-ls-files _git)

更新 对于您的
kubectl
示例,事情稍微不那么容易,因为它的完成不是Zsh原生的。相反,它只是围绕Bash完成函数的一个薄薄的Zsh包装器。在这种情况下,您必须编写自己的完成函数,但谢天谢地,它将是一个非常简短的函数:

_command2 () {
  # Fake having `kubectl get pod` on the line instead of `command2`.
  local -a words=( kubectl get pod $words[2,-1] )
  local -i CURRENT=$(( CURRENT + 2 ))

  # Call kubectl completion.
  eval "$_comps[kubectl]"
}
compdef _command2 command2

完成了

执行此操作以查找需要调用的函数的名称:

%git ls files^Xh#也就是说,按Ctrl-X,然后按H。
上下文中的标记:completion::complete:git ls files::
参数rest选项(_参数_git-ls-files _git)
上下文中的标记:completion::complete:git ls files:参数rest:
全局文件(_文件_参数_git-ls-files _git)
上下文中的标记:completion::complete:git::
参数rest(_arguments\u git)
如您所见,它是
\u git-ls-files

然后,丢弃前导的
并将剩余部分用作
compdef
$service
参数:

compdef\u git command2=git ls文件
现在它可以正常工作了:

%command2^Xh
上下文中的标记:completion::complete:command2::
参数rest选项(_参数_git-ls-files _git)
上下文中的标记:completion::complete:command2:参数rest:
全局文件(_文件_参数_git-ls-files _git)

更新 对于您的
kubectl
示例,事情稍微不那么容易,因为它的完成不是Zsh原生的。相反,它只是围绕Bash完成函数的一个薄薄的Zsh包装器。在这种情况下,您必须编写自己的完成函数,但谢天谢地,它将是一个非常简短的函数:

_command2 () {
  # Fake having `kubectl get pod` on the line instead of `command2`.
  local -a words=( kubectl get pod $words[2,-1] )
  local -i CURRENT=$(( CURRENT + 2 ))

  # Call kubectl completion.
  eval "$_comps[kubectl]"
}
compdef _command2 command2

完成了

谢谢。虽然这对我的特定示例有效,但还不够一般。这仅在实际存在专门为子命令定义的完成函数时有效。我见过的大多数comp都不是这样实现的。我用第二个例子更新了我的帖子;)@我更新了我的答案,我看到了。我想我会标记这个问题的答案,即使我明确指定:>而不编写自定义补全,但我认为没有一种完美的方式来完成我想要的w/zsh。我可能最终实现了一个包装器函数,该函数以类似于您为kubectl示例建议的方式自动创建comp。谢谢你花时间回答,我真的很感激。你的评论让我意识到我的第二个答案可以更短。我编辑了它;再看看。它可能会帮助您开始使用该通用包装函数。:)谢谢虽然这对我的特定示例有效,但还不够一般。这仅在实际存在专门为子命令定义的完成函数时有效。我见过的大多数comp都不是这样实现的。我用第二个例子更新了我的帖子;)@我更新了我的答案,我看到了。我想我会标记这个问题的答案,即使我明确指定:>而不编写自定义补全,但我认为没有一种完美的方式来完成我想要的w/zsh。我可能最终实现了一个包装器函数,该函数以类似于您为kubectl示例建议的方式自动创建comp。谢谢你花时间回答,我真的很感激。你的评论让我意识到我的第二个答案可以更短。我编辑了它;再看看。它可能会帮助您开始使用该通用包装函数。:)