zsh完成功能(compdef)未完成_arguments

问题描述 投票:0回答:1
的简化版本。

当i type

my-cli <TAB>
我可以看到

subcmd

自动完成。

当i type
my-cli macos <TAB>
我可以看到
_values

case

my-cli macos make-encrypted-volume <TAB>
自动完成。
当i type
_arguments 
我看不到该

case

compdef
自动完成。
i我在这里读到,
-
需要CLI从a开始,以激活
_arguments

,但是即使我做

my-cli macos make-encrypted-volume -<TAB>

都没有显示。
任何帮助?
#compdef my-cli

# Filter out global options -v / --verbose
local -a filtered_words
filtered_words=("${(@)words:#(-v|--verbose)}")

# Reassign $words/$CURRENT so that subcommand logic ignores -v/--verbose
words=("${filtered_words[@]}")
CURRENT=$#words

# Use a stateful _arguments approach
_arguments -C \
    '1:subcommand:->subcmd' \
    '2:action:->action' \
    '*::options:->options'

case "${state}" in
    subcmd)
        _values 'subcommand' \
            'macos[utilities for macOS]' \
            '--version[display version information and exit]' \
            '--help[show help message and exit]' \
        ;;

    action)
        case "${words[2]}" in
            macos)
                _values 'macos subcommand' \
                    'find-unencrypted-volumes[find all unencrypted volumes]' \
                    'make-encrypted-volume[make an encrypted APFS volume]' \
                    '--help[show help message and exit]' \
                    '-h[show help message and exit]'
                ;;
        esac
        ;;

    options)
        case "${words[2]}" in
            macos)
                case "${words[3]}" in
                    find-unencrypted-volumes)
                        _arguments \
                            '-h[show help message and exit]:show help message and exit'
                    ;;
                    make-encrypted-volume)
                        _arguments \
                            '-h[show help message and exit]:show help message and exit' \
                            '-n[REQUIRED name of the encrypted volume]:REQUIRED name of the encrypted volume' \
                            '-q[OPTIONAL size of the encrypted volume in Gb i.e. -q 50g]:OPTIONAL size of the encrypted volume in Gb i.e. -q 50g'
                    ;;
                esac
                ;;
        esac
        ;;
esac

return 0
    
我们可以通过

functions -T

(或
autocomplete zsh tab-completion bash-completion zsh-completion
1个回答
0
投票

)跟踪该功能,以查看什么是hapenning,除了

true
命令或
:
都可以像经典的printf/echo样式一样调试调试,这样:
% functions -T _my-cli  ;# trace the function to see what's happening.
% my-cli macos make-encrypted-volume <TAB> ;# (added newline here.)
+_my-cli:4> local -a filtered_words
+_my-cli:5> filtered_words=( my-cli macos make-encrypted-volume '' )
+_my-cli:8> words=( my-cli macos make-encrypted-volume '' )
+_my-cli:9> CURRENT=4
+_my-cli:12> _arguments -C '1:subcommand:->subcmd' '2:action:->action' '*::options:->options'
+_my-cli:17> case options (subcmd)
+_my-cli:17> case options (action)
+_my-cli:17> case options (options)
+_my-cli:38> case make-encrypted-volume (macos)
+_my-cli:57> return 0
% my-cli macos make-encrypted-volume
No matches for: `options'
在这种情况下,${words[2]}
make-encrypted-volume
而不是

macos
。因此,像以下差异一样倾倒
${words[@]}

--- _my-cli.orig
+++ _my-cli
@@ -14,6 +14,7 @@
     '2:action:->action' \
     '*::options:->options'

+: 'XXX*>' ${(q)words}
 case "${state}" in
     subcmd)
         _values 'subcommand' \
@@ -35,6 +36,7 @@
         ;;

     options)
+        : 'XXX*>' ${(q)words}
         case "${words[2]}" in
             macos)
                 case "${words[3]}" in
请参阅跟踪输出:
% unfunction _my-cli; autoload -Uz _my-cli; functions -T _my-cli
% my-cli macos make-encrypted-volume <TAB> ;# (added newline here.)
+_my-cli:4> local -a filtered_words
+_my-cli:5> filtered_words=( my-cli macos make-encrypted-volume '' )
+_my-cli:8> words=( my-cli macos make-encrypted-volume '' )
+_my-cli:9> CURRENT=4
+_my-cli:12> _arguments -C '1:subcommand:->subcmd' '2:action:->action' '*::options:->options'
+_my-cli:17> : 'XXX*>' macos make-encrypted-volume ''''''
+_my-cli:18> case options (subcmd)
+_my-cli:18> case options (action)
+_my-cli:18> case options (options)
+_my-cli:39> : 'XXX*>' macos make-encrypted-volume ''''''
+_my-cli:40> case make-encrypted-volume (macos)
+_my-cli:59> return 0
% my-cli macos make-encrypted-volume
No matches for: `options'
因此,我们可以看到

