I want to enable auto-completion for DEploid for a long time. Finally got time to do it this Christmas break. I use autotools for DEploid, which made the process extremely simple.

This post is a short summary for what is needed for enabling bash auto-completion. Basically, you first need to check and enable (step 1) bash-complete as part of the install (step 2). Most importantly, you need a bash script (step 3) to instruct the shell what should pop up the next when you press the “Tab”.

Step 0. Dependencies

You can use apt-get install to get the following:

  • For autotools: autoconf autoconf-archive
  • For bash-completion: bash-completion, pkg-config is needed for Docker
  • For DEploid: build-essential libcppunit-dev zlib1g-dev

Step 1. Add the following to `configure.ac’.

# bash complete
AC_ARG_WITH([bash-completion-dir],
    AS_HELP_STRING([--with-bash-completion-dir[=PATH]],
        [Install the bash auto-completion script in this directory. @<:@default=yes@:>@]),
    [],
    [with_bash_completion_dir=yes])

if test "x$with_bash_completion_dir" = "xyes"; then
    PKG_CHECK_MODULES([BASH_COMPLETION], [bash-completion >= 2.0],
        [BASH_COMPLETION_DIR="`pkg-config --variable=completionsdir bash-completion`"],
        [BASH_COMPLETION_DIR="$datadir/bash-completion/completions"])
else
    BASH_COMPLETION_DIR="$with_bash_completion_dir"
fi

AC_SUBST([BASH_COMPLETION_DIR])
AM_CONDITIONAL([ENABLE_BASH_COMPLETION],[test "x$with_bash_completion_dir" != "xno"])

Step 2. Add the following to `Makefile.am’.

if ENABLE_BASH_COMPLETION
bashcompletiondir = $(BASH_COMPLETION_DIR)
dist_bashcompletion_DATA = src/dEploid_completion.sh
endif

Step 3. Create a bash file src/dEploid_completion.sh.

There are two main parts for the auto-completion here:

  1. Completing a flag, of which the list “opts” contains.
  2. Completing what files followed by the flag (e.g. -ref, -alt, etc), which compgen will provide a list of possible files and directories.
#/usr/bin/env bash

_dEploid_completions()
{
    local cur prev opts
    COMPREPLY=()
    cur="${COMP_WORDS[COMP_CWORD]}"
    prev="${COMP_WORDS[COMP_CWORD-1]}"
    opts="-h -help \
    -ref -alt -plaf -panel -exclude\
    -vcf -sample -plafFromVcf \
    -o -seed -noPanel\
    -ibd -lasso -best"


    if [[ ${cur} == -* || ${prev} == "dEploid" ]] ; then
        COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
        return 0
    else
        if [[ ${prev} == "-ref" || ${prev} == "-alt" || ${prev} == "-plaf" || ${prev} == "-panel" || ${prev} == "-exclude" ]] ; then
            COMPREPLY=( $(compgen -o plusdirs -f -X '!*.@(txt|gz)' -- ${cur}) )
            for ((i=0; i < ${#COMPREPLY[@]}; i++)); do
                [ -d "${COMPREPLY[$i]}" ] && COMPREPLY[$i]=${COMPREPLY[$i]}/
            done
            return 0
        else
            if [[ ${prev} == "-vcf" ]] ; then
                COMPREPLY=( $(compgen -o plusdirs -f -X '!*.@(vcf|gz)' -- ${cur}) )
                for ((i=0; i < ${#COMPREPLY[@]}; i++)); do
                    [ -d "${COMPREPLY[$i]}" ] && COMPREPLY[$i]=${COMPREPLY[$i]}/
                done
                return 0
            else
                return 0
            fi
        fi
    fi
    return 0
}

complete -o filenames -o nospace -o bashdefault -F _dEploid_completions dEploid

Done!

Reference