Estoy tratando de escribir funciones de finalización para algunas funciones personalizadas que escribí, pero parece que tengo problemas incluso con las más básicas.
Una función de ejemplo es:
function eb_instances() {
if [ "$#" -ne 2 ]; then
echo "Usage eb_instances <aws profile name> <environment name>"
echo "e.g.:"
echo " eb_instances production kraken-prod-api"
return 1
fi
aws ec2 describe-instances --filters "Name=instance-state-name,Values=running" "Name=tag:Name,Values=$2" --profile=$1 --output=json | jq -r ".Reservations[].Instances[].PrivateIpAddress"
}
Esto tiene dos argumentos posicionales, <aws profile name>
y <environment name>
Quiero las opciones de finalización para <aws profile name>
para estar disponible dinámicamente ejecutandosed -n -E 's/[([a-zA-Z0-9_-]+)]/1/p' ~/.aws/credentials | tr \n ' '
y las terminaciones para <environment name>
para estar disponible dinámicamente al ejecutar otra función que he llamado eb_names
.
Estoy encontrando la documentación bastante escasa y difícil de seguir. También he visto el repositorio zsh-completions para comandos similares, pero parece que no puedo encontrar algo similar a lo que necesito.
¡Cualquier ayuda para empezar sería muy apreciada!
Actualizar
Basado en la respuesta de @cuonglm, usé:
#compdef ebinstances
_ebinstances() {
local state
_arguments
'1: :->aws_profile'
'*: :->eb_name'
case $state in
(aws_profile) _arguments '1:profiles:($(sed -n -E "s/[([a-zA-Z0-9_-]+)]/1/p" ~/.aws/credentials | tr \n " "))' ;;
(*) compadd "[email protected]" foo bar
esac
}
_ebinstances "[email protected]"
Lo que olvidé mencionar en la pregunta original fue que también quería que la finalización del segundo argumento dependiera del primero (ambos se basan dinámicamente en la ejecución de algún código), por ejemplo:
$ eb_instances <cursor>TAB
cuonglm test
obtiene las terminaciones que quiero. Una vez que seleccione, diga el primero e intente completar automáticamente:
$ eb_instances cuonglm <cursor>TAB
Quiero generar las opciones de finalización ejecutando eb_names cuonglm
y, si es posible, también, profundizar en las finalizaciones, por ejemplo, si el candidato correcto era foo-bar
,
$ eb_instances cuonglm foo<cursor>TAB
Quiero generar las opciones de finalización ejecutando eb_names cuonglm foo
Respuesta aceptada:
Al principio, el sistema de finalización zsh parece ser muy complejo y difícil de entender. Vamos a probar un ejemplo.
Lo primero que debes saber, zsh
el sistema de finalización cargará las funciones de finalización desde $fpath
. Asegúrese de que su directorio de finalizaciones aparezca en:
print -rl -- $fpath
(Si usó oh-my-zsh, hay .oh-my-zsh/completions
existía en $fpath
, puede simplemente crearlo y poner sus funciones de finalización allí)
Ahora, debe crear un archivo de finalización para su función, su nombre debe comenzar con un guión bajo _
, más el nombre de su función. En tu caso, su nombre es _eb_instances
.
Agregue estas líneas a _eb_instances
archivo:
#compdef eb_instances
_eb_instances() {
local state
_arguments
'1: :->aws_profile'
'*: :->eb_name'
case $state in
(aws_profile) _arguments '1:profiles:(cuonglm test)' ;;
(*) compadd "[email protected]" prod staging dev
esac
}
_eb_instances "[email protected]"
Estás listo. Guarde el archivo e inicie una nueva sesión para probar la finalización. Verá algo como esto:
$ eb_instances <cursor>TAB
cuonglm test
$ eb_instances cuonglm <cursor>TAB
dev prod staging
Puede leer la documentación del sistema de finalización zsh sobre _arguments
función, state
variable. También debe cambiar (cuonglm test)
con tu sed
comando y cambio prod staging dev
a sus eb_names
función.
Si desea generar el segundo argumento basado en el primer argumento pasado, puede usar $words[2]
variables:
case $state in
(aws_profile) _arguments '1:profiles:(cuonglm test)' ;;
(*) compadd "[email protected]" $(echo $words[2]) ;;
esac
Reemplazar echo
con su función real, en su caso, es $(eb_names $words[2])
.
Si todavía te cuesta lograr esto, simplemente define _eb_instances
y eb_instances
en su .zshrc
luego llame a la finalización como:
compdef _eb_instances eb_instances
Debe inicializar el sistema de finalización con:
autoload -U compinit
compinit
(Si usaste oh-my-zsh
, ha sido cargado)