# cd(1) completion -*- shell-script -*- # This meta-cd function observes the CDPATH variable, so that `cd` # additionally completes on directories under those specified in CDPATH. _comp_cmd_cd() { local cur prev words cword comp_args _comp_initialize -- "$@" || return if [[ $cur == -* ]]; then _comp_compgen_help -c help "$1" compopt +o nospace return fi local i j k compopt -o filenames # Use standard dir completion if no CDPATH or parameter starts with /, # ./ or ../ if [[ ! ${CDPATH-} || $cur == ?(.)?(.)/* ]]; then _comp_compgen_filedir -d return fi local mark_dirs="" mark_symdirs="" _comp_readline_variable_on mark-directories && mark_dirs=set _comp_readline_variable_on mark-symlinked-directories && mark_symdirs=set # we have a CDPATH, so loop on its contents local paths dirs _comp_split -F : paths "$CDPATH" for i in "${paths[@]}"; do # create an array of matched subdirs k=${#COMPREPLY[@]} _comp_compgen -v dirs -c "$i/$cur" -- -d for j in "${dirs[@]}"; do if [[ ($mark_symdirs && -L $j || $mark_dirs && ! -L $j) && ! -d ${j#"$i/"} ]]; then j+="/" fi COMPREPLY[k++]=${j#"$i/"} done done _comp_compgen -a filedir -d if ((${#COMPREPLY[@]} == 1)); then i=${COMPREPLY[0]} if [[ $i == "$cur" && $i != "*/" ]]; then COMPREPLY[0]="${i}/" fi fi } if shopt -q cdable_vars; then complete -v -F _comp_cmd_cd -o nospace cd pushd else complete -F _comp_cmd_cd -o nospace cd pushd fi