¿Cómo configuro las reglas de autocompletado de Zsh para el segundo argumento (de función) según las reglas de un comando existente?

¿Cómo configuro las reglas de autocompletado de Zsh para el segundo argumento (de función) según las reglas de un comando existente?

Tengouna función Zsh personalizadag:

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

Dentro de él, manejo argumentos cortos que ejecutan comandos de Git. Por ejemplo:

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

Necesito poder configurar las reglas de autocompletado según las reglas de Git para los argumentos breves, pero no estoy seguro de cómo hacerlo.

Por ejemplo, necesito g ls <TAB>completar con tabuladores las reglas git ls-files <TAB>que me darían los 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...

Esto no es simplemente una configuración gpara autocompletar, gitya que estoy asignando mis comandos cortos personalizados a los comandos de Git.

Respuesta1

Encontré /usr/share/zsh/functions/Completion/Unix/_gitque tenía algunos consejos para alias como este y terminé definiendo estas funciones para los alias:

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

Luego hice una recta compdef g=git. El sistema de autocompletar verá que estás ejecutando, por ejemplo, g lsy utilizará la _git-lsfunción de autocompletar.

Gracias al usuario67060 por guiarme en la dirección correcta.

Respuesta2

Tuve que hacer algo muy similar, así que esto es aproximadamente lo que debería resolver tu 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

Una cosa a tener en cuenta es que si cambia la cantidad de argumentos, deberá ajustar la $CURRENTvariable.

Respuesta3

Esto es lo que yo haría:

_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

Sin embargo, esto utiliza la finalización de Git, no la finalización de zsh:

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

información relacionada