Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bash Completion script to complete file path after certain arguments options

I am writing a bash completion script for a command-line tool:

_plink()
{
    local cur prev opts
    COMPREPLY=()
    cur="${COMP_WORDS[COMP_CWORD]}"
    prev="${COMP_WORDS[COMP_CWORD-1]}"
    opts="--1 --23file --a1-allele --a2-allele --adjust --aec"

    if [[ ${cur} == --*file ]] || [[ ${cur} == --out ]]; then
        COMPREPLY=( $(compgen -W "$(ls)" -- ${cur}) )
    elif [[ ${cur} == -* ]] ; then
        COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
        return 0
    fi
}
complete -F _plink plink1.9

The idea is if the after the option --*file and --out, bash should autocomplete the file path. Right now I am using "$(ls)" which only completes the filenames in current working path. Any suggestions?

like image 614
qed Avatar asked Jun 02 '14 15:06

qed


2 Answers

You can use compgen -f to complete filenames, like this:

if [[ ${prev} == --*file ]] || [[ ${prev} == --out ]]; then
    COMPREPLY=( $(compgen -f -- ${cur}) )
elif ...

However, compgen -f isn't great at completing filenames because it doesn't honour spaces in filenames.

A better way is to use the _filedir function available in bash-completion-lib. It might already be available on your system (type: declare -f _filedir to check).

Using _filedir, your completion function becomes:

if [[ ${prev} == --*file ]] || [[ ${prev} == --out ]]; then
    _filedir
elif ...
like image 132
dogbane Avatar answered Nov 01 '22 01:11

dogbane


Alternatively if you do not have the bash-completion-lib, I looked at the source of the _filedir() function and was able to get full bash completion using comptopt -o along with compgen -f:

if [[ ${prev} == --*file ]] || [[ ${prev} == --out ]]; then
    comptopt -o filenames 2>/dev/null
    COMPREPLY=( $(compgen -f -- ${cur}) )
elif ...

However, you do not get the functionality of resolving ~usernames or case-insensitivity that _filedir() provides.

like image 35
The Gargantuan Avatar answered Nov 01 '22 01:11

The Gargantuan