2016-09-29 3 views
3

Ich schreibe ein Zsh-Vervollständigungsskript für die Swift-Tools (Compiler und Paket-Manager). Dieser Befehl kann mit oder ohne Angabe eines Unterbefehls verwendet werden. Zum BeispielErstes Argument entweder Unterbefehl oder Flag mit Werten

# calls to the compiler 
# usage: swift [options] <inputs> 
1> swift my_file.swift 
2> swift -a 1 -b 2 my_file.swift 

# calls to build subcommand 
3> swift build 
4> swift build -c 1 

# calls to test subcommand 
5> swift test 
6> swift test -d 4 

Bis jetzt habe ich das folgende Abschluss-Skript. Es funktioniert meistens, aber für den nackten Anruf funktioniert die Autovervollständigung nicht ganz richtig. Es gibt die _compiler-Methode ein, aber es wird nicht korrekt nach swift -a automatisch vervollständigt. Es wird automatisch kompiliert, als hätte es -a vergessen. So sollte swift -a <TAB><TAB> das Menü zum Auswählen von 1-2-3 anzeigen; Stattdessen zeigt es eine Dateiliste. Für swift -a -a <TAB><TAB> zeigt es die korrekten Vervollständigungen, aber die Wiederholung -a ist nicht gültig.

Es hat wahrscheinlich etwas mit dem Zustand zu tun, der geändert wurde, während es für diesen speziellen Anwendungsfall nicht haben sollte. Für die Unterbefehle (build & test) sollte der Status jedoch so geändert werden, dass die entsprechenden Vervollständigungen ordnungsgemäß funktionieren.

Ich habe die Dokumentation durchgelaufen, aber es ist sehr kryptisch. Ich habe verschiedene andere Abschluss-Skripte überprüft, konnte aber den fehlenden Link nicht herausfinden. Also, wie kann ich eine Vervollständigung für einen Befehl angeben, der optionale Unterbefehle hat, die getrennte Merkergruppen haben (und auch Subunterbefehle selbst haben)?

#compdef swift 
local context state state_descr line 
typeset -A opt_args 

_swift() { 
    _arguments -C \ 
     ': :->command' \ 
     '*:: :->arg' 

    case $state in 
     (command) 
      local tools 
      tools=(
       'build:description for build' 
       'test:description for test' 
      ) 
      _alternative \ 
       'tools:common:{_describe "tool" tools }' \ 
       'compiler: :_compiler' 
      ;; 
     (arg) 
      case ${words[1]} in 
       (build) 
        _build 
        ;; 
       (test) 
        _test 
        ;; 
       (*) 
        _compiler 
        ;; 
      esac 
      ;; 
    esac 
} 

_compiler() { 
    _arguments -C \ 
     '(-a)-a[description for a]: :(1 2 3)' \ 
     '(-b)-b[description for b]: :(4 5 6)' \ 
     '*: :_files' 
} 

_build() { 
    _arguments -C \ 
     '-c[description for c]: :(1 2 3)'  
} 

_test() { 
    _arguments -C \ 
     '-d[description for d]: :(4 5 6)'  
} 

Antwort

0

Sie könnte es tun mit _regex_words und _regex_arguments:

local -a abopts buildopts testopts cmds aargs bargs cargs dargs 
local matchany=/$'[^\0]##\0'/ 
aargs=(/$'(1|2|3)\0'/ ':number:number:(1 2 3)') 
bargs=(/$'(4|5|6)\0'/ ':number:number:(4 5 6)') 
cargs=(/$'(1|2|3)\0'/ ':number:number:(1 2 3)') 
dargs=(/$'(4|5|6)\0'/ ':number:number:(4 5 6)') 
_regex_words opt 'options' '-a:description for a:$aargs' '-b:description for b:$bargs' 
abopts=("${reply[@]}") 
_regex_words opt 'options' '-c:description for c:$cargs' 
buildopts=("${reply[@]}") 
_regex_words opt 'options' '-d:description for d:$dargs' 
testopts=("${reply[@]}") 
_regex_words cmd 'commands' 'build:build command:$buildopts' 'test:test command:$testopts' 
cmds=("${reply[@]}") 

_regex_arguments _swift "$matchany" \("${cmds[@]}" \| "${abopts[@]}" "$matchany" ":file:file:{_files}" \) 
_swift "[email protected]" 

Sie darüber lesen, wie diese Funktionen hier verwenden: http://zsh.sourceforge.net/Doc/Release/Completion-System.html#Completion-Functions oder hier: https://github.com/vapniks/zsh-completions/blob/master/zsh-completions-howto.org

+0

Wenn ich das, es nur schlägt Dateien auf '' swift '' vor. Es vervollständigt auch '' swift bui '' zu '' swift build ''. – bouke

+0

Hmm, seltsam, 'swift bui ' funktioniert für mich. Wenn Sie in der Lage sein möchten, einen Dateinamen als erstes Argument vor beliebigen Optionen zu vervollständigen, fügen Sie in den Argumenten von _regex_arguments eine weitere Alternative für den Teil in Klammern hinzu: '_regex_arguments_swift" $ matchany "\ (" $ {cmds [@]} " \ | "$ {abopts [@]}" "$ matchany" ": Datei: file: {_ files}" \ | "$ matchany" ": Datei: file: {_ files}" \) '(das \ | verhält sich wie "oder") – Ben

+0

Haben Sie meinen Code genau so kopiert und eingefügt, wie er ist? Jeder kleine Tippfehler wird es wahrscheinlich brechen. – Ben

Verwandte Themen