2012-05-08 16 views
16

curlでファイルアップロードのセマンティクスを共有するツール用のbash補完スクリプトをビルドします。カールとタブ完了時にbash補完が文字を置き換えないようにする方法

は、あなたが行うことができます:

カール-Fするvar = @ファイル

ファイルをアップロードします。

私のアプリケーションは同様のセマンティクスを持っており、 '@'を押した後に可能なファイルを表示できるようにしたいと考えています。残念ながら、これは難しい証明されています

cur="${COMP_WORDS[COMP_CWORD]}" 
prev="${COMP_WORDS[COMP_CWORD-1]}" 
if [[ "$cur" == @* && "$prev" == '=' ]]; then 
    COMPREPLY=($(compgen -f ${cur:1})) 
    return 0 
fi 

ので、コマンドは(今のところ)で終わる場合:カレントディレクトリに

[email protected] 

ファイルが表示されます。

[email protected]/usr/                              
/usr/bin  /usr/games 

実際にタブを押して完了すると、「@」が消えてしまいます。

var=/usr/bin 

したがって、現在の単語全体をタブ付きのCOMPREPLYに置き換えているようです。

 COMPREPLY=($(compgen -f ${cur:1})) 
     for ((i=0; i<${#COMPREPLY[@]}; i++)); 
     do 
      COMPREPLY[$i]='@'${COMPREPLY[$i]} 
     done                              

しかし、今のタブ補完は、少なくとも言って奇妙に見える:

これを回避する唯一の方法は、これを実行することであった通常のファイルを表示するためにとにかくあり

@/usr/bin  @/usr/games 

タブの補完( '@'接頭辞なし)では、タブを押すと '@'が保持されますか?

+1

恐ろしい質問を、これを試してみてください!私はこれに多くのことを学んだ。 – sanmiguel

答えて

5

これは興味深いので、私はbash補完ソース(/ etc/bash_completionにあります)を読んでいます。

私はこの変数に遭遇しました:${COMP_WORDBREAKS}これは、どの文字が単語の区切りに使用されるかを制御できるように見えます。

また、_get_cwordと補完的な_get_pwordは、それぞれ${COMP_WORDS[COMP_CWORD]}${COMP_WORDS[COMP_CWORD-1]}の代わりに使用することをお勧めします。

だから、一緒にこのすべてを入れて、私はいくつかのテストを行なったし、ここで私が作ってみたものです:

# maintain the old value, so that we only affect ourselves with this 
OLD_COMP_WORDBREAKS=${COMP_WORDBREAKS} 
COMP_WORDBREAKS="${COMP_WORDBREAKS}@" 

cur="$(_get_cword)" 
prev="$(_get_pword)" 

if [[ "$cur" == '[email protected]' ]]; then 
    COMPREPLY=($(compgen -f ${cur:2})) 

    # restore the old value 
    COMP_WORDBREAKS=${OLD_COMP_WORDBREAKS} 
    return 0 
fi 

if [[ "$prev" == '[email protected]' ]]; then 
    COMPREPLY=($(compgen -f ${cur})) 

    # restore the old value 
    COMP_WORDBREAKS=${OLD_COMP_WORDBREAKS} 
    return 0 

fi 

を今:これはあまりにもあなたのために、少なくとも、うまくいけば、それは意志、私のために働くようです、私は分割がifケースが少し汚れていることを認めますが、確かにそれを行うためのより良い方法がありますが、私はより多くのカフェインが必要です。それはあなたに価値があるものは何でも私もそう

COMPREPLY=($(compgen -P @ -f ${cur:1})) 

だような、道に沿ってcompgenを呼び出した後$COMPREPLY[*]}アレイの上にループを有するからあなたを妨げるcompgenから-P <prefix>引数を、発見するためのさらなる

、しかし、完全なソリューションの面で少し冗長です。

+1

優れた研究。私はあなたがこれでどこに行くのが本当に好きです。スクリプトの外観から、これは私が望むようにタブの補完を行います。しかし、私は大きな懸念を持っています。ユーザーが@ =文字を入力すると、COMP_WORDBREAKSをリセットすることがわかります。しかし、もし彼が決してしなければどうなるでしょう? bashは永遠にCOMP_WORDBREAKSを修正したようです。このすべての答えは、ユーザーが行の入力を完了したときにCOMP_WORDBREAKSを元の値にリセットするための保証された方法です。 – UsAaR33

+0

あなたはそうです - それはその状態でCOMP_WORDBREAKSを残します。私は解決策と更新を見つけるでしょう。 – sanmiguel

+0

これはこれまでのところ最高の答えですので、私は恩恵をあげます。 COMP_WODBREAKSの問題を解決する際にこれを受け入れる(または将来の回答)。 – UsAaR33

0

....

function test 
{ 
    COMPREPLY=() 
    local cur="${COMP_WORDS[COMP_CWORD]}" 
    local opts="Whatever sort of tabbing options you want to have!" 
    COMPREPLY=($(compgen -W "${opts}" -- ${cur})) 
} 
complete -F "test" -o "default" "test" 
# complete -F "test" -o "nospace" "sd" ## Use this if you do not want a space after the completed word 
+0

これを拡張できますか?あなたはbash補完スクリプトの基本を示していますが、根本的な問題はどのように解決されますか? – UsAaR33

関連する問題