如何完成可变数量的包含空格的参数

How to complete a variable number of arguments containing spaces

我已经构建了一个命令行工具,我需要使用 zsh 完成参数。我从来没有写过 zsh 完成函数,所以我查看了 zsh 提供的脚本,但我遗漏了一些东西以便它可以正常工作。

因此,mytool 可以采用可变数量的值和两个选项。 以下是一些调用示例:

mytool ONE
mytool ONE TWO
mytool AAA BBB CCC DDD EEE --info

为了完成这些值,我有另一个可执行文件将所有可能的行输出到标准输出,就像这个名为 getdata:

的简化脚本
#!/usr/local/bin/zsh

echo ONE
echo TWO ONE
echo TWO TWO
# ... a lot of lines
echo OTHER ONE
echo ONE ANOTHER LINE
echo AAA BBB CCC DDD EEE

每个完成都必须匹配整行,所以在我的 getdata 示例中,不可能仅使用值二来完成,因为整行不存在,它必须是二一或二二。

由于这个脚本比较耗时,我想使用zsh缓存功能。所以,这是我的 zsh 完整脚本:

compdef _complete_mytool mytool
__mytool_caching_policy() {
    oldp=( ""(Nmh+1) )     # 1 hour
    (( $#oldp ))
}

__mytool_deployments() {
    local cache_policy

    zstyle -s ":completion:${curcontext}:" cache-policy cache_policy
    if [[ -z "$cache_policy" ]]; then
        zstyle ":completion:${curcontext}:" cache-policy __mytool_caching_policy
    fi

    if ( [[ ${+_mytool_values} -eq 0 ]] || _cache_invalid mytool_deployments ) \
        && ! _retrieve_cache mytool_deployments;
    then
        local -a lines
        _mytool_values=(${(f)"$(_call_program values getdata)"})
        _store_cache mytool_deployments _mytool_values
    fi
    _describe "mytool values" _mytool_values
}

_complete_mytool() {
    integer ret=1
    local -a context expl line state state_descr args
    typeset -A opt_args

    args+=(
    '*:values:->values'
    '--help[show this help message and exit]'
    '(-i --info)'{-i,--info}'[display info about values and exit]'
    '(-v --version)'{-v,--version}'[display version about values and exit]'
    )

    _call_function res __mytool_deployments

    return ret
}

但是当我尝试完成时,空格被反斜杠转义,我不希望出现这种情况。

mytool OTHER\ ONE

选项似乎也没有完成...所以,任何帮助将不胜感激。

感谢 freenode zsh 频道的 okdana 帮了我很多。

所以,解决方案是:

compdef _complete_mytool mytool
__mytool_caching_policy() {
    oldp=( ""(Nmh+1) )     # 1 hour
    (( $#oldp ))
}

__mytool_deployments() {
    local cache_policy

    zstyle -s ":completion:${curcontext}:" cache-policy cache_policy
    if [[ -z "$cache_policy" ]]; then
        zstyle ":completion:${curcontext}:" cache-policy __mytool_caching_policy
    fi

    if ( [[ ${+_mytool_values} -eq 0 ]] || _cache_invalid mytool_deployments ) \
        && ! _retrieve_cache mytool_deployments;
    then
        local -a lines
        _mytool_values=(${(f)"$(_call_program values getdata)"})
        _store_cache mytool_deployments _mytool_values
    fi
    _describe "mytool values" _mytool_values -Q
}

_complete_mytool() {
  _arguments : \
    ': :__mytool_deployments' \
    '--help[show this help message and exit]' \
    '(-i --info)'{-i,--info}'[display info about values and exit]' \
    '(-v --version)'{-v,--version}'[display version about values and exit]'
}