#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 +, 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 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(-/N)) # 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 $rep elif _popd || [[ $PREFIX != (\~|/|./|../)* && $#cdpath -ne 0 ]]; then local tdir tdir2 # With cdablevars, we can convert foo/bar/... to ~foo/bar/... if # there is no directory foo. In that case we could also complete # variable names, but it hardly seems worth it. # Note we need a tilde because cdablevars also allows user home # directories, hence we also need nonomatch to suppress error messages. if [[ -o cdablevars && -n "$PREFIX" && ! -d ${tdir::=${PREFIX%%/*}} && -d ${~tdir2::="~$tdir"} ]]; then PREFIX="~$PREFIX" _wanted directories expl directory _path_files -/ else local tmpcdpath tmpcdpath=(${${(@)cdpath:#.}:#$PWD}) _alternative \ 'local-directories:local directories:_path_files -/' \ "path-directories:directories in cdpath:_path_files -W tmpcdpath -/" fi else _wanted directories expl directory _path_files -/ fi