28

There is something confuse me when I implement a bash auto-completion function which I'll put it in /etc/bash_completion.d/

In order to achieve some feature, I want to remove the word break characters colon (:) from variable $COMP_WORDBREAKS and add a slash (/) at begin of $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

However, I can't reset COMP_WORDBREAKS directly because the value is shared with other completion scripts. By the time the completion function gets called, variable COMP_WORDS array has already been populated, so locally changes COMP_WORDBREAKS have no effect.

Is there any solution for changing COMP_WORDBREAKS in one completion script and no effect to other script?

$ echo $BASH_VERSION
4.2.10(1)-release
0

1 Answer 1

30

Modifying $COMP_WORDBREAKS in your completion script is not the recommended way (as it is a global variable and it could affect the behavior of other completion scripts - for example ssh).

However, bash completion offers some helper methods which you can use to achieve your goal.

The recommended way to handle non-word-breaking characters in completion words is by using the two helper methods:

  • _get_comp_words_by_ref with the -n EXCLUDE option
    • gets the word-to-complete without considering the characters in EXCLUDE as word breaks
  • __ltrim_colon_completions

So, here is a basic example of how to a handle a colon (:) in completion words:

_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

As a final tip, the helper methods are located in /etc/bash_completion. Take a look inside to read a detailed description of each method and to discover more helper methods.

Sign up to request clarification or add additional context in comments.

10 Comments

Thank you so much, this was really useful for my rake task completions in Ruby on Rails! Also, thanks for pointing out section E13 in the docs.
this only worked properly, when I put this line cur="${COMP_WORDS[COMP_CWORD]}" before _get_comp_words_by_ref -n : cur also good to know, if you use the prev too, you can add it at the end _get_comp_words_by_ref -n : cur prev
Content of /etc/bash_completion tells in the heading comment for __ltrim_colon_completions: "The preferred solution is to remove the colon (:) from COMP_WORDBREAKS in your .bashrc"
With the solution, completion works somewhat differently: Prefix ending with : is trimmed off from shown completions.
Instead of using _get_comp_words_by_ref you could use _init_completion -n :, but you have to declare more local variables then.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.