Modern Bash has a very useful programmatic tab-completion feature. This feature is one of the main reasons that the terminal is still the most convenient interface to interact with a computer, IMHO.

"Programmatic" means that it's easy to add completion features for your own command-line tools. Yesterday I figured it will be a good exercise to add this for pss to complete the names of file types it can recognize; the list is growing longer with every release, and it would be nice to be able to quickly come up with the right type name without looking in the help all the time (is it --js or --javascript? etc).

So, simple completion is now live in the master branch of pss on Github. It consists of two parts. The first is this bash script (in the tools/ directory):

_pss_complete()
{
    local cur_word prev_word type_list

    # COMP_WORDS is an array of words in the current command line.
    # COMP_CWORD is the index of the current word (the one the cursor is
    # in). So COMP_WORDS[COMP_CWORD] is the current word; we also record
    # the previous word here, although this specific script doesn't
    # use it yet.
    cur_word="${COMP_WORDS[COMP_CWORD]}"
    prev_word="${COMP_WORDS[COMP_CWORD-1]}"

    # Ask pss to generate a list of types it supports
    type_list=`pss --show-type-list`

    # Only perform completion if the current word starts with a dash ('-'),
    # meaning that the user is trying to complete an option.
    if [[ ${cur_word} == -* ]] ; then
        # COMPREPLY is the array of possible completions, generated with
        # the compgen builtin.
        COMPREPLY=( $(compgen -W "${type_list}" -- ${cur_word}) )
    else
        COMPREPLY=()
    fi
    return 0
}

# Register _pss_complete to provide completion for the following commands
complete -F _pss_complete pss pssc

It's commented enough to be self-documenting, I hope. The most useful resource I found online that explains everything in detail is this page from Debian. For a bunch of sample completion scripts in the Debian repository, see this page. And, of course there's man bash.

You'll note that above I call pss --show-type-list to produce a list of whitespace-separated words which is then used by Bash's compgen command to generate completions. This is a new hidden option I added to pss just for this purpose. It's actually a common pattern in Bash completions: the tool itself knows best, so tools usually have special options the completion script can use to query things before it presents a list to the user.

Lastly, this needs to be integrated into your system. All we really have to do is source this bash script somewhere so it's part of your shell. There's already a place for such completion scripts on Ubuntu systems, in /etc/bash_completion.d; all files in that directory are sourced by the main bash completion script. I added a soft link to my script there, and things work great.


Comments

comments powered by Disqus