2016-09-29 68 views
3

我正在为swift工具(编译器和包管理器)编写一个zsh完成脚本。该命令可以在有或没有指定子命令的情况下使用。例如第一个参数是子命令或标志值

# 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 

到目前为止,我有以下完成的脚本。它主要工作,但是对于裸呼叫自动完成并不完全正常工作。它确实输入_compiler方法,但在swift -a之后它不能正确自动完成。它自动完成,好像它已经忘记了-a。所以swift -a <TAB><TAB>应该显示选择1-2-3的菜单;而是显示文件列表。对于swift -a -a <TAB><TAB>它显示正确的完成,但重复-a无效。

它可能与已被更改的状态有关,但它不应该用于此特定用例。但是,对于子命令(构建&测试),应修改其各自的完成状态以正确工作。

我已经通过了文档,但它非常神秘。我检查过其他各种完成脚本,但找不到缺失的链接。那么如何为具有可选子命令的命令指定完成,这些子命令具有单独的标志集(并且还具有子子命令本身)?

#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)'  
} 

回答

0

你可以使用_regex_words_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]" 

您可以了解如何在这里使用这些功能:http://zsh.sourceforge.net/Doc/Release/Completion-System.html#Completion-Functions 或在这里:https://github.com/vapniks/zsh-completions/blob/master/zsh-completions-howto.org

+0

当我用这个,只有它在''swift ''上建议文件。它也没有完成''快速构建'''swift bui ''。 – bouke

+0

嗯,奇怪,'swift bui '适合我。如果您希望能够在任何选项之前完成文件名作为第一个参数,请在_regex_arguments参数的括号内为零件添加另一个备选:'_regex_arguments _swift“$ matchany”\(“$ {cmds [@]}” \ |“$ {abopts [@]}”“$ matchany”“:file:file:{_ files}”\ |“$ matchany”“:file:file:{_ files}”\)' “或”) – Ben

+0

您是否完全照原样复制并粘贴了我的代码?任何小的错字都可能会破坏它。 – Ben

相关问题