2012-05-18 3 views
12

次のbash補完は、可能な単語(つまり補完)の配列をcompgenに渡します。Bash Autocompletion - この配列を重大な空白を崩壊させずにcompgenに渡すには?

basenames=("foo" "fu bar" "baz"); 

COMPREPLY=($(compgen -W "${basenames[*]}" -- "${COMP_WORDS[COMP_CWORD]}")) 

問題が配列要素に空白が保持されないことである、すなわち、「FOOバー」である要素に関して単語分割のおかげで処理されます。 3つの要素が表示され、4ではなく、空白を保持する方法がありますか?

EDIT

basenamesはそれが(離れてから/と\ 0)ほぼすべての文字が許可されている、ファイル名が含まれています。

EDIT 2

は-Wフラグがfoo bar foobarのようなものである単一の単語を、期待しています。複数の要素を渡す(これが${basenames[@]}の場合)。

EDIT 3

変更examplaryベース名アレイ(SO foo barからfoofooが崩壊されません)。

単語を区切るために改行を使用して動作します。\0を使用して

local IFS=$'\n' 
COMPREPLY=($(compgen -W "$(printf "%s\n" "${basenames[@]}")" -- ${COMP_WORDS[COMP_CWORD]}")) 

はしていません:

local IFS=$'\0' 
COMPREPLY=($(compgen -W "$(printf "%s\0" "${basenames[@]}")" -- ${COMP_WORDS[COMP_CWORD]}")) 

答えて

8

なぜcompgenでわざわざ? COMPREPLYに手動で追加するだけです。以下は、一致するファイル名を/some/pathから完成させ、ファイル名を安全に処理します。

some_completion_function() { 
    local files=("/some/path/$2"*) 
    [[ -e ${files[0]} ]] && COMPREPLY=("${files[@]##*/}") 
} 

compgenはファイル名を安全に処理することはできません。

+0

+1これは私が実際に望んだものを達成した方法です。本当に良いアドバイス! – helpermethod

+0

"$ 2"と "## * /"は何ですか? – oluc

+0

## /最後の '/'まで頭を削除します。 $ 2が現在の補完単語です。 ? – oluc

-2

あなたは、ほとんどの場合、配列に添字代わりにアスタリスクの記号で使用する必要があります。

COMPREPLY=($(compgen -W "${basenames[@]}" -- "${COMP_WORDS[COMP_CWORD]}")) 
man bashから

(またはBash Reference Manualを参照してください):

添字が@または*であれば、単語は名前のすべてのメンバーに展開されます。これらの添え字は、単語が二重引用符で囲まれている場合にのみ異なります。単語が二重引用符で囲まれている場合、${name[*]}は、各配列メンバーの値がIFS特殊変数の最初の文字で区切られた単一の単語に展開され、${name[@]}は名前の各要素を別々の単語に展開します。

つまり、アットマークの形式は配列を「平坦化」します。アスタリスク形式で保存されます。

+4

*を@に置き換えると、自動補完は完全に機能しなくなります。 – helpermethod

+7

'compgen -W'は、全ての補完が' [@] 'はしない単一の"単語 "で提供されることを要求します。 [前の質問への私の答え](http://stackoverflow.com/questions/3348443/a-confusion-about-array-versus-array-in-the-context-of-a-bash-comple/3355375#)を参照してください。 3355375)を参照してください。 –

+11

-1:このアドバイスは文脈から逸脱しているため、間違っているだけです。 '-W'は単一の引数*を期待し、' @ 'を使うとそれらの数は不定になります。 – antak

1

おそらくこれは行う可能性があります:

COMPREPLY=($(compgen -W "$(printf "%q " "${basenames[*]}")" -- "${COMP_WORDS[COMP_CWORD]}")) 
+0

'*'ではなく '@'で動作するようです。 –

+0

これはほとんど動作しますが、 "foo bar"を2つの要素として扱いますが、1つの要素として表示する必要があります。 – helpermethod

+0

@OliverWeiler: '@ 'でglennを試しましたか? –

関連する問題