Search code examples
bashbash-completion

How to configure bash autocomplete for file search and custom search?


I want to have a command autocomplete uploaded scripts that would be run remotely, but the user could also pick a local script to upload. Here is a small example to illustrate the problem I have with the bash complete logic.

_test_complete()
{
    local cur prev opts uploaded_scripts
    uploaded_scripts='proc1.sh proc2.sh'
    
    COMPREPLY=()
    cur="${COMP_WORDS[COMP_CWORD]}"
    prev="${COMP_WORDS[COMP_CWORD-1]}"
    if [[ ${prev} == '-s' ]] ; then
        COMPREPLY=( $(compgen -W "${uploaded_scripts}" -- ${cur}) )
        return 0
    fi
}

complete -F _test_complete remote

The example almost works but it does not autocomplete local file searches anymore.

$ remote -s proc<TAB><TAB>
proc1.sh  proc2.sh

$ remote -s proc1.sh ./<TAB><TAB>

Nothing happens when you do the usual file search ./ which should list files in current dir. Any ideas on how you can enable both ?


EDIT: The above example had a problem you could only pick one file with file complete. I hacked a solution which works but if anyone has a better one please leave a comment. Also with the -o default from the accepted answer.

_test_complete()
{
    local cur prev opts uploaded_scripts
    uploaded_scripts='proc1.sh proc2.sh'

    COMPREPLY=()
    cur="${COMP_WORDS[COMP_CWORD]}"
    prev="${COMP_WORDS[COMP_CWORD-1]}"
    
    [[ $COMP_CWORD == '1' ]] && LAST_OPT=''
    [[ ${prev:0:1} == '-' ]] && LAST_OPT=${prev}
    
    if [[ ${LAST_OPT} == '-s' ]]; then
        COMPREPLY=( $(compgen -o default -W "${uploaded_scripts}" -- ${cur}) )
        return 0
    fi
}

complete -F _test_complete remote

Solution

  • You can use complete's -o default option (Usually I'd use both -o default and -o bashdefault):

    complete -o default -F _test_complete remote
    

    According to man bash:

    • bashdefault

      Perform the rest of the default bash completions if the compspec generates no matches.

    • default

      Use readline's default filename completion if the compspec generates no matches.