August 8, 2009
The poor man’s Bash Tab-completion

Bash has a built-in tab completion utility that sports an impressive array features and the ability to generate suggestions using complex logic. But what if you just want to add a static list of suggestions to a command? It took a little digging around the Bash manual but I finally found the magic words you need to add to you .bashrc file:

complete -o default -W "list of space separated words" [command]

Obviously, you need to replace list of space separated words and [command] with values of your choice. For the curious, let’s take this command apart and see what’s going on:

  • complete: Built in Bash command for controlling built-in tab completion behavior
  • -o default: Tell Bash to fall back on the default filename completion if no matches are found.
  • -W “list of space separated words”: This is where the magic happens. -W allows us to just provide a static list of suggestions. There are other flags that will dynamically evaluate suggestions at runtime, but we’ll leave that to a future post.
  • [command]: The command that tab-completion will apply to.

Say I want to just add the suggestions “all” and “clean” to the command make. The line I need to append to my .bashrc becomes:

complete -o default -W "all clean" make

Bonus: get a little dynamic

Using command substitution we can also generate the list of suggestions at Bash start time. This is very useful for completing names that can be found in other configuration files (like, say, SSH host-name completion).

complete -o default -W "`echo $(cat /path/to/file | grep 'lines i want')`" \
    [command]

(You might notice that we are using command substitution twice in the example above, once with back-ticks the other time using $(command). This is necessary because the -W argument does not accept new-line characters as delimiters. echoing will convert these new-lines in to spaces.)

Update: The friendly folks over at HN have pointed out that there non-stupid ways of putting together the aforementioned command substitution. Thanks for the correction folks! Here’s a better way to do it:

complete -o default -W "$(grep 'lines i want' /path/to/file | tr '\n' ' ')" \
    [command]

6:14pm  |   URL: https://tmblr.co/Zn_4by9TfRw
  
Filed under: bash cli howto 
  1. paksoy-blog posted this