10

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?

1
  • 1
    compgen -o filenames -G "$cur*" Commented Jun 2, 2014 at 16:12

2 Answers 2

15

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 ...
Sign up to request clarification or add additional context in comments.

Comments

2

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.

1 Comment

A minor typo: s/comptopt/compopt/

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.