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


18

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

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

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

回答:


22

初めて、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補完システムのドキュメントを読むことができます。また(cuonglm test)sedコマンドで変更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_instanceseb_instances、あなたの中.zshrcのように、呼び出しの完了:

compdef _eb_instances eb_instances

完了システムを初期化する必要があります:

autoload -U compinit
compinit

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


詳細な対応に感謝します。私が行うには十分に文書化の方法を見つけるように見えることができない問題しかし、私の終了オプションは、私が望んでいた場合はどのようなあなたの例では、ダイナミック、または他の関数/スクリプトから来る、すなわち、どのようなものされている場合cuonglm testから来てsed -n -E 's/\[([a-zA-Z0-9_\-]+)\]/\1/p' ~/.aws/credentials | tr \\n ' '
zsquare

@zsquare:に置き換え(cuonglm test)($(sed -n -E 's/\[([a-zA-Z0-9_\-]+)\]/\1/p' ~/.aws/credentials | tr \\n ' '))、に変更compadd "$@" prod staging devcompadd "$@" $(eb_names)ます。
クオンルム

これは、私は必要が合格することを、言及するのを忘れて、それを少しストレッチすることができるが、eb_namesすなわち、最初の引数を、productionまたはstaging、私はそれをどのように行うのですか?どうもありがとう、これで整理されたものがかなりありました。
zsquare

つまり、最初の引数を使用してeb_namesに渡したいわけではありません。$1またはを参照しようとしました$2が、サイコロはありません。
zsquare

2
あなたは魔法使いだ、ハリー。
camな
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.