既存のコマンドのルールに、関数の 2 番目の引数の Zsh 自動補完ルールを設定するにはどうすればよいですか?

既存のコマンドのルールに、関数の 2 番目の引数の 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...

これは、カスタムの短いコマンドを Git コマンドにマッピングしているため、単にgオートコンプリートを設定するだけではありません。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

ただし、これは zsh の補完ではなく、Git の補完を使用しています。

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

関連情報