An Introduction to Programmable Completion in Bash

Variant 2: Using a Function

The built-in command complete can be used to assign a user-defined function as the completion logic for a command by using the option -F followed by the name of the function. For example, if we define a function _pulseaudio_tcp_completion, we can assign it to the command pulseaudio-tcp as follows:

complete -F _pulseaudio_tcp_completion -- pulseaudio-tcp

If a Bash function is associated with the completion of a certain command, that function is called every time a completion is requested for that command. The function interacts with the command line interpreter by means of special Shell variables the names of which all start with COMP…. Three of these special variables will be presented here:

  • COMP_WORDS: Bash array containing a list of words the interpreter already was able to parse . The array contains the command name as first element.
    • Note that if the user has already started typing an (incomplete) last word, then the array includes the already typed string as last element.
    • Also note that the cursor need not necessarily be located at the last word, the user could also attempt to complete an intermediate word.
  • COMP_CWORD: Contains the index of the word that the cursor is currently located in.
  • The function is expected to assign the list of completions that are available to the user in this situation to an array variable COMPREPLY.

Note: The list above is not exhaustive; the Bash manual sections „Programmable Completion“ and „Shell Variables“ contain further information and the full set of special variables and keywords.

For example, given the following command line, where the cursor is currently located at the end of the second word, st, and the Tabulator key has been pressed:

prompt> pulseaudio-tcpst--debug
  • COMP_WORDS contains the elements pulseaudio-tcp, st and --debug, and
  • COMP_CWORD has the value 1 (the index of st in COMP_WORDS).

Given this information, a rough outline for a completion function could be:

_pulseaudio_tcp_completion() {

    1. Find the word that is currently to be completed, which will be
       the element at COMP_CWORD in array COMP_WORDS.

    2. Determine a list of words that the command in question supports
       as valid parameter values.

    3. Given the list of valid words, based on the currently possibly
       incomplete word "COMP_WORDS[COMP_CWORD]", determine a list of
       effective completions. Note: One way to do this is by determining
       the output of
    
         compgen -W "$valid_words" -- "$incomplete_word"

    4. Store the list of effective completions to array COMPREPLY.

    5. Exit successfully.

}