¿Cómo puedo autocompletar cada parámetro de forma diferente?

¿Cómo puedo autocompletar cada parámetro de forma diferente?

Tengo una función llamada load_pg, que se define así:

load_pg () {
    pg_restore --verbose --clean --no-acl --no-owner -h localhost -U $1 -d $2 $3
}

Y estoy intentando autocompletar cada parámetro, con el siguiente código:

#compdef load_pg
_arguments -s \
  "1::_ldpguser" \
  "2::_ldpgdb" \
  "3::_ldpgfile"

_ldpguser () {
  compadd $USER
}

_ldpgdb () {
  compadd $(cat config/database.yml | grep -i database | awk '{print $2}')
}

_ldpgfile () {
  compadd $(ls *.dump*)
}

Desafortunadamente, no sucede nada cuando presiono TAB. ¿Qué estoy haciendo mal? Intenté usar el código delsiguiente respuesta

Respuesta1

Primer obstáculo: la sintaxis de un argumento _argumentses donde no se permite que esté vacío. Si agrega un mensaje, verá algunos avances:n:message:actionmessage

_arguments -s \
  "1:username:_ldpguser" \
  "2:database:_ldpgdb" \
  "3:dump file:_ldpgfile"

El siguiente obstáculo es que las funciones auxiliares se definen después de _argumentslas ejecuciones, por lo que la primera vez que complete los argumentos recibirá un mensaje de error quejándose de que una de las funciones no existe. Defina las funciones antes de usarlas. Mejor, haga explícita la definición de la _load_pgfunción y llámela al final del archivo cargado automáticamente. Esto parece torpe, pero es la forma en que se escriben la mayoría de las funciones de finalización multifunción enviadas con zsh.

#compdef load_pg

_ldpguser () {
  compadd $USER
}

_ldpgdb () {
  compadd $(cat config/database.yml | grep -i database | awk '{print $2}')
}

_ldpgfile () {
  compadd $(ls *.dump*)
}

_load_pg () {
  _arguments -s \
    "1:user:_ldpguser" \
    "2:database:_ldpgdb" \
    "3:dump file:_ldpgfile"
}

_load_pg "$@"

Esto le proporciona el núcleo de la función. Luego querrás limpiar las funciones individuales. A lo mínimo:

  • compadd $USERParece inútil: si solo desea llamar a la función con su nombre de usuario, ¿por qué no incorporarla? Para completar los nombres de usuario, llame al _users.
  • La sustitución de comandos sustituye a todos los espacios en blanco. Para dividir líneas, utilice @yf banderas de expansión de parámetros. Probablemente también deberías hacer que tu grepcomando sea más preciso y es posible que puedas combinarlo con grep.
  • Cuando llames compadda una acción desde _arguments, pásale las opciones contextuales en $expl.
  • Es posible que desee proporcionar una descripción para las terminaciones con_describe.
  • $(ls *.dump*)es una forma complicada de escribir " *.dump*, y si no hay coincidencia, haga algo que dependa de la configuración actual del shell".No analices la salida dels, mmm ¿vale? Podrías usarN calificador globaltener una lista vacía de finalizaciones cuando no hay coincidencias. Sin embargo, en su lugar deberías llamar_filesque se encarga de completar archivos en subdirectorios, entre otras sutilezas.
#compdef load_pg

_ldpgdb () {
  compadd $expl[@] -- "${(@f)$(<config/database.yml grep -i database | awk '{print $2}')}"
}

_load_pg () {
  _arguments -s \
    '1:user:_users' \
    '2:database:_ldpgdb' \
    '3:dump file:_files -g "*.dump*"'
}

_load_pg "$@"

información relacionada