2012-02-18 11 views
1

最近使用しているコマンドラインプログラムにbash補完サポートを追加しようとしていましたが、壁に衝突したようです。ここでネストされたbash自動補完スクリプト

は、私はオートコンプリート

  • メインコマンドしたいコマンドとサブコマンドは、自動補完がprocess、サブコマンドversionのために行われ、helpする必要があり、fooです。さらにオートコンプリートはサブコマンドによって異なります。

    • ユーザがメインコマンドの後-を入力した場合、自動補完はこれらの単語の補完を行います。--activateまたは--deactivate

    • ユーザーが--deactivateを入力した場合、それは(のは言わせbashコマンド出力の自動補完を実行する必要がありますls)。

  • version:NOオートコンプリートは
  • processを行わない:ユーザーが-を入力した場合、ディレクトリを列挙するオートコンプリートのデフォルト(現在の親を含む)

    • 、オートコンプリートは、これらの単語を補完を行う:--color--verboseその後停止します。
  • ユーザがhelpと入力した場合、オートコンプリートは他のサブコマンド(processまたはversion)に適用されます。

    _foo() { 
        local cur prev opts 
        COMPREPLY=() 
        cur="${COMP_WORDS[COMP_CWORD]}" 
        prev="${COMP_WORDS[COMP_CWORD-1]}" 
        words=("${COMP_WORDS[@]}") 
        cword=$COMP_WORD 
        opts="process version help" 
    
        case "$prev" in 
        -*) 
         local subopts="--activate --deactivate" 
          COMPREPLY=($(compgen -W "${subopts}" -- ${cur})) 
          case "$cur" in 
           --deactivate) 
            COMPREPLY=($(ls)) 
           ;; 
          esac 
         ;; 
        version) 
         COMPREPLY=() 
         ;; 
        process) 
         case "$cur" in 
          -*) 
           local subopts="--color --verbose" 
           COMPREPLY=($(compgen -W "${subopts}" -- ${cur})) 
           ;; 
          *) 
           COMPREPLY=($(compgen -A directory)) 
           ;; 
         esac 
         ;; 
        help) 
         COMPREPLY=($(compgen -W "process version" -- ${cur})) 
         ;; 
        esac 
        } 
    complete -F _foo foo 
    

    おそらく、バッシュは、同様に私の主な得意ではないことがわかります。

は、ここで(ひどく失敗している)自動補完スクリプトの私の現在の実装です。私は各サブコマンドに対して別々のbash関数を書くことを考えていましたが、現時点でどうやってそれを行うのか分かりません。これを実装する方法についてのご提案がありましたら、本当にありがとうございます。

ありがとうございます!

答えて

3

第1レベルの可能なサブコマンドの場合、私にとっては少し不明です。 foo --activateまたはfoo - --activateを入力する必要がありますか?後者は何とか変わったように見えますが、あなたの与えられたコードに適合する可能性があります。 最初の方がより合理的ですが、--activateなどを、サブコマンドのように同じレベルで扱われるグローバルパラメータの種類として含意します。

まだ何も入力していない場合でも、デフォルトを見逃しました。 は、次のコードを試してみてください。彼らは完了しますので、あなたの最初のレベルのサブコマンドにCOMPREPLYを設定し、一番下に :

_foo() { 
    local cur prev opts 

    COMPREPLY=() 
    cur="${COMP_WORDS[COMP_CWORD]}" 
    prev="${COMP_WORDS[COMP_CWORD-1]}" 
    words=("${COMP_WORDS[@]}") 
    cword=$COMP_CWORD 
    opts="process version help" 

    case "$prev" in 
    -*) 
     local subopts="--activate --deactivate" 
     COMPREPLY=($(compgen -W "${subopts}" -- ${cur})) 
     case "$cur" in 
      --deactivate) 
       COMPREPLY=($(ls)) 
      ;; 
     esac 
     return 0 
     ;; 
    version) 
     COMPREPLY=() 
     return 0 
     ;; 
    process) 
     case "$cur" in 
      -*) 
       local subopts="--color --verbose" 
       COMPREPLY=($(compgen -W "${subopts}" -- ${cur})) 
       ;; 
      *) 
       COMPREPLY=($(compgen -A directory)) 
       ;; 
     esac 
     return 0 
     ;; 
    help) 
     COMPREPLY=($(compgen -W "process version" -- ${cur})) 
     return 0 
     ;; 
    esac 
    COMPREPLY=($(compgen -W "${opts}" -- ${cur})) 
    return 0 
} 
complete -F _foo foo 

基本的にはあなたと同じしかし、です。 サブコマンドを入力した場合は、(0)を返して最終的なステートメントに到達しないようにしてください。

例はfoo - --activateで動作しますが、これはあなたが望んでいない可能性があります。 foo --activateと入力したい場合は、行を

に変更してください。
case "$prev" in 
    --activate) 
     COMPREPLY=() 
     return 0 
     ;; 
    --deactivate) 
     COMPREPLY=($(compgen -W "$(ls)" -- ${cur})) 
     return 0 
     ;; 
    version) 
    ...