Chapter 8: Command Line Editing

131

local cur _skipdot _cdpath local i j k

# Tilde expansion, with side effect of expanding tilde to full pathname case "$2" in

\~*) eval cur="$2" ;;

*) cur=$2 ;; esac

# no cdpath or absolute pathname -- straight directory completion if [[ -z "${CDPATH:-}" ]] || [[ "$cur" == @(./*|../*|/*) ]]; then

# compgen prints paths one per line; could also use while loop

IFS=$’\n’

COMPREPLY=( $(compgen -d -- "$cur") )

IFS=$’ \t\n’

# CDPATH+directories in the current directory if not in CDPATH else

IFS=$’\n’

_skipdot=false

# preprocess CDPATH to convert null directory names to .

_cdpath=${CDPATH/#:/.:}

_cdpath=${_cdpath//::/:.:}

_cdpath=${_cdpath/%:/:.} for i in ${_cdpath//:/$’\n’}; do if [[ $i -ef . ]]; then _skipdot=true; fi k="${#COMPREPLY[@]}" for j in $( compgen -d -- "$i/$cur" ); do

COMPREPLY[k++]=${j#$i/}

# cut off directory done done

$_skipdot || COMPREPLY+=( $(compgen -d -- "$cur") )

IFS=$’ \t\n’ fi

# variable names if appropriate shell option set and no completions if shopt -q cdable_vars && [[ ${#COMPREPLY[@]} -eq 0 ]]; then

COMPREPLY=( $(compgen -v -- "$cur") ) fi return 0

}

We install the completion function using the -F option to complete:

# Tell readline to quote appropriate and append slashes to directories;

# use the bash default completion for other arguments complete -o filenames -o nospace -o bashdefault -F _comp_cd cd