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)