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 _arguments
es donde no se permite que esté vacío. Si agrega un mensaje, verá algunos avances:n:message:action
message
_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 _arguments
las 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_pg
funció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 $USER
Parece 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 tugrep
comando sea más preciso y es posible que puedas combinarlo congrep
. - Cuando llames
compadd
a 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_files
que 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 "$@"