如何将(函数的)第二个参数的Zsh自动完成规则设置为现有命令的规则?


9

我有一个自定义的Zsh函数g

function g() {
  # Handle arguments [...]
}

在其中,我处理执行Git命令的简短参数。例如:

g ls # Executes git ls-files ...
g g  # Executes git grep ...

我需要能够为简短参数将自动完成规则设置为Git的规则,但是我不确定如何执行此操作。

例如,我需要g ls <TAB>制表完成规则,git ls-files <TAB>这些规则将为我提供以下参数git ls-files

$ g ls --<TAB>
--abbrev                 -- set minimum SHA1 display-length
--cached                 -- show cached files in output
--deleted                -- show deleted files in output
# Etc...

这并不是简单地设置g为自动完成,git因为我正在将自定义的简短命令映射到Git命令。


1
如果您的函数仅将较短的名称映射到git子命令,则也可以使用git别名系统。阅读关于它的联机帮助页:man git-config
卢卡斯

Answers:


3

我发现/usr/share/zsh/functions/Completion/Unix/_git其中有一些针对此类别名的提示,最终为别名定义了以下功能:

_git-ls () {
  # Just return the _git-ls-files autocomplete function
  _git-ls-files
}

然后,我做了一个直线compdef g=git。例如,自动完成系统将显示您正在运行,g ls并使用_git-ls自动完成功能。

感谢user67060为我指引了正确的方向。


2

我不得不做一些非常相似的事情,因此这大致可以解决您的问题。

_g () {
    case "${words[2]}" in
      ls) words[1,2]=(git ls-files);;
      g) words[1,2]=(git grep);;
      *) return 1;;
    esac

    _git # Delegate to completion
}
compdef _g g

需要注意的一件事是,如果更改参数数量,则需要调整$CURRENT变量。


1

这就是我要做的:

_tg () {
    local _ret=1
    local cur cword prev

    cur=${words[CURRENT]}
    prev=${words[CURRENT-1]}
    cmd=${words[2]}
    let cword=CURRENT-1

    case "$cmd" in
    ls)
        emulate ksh -c _git_ls_files
        ;;
    g)
        emulate ksh -c _git_grep
        ;;
    esac

    let _ret && _default && _ret=0
    return _ret
}

compdef _tg tg

但是,这使用的是Git的完成,而不是zsh的完成:

https://git.kernel.org/cgit/git/git.git/tree/contrib/completion/git-completion.zsh


谢谢,我最终走了一条不同的路,因为我不知道在哪里可以找到Git完成规则,并且遇到了错误。看我的答案。
Erik Nomitch 2014年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.