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)'
}
Wenn ich das, es nur schlägt Dateien auf '' swift '' vor. Es vervollständigt auch '' swift bui '' zu '' swift build ''. –
bouke
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
Haben Sie meinen Code genau so kopiert und eingefügt, wie er ist? Jeder kleine Tippfehler wird es wahrscheinlich brechen. – Ben