自动完成中引用的参数

自动完成中引用的参数

我有一个 bash 自动完成功能,仅当参数是单个单词时才起作用。我可以自动完成引用的语句,然后在 case 语句中使用来标记文件(想想元数据标记,有时需要多个单词。)

有没有办法让自动完成功能在特定选项后显示目录?脚本如下:

_script()
{
        local cur prev opts iter
        COMPREPLY=()
        cur="${COMP_WORDS[COMP_CWORD]}"
        prev="${COMP_WORDS[COMP_CWORD-1]}"
        opts="-t"
        if [[ ${cur} == -* ]] ; then
                COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
                return 0
        fi
        case "$prev" in
                -t)
                        option="single \"double\ word\""
                        option="${option//\\ /___}"
                        for iter in $option; do
                                if [[ $iter =~ ^$cur ]]; then
                                        COMPREPLY+=( "${iter//___/ }" )
                                fi
                        done
                        return 0
                        ;;
                "single"|"double word")
                        compopt -o default
                        COMPREPLY=()
                        return 0
                        ;;
        esac
}
complete -F _script script

当我这样使用它时:

script -t <tab>:它向我显示了正确的选项:single "double word"并且不显示目录(是的!这就是我想要的!)

如果我使用:

script -t single <tab>:它显示了可用的目录(是的!这就是我想要的!)

如果我使用:

script -t "double word" <tab>:它在选项卡上不输出任何内容。这就是我想要解决的问题。

答案1

你的处理double word是错误的(尽管它比shell,至少是bash,更有意义);因此它在 中不被识别case

如果将其放在set -x函数代码的顶部(或您感兴趣的行之前),您可以看到会发生什么。

您返回正确的字符串 ,"double word"其中"being 是可编程补全看到的单词的一部分。这有点奇怪,因为引号被识别,所以这"double word"只是一个单词,但它们没有被删除,以便函数_script确实看到它们。因此,完成可以使用"double word"但不能使用,double\ word尽管它与执行时的 shell 相同。所以这是文字和解析的命令行字符串的反直觉组合。

解决方案

如果你替换你的代码就可以工作

"single"|"double word"

"single"|"\"double word\""

甚至更好

"single"|"\"double word\""|"double\ word"|"'double word'"

建议

不过,我想建议一些更多的改变:

_script()
{ 
        local cur prev opts iter
        COMPREPLY=()
        cur="${COMP_WORDS[COMP_CWORD]}"
        prev="${COMP_WORDS[COMP_CWORD-1]}"
        opts="-t"
        if [[ ${cur} == -* ]] ; then
                COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
                return 0
        fi
        case "$prev" in
                -t)
                        options=(single "double\ word")
                        for iter in "${options[@]}"; do
                                if [[ $iter =~ ^$cur ]]; then
                                        COMPREPLY+=( "$iter" )
                                fi
                        done
                        return 0
                        ;;
                "single"|"double\ word")
                        compopt -o default
                        COMPREPLY=()
                        return 0
                        ;;
        esac
}

相关内容