summaryrefslogtreecommitdiffstats
path: root/completions/cd
diff options
context:
space:
mode:
Diffstat (limited to 'completions/cd')
-rw-r--r--completions/cd59
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