Search code examples
autocompletezshoh-my-zshzsh-completion

zsh completion with nested control functions


I'm writing completion function for zsh. I took cargo completion function as a basis for mine. For the most part it works fine except for -h and --help options. Completion ouput for these functions is unaligned and repeated multiple times (presented below). This only happens when control functions (_describe, _arguments etc) are present in case structure. Why this is happening and how can I fix this behavior?

Completion function:

#compdef test
_test() {
    local context state state_descr line
    typeset -A opt_args
    _arguments \
        "(- 1 *)"{-h,--help}"[Help]" \
        "1: :->command" \
        "*:: :->args"

    case $state in
        command)
            _alternative 'arguments:custom arg:(a b c)'
            ;;
        args)
            _arguments \
              "-a[All]" \
              "-n[None]"
    esac
}
_test

Shell output:

> test -[TAB]
--help
-h
-- Help
--help
-h
-- Help
--help
-h
-- Help

Solution

  • I've just encountered the same issue. The solution is to return zero from your completion function:

    #compdef test
    
    _test() {
        ...
    
        return 0
    }
    
    _test
    

    All completion scripts that I've seen use ret variable which is initially 1 and then set to 0 if any completion function succeeded:

    #compdef test
    _test() {
        local context state state_descr line
        local ret=1
    
        typeset -A opt_args
        _arguments \
            "(- 1 *)"{-h,--help}"[Help]" \
            "1: :->command" \
            "*:: :->args" && ret=0
    
        case $state in
            command)
                _alternative 'arguments:custom arg:(a b c)' && ret=0
                ;;
            args)
                _arguments \
                  "-a[All]" \
                  "-n[None]" && ret=0
        esac
    
        return ret
    }
    
    _test
    

    I'm not sure why they do it, though.