2016-09-29 70 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

相關問題