_arguments ... '*::options:->options'
$words

$line
中删除了一些部分。快速的解决方法将遵循:

使用
_arguments
使用
->

notement²(因为
    _arguments
  • 修改
    $words
    )。
    使用
    compset
    强迫修改
    $words
    (和
    $CURRENT
  • 等),例如如何修改以匹配后续的
  • _arguments.
    _arguments
    
    
    上文的一些注释:
    --- _my-cli.orig
    +++ _my-cli
    @@ -1,5 +1,9 @@
     #compdef my-cli
    
    +# _arguments documentation says this: ³
    +local context state state_descr line ret=1
    +local -A opt_args
    +
     # Filter out global options -v / --verbose
     local -a filtered_words
     filtered_words=("${(@)words:#(-v|--verbose)}")
    @@ -14,6 +18,8 @@
         '2:action:->action' \
         '*::options:->options'
    
    +: 'XXX*>' ${(q)words}
    +: 'XXX*=' ${(q)line}
     case "${state}" in
         subcmd)
             _values 'subcommand' \
    @@ -35,9 +41,13 @@
             ;;
    
         options)
    -        case "${words[2]}" in
    +        : 'XXX*>' ${(q)words}
    +        : 'XXX*=' ${(q)line}
    +        compset -n 2
    +        : 'XXX*>' ${(q)words}
    +        case "${line[1]}" in
                 macos)
    -                case "${words[3]}" in
    +                case "${line[2]}" in
                         find-unencrypted-volumes)
                             _arguments \
                                 '-h[show help message and exit]:show help message and exit'
    
  • 中删除了一些部分
在ZSH手册中描述了这一点(来自
_arguments ... '*::options:->options'

):

$words

...

在消息前有两个结肠,“特殊数组”和“当前特殊参数”单词被修改以在执行或评估操作时仅参考正常参数。

²如果使用

_arguments
notations,请使用*::MESSAGE:ACTION

检查命令行元素
在ZSH手册中的

$line

是什么(来自'
Specs:Actions
'的底部附近):

在动作的性能中,数组“行”将设置为命令行的正常参数,即命令名称后的命令行中的单词不包括所有选项及其参数。

_arguments

这些声明在ZSH手册中(摘自

->

,'
Specs:actions',
$line
):
在$ state和$ state_descr中,_arguments还设置了如下所述的全局参数“上下文”,“ line”和“ opt_args”,并且不会重置对特殊参数(例如前缀和单词)所做的任何更改。 这使调用函数可以选择重置这些参数或在其中传播更改。

函数呼叫_arguments至少一个包含一个操作
_arguments

的函数必须声明适当的本地参数:

+local context state state_descr line


这里是以上整个代码:

local
在将来添加选项时,检查the theckile是脆弱的。因此,这是一个实现,避免了使用
_arguments
的实现,使用->string更多,然后筑巢
->string
用于命令,然后将其嵌套。

local context state state_descr line typeset -A opt_args

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.