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

9

Tengo una función Zsh personalizadag :

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

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

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

Necesito poder establecer las reglas de autocompletar a las reglas de Git para los argumentos cortos, pero no estoy seguro de cómo hacerlo.

Por ejemplo, necesito g ls <TAB>completar con tabulación las reglas para las git ls-files <TAB>cuales 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 configurar gpara autocompletar, gitya que estoy asignando mis comandos cortos personalizados a los comandos Git.

Erik Nomitch
fuente
1
Si su función solo asigna nombres más cortos a subcomandos git, también puede usar el sistema alias git para esto. Leer sobre él en el mapage: man git-config.
Lucas

Respuestas:

3

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
}

Entonces, hice una escalera compdef g=git. El sistema de autocompletar verá que está ejecutando, por ejemplo, g lsy usará la _git-lsfunción de autocompletar.

Gracias a user67060 por guiarme en la dirección correcta.

Erik Nomitch
fuente
2

Tenía que hacer algo muy similar, así que esto es más o menos lo que debería resolver su 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 necesitará ajustar la $CURRENTvariable.

Kevin Cox
fuente
1

Esto es lo que 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 está usando 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

FelipeC
fuente
Gracias, terminé yendo por una ruta diferente ya que no sabía dónde encontrar las reglas de finalización de Git y recibía errores. Mira mi respuesta.
Erik Nomitch