2016-08-26 53 views
9

http://robo.li ve n98-magerun.phar PHP araçlarını kullanıyorum - her ikisi de Sympfony'nin CLI bileşenlerini temel alıyor. ama bununla - - ilişkisiz - yerinde robo tamamlama, scp kaldırırSymfony tabanlı otomatik tamamlama SCP otomatik tamamlama sonları

Genellikle uzak sunucudaki dosyaları tamamlar scp komutunun otomatik tamamlama (kırar
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//:} 

: Ben böyle bir otomatik tamamlama komut dosyası kullanmak

komuttan ana bilgisayar adı)

Neden? Nasıl düzeltilir?

DÜZENLEME Yanıta göre

, sabit sürüm burada: Bu muhtemelen robo tamamlama belirtimi ile ilgisi yoktur

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

+2

Bu sorununuzu çözmeyecek, ancak yan not: tamamlama komut dosyaları *, (genellikle "~/.bashrc" veya "/ etc/bash.bashrc" biçimindedir), böylece shebang çizgisi önemsizdir. Eğer * yoksayılsaydı *, şeyler kırılırdı çünkü 'sh' dizileri bilmez ama onları kullanırsın. –

cevap

3

. scp ile ilişkili _scp tamamlama işlevi ile de.

Muhtemelen COMP_WORDBREAKS=${COMP_WORDBREAKS//:}'unuzdan kaynaklanmaktadır.

Ayraçlar listesinden : kaldırdınız. Görünüşe göre _scp, kelime ayırıcı olarak : ile aynı veya onlarla aynı davranmaya yetecek kadar sağlamdır. Aynı aday listesi tamamlandı. Ancak, _scp, tamamlandığında yalnızca bir aday döndürdüğünde ikame edilen simge, ör. scp host:public_ht, yalnızca public_ht yerine host:public_ht'dur. Kanıt: Eğer foobar host:public_ht tamamlamak çalışırsanız ikame kodu yalnızca public_ht çünkü

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

, sen foobar host:bazcux olsun. ile zaman: o bazcux ile değiştirilir tam host:public_ht çünkü

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

Eğer foobar host:public_ht tamamlamak için çalışırsanız, foobar bazcux olsun.

Sorununuza çözüm, :'un kelime ayırıcı olarak kullanılmasını gerektirmeyecek şekilde _robo tamamlama işlevinize uyum sağlamasıdır.

_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 

bir çok (görünüşte) basit bir çözüm bash_completion kütüphanede mevcut __reassemble_comp_words_by_ref işleviyle yukarıda _stem fonksiyonunu değiştirmekten ibarettir: Bir şey gibi

_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 

Bütün bunlar istemiyor tam olarak ne muhtemelen . robo.il'u bilmiyorum ve belirli tamamlamaları önermek için daha fazla bağlamı hesaba katacak birçok gelişme var. Ama bir başlangıç ​​noktası olabilir.

+0

"Sorununuza çözüm muhtemelen _robo tamamlama işlevinizi buna gereksinim duymayacak şekilde ayarlamaktır: bir sözcük ayırıcı değildir." Bu nasıl çalışır? Kabaca? O kelime dalgalarını nereye gerektiriyor? – Alex

+0

Ah, şey, robo/symfony komutlarının şu şekildedir: “robo main: sub: subsubcommand” yani bu yüzden wordsepratör yerleştirmek için geliyor. Bu kelime ayırıcısını sadece "robo" ve "magerun" için değil, scp için etkinleştirmek mümkün mü? – Alex

+1

@Alex Hayır, maalesef komuta başına 'COMP_WORDBREAKS' konusunda uzmanlaşabileceğinizi düşünmüyorum. Gerçekten biraz daha karmaşık '_robo' fonksiyonunu uygulamak zorunda kalacaksınız 1) 'COMP_WORDS' dizisini" ana: sub: subsu "sapını oluşturmak için" COMP_CWORD "den başlayarak geriye doğru hareket ettirin. olası tamamlamalar, 3) sapı onlardan çıkarın ve sonucu döndürün. Onların iki olasılık olduğunu unutmayın: kelime düzeyinde tamamlama (': '' 'yol tamamlama işlemi durdurma' /') veya tam grup tamamlama. Bu senin seçimin. –