diff options
Diffstat (limited to 'Completion')
-rw-r--r-- | Completion/Zsh/Command/_cd | 70 | ||||
-rw-r--r-- | Completion/Zsh/Context/_tilde | 2 |
2 files changed, 48 insertions, 24 deletions
diff --git a/Completion/Zsh/Command/_cd b/Completion/Zsh/Command/_cd index 71fa1a8ad..fe347ae4c 100644 --- a/Completion/Zsh/Command/_cd +++ b/Completion/Zsh/Command/_cd @@ -5,7 +5,7 @@ # 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 +# - 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 @@ -24,31 +24,55 @@ if [[ CURRENT -eq 3 ]]; then rep=(${${rep#${PWD%%$words[2]*}}%${PWD#*$words[2]}}) (( $#rep )) && _wanted -C replacement strings expl replacement compadd -a rep else - [[ CURRENT -gt 1 ]] && _directory_stack && ret=0 - - if [[ $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 -/ && ret=0 - else - local tmpcdpath - - tmpcdpath=(${${(@)cdpath:#.}:#$PWD}) - _alternative \ - 'local-directories:local directories:_path_files -/' \ + # 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 - else - _wanted directories expl directory _path_files -/ && ret=0 fi + _wanted directories expl directory _path_files -/ && ret=0 return ret fi diff --git a/Completion/Zsh/Context/_tilde b/Completion/Zsh/Context/_tilde index 7d7bf5aea..7f1b6b36a 100644 --- a/Completion/Zsh/Context/_tilde +++ b/Completion/Zsh/Context/_tilde @@ -6,7 +6,7 @@ [[ -n "$compstate[quote]" ]] && return 1 -local expl suf dirs list lines revlines i ret disp nm="$compstate[nmatches]" +local expl suf ret if [[ "$SUFFIX" = */* ]]; then ISUFFIX="/${SUFFIX#*/}$ISUFFIX" |