2016-08-26 7 views
9

私はPHPツールhttp://robo.liとn98-magerun.pharを使用しています。どちらもSympfonyのCLIコンポーネントに基づいています。しかし、これで - - 無関係 - 場所でロボ完了、scpは削除しSymfonyベースのオートコンプリートは、SCPオートコンプリートを中断します

それは通常、リモートサーバー上のファイルを完了し scpコマンドのオートコンプリートを(破っ
https://gist.github.com/caseyfw/51bdbcb37e5dfb91b74e 

#!/bin/sh 
function __robo_list_cmds() 
{ 
     robo list --raw | awk '{print $1}' | sort 
} 

function __robo_list_opts() 
{ 
    robo list --no-ansi | sed -e '1,/Options:/d' -e '/^$/,$d' -e 's/^ *//' -e 's/ .*//' | sort 
} 

_robo() 
{ 
    local cur="${COMP_WORDS[COMP_CWORD]}" 
    COMPREPLY=($(compgen -W "$(__robo_list_opts) $(__robo_list_cmds)" -- ${cur})) 
    return 0; 
} 

complete -o default -F _robo robo 
COMP_WORDBREAKS=${COMP_WORDBREAKS//:} 

:私は、このようなオートコンプリートスクリプトを使用

コマンドのホスト名)

なぜですか?直し方?回答に基づいて

EDIT

、固定版はこちら:

https://gist.github.com/amenk/d68f1fe54b156952ced621f771ff48ba

+2

これはあなたの問題を解決することはできませんが、補足スクリプトは*ソース*(通常は '〜/ .bashrc'または'/etc/bash.bashrc')になりますので、シバン行は重要ではありません。 * sh *が無視されていない場合、 'sh'は配列について知りませんが、あなたはそれらを使います。 –

答えて

3

これはおそらく、あなたのrobo補完仕様とは何の関係もありません。完了関数はscpに関連付けられていません。

おそらくあなたのCOMP_WORDBREAKS=${COMP_WORDBREAKS//:}が原因です。

セパレータのリストから:を削除しました。明らかに_scpは、ワードセパレータとして:の有無にかかわらず同じように動作するように頑強です。候補補完の同じリストを返します。しかし、_scpが完了のためのただ1つの候補を返すときに置換されるトークン。 scp host:public_htは、ではなく、host:public_htです。証明:あなたはfoobar host:public_htを完了しようとした場合、置換トークンがちょうどpublic_htあるので

$ _foobar() { COMPREPLY=bazcux; return 0; } 
$ complete -o default -F _foobar foobar 
$ echo $COMP_WORDBREAKS 
"'><=;|&(: 

は、あなたがfoobar host:bazcuxを取得します。しながら:それはbazcuxに置き換えられて、完全なhost:public_htあるので

$ COMP_WORDBREAKS=${COMP_WORDBREAKS//:} 
$ echo $COMP_WORDBREAKS 
"'><=;|&(

あなたはfoobar host:public_htを完了しようとした場合、あなたはfoobar bazcuxを取得します。

_robo完了機能にはおそらく、:が単語区切り記号ではないことを必要としないように問題を解決することが考えられます。以下のような何か:

_stem() { 
    local lcur lprev 
    lcur="$cur" 
    stem="$lcur" 
    for ((i = cword - 1; i >= 0; i -= 1)); do 
     lprev="${words[i]}" 
     [[ $lcur == ":" ]] && [[ $lprev == ":" ]] && break 
     [[ $lcur != ":" ]] && [[ $lprev != ":" ]] && break 
     stem="$lprev$stem" 
     lcur="$lprev" 
    done 
} 

_robo() { 
    local cur prev words cword 
    _init_completion || return 
    local stem options 
    options=($(__robo_list_opts) $(__robo_list_cmds)) 
    COMPREPLY=() 
    _stem 
    COMPREPLY=($(compgen -W '${options[@]}' -- "$stem")) 
    [[ $stem =~ : ]] && stem=${stem%:*}: && COMPREPLY=(${COMPREPLY[@]#"$stem"}) 
    return 0 
} 

complete -o default -F _robo robo 

(明らかに)はるかに簡単な解決策はbash_completionライブラリの既存__reassemble_comp_words_by_ref機能により、上記_stem機能を置き換えることで構成されています。このすべてが正確に何をしたい、おそらくではありません

_robo() { 
    local cur prev words cword 
    _init_completion || return 
    __reassemble_comp_words_by_ref ":" words cword 
    options=($(__robo_list_opts) $(__robo_list_cmds)) 
    COMPREPLY=($(compgen -W '${options[@]}' -- "$cur")) 
    return 0 
} 

complete -o default -F _robo robo 

。私はrobo.ilを知らないし、具体的な補完を提案するためにもっと多くの文脈を考慮すると、おそらく多くの改善があるだろう。しかし、それは出発点かもしれない。

+0

"あなたの問題を解決するには、_robo補完機能を採用する必要があります。つまり、単語区切り記号ではありません。それはどのように働くでしょうか?おお、大丈夫?それらの言葉の刻印はどこで必要ですか? – Alex

+0

ああ、Robo/symfonyのコマンドは 'robo main:sub:subsubcommand'のようになっているので、wordseperatorが置かれているのはこのためです。 'robo'と' magerun'に対してのみ単語区切りを有効にできますが、 'scp'では有効にできませんか? – Alex

+1

@Alexいいえ、残念ながら、コマンドごとに 'COMP_WORDBREAKS'を特化することはできません。実際には、1) 'COMP_WORDS'配列を' COMP_CWORD'から後方に 'main:sub:subsu'ステムを構築するために後方に解析し、' compgen'を呼び出して全てを取得するように、より複雑な '_robo'関数を実装する必要があります可能な補完、3)それらからステムを除去し、結果を返す。それらは2つの可能性があることに注意してください:単語レベルの補完( ':'のような ':' ''/''で終わるパス補完は完全なグループ補完です)。君の選択。 –

関連する問題