ZSHの完了は、提供された引数によって異なります。

ZSHの完了は、提供された引数によって異なります。

ZSH完了スクリプトで提供されたパラメータに変数としてアクセスする方法はありますか?

例は次のとおりです。

#compdef test

_test_comp(){
 t=($(cat /tmp/file_with_opts))
 _wanted t expl "availavle options" compadd -a t
}

_arguments -C -S  \
 '-f[input file]:filename:_files' \
 '*:test_autocomplete:_test_comp'

スクリプトtestは、ハードコードされたファイルからオプションを選択/tmp/file_with_optsし、を通じて定義されたファイルからオートコンプリートオプションを選択できるようにします-f。または、-f <filename>定義されている場合は、デフォルトファイルの代わりにこのファイルを解析したいと思います。これを行う方法についてのアドバイスはありますか?

答え1

これはXYの問題と少し似ているようです。提供されたオプションを使用して実行される方法の変更に正確に動機付けるものは何ですか?環境変数を使用して変更を実行できるのはなぜですか。

それにもかかわらず、オプション処理-f ...のいずれかの時点で、ファイルはコマンドラインの他のコンテンツに関連して表示される場所によって問題を引き起こす可能性があります。さらに、完了コードは繰り返し呼び出されるので、同じコマンドインスタンスと新しいインスタンスに対する異なる呼び出し間の状態を維持するのは難しいかもしれません。そして、コンテンツを$(cat /tmp/file_with_opts)不必要に分岐してから分割するので良いではありません。まあ、誰が知っていますか?cat

これらの問題を念頭に置いて、どのオプションを使用できるかを調べる1つの方法は、set > ~/tmp/what-is-set完成コードの適切な部分にこのような内容を追加し、オプションの有無にかかわらず複数の場所にカーソルを置き、タップして-f ...出力ファイルを調べることによって完了しますスクリプトに使用できる項目を確認してください。

% grep file_ what-is-set
BUFFER='foo  -f file_with_opts '
RBUFFER=' -f file_with_opts '
opt_args=( [-f]=file_with_opts )
words=( foo '' -f file_with_opts )

この場合は、foo後で以前にタブを完成させている-f ...ため、プログラムに関連していない他のコマンドが完了スクリプトを混同して完了動作を変更する可能性があるため、配列を確認したり、BUFFERよりよく確認したりできます。wordsBUFFER-f ...

したがって、ループを実行すると、次のようなwordsオプションがあるかどうか(多くのエラーチェックなし)で読み取ったファイルを変更できます-f ...

#compdef foo

local curcontext="$curcontext" state line ret=1

_arguments -C -S  \
  '-f[input file]:filename:_files' \
  '*:options:->vary' \
  && ret=0

case "$state" in
  vary)
    integer i
    local optsfile
    #set > ~/tmp/what-is-set
    # default filename
    optsfile=~/tmp/file_with_opts
    for (( i = 1; i <= $#words - 1; i++ )); do
      if [[ $words[$i] == -f ]]; then
        optsfile=$words[$((i+1))]
        break
      fi
    done
    # cat-free read of file with split on newlines
    t=(${(f)"$(<$optsfile)"})
    _wanted t expl "available options" compadd -a t
  ;;
esac

return $ret

このディレクトリ$fpath[-1]の既存の完了項目を調べると便利です。

関連情報