diff options
Diffstat (limited to 'completions/cd')
-rw-r--r-- | completions/cd | 59 |
1 files changed, 59 insertions, 0 deletions
diff --git a/completions/cd b/completions/cd new file mode 100644 index 0000000..67dc3de --- /dev/null +++ b/completions/cd @@ -0,0 +1,59 @@ +# 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 |