当我的单词包含冒号时如何给出正确的选项卡完成建议

tof*_*tis 5 bash bash-completion

我正在为一个实用程序编写一个 bash 选项卡完成文件,该文件有时需要表单上的完整 URL:protocol://host:port. 这包含两个冒号,已被证明对制表符补全有问题。这是因为冒号被视为分词符。我已阅读,我不应该改变COMP_WORDBREAKS直接,所以我想用_get_comp_words_by_ref__ltrim_colon_completions为这里建议:如何重置COMP_WORDBREAKS,而不影响其他完成脚本?

这适用于单个冒号,但第二个冒号会导致一个小问题,如这个最小示例所示:

这个例子说明了这个问题。它出现在建议中的任意数量的冒号上。

[root@2e3e8853cc0c /]# cat /etc/bash_completion.d/foo 
_foo()
{
    local cur
    COMPREPLY=()
    _get_comp_words_by_ref -n : -c cur

    COMPREPLY=( $(compgen -W "http://host:1234/aaa http://host:1234/bbb http://host:1234/ccc" -- ${cur}) )
    __ltrim_colon_completions "$cur"
    return 0
}
complete -F _foo foo
Run Code Online (Sandbox Code Playgroud)

foo成功完成公共部分后点击选项卡。之后点击两次 Tab 会产生以下建议:

[root@2e3e8853cc0c /]# foo http://host:1234/
1234/aaa  1234/bbb  1234/ccc
Run Code Online (Sandbox Code Playgroud)

想要的结果当然是:

[root@2e3e8853cc0c /]# foo http://host:1234/
http://host:1234/aaa  http://host:1234/bbb  http://host:1234/ccc
Run Code Online (Sandbox Code Playgroud)

之后,按 a、b 或 c 加选项卡按预期工作,它完成了完整的 URL。

关于如何产生正确输出的任何建议?我是否需要手动更改COMPREPLY变量,还是我只是使用了错误的函数?

pyn*_*exj 2

我根据我经常使用的一个技巧想出了一个解决方案。希望它会有所帮助。

\n
_bar()\n{\n    local CUR=$2\n    local cur\n    local -a compreply=()\n    local -a urls=(ftp://gnu.org \\\n                   http://host1:1234/aaa \\\n                   http://host2:1234/bbb \\\n                   http://host2:1234/ccc)\n\n    _get_comp_words_by_ref -n : -c cur\n\n    compreply=( $(compgen -W "${urls[*]}" -- "$cur") )\n    COMPREPLY=( "${compreply[@]}" )\n    __ltrim_colon_completions "$cur"\n\n    if [[ ${#COMPREPLY[@]} -gt 1 ]]; then\n        local common_prefix\n        common_prefix=$( printf '%s\\n' "${COMPREPLY[@]}" \\\n                         | sed '$q;N;s/^\\(.*\\).*\\n\\1.*$/\\1/;h;G;D' )\n        if [[ $common_prefix == "$CUR" ]]; then\n            COMPREPLY=( "${compreply[@]}" " " )\n        fi\n    fi\n\n    return 0\n}\n\ncomplete -F _bar bar\n
Run Code Online (Sandbox Code Playgroud)\n

以下是它的样子(用 测试Bash 4.3.33):

\n
[STEP 101] $ bar <TAB><TAB>\n                       http://host1:1234/aaa  http://host2:1234/ccc\nftp://gnu.org          http://host2:1234/bbb\n[STEP 101] $ bar f<TAB>\n[STEP 101] $ bar ftp://gnu.org\xe2\x90\xa3\n[STEP 101] $ bar ftp://gnu.org <ENTER>\nbash: bar: command not found\n[STEP 102] $ bar h<TAB>\n[STEP 102] $ bar http://host\n[STEP 102] $ bar http://host<TAB><TAB>\n                       http://host2:1234/bbb\nhttp://host1:1234/aaa  http://host2:1234/ccc\n[STEP 102] $ bar http://host2<TAB>\n[STEP 102] $ bar http://host2:1234/\n[STEP 102] $ bar http://host2:1234/<TAB><TAB>\n                       http://host2:1234/bbb  http://host2:1234/ccc\n[STEP 102] $ bar http://host2:1234/b<TAB>\n[STEP 102] $ bar http://host2:1234/bbb\xe2\x90\xa3\n[STEP 102] $ bar http://host2:1234/bbb <ENTER>\nbash: bar: command not found\n[STEP 103] $\n
Run Code Online (Sandbox Code Playgroud)\n

实际上,问题并不特定于两个或多个冒号。一个冒号也有类似的问题。

\n