2016-07-09 19 views
2

Ich lerne über Bash Abschluss. Ich kann den Inhalt nur des aktuellen Verzeichnisses auflisten. Hier ist mein Code:Wie kann die Bash-Vervollständigung in einem anderen Verzeichnis erweitert werden?

_foo() 
    { 
     local cur prev opts 
     COMPREPLY=() 
     cur="${COMP_WORDS[COMP_CWORD]}" 
     prev="${COMP_WORDS[COMP_CWORD-1]}" 

     opts="push pull" 
     OUTPUT=" $(ls) " 

     case "${prev}" in 
      push) 
       COMPREPLY=($(compgen -W "--in --out" -- ${cur})) 
       return 0 
       ;; 
      --in) 
       COMPREPLY=($(compgen -W "$OUTPUT" -- ${cur})) 
       return 0 
       ;; 
     esac 

     COMPREPLY=($(compgen -W "${opts}" -- ${cur})) 
     return 0 
    } 
    complete -F _foo foo 

Es ist Ausgabe lautet:

$ foo push --in[TAB] 
file1.txt file2.txt foo ;; content of pwd 

Aber wenn ich dies tun:

$ foo push --in ~[TAB] 

Es funktioniert nicht. Also ich möchte wissen, wie bash completion in einem anderen Verzeichnis zu tun (nicht nur in pwd)? Vielen Dank.

+0

Oh sie sind in Skript eigentlich nicht. Dies sind nur wegen Vim-Editor. Und ich habe dieses Skript von dort kopiert, so dass auch die Zeilennummer kopiert wurde. –

Antwort

2

können Sie -f verwenden Dateinamen übereinstimmen:

#!/bin/bash 
_foo() { 
     local cur prev opts 
     COMPREPLY=() 
     cur="${COMP_WORDS[COMP_CWORD]}" 
     prev="${COMP_WORDS[COMP_CWORD-1]}" 
     opts="push pull" 

     case "${prev}" in 
      push) 
       COMPREPLY=($(compgen -W "--in --out" -- ${cur})) 
       return 0 
       ;; 
      --in) 
       COMPREPLY=($(compgen -f ${cur})) 
       return 0 
       ;; 
     esac 

     COMPREPLY=($(compgen -W "${opts}" -- ${cur})) 
     return 0 
} 

complete -F _foo foo 

aber es scheint, dass es nicht für ~ allein funktioniert aber $ foo push --in ~/[TAB] Werke und alle anderen Verzeichnisse Diese Lösung wird nicht Strich enthalten für Datei im Verzeichnis suchen : $ foo push --in /etc[TAB] wird foo push --in /etc geben und nicht foo push --in /etc/

Der folgende Beitrag löst dieses Problem Standardmodus mit:
Getting compgen to include slashes on directories when looking for files

Standard

Verwenden Readlines Standarddateinamen-Vervollständigung, wenn der Comspec keine Treffer erzeugt.

So können Sie verwenden:

#!/bin/bash 
_foo() 
    { 
     local cur prev opts 
     COMPREPLY=() 
     cur="${COMP_WORDS[COMP_CWORD]}" 
     prev="${COMP_WORDS[COMP_CWORD-1]}" 

     opts="push pull" 
     OUTPUT=" $(ls) " 

     case "${prev}" in 
      push) 
       COMPREPLY=($(compgen -W "--in --out" -- ${cur})) 
       return 0 
       ;; 
      --in) 
       COMPREPLY=() 
       return 0 
       ;; 
      --port) 
       COMPREPLY=("") 
       return 0 
       ;; 
     esac 

     COMPREPLY=($(compgen -W "${opts}" -- ${cur})) 
     return 0 
    } 
    complete -o default -F _foo foo 

oder die Einstellung in den Standardmodus, wenn Sie diesen Beitrag zu mögen brauchen: https://unix.stackexchange.com/a/149398/146783

+0

Das ist gut. Aber was, wenn ich im Einzelfall nichts machen will. Angenommen es gibt ein Argument --port, Und ich möchte es von der Tastatur nehmen. Es sollte so sein '$ foo drücken --port [TAB]' ;; Autovervollständigung sollte aufhören, kein Ergebnis. Zeigt an, dass der Benutzer --port Wert von der Tastatur übergeben. Aber durch Ihre Antwort wird es '$ foo Push --port [TAB]' ;; Inhalt von pwd Also gibt es eine Möglichkeit, das zu spezifizieren, führen wir nicht standardmäßig in diesen Fällen? –

+0

Aber das funktioniert nicht. '$ foo push --in [TAB] bash: compopt: Befehl nicht gefunden' Das ist eine Fehlermeldung die ich bekommen habe. –

+0

Haben Sie die Datei in bash_completion.d? versuche, '#!/bin/bash' oben hinzuzufügen, um sicherzugehen, dass es die richtige bash verwendet. Wenn deine Bash nicht in '/ bin/bash' ist, ersetze sie mit der richtigen Bash-Position (' which bash') –