1
0
mirror of git://git.code.sf.net/p/zsh/code synced 2024-10-03 09:21:19 +02:00
zsh/Completion/Zsh/Command/_cd

79 lines
2.7 KiB
Plaintext

#compdef cd chdir pushd
# Handling of cd.
# - Normally just completes directories. Uses cdpath if that's set
# and the string doesn't begin with ~, /, ./ or ../.
# - In the second argument to cd for the form `cd old new', completes
# possible `new' strings by examining `old' and $PWD.
# - After - or +, _directory_stack completes numbers, but the listing
# gives you the list of directories to complete. This turns on
# menu-completion and lists the possibilities automatically, otherwise
# it's not a lot of use. If you don't type the + or - it will
# complete directories as normal.
setopt localoptions nonomatch
local expl ret=1
if [[ CURRENT -eq 3 ]]; then
# cd old new: look for old in $PWD and see what can replace it
local rep
# Get possible completions using word in position 2
rep=(${~PWD/$words[2]/*}~$PWD(-/))
# Now remove all the common parts of $PWD and the completions from this
rep=(${${rep#${PWD%%$words[2]*}}%${PWD#*$words[2]}})
(( $#rep )) && _wanted -C replacement strings expl replacement compadd -a rep
else
# Complete directory stack entries with ~ or when not in command position
# (the rest of this test is optimization for the _tilde call below)
if [[ "$PREFIX" == (#b)(\~|)[^/]# &&
( -n "$match[1]" || ( CURRENT -gt 1 && ! -o cdablevars ) ) ]]; then
_directory_stack && ret=0
fi
if [[ $PREFIX != (\~|/|./|../)* ]]; then
local tmpcdpath
tmpcdpath=(${${(@)cdpath:#.}:#$PWD})
# With cdablevars, we can complete foo as if ~foo/
if [[ -o cdablevars && -n "$PREFIX" ]]; then
if [[ "$PREFIX" != */* ]]; then
_tilde && ret=0
else
local oipre="$IPREFIX" opre="$PREFIX" dirpre dir
# Note we need a tilde because cdablevars also allows user home
# directories, hence nonomatch (above) to suppress error messages.
dirpre="${PREFIX%%/*}/"
IPREFIX="$IPREFIX$dirpre"
eval "dir=( ~$dirpre )"
PREFIX="${PREFIX#*/}"
[[ $#dir -eq 1 && "$dir[1]" != "~$dirpre" ]] &&
_wanted named-directories expl 'directories after cdablevar' \
_path_files -W dir -/ && ret=0
PREFIX="$opre"
IPREFIX="$oipre"
fi
fi
if [[ $#tmpcdpath -ne 0 ]]; then
# Don't complete local directories in command position, that's
# already handled by _command_names (see _autocd)
if [[ CURRENT -eq 1 ]]; then
_wanted path-directories expl 'directories in cdpath' \
_path_files -W tmpcdpath -/ && ret=0
else
_alternative \
'local-directories:local directories:_path_files -/' \
"path-directories:directories in cdpath:_path_files -W tmpcdpath -/" && ret=0
fi
return ret
fi
fi
_wanted directories expl directory _path_files -/ && ret=0
return ret
fi