web-dev-qa-db-ja.com

カスタムコマンドの動的zshオートコンプリート

私が書いたいくつかのカスタム関数の補完関数を書き込もうとしていますが、最も基本的な関数でさえ本当に苦労しているようです。

関数の例は次のとおりです。

_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"
}
_

これには、2つの位置引数、_<aws profile name>_と_<environment name>_があります。

_<aws profile name>_の補完オプションをsed -n -E 's/\[([a-zA-Z0-9_\-]+)\]/\1/p' ~/.aws/credentials | tr \\n ' 'を実行することで動的に利用できるようにして、_<environment name>_の補完を、_eb_names_を呼び出した別の関数を実行することで動的に利用できるようにしたい。

ドキュメンテーションはかなりまばらで、追跡が困難です。同様のコマンドのzsh-completionsリポジトリも確認しましたが、必要なものに似たものを見つけることができません。

どんな手助けも始めていただければ幸いです!

更新

@ cuonglmの答え に基づいて、私は以下を使用しました:

_#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 "$@" foo bar
  esac
}

_ebinstances "$@"
_

私が最初の質問で言及するのを忘れていたのは、2番目の引数の完了も最初の引数に依存するようにしたかったことです(どちらも動的ベースのコードの実行です)。

_$ eb_instances <cursor>TAB
cuonglm  test
_

必要な完了を取得します。最初のものを言って選択し、オートコンプリートを試みます:

_$ eb_instances cuonglm <cursor>TAB
_

_eb_names cuonglm_を実行して補完オプションを生成したいと思います。また、可能であれば、たとえば、正しい候補が_foo-bar_だった場合に、補完をドリルダウンします。

_$ eb_instances cuonglm foo<cursor>TAB
_

_eb_names cuonglm foo_を実行して補完オプションを生成したい

20
zsquare

最初は zsh Completion System は非常に複雑で把握しにくいようです。例を試してみましょう。

最初に知っておく必要があるのは、zsh補完システムが_$fpath_から補完関数をロードすることです。完了ディレクトリが次の場所にあることを確認してください。

_print -rl -- $fpath
_

oh-my-zsh を使用した場合、_.oh-my-zsh/completions_は_$fpath_に存在します。作成して完了関数をそこに配置できます)

次に、関数の補完ファイルを作成する必要があります。その名前は、アンダースコア___と関数名で始まる必要があります。あなたの場合、その名前は__eb_instances_です。

これらの行を__eb_instances_ファイルに追加します。

_#compdef eb_instances

_eb_instances() {
  local state

  _arguments \
    '1: :->aws_profile'\
    '*: :->eb_name'

  case $state in
    (aws_profile) _arguments '1:profiles:(cuonglm test)' ;;
              (*) compadd "$@" prod staging dev
  esac
}

_eb_instances "$@"
_

完了です。ファイルを保存し、新しいセッションを開始して完了をテストします。次のようなものが表示されます。

_$ eb_instances <cursor>TAB
cuonglm  test

$ eb_instances cuonglm <cursor>TAB
dev      prod     staging
_

__arguments_関数、state変数に関するzsh補完システムのドキュメントを読むことができます。また、sedコマンドで_(cuonglm test)_を変更し、_prod staging dev_を_eb_names_関数に変更する必要もあります。

1番目の引数が渡したものに基づいて2番目の引数を生成する場合は、_$words[2]_変数を使用できます。

_case $state in
  (aws_profile) _arguments '1:profiles:(cuonglm test)' ;;
            (*) compadd "$@" $(echo $words[2]) ;;
esac
_

echoを実際の関数に置き換えます。この場合、$(eb_names $words[2])になります。

それでもこれを達成するのが難しいと感じる場合は、__eb_instances_で_eb_instances_および_.zshrc_を定義して、完了を次のように呼び出します。

_compdef _eb_instances eb_instances
_

以下を使用して補完システムを初期化する必要があります。

_autoload -U compinit
compinit
_

(_oh-my-zsh_を使用した場合、ロードされています)

24
cuonglm