带有等号的完整命令选项

问题描述 投票:5回答:2

我正在尝试为可能需要较长选项的命令编写Bash完成脚本,格式为--option--param=value。如果用户已经在命令行上输入了一个选项,则该选项应从完成列表中排除(假设仅在命令行上一次指定给定选项才有意义)。

这里是第一次尝试:

_myprog()
{
    local cur="${COMP_WORDS[$COMP_CWORD]}"

    local words=(--help --param1= --param-state --param2=)
    _exclude_cmd_line_opts
    COMPREPLY=( $(compgen -W "${words[*]}" -- "$cur") )
}
complete -F _myprog myprog

_exclude_cmd_line_opts() {
    local len=$(($COMP_CWORD - 1))
    local i
    for i in "${COMP_WORDS[@]:1:$len}" ; do
         [[ $i == --* ]] && words=( "${words[@]/$i}" )
    done
}

如果源此脚本为source script.sh,然后编写:

$ myprog --param1= <tab><tab>

我得到以下完成列表:

=              --help         --param2=      --param-state

所以它几乎可以正常工作,除了在完成列表中出现一个虚假的'='符号。有什么建议吗?

bash
2个回答
1
投票

由于默认内容COMP_WORDBREAKS,因此在命令行上输入等号会导致单词中断。效果似乎是等号在COMP_WORDS中作为单独的单词输入。在_exclude_cmd_line_opts的以下修改中利用了这一点:

_exclude_cmd_line_opts() {
    local len=$(($COMP_CWORD - 1))
    local i
    for ((i=1 ; i<=len; i++)) ; do
        local j="${COMP_WORDS[$i]}"
        if [[ $j == --* ]] ; then
            (( i<len )) && [[ ${COMP_WORDS[$(( i + 1))]} == '=' ]] && j="$j="
            words=( "${words[@]/$j}" )
        fi
    done
}

_exclude_cmd_line_opts原始版本的问题是,例如${words[@]/$j}=时,words=(param1=)会给出伪造的j="param1"(请注意$j中缺少的尾随等号,这是由[ C0])..

更新

我发现了另一个特殊之处。上面的情况很好用,因为我不必在COMP_WORDBREAKS符号后立即输入<tab>。但是,例如,如果=且我键入words=(--param= --param-info),则仍有两个候选补全,并且当前单词仅部分完成以成为--par<tab>。此时,我想选择两个候选者中的第一个,然后在命令行上键入一个显式的--param符号,然后键入=,现在发生的是Bash认为您已经键入了空格(因为COMP_WORDBREAKS包含<tab>),当前完成字从=变为--param=。再次,这将使Bash readline省略插入通常的空格,因此用户被迫键入空格以继续完成下一个选项。

通过返回带有空字符串的=数组,可以避免在上述情况下必须输入空格。

COMPREPLY

1
投票

此解决方案利用了_myprog() { local cur="${COMP_WORDS[$COMP_CWORD]}" local prev="" (( COMP_CWORD > 0 )) && prev="${COMP_WORDS[$(( COMP_CWORD - 1))]}" [[ $cur == '=' && $prev == --* ]] && { COMPREPLY=( "" ); return; } local words=(--param= --param-info) _exclude_cmd_line_opts COMPREPLY=( $(compgen -W "${words[*]}" -- "$cur") ) } 功能。它不会为采用此选项的选项填写参数。它还接受格式为_init_completion的长选项。这不会检查光标位置后的行是否包含排除选项,但是可以根据需要进行修改以考虑整个命令行。

--param value
© www.soinside.com 2019 - 2024. All rights reserved.