Como defino regras de preenchimento automático Zsh para o segundo argumento (de função) para as regras de um comando existente?

Como defino regras de preenchimento automático Zsh para o segundo argumento (de função) para as regras de um comando existente?

Eu tenhouma função Zsh personalizadag:

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

Nele, eu lido com argumentos curtos que executam comandos do Git. Por exemplo:

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

Preciso ser capaz de definir as regras de preenchimento automático de acordo com as regras do Git para argumentos curtos, mas não tenho certeza de como fazer isso.

Por exemplo, preciso g ls <TAB>preencher com tabulação as regras para git ls-files <TAB>as quais me dariam os argumentos para 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...

Isso não é simplesmente uma configuração gpara preenchimento automático, gitpois estou mapeando meus comandos curtos personalizados para os comandos do Git.

Responder1

Descobri /usr/share/zsh/functions/Completion/Unix/_gitque tinha algumas dicas para aliases como esse e acabei definindo essas funções para os aliases:

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

Aí eu fiz uma reta compdef g=git. O sistema de preenchimento automático verá que você está executando, por exemplo, g lse usará a _git-lsfunção de preenchimento automático.

Obrigado ao user67060 por me orientar na direção certa.

Responder2

Eu tive que fazer algo muito semelhante, então é isso que deve resolver o seu problema.

_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

Uma coisa a observar é que se você alterar o número de argumentos, precisará ajustar a $CURRENTvariável.

Responder3

Isto é o que eu faria:

_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

No entanto, isso está usando a conclusão do Git, não a conclusão do zsh:

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

informação relacionada