Zsh 基于 git 的函数自动补全,为什么 compdef 在 .zshrc 中不起作用?

Zsh 基于 git 的函数自动补全,为什么 compdef 在 .zshrc 中不起作用?

我有一个别名git定义为

alias g=git

有了这个和我的 zsh 和抗原setup,g具有与 相同的自动完成功能git

但是,当我替换g为默认显示 git 状态的函数时

g() {
  if [ "$#" -eq 0 ]; then
    git status --short --branch
  else
    git "$@"
  fi
}

这自然不再起作用了。这同样适用于git-all在子目录中的所有存储库中运行相同 git 命令的函数

git-all() { 
  if [ "$#" -eq 0 ]; then
    find . -maxdepth 3 -type d -name .git -execdir echo \; -execdir pwd \; -execdir git status --short --branch \;
  else
    find . -maxdepth 3 -type d -name .git -execdir echo \; -execdir pwd \; -execdir git "$@" \;
  fi
}
alias ga='git-all'

我希望完成所有这些 、ggit-allga,就像 一样git

文档

如果您希望一个命令(例如 cmd1)与另一个命令(例如 cmd2)具有相同的完成,该命令已经为其定义了完成,您可以这样做:

compdef cmd1=cmd2

所以,我输入

compdef git-all=git

在我当前的zsh会话中,它有效!好的。

因此,我将 compdef 放在.zshrc抗原设置之后(必须zsh-users/zsh-completions初始化完成)以及别名和函数定义之后

if [ -f ~/.antigenrc ]; then
  source ~/.antigenrc
fi

if [ -f ~/.sh_aliases ]; then
  source ~/.sh_aliases
fi

compdef g=git
compdef ga=git
compdef git-all=git

antigen apply

我的 antigenrc 看起来像这样:

source /usr/share/zsh-antigen/antigen.zsh

antigen use oh-my-zsh

antigen bundle gradle/gradle-completion
antigen bundle command-not-found
antigen bundle MikeDacre/cdbk
antigen bundle zsh-users/zsh-completions
antigen bundle zsh-users/zsh-syntax-highlighting

antigen theme ys

然后我启动一个新的 zsh shell。现在完成工作不起作用。

怎么可能?交互式 zsh shell 读取 .zshrc (如果我将 .zshrc 放在echo那里,我会看到输出)。如果我将 compdef 放在抗原设置之前,则会收到有关 compdef 未定义的错误,但是当它们位于最后时,它们不会显示错误,它们只是不起作用。也许抗原正在做一些奇怪的事情,但即便如此,完成是在抗原设置之后定义的,所以抗原不应该把它们弄乱吗?

我还尝试_git 2>/dev/null按照建议添加到我的 .zshrc这里,或compdef '_dispatch git git' g按照建议使用这里,无济于事。

我的zsh版本是5.8。

答案1

我终于弄明白了。看来是有抗原的虫子。还有一个问题在抗原 Github 上,其中包含一个解决方法:

对我来说,修复它的方法是在 .antigen/init.zsh 中注释掉以下几行:

# autoload -Uz add-zsh-hook; add-zsh-hook precmd _antigen_compinit
# compdef () {}

我知道这不是修复它的正确方法,并且它可能会导致一些其他错误,但我大量使用 kubectl,所以我非常需要自动完成

该函数compdef () {}显然不执行任何操作,并且是我的.zshrc.引用的解决方法对我不起作用,因为它是由抗原(重新)生成的,但对我有用的是在我的 s之前.antigen/init.zsh放置:autoload -U +X compinit && compinitcompdef.zshrc

#type compdef #uncomment this to see the problem
autoload -U +X compinit && compinit
#type compdef #uncomment this to see the solution
compdef g=git
compdef ga=git
compdef git-all=git

答案2

正如建议的Github问题评论,一种解决方法(未知后果),您需要在antigen.zshnot中注释以下行.antigen/init.zsh(因为init.zsh每次抗原加载时都会生成)

# autoload -Uz add-zsh-hook; add-zsh-hook precmd _antigen_compinit
# compdef () {}

相关内容