3

I created a beautiful autocompletion for my script.

One thing though: when the argument is left for the user to decide (for example, the first argument is the name of the new project), I'd like to display a little line describing what is expected.

For example:
$> script [TAB][TAB]
<name of project>
$> script my_new_project

.

Of course, I thought about this:

if [ $COMP_CWORD -eq 1 ]; then
        local IFS=$'\n'
        COMPREPLY+=($(compgen -W "<name of project>"))

The problem though is that I obtain this:

$> script [TAB][TAB]
$> script <name of project>

That is, the one text I defined is automatically added to the command line when I press TAB.

.

I also tried this:

local IFS=$':'
COMPREPLY+=($(compgen -W "Help: <domain name associated with the project>"))

But the result is garbled, and it still add the words to the command line:

$> script [TAB][TAB]
<domain name associated with the project> Help:
$> script <domain name associated with the project>

.

Please, do you know if there's a sort of heredoc for autocompletion, where a help text just appears, but is not added to the command line?

Thank you!

Bibelo
  • 221
  • 2
  • 8
  • 1
    You may find [this approach](https://brbsix.github.io/2015/11/29/accessing-tab-completion-programmatically-in-bash/) useful. I haven't tried it out yet. But I also need the same effect you asked for. – Pedram Feb 04 '21 at 20:17
  • Wow sometimes it's about patience ^^ Thank you for your comment, I'm going to have a look ASAP – Bibelo Feb 05 '21 at 23:23
  • I have updated the answer with a heredoc example. – Pedram Feb 11 '21 at 08:04

1 Answers1

0

You could always use printf wherever you need in the completion script. Here is what I would do:

if [ $COMP_CWORD -eq 1 ]; then
   printf "\n *** Enter a project name: %s" "${COMP_LINE[@]}"
fi

Printing the COMP_LINE array is not particularly useful for the first argument though. If you have many more arguments and want to show the user what they have typed in so far, printing COMP_LINE might be the way to do it.

Also, you might want to suggest the existing project names to the user. In that case:

if [ $COMP_CWORD -eq 1 ]; then
   printf "\n *** Enter a project name: %s" "${COMP_LINE[@]}"
   list_of_project_names=("project1" "theotherproject" "testproject")
   COMPREPLY=($(compgen -W "${list_of_project_names[@]}" -- "$2"))
fi

Note that in a completion script, $2 is the current word being completed, $3 is the previous word, and $1 is the first word in the current command line.

For much longer descriptions, you can use 'heredoc':

if [ $COMP_CWORD -eq 1 ]; then
  cat<<EOF
# leave a blank line for formatting

*** You can select a project from suggestions or enter a
*** name for your new project:
EOF
  # Use _printf_ for printing the "${COMP_LINE[@]}" because
  # the _heredoc_ adds a newline to the end.
  printf ">>> %s" "${COMP_LINE[@]}"
  list_of_project_names=("project1" "theotherproject" "testproject")
  COMPREPLY=($(compgen -W "${list_of_project_names[@]}" -- "$2"))
fi

You can also use the read command with -e option as suggested here https://stackoverflow.com/a/4819945/6474744

For more complex behavior, you might find this interesting https://brbsix.github.io/2015/11/29/accessing-tab-completion-programmatically-in-bash/

Cheers

Pedram
  • 921
  • 1
  • 10
  • 17