如何將(函數)第二個參數的 Zsh 自動完成規則設定為現有命令的規則?

如何將(函數)第二個參數的 Zsh 自動完成規則設定為現有命令的規則?

我有自訂 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

我發現/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變數。

答案3

這就是我要做的:

_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

相關內容