如何为带有子命令的命令定义zsh自动完成功能?

时间:2020-04-10 19:29:32

标签: zsh zsh-completion

我正在尝试为borg编写一个制表符补全脚本。

到目前为止,我已经设法为borg本身,borg key及其子命令以及borg benchmark及其单数子命令定义了补全。但是,我现在正在尝试为borg init定义完成,但是遇到了麻烦。

当我在borg init命令下定义两个参数以使用相同的描述文本时,问题仅出现在 上。即-e--encryption应该使用相同的描述,因为它们实际上是相同的参数。对于borg的论点来说,这已经很好用了,但是现在可以了。

这是我的代码,略作编辑以节省您的冗余:

compdef _borg borg

function _borg {
    local line ret=1
    local -a argus

    local logs="--critical --error --warning --debug --info -v --verbose"

    argus+=(
        "(*)"{-h,--help}"[Show help and exit]"
        "(*)-V[Show Borg version and exit]"
        "($logs)--critical[Work on log level CRITICAL]"
        "($logs)--error[Work on log level ERROR]"
        "($logs)--warning[Work on log level WARNING (default)]"
        "($logs)"{--info,-v,--verbose}"[Work on log level INFO]"
        "($logs)--debug[Enable debug output; log level DEBUG]"
        {-p,--progress}"[Show progress]"
        "--log-json[Output one JSON object per log line instead of formatted text]"
        "--show-version[Show/log borg version]"
        "--show-rc[Show/log returncode]"
        "--consider-part-files[treat part files like normal files (e.g. to list/extract them)]"
        "--lock-wait[Wait at most SECONDS for acquiring a repository/cache lock (default 1)]:SECONDS:()"
        "--umask[Set umask to M (local and remote; default 0077)]:M (umask value, e.g. 0077):()"
        "--remote-path[Use PATH as borg executable on the remote (default: \"borg\")]:PATH:()"
        "--remote-ratelimit[Set remote network upload rate limit in kiByte/s (default: 0=unlimited)]:RATE:()"
        "--debug-profile[Write execution profile in Borg format into FILE.]:FILE:_files"
        "--rsh[Use this command to connect to the \"borg serve\" process (default: \"ssh\")]:RSH:()"
        "1: :((init\:\"Initialize a new repository\" \
                create\:\"Create a new archive\" \
                extract\:\"Extract the contents of an archive\" \
                check\:\"Verifies consistency of a repository and its archives\" \
                rename\:\"Renames an archive in a repository\" \
                list\:\"Lists contents of a repository or archive\" \
                diff\:\"Finds differences between archives\" \
                delete\:\"Deletes an archive or an entire repository (and its cache)\" \
                prune\:\"Prunes a repository\" \
                info\:\"Shows info about a repository or archive\" \
                mount\:\"Mounts an archive as a FUSE filesystem\" \
                unmount\:\"Unmounts a FUSE filesystem mounted with \\\"borg mount\\\"\" \
                key\:\"Keyword for key-related functions\" \
                upgrade\:\"Upgrade a local Borg repository\" \
                recreate\:\"EXPERIMENTAL: Recreates contents of existing archives\" \
                export-tar\:\"Creates a tarball from an archive\" \
                serve\:\"Starts repository server process. Not usually used manually.\" \
                config\:\"Gets and sets options in local repository and cache config files\" \
                with-lock\:\"Executes another command with the repository lock held\" \
                break-lock\:\"Breaks the repository and cache locks\" \
                benchmark\:\"Keyword for the benchmark function\"))" \
        "*::arg:->args"
    )

    _arguments -w -s -S -C $argus[@] && ret=0

    case $line[1] in
        benchmark)
            _borg_benchmark
            ;;
        init)
            _borg_init
            ;;
        key)
            _borg_key
            ;;
    esac
    return ret
}

function _borg_benchmark {
# stuff
}

function _borg_benchmark_crud {
# stuff again
}

function _borg_init {
    local line ret=1
    local -a argus

    argus+=(
        "-t[This is a test]"
        "--test[This is a test]"
        "(--append-only)--append-only[Create an append-only mode repository]"
        "*::arg:->args"
    )

    _arguments -w -s -S -C $argus[@] && ret=0

    return ret
}

function _borg_key {
# key stuff
}

function _borg_key_changepassphrase {
# stuff
}

function _borg_key_export {
# more stuff
}

function _borg_key_import {
# other stuff
}

如果我尝试使用此设置来对borg init -进行制表符补全,则会得到以下输出:

$ borg init -
Completing option
--append-only                                              
--test                                                     

-t                                                         
-- Create an append-only mode repository                   
-- This is a test                                          
--append-only                                              
--test                                                     

-t                                                         
-- Create an append-only mode repository                   
-- This is a test                                          
--append-only                                              
--test                                                     

-t                                                         
-- Create an append-only mode repository                   
-- This is a test                                          
--append-only                                              
--test                                                     

-t                                                         
-- Create an append-only mode repository                   
-- This is a test

完成似乎忘记了选项卡,并重复四次。如果我将--test[This is a test]中的--test[This is another test]更改为_borg_init,则会得到以下完成:

$ borg init -
Completing option
--append-only  -- Create an append-only mode repository
--test         -- This is another test
-t             -- This is a test

在没有损坏的意义上,以上内容是“正确的”,但我似乎无法在子命令中定义共享描述的自变量。我该怎么办?而且,更一般地说,您如何应该定义带有子命令(反过来可能具有更多自变量)的命令的补全?

0 个答案:

没有答案