mirror of
git://git.code.sf.net/p/zsh/code
synced 2024-11-19 21:44:11 +01:00
81 lines
2.7 KiB
Plaintext
81 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 alt
|
|
|
|
alt=()
|
|
|
|
tmpcdpath=(${${(@)cdpath:#.}:#$PWD})
|
|
|
|
(( $#tmpcdpath )) &&
|
|
alt=( 'path-directories:directory in cdpath:_path_files -W tmpcdpath -/' )
|
|
|
|
# With cdablevars, we can complete foo as if ~foo/
|
|
if [[ -o cdablevars && -n "$PREFIX" && "$PREFIX" != <-> ]]; then
|
|
if [[ "$PREFIX" != */* ]]; then
|
|
alt=( "$alt[@]" 'named-directories: : _tilde' )
|
|
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 'directory after cdablevar' \
|
|
_path_files -W dir -/ && ret=0
|
|
|
|
PREFIX="$opre"
|
|
IPREFIX="$oipre"
|
|
fi
|
|
fi
|
|
# Don't complete local directories in command position, that's
|
|
# already handled by _command_names (see _autocd)
|
|
|
|
[[ CURRENT -ne 1 ]] &&
|
|
alt=( "${cdpath+local-}directories:${cdpath+local }directory:_path_files -/" "$alt[@]" )
|
|
|
|
_alternative "$alt[@]" && ret=0
|
|
|
|
return ret
|
|
fi
|
|
_wanted directories expl directory _path_files -/ && ret=0
|
|
|
|
return ret
|
|
fi
|