Snažím se psát dokončovací funkce pro některé vlastní funkce, které jsem napsal, ale zdá se, že opravdu bojuji i s těmi nejzákladnějšími.
Příklad funkce je:
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"
}
To má dva poziční argumenty, <aws profile name>
a <environment name>
Chci možnosti dokončení pro <aws profile name>
být dynamicky dostupný spuštěnímsed -n -E 's/[([a-zA-Z0-9_-]+)]/1/p' ~/.aws/credentials | tr \n ' '
a dokončení pro <environment name>
být dynamicky dostupný spuštěním jiné funkce, kterou jsem nazval eb_names
.
Dokumentace mi připadá dost řídká a těžko sledovatelná. Také jsem viděl repo zsh-completions pro podobné příkazy, ale zdá se, že nemohu najít něco podobného tomu, co potřebuji.
Jakákoli pomoc do začátku by byla velmi oceněna!
Aktualizovat
Na základě odpovědi @cuonglm jsem použil:
#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]"
V původní otázce jsem zapomněl zmínit, že jsem také chtěl, aby dokončení druhého argumentu záviselo na prvním argumentu (oba jsou dynamicky založené na provádění nějakého kódu), například:
$ eb_instances <cursor>TAB
cuonglm test
dostane dokončení, které chci. Jakmile vyberu, řeknu první a pokusím se o automatické dokončení:
$ eb_instances cuonglm <cursor>TAB
Chci vygenerovat možnosti dokončení spuštěním eb_names cuonglm
, a pokud je to možné, také rozbalení dokončených položek, například pokud byl správný kandidát foo-bar
,
$ eb_instances cuonglm foo<cursor>TAB
Chci vygenerovat možnosti dokončení spuštěním eb_names cuonglm foo
Přijatá odpověď:
Napoprvé se zdá, že zsh Completion System je velmi složitý a obtížně uchopitelný. Zkusme příklad.
První věc, kterou potřebujete vědět, zsh
dokončovací systém načte dokončovací funkce z $fpath
. Ujistěte se, že se váš adresář dokončení zobrazuje v:
print -rl -- $fpath
(Pokud jste použili oh-my-zsh, je zde .oh-my-zsh/completions
existoval v $fpath
, stačí jej vytvořit a vložit tam své dokončovací funkce)
Nyní musíte vytvořit soubor dokončení pro vaši funkci, jeho název musí začínat podtržítkem _
, plus název vaší funkce. Ve vašem případě je jeho název _eb_instances
.
Přidejte tyto řádky do _eb_instances
soubor:
#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]"
Jsi hotov. Uložte soubor a spusťte novou relaci pro dokončení testu. Uvidíte něco takového:
$ eb_instances <cursor>TAB
cuonglm test
$ eb_instances cuonglm <cursor>TAB
dev prod staging
Můžete si přečíst dokumentaci systému pro dokončení zsh o _arguments
funkce, state
variabilní. Také musíte změnit (cuonglm test)
s vaším sed
příkaz a změna prod staging dev
na vaše eb_names
funkce.
Pokud chcete vygenerovat základ 2. argumentů na základě toho, co předal 1. argument, můžete použít $words[2]
proměnná:
case $state in
(aws_profile) _arguments '1:profiles:(cuonglm test)' ;;
(*) compadd "[email protected]" $(echo $words[2]) ;;
esac
Nahraďte echo
s vaší skutečnou funkcí je to ve vašem případě $(eb_names $words[2])
.
Pokud se stále cítíte obtížné toho dosáhnout, definujte _eb_instances
a eb_instances
ve vašem .zshrc
pak dokončení volání jako:
compdef _eb_instances eb_instances
Musíte inicializovat systém dokončení pomocí:
autoload -U compinit
compinit
(Pokud jste použili oh-my-zsh
, byl načten)