You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

zsh compdef中_arguments补全失效问题求助

zsh补全函数第三级命令选项无法补全的修复方案

问题现象

我为个人CLI编写了zsh补全函数,遇到以下问题:

  • 输入my-cli <TAB>时,子命令补全正常;
  • 输入my-cli macos <TAB>时,macos下的子命令补全正常;
  • 输入my-cli macos make-encrypted-volume <TAB>或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:-&gt;subcmd' \
    '2:action:-&gt;action' \
    '*::options:-&gt;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

问题原因

  1. _arguments状态定义不合理:原代码中_arguments -C的固定位置状态定义,无法正确流转到第三级命令的选项补全逻辑,输入第三级命令后state未触发对应的options分支。
  2. 选项定义格式冗余:_arguments中选项后的描述重复,虽不直接报错,但可能干扰补全解析逻辑。

修复后的代码

#compdef my-cli

# 过滤全局选项 -v / --verbose
local -a filtered_words
filtered_words=("${(@)words:#(-v|--verbose)}")

# 重新赋值words和CURRENT,让子命令逻辑忽略全局选项
words=("${filtered_words[@]}")
CURRENT=$#words

# 调整状态流转逻辑,适配多级子命令补全
_arguments -C \
    '1:subcommand:-&gt;subcmd' \
    '*:: :->cmds'

case "${state}" in
    subcmd)
        _values 'subcommand' \
            'macos[macOS实用工具集]' \
            '--version[显示版本信息并退出]' \
            '--help[显示帮助信息并退出]'
        ;;

    cmds)
        case "${words[2]}" in
            macos)
                _values 'macos子命令' \
                    'find-unencrypted-volumes[查找所有未加密卷]' \
                    'make-encrypted-volume[创建加密APFS卷]' \
                    '--help[显示帮助信息并退出]' \
                    '-h[显示帮助信息并退出]'
                # 选中macos子命令后,切换到选项补全状态
                state='macos_subcmd_options'
                ;;
        esac
        ;;

    macos_subcmd_options)
        case "${words[3]}" in
            find-unencrypted-volumes)
                _arguments \
                    '-h[显示帮助信息并退出]'
                ;;
            make-encrypted-volume)
                _arguments \
                    '-h[显示帮助信息并退出]' \
                    '-n[加密卷名称(必填)]:加密卷名称:' \
                    '-q[加密卷大小(可选,单位Gb,如 -q 50g)]:加密卷大小:'
                ;;
        esac
        ;;
esac

return 0

修复说明

  1. 优化状态流转:将固定位置状态定义改为动态的*:: :->cmds,处理完第二级子命令后手动切换到macos_subcmd_options状态,确保第三级命令的选项补全逻辑被触发。
  2. 简化选项定义:移除_arguments中选项后重复的描述,遵循-opt[描述]:参数提示:的标准格式,避免冗余。
  3. 保留全局选项过滤:维持原有全局选项过滤逻辑,确保-v/--verbose不干扰子命令的补全判断。

内容的提问来源于stack exchange,提问作者64rl0

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 20:42:18