カンマ区切りのパラメータリストの補完ルールを作成したいのですが。例えば。サーバー名のリストを受け取るコマンドがあります:
myscript -s name1,name2,name3
この時点で、私は次の完了をなんとか書くことができました:
_myscript () {
local cur prev opts
_get_comp_words_by_ref cur prev
opts='-s'
servers='name1 name2 name3'
if [[ ${cur} == -* ]] ; then
COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
else
case "${prev}" in
-s)
if [[ "$cur" == *,* ]]; then
local realcur prefix
realcur=${cur##*,}
prefix=${cur%,*}
COMPREPLY=( $(compgen -W "${servers}" -P "${prefix}," -- ${realcur}) )
else
COMPREPLY=( $(compgen -W "${servers}" -- ${cur}) )
fi
;;
*)
# do nothing
;;
esac
fi
}
しかし、少なくとも2つの問題があります。
そのような場合のベストプラクティスは何ですか?たぶんbash-completionsにはcsvリスト用のバンドルされた関数がいくつかありますか?
Bashはディスプレイで直接COMPREPLY
の値を使用し、次にユーザーのテキストを置き換えるため、基本的に説明した問題を修正する方法はありません。必要なものを取得するには、最初に生成する必要があります。 bashが表示する可能性のある補完(プレフィックスなしの追加のサーバー名のみ)。bashがユーザーテキストを競合しない最長の文字列に置き換えようとしているときに、スクリプトを再度呼び出してテキストを生成する必要があります。接頭辞が-で、bashにはそのための機能がありません。
私が思いつくことができる最善の方法は、接頭辞全体(COMPREPLY=( "${prefix},"$(compgen -W "${servers[@]}" -- ${realcur}) )
)を持つ最初の単語のみを使用してCOMPREPLY
を生成することです。これにより、可能な補完が1つしかない場合は、自動的に正しく完了しますが、可能な完了が複数ある場合、bashはこれまでに入力されたものを削除しません(COMPREPLY
の最初の単語にはプレフィックス全体が含まれているため、現在入力されているテキストと一致し、ユーザーのテキストを置き換えるためにbashによって選択されます)、プレフィックスなしのオプションが表示されます-すでにプレフィックスが含まれている1つの単語を除いて、出力は次のようになります。
_$ command -s banana,a
ananas apricot banana,Apple
_
「Apple」は、「b」で始まるプレフィックスが付いているため、補完オプションの最後に並べ替えられています。非常にわかりにくいです。だから私はそれをすることをお勧めしません。
重複について-重複を表示しないようにするには、_$prefix
_をその部分に分割し(簡単:IFS="," prefix_parts=($prefix)
)、それらを繰り返し処理して_$servers
_のみを残す必要があります。まだリストされていない名前。入力するのが面倒なので、ここでは示しませんが、比較的簡単なので、管理できると確信しています:-)。
要約すると、少なくともbashが完了に役立つと期待する場合は、入力オプションにコンマ区切りの値を使用するべきではないと思います。
次のようなオプション形式をサポートできます:_command -s <server> [<server> [..]]
_次に、_-s
_オプションの直後以外のエントリを完了するには、_$COMP_WORDS
_配列から_$COMP_CWORD
_配列をスキャンして戻します。 )__オプション(_-*
_に一致する文字列)が見つかるまで、その「-s」の場合は、サーバー名を補完する必要があります。