Bash – Smart Bash Completion Depending on Argument position

autocompletebash

I have a simple bash function, a wrapper around scp basically. Invoked using

copytomachine <Machine> <File>

I have set up some simple auto complete such that when I type

copytomachine <TAB><TAB>

It presents me a list of the available machines, just a hard-coded sequence at present, which is fine for my needs.

If however I type

copytomachine BUILD_SERVER <TAB><TAB>

I would like it to offer me a list of files in my directory and be able to autocomplete their paths etc. However, I do not want this list of files to be presented to me for the first param (the machine name).

My current completion script looks like:

_machines_completions()
{
    local opts
    opts="BUILD_SERVER TEST_SERVER LOCAL_MACHINE"
    COMPREPLY=( $(compgen -W "${opts}" -- ${COMP_WORDS[COMP_CWORD]}) )
    return 0
}

Can anyone advise how I can modify this to allow me to tab-complete for these defined machine names for parameter 1, and tab-complete for filenames on parameter 2?

Best Answer

Since COMP_CWORD is the word number, you could test its value:

_machines_completions()
{
    local opts
    opts="BUILD_SERVER TEST_SERVER LOCAL_MACHINE"
    case $COMP_CWORD in
        1)
            COMPREPLY=( $(compgen -W "${opts}" -- "${COMP_WORDS[COMP_CWORD]}") )
            ;;
        2)
            COMPREPLY=( $(compgen -o default -- "${COMP_WORDS[COMP_CWORD]}") )
            ;;
    esac
    return 0
}

-o default will:

Use Readline’s default filename completion if the compspec generates no matches.

Related Question