Ich versuche, Vervollständigungsfunktionen für einige von mir geschriebene benutzerdefinierte Funktionen zu schreiben, scheine aber selbst mit den grundlegendsten zu kämpfen.
Eine Beispielfunktion ist:
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"
}
Dies hat zwei Positionsargumente, <aws profile name>
und <environment name>
Ich möchte die Vervollständigungsoptionen für <aws profile name>
dynamisch verfügbar sein, indem Sie sed -n -E 's/[([a-zA-Z0-9_-]+)]/1/p' ~/.aws/credentials | tr \n ' '
, und die Vervollständigungen für <environment name>
um dynamisch verfügbar zu sein, indem eine andere Funktion ausgeführt wird, die ich eb_names
genannt habe .
Ich finde die Dokumentation ziemlich spärlich und schwer nachzuvollziehen. Ich habe auch das zsh-completions-Repo für ähnliche Befehle gesehen, kann aber scheinbar nichts finden, was dem entspricht, was ich brauche.
Jede Hilfe beim Einstieg wäre sehr willkommen!
Aktualisieren
Basierend auf der Antwort von @cuonglm habe ich verwendet:
#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]"
Was ich in der ursprünglichen Frage vergessen hatte zu erwähnen, war, dass ich auch wollte, dass die Vervollständigung des zweiten Arguments vom ersten abhängig ist (beide davon basieren auf dynamischer Ausführung von Code), zum Beispiel:
$ eb_instances <cursor>TAB
cuonglm test
bekommt die Vervollständigungen, die ich will. Sobald ich das erste auswähle, sage ich und versuche es automatisch zu vervollständigen:
$ eb_instances cuonglm <cursor>TAB
Ich möchte die Vervollständigungsoptionen generieren, indem ich eb_names cuonglm
ausführe , und wenn möglich, auch Drilldown zu den Vervollständigungen, zum Beispiel wenn der richtige Kandidat foo-bar
war ,
$ eb_instances cuonglm foo<cursor>TAB
Ich möchte die Vervollständigungsoptionen generieren, indem ich eb_names cuonglm foo
ausführe
Akzeptierte Antwort:
Das zsh Completion System erscheint auf den ersten Blick sehr komplex und schwer verständlich. Lassen Sie es ein Beispiel versuchen.
Das erste, was Sie wissen müssen, zsh
Das Vervollständigungssystem lädt Vervollständigungsfunktionen von $fpath
. Stellen Sie sicher, dass Ihr Vervollständigungsverzeichnis in:
print -rl -- $fpath
(Wenn Sie oh-my-zsh verwendet haben, gibt es .oh-my-zsh/completions
existierte in $fpath
, Sie können es einfach erstellen und Ihre Vervollständigungsfunktionen dort ablegen)
Jetzt müssen Sie eine Vervollständigungsdatei für Ihre Funktion erstellen, deren Name mit dem Unterstrich _
beginnen muss , plus Ihren Funktionsnamen. In Ihrem Fall lautet der Name _eb_instances
.
Fügen Sie diese Zeilen zu _eb_instances
hinzu Datei:
#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]"
Du bist fertig. Speichern Sie die Datei und starten Sie eine neue Sitzung, um den Abschluss zu testen. Sie werden so etwas sehen:
$ eb_instances <cursor>TAB
cuonglm test
$ eb_instances cuonglm <cursor>TAB
dev prod staging
Sie können die Dokumentation des zsh-Vervollständigungssystems über _arguments
lesen Funktion, state
Variable. Außerdem müssen Sie (cuonglm test)
ändern mit Ihrem sed
Befehl und ändern Sie prod staging dev
zu Ihren eb_names
Funktion.
Wenn Sie das zweite Argument basierend auf dem übergebenen ersten Argument generieren möchten, können Sie $words[2]
verwenden Variable:
case $state in
(aws_profile) _arguments '1:profiles:(cuonglm test)' ;;
(*) compadd "[email protected]" $(echo $words[2]) ;;
esac
Ersetzen Sie echo
mit Ihrer eigentlichen Funktion ist es in Ihrem Fall $(eb_names $words[2])
.
Wenn Sie sich immer noch schwer tun, dies zu erreichen, definieren Sie einfach _eb_instances
und eb_instances
in Ihrer .zshrc
Rufen Sie dann die Vervollständigung auf als:
compdef _eb_instances eb_instances
Sie müssen das Vervollständigungssystem initialisieren mit:
autoload -U compinit
compinit
(Wenn Sie oh-my-zsh
verwendet haben , es wurde geladen)