3 つの部分からなる形式で引数を取るコマンド ライン ツールがあります。
$ t first_second_third
の有効な値のfirst
セット、 の有効な値second
のセット、および の有効な値のセットがありますthird
。次の例のように、Bash の完全な機能を使用して、オプション値の各部分を完成させたいと考えています。
$ t [tab][tab] # shows options for first part
walk run skip bike
$ t w[tab] # completes first part and appends delimiter
$ t walk_[tab][tab] # shows options for second part
home work park
$ t walk_h[tab] # completes second part and appends delimiter
$ t walk_home_[tab][tab] # shows options for second part
morning afternoon evening
$ t walk_home_a[tab] # completes second part and appends space
$ t walk_home_afternoon
私はこのコードを持っています:
_tool () {
local cur="${COMP_WORDS[COMP_CWORD]}"
local first="walk run skip bike"
local second="home work park"
local third="morning afternoon evening"
case "${cur}" in
*_*_*)
COMPREPLY=( $(compgen -W "${third}" -- "") ); return 0;;
*_*)
COMPREPLY=( $(compgen -W "${second}" -S "_" -- ${cur}) ); compopt -o nospace; return 0;;
*)
COMPREPLY=( $(compgen -W "${first}" -S "_" -- ${cur}) ); compopt -o nospace; return 0;;
esac
}
complete -F _tool t
最初の節はうまく機能します。特別なことは何もありません。しかし、2 番目の句にはオプションや補完がありません。
$ t [tab][tab]
bike_ run_ skip_ walk_
$ t b[tab]
$ t bike_[tab][tab] # nothing but bells
2 番目の句を次のように置き換えました (つまり${cur}
、呼び出しで空の文字列に置き換えましたCOMPREPLY
)。
COMPREPLY=( $(compgen -W "${second}" -S "_" -- "") ); compopt -o nospace; return 0;;
コマンドラインですべてのオプションのリストを取得しますが、補完はありません。
$ t bike_[tab][tab]
home_ park_ work_
$ t bike_h[tab][tab]
home_ park_ work_
$ t bike_ho[tab][tab]
home_ park_ work_
${cur}
単語リストとの相互作用が悪いのではないかと考えたCOMPREPLY
ので、2 番目の句を再度変更し、現在の単語の最初の部分に一致する接頭辞を追加しました。
local prefix=( $(expr "${cur}" : '\(.*_\)') )
COMPREPLY=( $(compgen -W "${second}" -P "${prefix}" -S "_" -- "") ); compopt -o nospace; return 0;;
これはあまり役に立ちませんでした。コマンドが${cur}
まだ残っているCOMPREPLY
ので、オプションも補完もありません。代わりに空の文字列を使用すると、(現在の部分だけでなく) 完全なオプションが得られます。ただし、タブを押すと、入力した内容が消去されます。
$ t bike_[tab][tab]
bike_home_ bike_park_ bike_work_
$ t bike_ho[tab]
$ t bike_ # "ho" was erased
もちろん、第3部でも同じ問題があります。
- Bashに現在の単語を部分的に完成させるにはどうすればよいですか?
- オプションが選択されるまでBashに区切り文字を追加させないようにするにはどうすればよいですか?
これは別の Bash complete questionに似ていますが、値のすべての可能な順列をリストしたくなく、ファイル名としてフォーマットされていません (ファイル名のパターンが違いを生むかどうかはわかりません)。
助けてくれてありがとう!
--ap