如何在不影响其他完成脚本的情况下重置COMP_WORDBREAKS?

Ray*_*ond 22 bash shell autocomplete bash-completion

当我实现bash自动完成功能时,有些东西让我感到困惑,我将它放在/etc/bash_completion.d/中

为了实现某些功能,我想:从变量中删除单词break字符冒号()$COMP_WORDBREAKS/在开头添加斜杠()$COMP_WORDBREAKS.

COMP_WORDBREAKS=" /'><=;|&("
_mytool()
{
    local cur=${COMP_WORDS[COMP_CWORD]}
    compopt -o nospace

    # my implement here

    COMPREPLY=( $(compgen ..........my_implement......... -- $cur) )
}
complete -F _mytool mytool
Run Code Online (Sandbox Code Playgroud)

但是,我无法COMP_WORDBREAKS直接重置,因为该值与其他完成脚本共享.调用完成函数时,COMP_WORDS已经填充了变量数组,因此本地更改COMP_WORDBREAKS不起作用.

是否有任何解决方案可以更改COMP_WORDBREAKS一个完成脚本而对其他脚本没有影响?

$ echo $BASH_VERSION
4.2.10(1)-release
Run Code Online (Sandbox Code Playgroud)

Rad*_*ler 24

$COMP_WORDBREAKS在完成脚本中修改不是推荐的方式(因为它是一个全局变量,它可能会影响其他完成脚本的行为 - 例如ssh).

但是,bash完成提供了一些帮助方法,您可以使用它们来实现目标.

在完成单词中处理非破坏字符的推荐方法是使用两个辅助方法:

  • _get_comp_words_by_ref-n EXCLUDE选项
    • 获得单词到完成而不考虑EXCLUDE中的字符作为单词中断
  • __ltrim_colon_completions

所以,这是一个如何在完成单词中处理冒号(:)的基本示例:

_mytool()
{
    local cur
    _get_comp_words_by_ref -n : cur

    # my implementation here

    COMPREPLY=( $(compgen ..........my_implement......... -- $cur) )

    __ltrim_colon_completions "$cur"
}
complete -F _mytool mytool
Run Code Online (Sandbox Code Playgroud)

作为最后的提示,辅助方法位于/etc/bash_completion.查看内部以阅读每种方法的详细说明并发现更多辅助方法.

  • 您可以使用“_init_completion -n :”代替“_get_comp_words_by_ref”,但必须声明更多局部变量。 (3认同)
  • 这只能正常工作,当我将这行 `cur="${COMP_WORDS[COMP_CWORD]}"` 放在 `_get_comp_words_by_ref -n : cur` 之前也很高兴知道,如果您也使用 prev,则可以将其添加到最后`_get_comp_words_by_ref -n:当前上一个` (2认同)
  • `/etc/bash_completion` 的内容在 `__ltrim_colon_completions` 的标题注释中告诉我们:“首选解决方案是从 .bashrc 中的 COMP_WORDBREAKS 中删除冒号 (:)” (2认同)