zsh-completion - 第一个参数是子命令或带有值的标志

标签 zsh-completion

我正在为 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)'    
}

最佳答案

你可以使用 _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 "$@"

您可以在此处阅读有关如何使用这些功能的信息:http://zsh.sourceforge.net/Doc/Release/Completion-System.html#Completion-Functions
或在这里:https://github.com/vapniks/zsh-completions/blob/master/zsh-completions-howto.org

关于zsh-completion - 第一个参数是子命令或带有值的标志,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39776973/

相关文章:

linux - zsh compinit : insecure directories. Compaudit 显示/tmp 目录

zsh完成差异

zsh:显示完成组名称

Zsh:如何在一组字符之后强制文件完成?

azure - 如何在 zsh 中为 Azure CLI 启用命令完成?

macos - Zsh tab 完成复制命令名称

git - git 的 ZSH 自动完成需要大量时间,我可以将其关闭或优化吗?

zsh - zsh 中的多点路径,如 `cd ....`

git - 自定义 git "bang"别名的 Zsh 完成 - Git 分支名称

zsh - 为多个命令定义 ZSH 补全函数 (compdef)