bashの完成はオプションではなく最初の単語でのみ機能しますか?

bashの完成はオプションではなく最初の単語でのみ機能しますか?

foo他の多くのプログラムと同様に、次の形式のコマンドライン引数を使用するプログラムがあります。

foo[オプション]注文する...

どこオプションゼロ以上の短い(例-s:)または長い(例--long:)スタイルオプション。まさに一つコマンドキーワードの後に​​は、コマンドの引数が続きます。

長いオプションやコマンドを完了できるBashコンプリート機能が必要です。便利なことに、オプションリストとコマンドリストを印刷するオプションもfooあります。--options--commands

提案を提供する機能が欲しいただオプションではなく最初の単語(注文する)コマンドラインで次を提供します。いいえ入力時に続く単語の提案ですtab

使用部分この回答COMP_CWORD、値が1の場合にのみ使用し、完了を実行しようとしました。これはこれまでの私の完成機能です。

_foo() {
  local cur=${COMP_WORDS[COMP_CWORD]}

  if [[ "$cur" == -* ]]
  then COMPREPLY=($(compgen -W "$(foo --options)" -- $cur))
  else
    if (( COMP_CWORD == 1 ))
    then COMPREPLY=($(compgen -W "$(foo --commands)" -- $cur))
    else COMPREPLY=()
    fi
  fi
}

これほぼ働くただし、ユーザーが次のような場合注文する良い:

foo --long tab

それからを押すと、tabケースからビープ音が鳴ります。COMP_CWORD今はオプションと非オプションを区別しないので2だからだそうです。

-さて、私は現在の単語の前にあるすべての単語をスキャンし、次のように始まる単語の数を減算する関数が欲しいです。

_foo() {
  local cur=${COMP_WORDS[COMP_CWORD]}

  if [[ "$cur" == -* ]]
  then
    COMPREPLY=($(compgen -W "$(foo --options)" -- $cur))
  else
    local i=$COMP_CWORD
    while (( i > 1 ))
    do
      [[ "${COMP_WORDS[i-1]}" != -* ]] && break
      ((--i))
    done
    if (( i == 1 ))
    then COMPREPLY=($(compgen -W "$(foo --commands)" -- $cur))
    else COMPREPLY=()
    fi
  fi
}

これはうまくいきますが、問題は、ユーザーに引数を受け入れ、その引数を次の単語として提供する短いオプションがある場合です。たとえば、次のようになります。

foo -s arg tab

これにより、インデックスが1ずつ減少します。補完関数は、引数を使用するかどうかにかかわらず、すべてのオプションを詳細に知る必要があり、正しいインデックスを取得するためにすべてのオプションを効率的に解析する必要があります。

これは多くのことのようです。私の完成機能にオプションではなく、最初の単語にのみ提案を提供させるより簡単な方法はありますか?それとも、単にあきらめて常にアドバイスを提供していますか?

関連情報