Как определяются zsh автозаполнения для команд с подкомандами? - PullRequest
1 голос
/ 10 апреля 2020

Я пытаюсь написать скрипт завершения табуляции для 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
}

Если я пытаюсь перейти -complete 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

Выше приведено «правильно», в том смысле, что оно не нарушено, но я не могу показаться определить аргументы, которые разделяют описание в подкоманде. Как мне это сделать? И, в более общем смысле, как вы должны определять завершения для команд с подкомандами (которые, в свою очередь, могут иметь больше аргументов)?

...