J'essaie d'écrire des fonctions de complétion pour certaines fonctions personnalisées que j'ai écrites, mais je semble vraiment avoir du mal avec les plus basiques.
Un exemple de fonction est :
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"
}
Cela a deux arguments de position, <aws profile name>
et <environment name>
Je veux les options d'achèvement pour <aws profile name>
être disponible dynamiquement en exécutantsed -n -E 's/[([a-zA-Z0-9_-]+)]/1/p' ~/.aws/credentials | tr \n ' '
, et les complétions pour <environment name>
être disponible dynamiquement en exécutant une autre fonction que j'ai appelée eb_names
.
Je trouve la documentation assez clairsemée et difficile à suivre. J'ai également vu le référentiel zsh-completions pour des commandes similaires, mais je n'arrive pas à trouver quelque chose de similaire à ce dont j'ai besoin.
Toute aide pour démarrer serait très appréciée !
Mettre à jour
D'après la réponse de @cuonglm, j'ai utilisé :
#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]"
Ce que j'ai oublié de mentionner dans la question d'origine, c'est que je voulais aussi que l'achèvement du deuxième argument dépende du premier (qui sont tous deux basés sur l'exécution dynamique de code), par exemple :
$ eb_instances <cursor>TAB
cuonglm test
obtient les finitions que je veux. Une fois que j'ai sélectionné, dites le premier et essayez de compléter automatiquement :
$ eb_instances cuonglm <cursor>TAB
Je souhaite générer les options de complétion en exécutant eb_names cuonglm
, et si possible, également, analysez les complétions, par exemple si le bon candidat était foo-bar
,
$ eb_instances cuonglm foo<cursor>TAB
Je souhaite générer les options de complétion en exécutant eb_names cuonglm foo
Réponse acceptée :
À première vue, zsh Completion System semble être très complexe et difficile à appréhender. Essayons un exemple.
Première chose que vous devez savoir, zsh
le système de complétion chargera les fonctions de complétion depuis $fpath
. Assurez-vous que votre répertoire de complétions apparaît dans :
print -rl -- $fpath
(Si vous avez utilisé oh-my-zsh, il y a .oh-my-zsh/completions
existait dans $fpath
, vous pouvez simplement le créer et y mettre vos fonctions de complétion)
Maintenant, vous devez créer un fichier de complétion pour votre fonction, son nom doit commencer par le trait de soulignement _
, plus le nom de votre fonction. Dans votre cas, son nom est _eb_instances
.
Ajoutez ces lignes à _eb_instances
fichier :
#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]"
Vous avez terminé. Enregistrez le fichier et démarrez une nouvelle session pour tester l'achèvement. Vous verrez quelque chose comme ceci :
$ eb_instances <cursor>TAB
cuonglm test
$ eb_instances cuonglm <cursor>TAB
dev prod staging
Vous pouvez lire la documentation du système de complétion zsh à propos de _arguments
fonction, state
variable. Vous devez également modifier (cuonglm test)
avec votre sed
commandez et modifiez prod staging dev
à vos eb_names
fonction.
Si vous souhaitez générer le 2ème argument basé sur le 1er argument passé, vous pouvez utiliser $words[2]
variables :
case $state in
(aws_profile) _arguments '1:profiles:(cuonglm test)' ;;
(*) compadd "[email protected]" $(echo $words[2]) ;;
esac
Remplacer echo
avec votre vraie fonction, dans votre cas, c'est $(eb_names $words[2])
.
Si vous avez encore du mal à accomplir cela, définissez simplement _eb_instances
et eb_instances
dans votre .zshrc
puis appelez l'achèvement comme :
compdef _eb_instances eb_instances
Vous devez initialiser le système de complétion avec :
autoload -U compinit
compinit
(Si vous avez utilisé oh-my-zsh
, il a été chargé)