File bash-completion-cd.patch of Package bash-completion
--- bash_completion
+++ bash_completion 2008-11-11 16:23:37.662500904 +0100
@@ -3015,51 +3015,83 @@ complete -F _autorpm autorpm
#
_cd()
{
- local IFS=$'\t\n' cur=${COMP_WORDS[COMP_CWORD]} i j k
-
- # try to allow variable completion
- if [[ "$cur" == ?(\\)\$* ]]; then
- COMPREPLY=( $( compgen -v -P '$' -- "${cur#?(\\)$}" ) )
- return 0
- fi
+ local c=${COMP_WORDS[COMP_CWORD]}
+ local s x
+ local IFS=$'\n'
+ local -i o
+
+ case "$c" in
+ \$\(*\)) eval COMPREPLY=\(${c}\) ;;
+ \$\(*) COMPREPLY=($(compgen -c -P '$(' -S ')' -- ${c#??})) ;;
+ \`*\`) eval COMPREPLY=\(${c}\) ;;
+ \`*) COMPREPLY=($(compgen -c -P '\`' -S '\`' -- ${c#?})) ;;
+ \$\{*\}) eval COMPREPLY=\(${c}\) ;;
+ \$\{*) COMPREPLY=($(compgen -v -P '${' -S '}' -- ${c#??})) ;;
+ \$*) COMPREPLY=($(compgen -v -P '$' -S / -- ${c#?})) ;;
+ \~*/*) COMPREPLY=($(compgen -d -S / -- "${c}")) ;;
+ \~*) COMPREPLY=($(compgen -u -S / -- "${c}")) ;;
+ *\:*)
+ if [[ $COMP_WORDBREAKS =~ : ]] ; then
+ local C=${c%"${c##*[^\\]:}"}
+ COMPREPLY=($(compgen -d -S / -- "${c}"))
+ for ((o=0; o<${#COMPREPLY[@]}; o++)) ; do
+ COMPREPLY[o]=${COMPREPLY[o]#"$C"}
+ done
+ fi
+ esac
- # Use standard dir completion if no CDPATH or parameter starts with /,
- # ./ or ../
- if [ -z "${CDPATH:-}" ] || [[ "$cur" == ?(.)?(.)/* ]]; then
- _filedir -d
- return 0
+ if test ${#COMPREPLY[@]} -gt 0 ; then
+ #
+ # Handle the CDPATH variable
+ #
+ x="$(bind -v)"
+ local dir=$([[ $x =~ mark-directories+([[:space:]])on ]] && echo on)
+ local sym=$([[ $x =~ mark-symlinked-directories+([[:space:]])on ]] && echo on)
+
+ for x in ${CDPATH//:/$'\n'}; do
+ o=${#COMPREPLY[@]}
+ for s in $(compgen -d $x/$c); do
+ if [[ (($sym == on && -h $s) || ($dir == on && ! -h $s)) && ! -d ${s#$x/} ]] ; then
+ s="${s}/"
+ fi
+ COMPREPLY[o++]=${s#$x/}
+ done
+ done
fi
- local -r mark_dirs=$(_rl_enabled mark-directories && echo y)
- local -r mark_symdirs=$(_rl_enabled mark-symlinked-directories && echo y)
-
- # we have a CDPATH, so loop on its contents
- for i in ${CDPATH//:/$'\t'}; do
- # create an array of matched subdirs
- k=${#COMPREPLY[@]}
- for j in $( compgen -d $i/$cur ); do
- if [[ ( $mark_symdirs && -h $j || $mark_dirs && ! -h $j ) && ! -d ${j#$i/} ]]; then
- j="${j}/"
- fi
- COMPREPLY[k++]=${j#$i/}
+ if test ${#COMPREPLY[@]} -gt 0 ; then
+ #
+ # Escape spaces and braces in path names with `\'
+ #
+ s="${COMP_WORDBREAKS// }"
+ s="${s// }"
+ s="${s//[\{\}()\[\]]}"
+ s="${s} (){}[]"
+ o=${#s}
+
+ while test $((o--)) -gt 0 ; do
+ c="${s:${o}:1}"
+ COMPREPLY=(${COMPREPLY[*]//${c}/\\${c}})
done
- done
-
- _filedir -d
+ fi
- if [[ ${#COMPREPLY[@]} -eq 1 ]]; then
- i=${COMPREPLY[0]}
- if [ "$i" == "$cur" ] && [[ $i != "*/" ]]; then
- COMPREPLY[0]="${i}/"
- fi
+ #
+ # Append a slash on the real result, avoid annoying double tab
+ #
+ if test ${#COMPREPLY[@]} -eq 1 ; then
+ x=${COMPREPLY[0]}
+ o=$((${#x} - 1))
+ if test "$x" = "$c" -a "${x:${o}:1}" != "/"; then
+ COMPREPLY[0]="${x}/"
+ fi
fi
-
return 0
}
+
if shopt -q cdable_vars; then
- complete -v -F _cd $nospace $filenames cd
+ complete -v -F _cd $nospace $dirnames $bashdefault cd
else
- complete -F _cd $nospace $filenames cd
+ complete -F _cd $nospace $dirnames $bashdefault cd
fi
# A meta-command completion function for commands like sudo(8), which need to