5

I'm writing a tab completion script for Bash, using Python to deliver the results of the completion. I'm using a dummy script to show the problem I'm having, the content is not important.

I've got a Bash script called dothat, with the following code:

var=$1
echo "You have chosen $var"

I've also got a script which creates the tab-completion for dothat, called dothat-completion.bash:

_comp_func()
{
    COMPREPLY=()

    # Gets the output of a Python file and puts it into a variable
    fruits=$(python fruit.py)

    COMPREPLY=($(compgen -W "${fruits[*]}" -- $cur)) 
}

complete -F _comp_func dothat

And the (simple) content of fruit.py:

print('fruit:', end='')

The Python script just prints the string to STDOUT, and this is then captured by the Bash completion function, and used to generate possible matches for tab completion.

Now, what I want to do with this script is, when I type dothat <TAB>, it will then complete to dothat fruit:, with no space on the end. The problem is, when I type dothat and press tab, it completes to dothat fruit: , with the unwanted trailing space.

I've tried changing the contents of the Python to the following, and all with the same result:

print('"fruit:"', end='')
print("'fruit:'", end='')
print('fruit:', end='')
print("fruit:", end='')
print("fruit: ", end='')
print("fruit:          ", end='')
print('fruit')

Even:

foo='fruit'
print(foo)

And all of my attempts are fruitless, as they achieve the same result. It doesn't matter whether there are zero, one or twenty spaces on the string: if the Python outputs the string fruit: and feeds it back into the Bash completion script, compgen will decide to complete fruit: with a space.

Is there an obvious solution here that I've missed? For either the Bash or the Python?

1 Answer 1

7

This is the default behaviour for complete when a full match is found, to append a space and allow further typing into the line, indicating that this word has been completed. And here you have only one word into COMPREPLY, so after TAB you get this word completed.

To overrride this default behavior, you could use -o nospace. From man bashbuiltins:

nospace Tell readline not to append a space (the default) to words completed at the end of the line.

2
  • 1
    Perfect, that solves the problem! Thank you!
    – Lou
    Nov 10, 2020 at 13:00
  • How can I use the nospace option only for a sub set of completions though? Jan 21 at 1:53

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .