Bash Auto-Completion: Setup and Troubleshooting Guide

autocompletebash

I'm trying to figure out how autocompletion works. I read this and the whole bash reference on complete, compgen and compopt, but this doesn't tell me how they really work together.

I'm trying to create an auto-completion for a command that takes a verb (from a rather small set) followed by the name of an existing file. So far I have this:

verbs=(upload download delete)

function ac_complete {
    printf "COMP_WORDS[%d/%d]: "  ${COMP_CWORD} ${#COMP_WORDS[@]}
    printf "[%s] " "${COMP_WORDS[@]}"
    printf "\n"
    
    if [[ COMP_CWORD -eq 1 ]] 
    then 
        COMPREPLY=( "${verbs[@]}" )
    else
        compopt -o default
    fi
}

complete -F ac_complete testit

but it doesn't work, I never see bash completing the verb.

  • How are possible completions returned?
  • What should be returned? Only those still valid at that point (ie, after a "d", should the set be "upload"/"download"/"delete" or only "download"/"delete" (if so there is a quick way to apply that restriction?)?

The completion for the file works, but I'd like to restrict it to few filetypes…

Best Answer

Look at the bash_completion package for examples.

The most common way to generate completions is to call compgen to build the COMPREPLY array. Figure out what arguments are valid this particular context, then translate that a compgen call. The compgen builtin filters arguments that aren't completions of the specified prefix. For example:

COMPREPLY=( $(compgen -W "${verbs[*]}" -- "${COMP_WORDS[COMP_CWORD]}") )

compgen is the step that figures out that to complete d, only download and delete are valid.

For files, use compgen -G "*.ext" to restrict the completion to files with the extension .ext. This simple idiom breaks on file names with spaces (or wildcard characters). The _filedir function from bash_completion handles file names in a more robust way (which still breaks on newlines and wildcard characters): _filedir '*.ext'.

Related Question