mirror of
git://git.code.sf.net/p/zsh/code
synced 2024-11-19 13:33:52 +01:00
moved to Completion/Unix/Type/_path_files
This commit is contained in:
parent
0997bf8705
commit
7a6bbdfea9
@ -1,650 +0,0 @@
|
||||
#autoload
|
||||
|
||||
# Utility function for in-path completion. This allows `/u/l/b<TAB>'
|
||||
# to complete to `/usr/local/bin'.
|
||||
|
||||
local linepath realpath donepath prepath testpath exppath skips skipped
|
||||
local tmp1 tmp2 tmp3 tmp4 i orig eorig pre suf tpre tsuf opre osuf cpre
|
||||
local pats haspats ignore pfxsfx sopt gopt opt sdirs ignpar cfopt listsfx
|
||||
local nm=$compstate[nmatches] menu matcher mopts sort match mid accex fake
|
||||
|
||||
typeset -U prepaths exppaths
|
||||
|
||||
exppaths=()
|
||||
|
||||
# Get the options.
|
||||
|
||||
zparseopts -a mopts \
|
||||
'P:=pfxsfx' 'S:=pfxsfx' 'q=pfxsfx' 'r:=pfxsfx' 'R:=pfxsfx' \
|
||||
'W:=prepaths' 'F:=ignore' 'M+:=matcher' \
|
||||
J+: V+: X+: 1: 2: n: 'f=tmp1' '/=tmp1' 'g+:-=tmp1'
|
||||
|
||||
sopt="-${(@j::M)${(@)tmp1#-}#?}"
|
||||
(( $tmp1[(I)-[/g]*] )) && haspats=yes
|
||||
(( $tmp1[(I)-g*] )) && gopt=yes
|
||||
if (( $tmp1[(I)-/] )); then
|
||||
pats=( '*(-/)' ${=${(M)tmp1:#-g*}#-g} )
|
||||
else
|
||||
pats=( "${(@)=${(@M)tmp1:#-g*}#-g}" )
|
||||
fi
|
||||
pats=( "${(@)pats:# #}" )
|
||||
|
||||
if (( $#prepaths )); then
|
||||
tmp1="${prepaths[2]}"
|
||||
if [[ "$tmp1[1]" = '(' ]]; then
|
||||
prepaths=( ${^=tmp1[2,-2]%/}/ )
|
||||
elif [[ "$tmp1[1]" = '/' ]]; then
|
||||
prepaths=( "${tmp1%/}/" )
|
||||
else
|
||||
prepaths=( ${(P)^tmp1%/}/ )
|
||||
(( ! $#prepaths )) && prepaths=( ${tmp1%/}/ )
|
||||
fi
|
||||
(( ! $#prepaths )) && prepaths=( '' )
|
||||
else
|
||||
prepaths=( '' )
|
||||
fi
|
||||
|
||||
if (( $#ignore )); then
|
||||
if [[ "${ignore[2]}" = \(* ]]; then
|
||||
ignore=( ${=ignore[2][2,-2]} )
|
||||
else
|
||||
ignore=( ${(P)ignore[2]} )
|
||||
fi
|
||||
fi
|
||||
|
||||
# If we were given no file selection option, we behave as if we were given
|
||||
# a `-f'.
|
||||
|
||||
if [[ "$sopt" = -(f|) ]]; then
|
||||
if [[ -z "$gopt" ]]; then
|
||||
sopt='-f'
|
||||
pats=('*')
|
||||
else
|
||||
unset sopt
|
||||
fi
|
||||
fi
|
||||
|
||||
if (( ! $mopts[(I)-[JVX]] )); then
|
||||
local expl
|
||||
|
||||
if [[ -z "$gopt" && "$sopt" = -/ ]]; then
|
||||
_description directories expl directory
|
||||
else
|
||||
_description files expl file
|
||||
fi
|
||||
tmp1=$expl[(I)-M*]
|
||||
if (( tmp1 )); then
|
||||
if (( $#matcher )); then
|
||||
matcher[2]="$matcher[2] $expl[1+tmp1]"
|
||||
else
|
||||
matcher=(-M "$expl[1+tmp1]")
|
||||
fi
|
||||
fi
|
||||
mopts=( "$mopts[@]" "$expl[@]" )
|
||||
fi
|
||||
|
||||
# If given no `-F' option, we may want to use $fignore, turned into patterns.
|
||||
|
||||
[[ -z "$_comp_no_ignore" && $#ignore -eq 0 &&
|
||||
( -z $gopt || "$pats" = \ #\*\ # ) && -n $FIGNORE ]] &&
|
||||
ignore=( "?*${^fignore[@]}" )
|
||||
|
||||
if (( $#ignore )); then
|
||||
_comp_ignore=( "$_comp_ignore[@]" "$ignore[@]" )
|
||||
(( $mopts[(I)-F] )) || mopts=( "$mopts[@]" -F _comp_ignore )
|
||||
fi
|
||||
|
||||
(( $#matcher )) && mopts=( "$mopts[@]" "$matcher[@]" )
|
||||
|
||||
if zstyle -s ":completion:${curcontext}:" file-sort tmp1; then
|
||||
case "$tmp1" in
|
||||
*size*) sort=oL;;
|
||||
*links*) sort=ol;;
|
||||
*(time|date|modi)*) sort=om;;
|
||||
*access*) sort=oa;;
|
||||
*(inode|change)*) sort=oc;;
|
||||
*) sort=on;;
|
||||
esac
|
||||
[[ "$tmp1" = *rev* ]] && sort[1]=O
|
||||
|
||||
if [[ "$sort" = on ]]; then
|
||||
sort=
|
||||
else
|
||||
mopts=( "${(@)mopts/#-J/-V}" )
|
||||
|
||||
tmp2=()
|
||||
for tmp1 in "$pats[@]"; do
|
||||
if [[ "$tmp1" = (#b)(*[^\$])(\(\([^\|~]##\)\)) ]]; then
|
||||
tmp2=( "$tmp2[@]" "${match[1]}((${sort}${match[2][3,-1]}" )
|
||||
elif [[ "$tmp1" = (#b)(*[^\$])(\([^\|~]##\)) ]]; then
|
||||
tmp2=( "$tmp2[@]" "${match[1]}(${sort}${match[2][2,-1]}" )
|
||||
else
|
||||
tmp2=( "$tmp2[@]" "${tmp1}(${sort})" )
|
||||
fi
|
||||
done
|
||||
pats=( "$tmp2[@]" )
|
||||
fi
|
||||
fi
|
||||
|
||||
# Check if we have to skip over sequences of slashes. The value of $skips
|
||||
# is used below to match the pathname components we always have to accept
|
||||
# immediatly.
|
||||
|
||||
if zstyle -t ":completion:${curcontext}:paths" squeeze-slashes; then
|
||||
skips='((.|..|)/)##'
|
||||
else
|
||||
skips='((.|..)/)##'
|
||||
fi
|
||||
|
||||
zstyle -s ":completion:${curcontext}:paths" special-dirs sdirs
|
||||
zstyle -t ":completion:${curcontext}:paths" list-suffixes &&
|
||||
listsfx=yes
|
||||
|
||||
[[ "$pats" = ((|*[[:blank:]])\*(|[[:blank:]]*)|*\([^[:blank:]]#/[^[:blank:]]#\)*) ]] &&
|
||||
sopt=$sopt/
|
||||
|
||||
zstyle -a ":completion:${curcontext}:paths" accept-exact accex
|
||||
zstyle -a ":completion:${curcontext}:" fake-files fake
|
||||
|
||||
zstyle -s ":completion:${curcontext}:" ignore-parents ignpar
|
||||
|
||||
if [[ -n "$compstate[pattern_match]" &&
|
||||
( ( -z "$SUFFIX" && "$PREFIX" = (|*[^\$])\([^\|\~]##\) ) ||
|
||||
"$SUFFIX" = (|*[^\$])\([^\|\~]##\) ) ]]; then
|
||||
# Copy all glob qualifiers from the line to
|
||||
# the patterns used when generating matches
|
||||
if [[ "$SUFFIX" = *\([^\|\~]##\) ]]; then
|
||||
tmp3="${${(M)SUFFIX%\([^\|\~]##\)}[2,-2]}"
|
||||
SUFFIX="${SUFFIX%\($tmp3\)}"
|
||||
else
|
||||
tmp3="${${(M)PREFIX%\([^\|\~]##\)}[2,-2]}"
|
||||
PREFIX="${PREFIX%\($tmp3\)}"
|
||||
fi
|
||||
tmp2=()
|
||||
for tmp1 in "$pats[@]"; do
|
||||
if [[ "$tmp1" = (#b)(*[^\$])(\(\([^\|~]##\)\)) ]]; then
|
||||
tmp2=( "$tmp2[@]" "${match[1]}((${tmp3}${match[2][3,-1]}" )
|
||||
elif [[ "$tmp1" = (#b)(*[^\$])(\([^\|~]##\)) ]]; then
|
||||
tmp2=( "$tmp2[@]" "${match[1]}(${tmp3}${match[2][2,-1]}" )
|
||||
else
|
||||
tmp2=( "$tmp2[@]" "${tmp1}(${tmp3})" )
|
||||
fi
|
||||
done
|
||||
pats=( "$tmp2[@]" )
|
||||
fi
|
||||
|
||||
# We get the prefix and the suffix from the line and save the whole
|
||||
# original string. Then we see if we will do menucompletion.
|
||||
|
||||
pre="$PREFIX"
|
||||
suf="$SUFFIX"
|
||||
opre="$PREFIX"
|
||||
osuf="$SUFFIX"
|
||||
orig="${PREFIX}${SUFFIX}"
|
||||
eorig="$orig"
|
||||
|
||||
[[ $compstate[insert] = (*menu|[0-9]*) || -n "$_comp_correct" ||
|
||||
( -n "$compstate[pattern_match]" &&
|
||||
"${orig#\~}" != (|*[^\\])[][*?#~^\|\<\>]* ) ]] && menu=yes
|
||||
[[ -n "$_comp_correct" ]] && cfopt=-
|
||||
|
||||
# Now let's have a closer look at the string to complete.
|
||||
|
||||
if [[ "$pre[1]" = \~ && -z "$compstate[quote]" ]]; then
|
||||
# It begins with `~', so remember anything before the first slash to be able
|
||||
# to report it to the completion code. Also get an expanded version of it
|
||||
# (in `realpath'), so that we can generate the matches. Then remove that
|
||||
# prefix from the string to complete, set `donepath' to build the correct
|
||||
# paths and make sure that the loop below is run only once with an empty
|
||||
# prefix path by setting `prepaths'.
|
||||
|
||||
linepath="${pre[2,-1]%%/*}"
|
||||
if [[ -z "$linepath" ]]; then
|
||||
realpath="${HOME%/}/"
|
||||
elif (( $+userdirs[$linepath] )); then
|
||||
realpath="${userdirs[$linepath]%/}/"
|
||||
elif (( $+nameddirs[$linepath] )); then
|
||||
realpath="${nameddirs[$linepath]%/}/"
|
||||
elif [[ "$linepath" = ([-+]|)[0-9]## ]]; then
|
||||
if [[ "$linepath" != [-+]* ]]; then
|
||||
if [[ -o pushdminus ]]; then
|
||||
tmp1="-$linepath"
|
||||
else
|
||||
tmp1="+$linepath"
|
||||
fi
|
||||
else
|
||||
tmp1="$linepath"
|
||||
fi
|
||||
if [[ "$linepath" = -* ]]; then
|
||||
tmp1=$(( $#dirstack $tmp1 ))
|
||||
else
|
||||
tmp1=$tmp1[2,-1]
|
||||
fi
|
||||
[[ -o pushdminus ]] && tmp1=$(( $#dirstack - $tmp1 ))
|
||||
if (( ! tmp1 )); then
|
||||
realpath=$PWD/
|
||||
elif [[ tmp1 -le $#dirstack ]]; then
|
||||
realpath=$dirstack[tmp1]/
|
||||
else
|
||||
_message 'not enough directory stack entries'
|
||||
return 1
|
||||
fi
|
||||
elif [[ "$linepath" = [-+] ]]; then
|
||||
realpath=${~:-\~$linepath}/
|
||||
else
|
||||
_message "unknown user \`$linepath'"
|
||||
return 1
|
||||
fi
|
||||
linepath="~${linepath}/"
|
||||
[[ "$realpath" = "$linepath" ]] && return 1
|
||||
pre="${pre#*/}"
|
||||
orig="${orig#*/}"
|
||||
donepath=
|
||||
prepaths=( '' )
|
||||
elif [[ "$pre" = *\$*/* && "$compstate[quote]" != \" ]]; then
|
||||
|
||||
# If there is a parameter expansion in the word from the line, we try
|
||||
# to complete the beast by expanding the prefix and completing anything
|
||||
# after the first slash after the parameter expansion.
|
||||
# This fails for things like `f/$foo/b/<TAB>' where the first `f' is
|
||||
# meant as a partial path.
|
||||
|
||||
linepath="${(M)pre##*\$[^/]##/}"
|
||||
eval 'realpath=${(e)~linepath}' 2>/dev/null
|
||||
[[ -z "$realpath" || "$realpath" = "$linepath" ]] && return 1
|
||||
pre="${pre#${linepath}}"
|
||||
i="${#linepath//[^\\/]}"
|
||||
orig="${orig[1,(in:i:)/][1,-2]}"
|
||||
donepath=
|
||||
prepaths=( '' )
|
||||
else
|
||||
# If the string does not start with a `~' we don't remove a prefix from the
|
||||
# string.
|
||||
|
||||
linepath=
|
||||
realpath=
|
||||
|
||||
if [[ "$pre[1]" = / ]]; then
|
||||
# If it is a absolute path name, we remove the first slash and put it in
|
||||
# `donepath' meaning that we treat it as the path that was already handled.
|
||||
# Also, we don't use the paths from `-W'.
|
||||
|
||||
pre="$pre[2,-1]"
|
||||
orig="$orig[2,-1]"
|
||||
donepath='/'
|
||||
prepaths=( '' )
|
||||
else
|
||||
# The common case, we just use the string as it is, unless it begins with
|
||||
# `./' or `../' in which case we don't use the paths from `-W'.
|
||||
|
||||
[[ "$pre" = (.|..)/* ]] && prepaths=( '' )
|
||||
donepath=
|
||||
fi
|
||||
fi
|
||||
|
||||
# Now we generate the matches. First we loop over all prefix paths given
|
||||
# with the `-W' option.
|
||||
|
||||
for prepath in "$prepaths[@]"; do
|
||||
|
||||
# Get local copies of the prefix, suffix, and the prefix path to use
|
||||
# in the following loop, which walks through the pathname components
|
||||
# in the string from the line.
|
||||
|
||||
skipped=
|
||||
cpre=
|
||||
tpre="$pre"
|
||||
tsuf="$suf"
|
||||
testpath="$donepath"
|
||||
|
||||
tmp2="${(M)tpre##${~skips}}"
|
||||
tpre="${tpre#$tmp2}"
|
||||
|
||||
tmp1=( "$prepath$realpath$donepath$tmp2" )
|
||||
|
||||
while true; do
|
||||
|
||||
# Get the prefix and suffix for matching.
|
||||
|
||||
if [[ "$tpre" = */* ]]; then
|
||||
PREFIX="${tpre%%/*}"
|
||||
SUFFIX=
|
||||
else
|
||||
PREFIX="${tpre}"
|
||||
SUFFIX="${tsuf%%/*}"
|
||||
fi
|
||||
|
||||
# Force auto-mounting. There might be a better way...
|
||||
|
||||
: ${^tmp1}/${PREFIX}${SUFFIX}/.(/)
|
||||
|
||||
# Get the matching files by globbing.
|
||||
|
||||
if [[ "$tpre$tsuf" = */* ]]; then
|
||||
compfiles -P$cfopt tmp1 accex "$skipped" "$_matcher" "$sdirs" fake
|
||||
elif [[ "$sopt" = *[/f]* ]]; then
|
||||
compfiles -p$cfopt tmp1 accex "$skipped" "$_matcher" "$sdirs" fake "$pats[@]"
|
||||
else
|
||||
compfiles -p$cfopt tmp1 accex "$skipped" "$_matcher" '' fake "$pats[@]"
|
||||
fi
|
||||
tmp1=( $~tmp1 )
|
||||
|
||||
if [[ -n "$PREFIX$SUFFIX" ]]; then
|
||||
# See which of them match what's on the line.
|
||||
|
||||
if [[ "$tmp1[1]" = */* ]]; then
|
||||
if [[ -n "$_comp_correct" ]]; then
|
||||
tmp2=( "$tmp1[@]" )
|
||||
builtin compadd -D tmp1 -F _comp_ignore "$matcher[@]" - "${(@)tmp1:t}"
|
||||
|
||||
if [[ $#tmp1 -eq 0 ]]; then
|
||||
tmp1=( "$tmp2[@]" )
|
||||
compadd -D tmp1 -F _comp_ignore "$matcher[@]" - "${(@)tmp2:t}"
|
||||
fi
|
||||
else
|
||||
tmp2=( "$tmp1[@]" )
|
||||
compadd -D tmp1 -F _comp_ignore "$matcher[@]" - "${(@)tmp1:t}"
|
||||
fi
|
||||
else
|
||||
tmp2=( '' )
|
||||
compadd -D tmp1 -F _comp_ignore "$matcher[@]" -a tmp1
|
||||
fi
|
||||
|
||||
# If no file matches, save the expanded path and continue with
|
||||
# the outer loop.
|
||||
|
||||
if (( ! $#tmp1 )); then
|
||||
if [[ "$tmp2[1]" = */* ]]; then
|
||||
tmp2=( "${(@)tmp2#${prepath}${realpath}}" )
|
||||
if [[ "$tmp2[1]" = */* ]]; then
|
||||
tmp2=( "${(@)tmp2:h}" )
|
||||
compquote tmp2
|
||||
if [[ "$tmp2" = */ ]]; then
|
||||
exppaths=( "$exppaths[@]" ${^tmp2}${tpre}${tsuf} )
|
||||
else
|
||||
exppaths=( "$exppaths[@]" ${^tmp2}/${tpre}${tsuf} )
|
||||
fi
|
||||
elif [[ ${tpre}${tsuf} = */* ]]; then
|
||||
exppaths=( "$exppaths[@]" ${tpre}${tsuf} )
|
||||
|
||||
### this once was in an `else' (not `elif')
|
||||
fi
|
||||
fi
|
||||
continue 2
|
||||
fi
|
||||
elif (( ! $#tmp1 )); then
|
||||
# A little extra hack: if we were completing `foo/<TAB>' and `foo'
|
||||
# contains no files, this will normally produce no matches and other
|
||||
# completers might think that's it's their time now. But if the next
|
||||
# completer is _correct or something like that, this will result in
|
||||
# an attempt to correct a valid directory name. So we just add the
|
||||
# original string in such a case so that the command line doesn't
|
||||
# change but other completers still think there are matches.
|
||||
# We do this only if we weren't given a `-g' or `-/' option because
|
||||
# otherwise this would keep `_files' from completing all filenames
|
||||
# if none of the patterns match.
|
||||
|
||||
if [[ -z "$tpre$tsuf" && -n "$pre$suf" ]]; then
|
||||
pfxsfx=(-S '' "$pfxsfx[@]")
|
||||
### Don't remember what the break was good for. We explicitly
|
||||
### execute this only when there are no matches in the directory,
|
||||
### so why continue?
|
||||
###
|
||||
### tmp1=( "$tmp2[@]" )
|
||||
### break
|
||||
elif [[ -n "$haspats" && -z "$tpre$tsuf$suf" && "$pre" = */ ]]; then
|
||||
PREFIX="${opre}"
|
||||
SUFFIX="${osuf}"
|
||||
compadd -nQS '' - "$linepath$donepath$orig"
|
||||
tmp4=-
|
||||
fi
|
||||
continue 2
|
||||
fi
|
||||
|
||||
if [[ -n "$ignpar" && -z "$_comp_no_ignore" &&
|
||||
"$tpre$tsuf" != */* && $#tmp1 -ne 0 &&
|
||||
( "$ignpar" != *dir* || "$pats" = '*(-/)' ) &&
|
||||
( "$ignpar" != *..* || "$tmp1[1]" = *../* ) ]]; then
|
||||
|
||||
compfiles -i tmp1 _comp_ignore "$ignpar" "$prepath$realpath$donepath"
|
||||
|
||||
(( $#_comp_ignore && $mopts[(I)-F] )) ||
|
||||
mopts=( "$mopts[@]" -F _comp_ignore )
|
||||
fi
|
||||
|
||||
# Step over to the next component, if any.
|
||||
|
||||
if [[ "$tpre" = */* ]]; then
|
||||
tpre="${tpre#*/}"
|
||||
elif [[ "$tsuf" = */* ]]; then
|
||||
tpre="${tsuf#*/}"
|
||||
tsuf=
|
||||
else
|
||||
break
|
||||
fi
|
||||
|
||||
# There are more components, so skip over the next components and make a
|
||||
# slash be added.
|
||||
|
||||
tmp1=( ${tmp1//(#b)([][()|*?^#~<>\\=])/\\${match[1]}} )
|
||||
tmp2="${(M)tpre##((.|..|)/)##}"
|
||||
if [[ -n "$tmp2" ]]; then
|
||||
skipped="/$tmp2"
|
||||
tpre="${tpre#$tmp2}"
|
||||
else
|
||||
skipped=/
|
||||
fi
|
||||
done
|
||||
|
||||
# The next loop searches the first ambiguous component.
|
||||
|
||||
tmp3="$pre$suf"
|
||||
tpre="$pre"
|
||||
tsuf="$suf"
|
||||
[[ -n "${prepath}${realpath}${testpath}" ]] &&
|
||||
tmp1=( "${(@)tmp1#${prepath}${realpath}${testpath}}" )
|
||||
|
||||
while true; do
|
||||
|
||||
# First we check if some of the files match the original string
|
||||
# for this component. If there are some we remove all other
|
||||
# names. This avoids having `foo' complete to `foo' and `foobar'.
|
||||
# The return value is non-zero if the component is ambiguous.
|
||||
|
||||
compfiles -r tmp1 "$tmp3"
|
||||
tmp4=$?
|
||||
|
||||
if [[ "$tpre" = */* ]]; then
|
||||
tmp2="${cpre}${tpre%%/*}"
|
||||
PREFIX="${donepath}${linepath}${tmp2}"
|
||||
SUFFIX="/${tpre#*/}${tsuf#*/}"
|
||||
else
|
||||
tmp2="${cpre}${tpre}"
|
||||
PREFIX="${donepath}${linepath}${tmp2}"
|
||||
SUFFIX="${tsuf}"
|
||||
fi
|
||||
|
||||
# This once tested `|| [[ -n "$compstate[pattern_match]" &&
|
||||
# "$tmp2" = (|*[^\\])[][*?#~^\|\<\>]* ]]' but it should now be smart
|
||||
# enough to handle multiple components with patterns.
|
||||
|
||||
if (( tmp4 )); then
|
||||
# It is. For menucompletion we now add the possible completions
|
||||
# for this component with the unambigous prefix we have built
|
||||
# and the rest of the string from the line as the suffix.
|
||||
# For normal completion we add the rests of the filenames
|
||||
# collected as the suffixes to make the completion code expand
|
||||
# it as far as possible.
|
||||
|
||||
tmp2="$testpath"
|
||||
if [[ -n "$linepath" ]]; then
|
||||
compquote -p tmp2 tmp1
|
||||
elif [[ -n "$tmp2" ]]; then
|
||||
compquote -p tmp1
|
||||
compquote tmp2
|
||||
else
|
||||
compquote tmp1 tmp2
|
||||
fi
|
||||
|
||||
if [[ -z "$_comp_correct" &&
|
||||
"$compstate[pattern_match]" = \* && -n "$listsfx" &&
|
||||
"$tmp2" = (|*[^\\])[][*?#~^\|\<\>]* ]]; then
|
||||
PREFIX="$opre"
|
||||
SUFFIX="$osuf"
|
||||
fi
|
||||
|
||||
if [[ -n $menu || -z "$compstate[insert]" ]] ||
|
||||
! zstyle -t ":completion:${curcontext}:paths" expand suffix ||
|
||||
[[ -z "$listsfx" &&
|
||||
( -n "$_comp_correct" ||
|
||||
-z "$compstate[pattern_match]" || "$SUFFIX" != */* ||
|
||||
"${SUFFIX#*/}" = (|*[^\\])[][*?#~^\|\<\>]* ) ]]; then
|
||||
(( tmp4 )) && zstyle -t ":completion:${curcontext}:paths" ambiguous &&
|
||||
compstate[to_end]=
|
||||
if [[ "$tmp3" = */* ]]; then
|
||||
if [[ -z "$listsfx" || "$tmp3" != */?* ]]; then
|
||||
compadd -Qf "$mopts[@]" -p "$linepath$tmp2" -s "/${tmp3#*/}" \
|
||||
-W "$prepath$realpath$testpath" \
|
||||
"$pfxsfx[@]" -M "r:|/=* r:|=*" \
|
||||
- "${(@)tmp1%%/*}"
|
||||
else
|
||||
compadd -Qf "$mopts[@]" -p "$linepath$tmp2" \
|
||||
-W "$prepath$realpath$testpath" \
|
||||
"$pfxsfx[@]" -M "r:|/=* r:|=*" \
|
||||
- "${(@)^tmp1%%/*}/${tmp3#*/}"
|
||||
fi
|
||||
else
|
||||
compadd -Qf "$mopts[@]" -p "$linepath$tmp2" \
|
||||
-W "$prepath$realpath$testpath" \
|
||||
"$pfxsfx[@]" -M "r:|/=* r:|=*" \
|
||||
-a tmp1
|
||||
fi
|
||||
else
|
||||
if [[ "$tmp3" = */* ]]; then
|
||||
tmp4=( -Qf "$mopts[@]" -p "$linepath$tmp2"
|
||||
-W "$prepath$realpath$testpath"
|
||||
"$pfxsfx[@]" -M "r:|/=* r:|=*" )
|
||||
if [[ -z "$listsfx" ]]; then
|
||||
for i in "$tmp1[@]"; do
|
||||
compadd "$tmp4[@]" -s "/${i#*/}" - "${i%%/*}"
|
||||
done
|
||||
else
|
||||
[[ -n "$compstate[pattern_match]" ]] && SUFFIX="${SUFFIX:s./.*/}*"
|
||||
|
||||
for i in "$tmp1[@]"; do
|
||||
compadd "$tmp4[@]" - "$i"
|
||||
done
|
||||
fi
|
||||
else
|
||||
compadd -Qf "$mopts[@]" -p "$linepath$tmp2" \
|
||||
-W "$prepath$realpath$testpath" \
|
||||
"$pfxsfx[@]" -M "r:|/=* r:|=*" \
|
||||
-a tmp1
|
||||
fi
|
||||
fi
|
||||
tmp4=-
|
||||
break
|
||||
fi
|
||||
|
||||
# If we have checked all components, we stop now and add the
|
||||
# strings collected after the loop.
|
||||
|
||||
if [[ "$tmp3" != */* ]]; then
|
||||
tmp4=
|
||||
break
|
||||
fi
|
||||
|
||||
# Otherwise we add the unambiguous component to `testpath' and
|
||||
# take it from the filenames.
|
||||
|
||||
testpath="${testpath}${tmp1[1]%%/*}/"
|
||||
|
||||
tmp3="${tmp3#*/}"
|
||||
|
||||
if [[ "$tpre" = */* ]]; then
|
||||
if [[ -z "$_comp_correct" && -n "$compstate[pattern_match]" &&
|
||||
"$tmp2" = (|*[^\\])[][*?#~^\|\<\>]* ]]; then
|
||||
cpre="${cpre}${tmp1[1]%%/*}/"
|
||||
else
|
||||
cpre="${cpre}${tpre%%/*}/"
|
||||
fi
|
||||
tpre="${tpre#*/}"
|
||||
elif [[ "$tsuf" = */* ]]; then
|
||||
[[ "$tsuf" != /* ]] && mid="$testpath"
|
||||
if [[ -z "$_comp_correct" && -n "$compstate[pattern_match]" &&
|
||||
"$tmp2" = (|*[^\\])[][*?#~^\|\<\>]* ]]; then
|
||||
cpre="${cpre}${tmp1[1]%%/*}/"
|
||||
else
|
||||
cpre="${cpre}${tpre}/"
|
||||
fi
|
||||
tpre="${tsuf#*/}"
|
||||
tsuf=
|
||||
else
|
||||
tpre=
|
||||
tsuf=
|
||||
fi
|
||||
|
||||
tmp1=( "${(@)tmp1#*/}" )
|
||||
done
|
||||
|
||||
if [[ -z "$tmp4" ]]; then
|
||||
if [[ "$mid" = */ ]]; then
|
||||
PREFIX="${opre}"
|
||||
SUFFIX="${osuf}"
|
||||
|
||||
tmp4="${testpath#${mid}}"
|
||||
tmp3="${mid%/*/}"
|
||||
tmp2="${${mid%/}##*/}"
|
||||
if [[ -n "$linepath" ]]; then
|
||||
compquote -p tmp3
|
||||
else
|
||||
compquote tmp3
|
||||
fi
|
||||
compquote tmp4 tmp2 tmp1
|
||||
for i in "$tmp1[@]"; do
|
||||
compadd -Qf "$mopts[@]" -p "$linepath$tmp3/" -s "/$tmp4$i" \
|
||||
-W "$prepath$realpath${mid%/*/}/" \
|
||||
"$pfxsfx[@]" -M "r:|/=* r:|=*" - "$tmp2"
|
||||
done
|
||||
else
|
||||
if [[ "$osuf" = */* ]]; then
|
||||
PREFIX="${opre}${osuf}"
|
||||
SUFFIX=
|
||||
else
|
||||
PREFIX="${opre}"
|
||||
SUFFIX="${osuf}"
|
||||
fi
|
||||
tmp4="$testpath"
|
||||
if [[ -n "$linepath" ]]; then
|
||||
compquote -p tmp4 tmp1
|
||||
elif [[ -n "$tmp4" ]]; then
|
||||
compquote -p tmp1
|
||||
compquote tmp4
|
||||
else
|
||||
compquote tmp4 tmp1
|
||||
fi
|
||||
if [[ -z "$_comp_correct" && -n "$compstate[pattern_match]" &&
|
||||
"${PREFIX#\~}$SUFFIX" = (|*[^\\])[][*?#~^\|\<\>]* ]]; then
|
||||
compadd -Qf -W "$prepath$realpath" "$pfxsfx[@]" "$mopts[@]" \
|
||||
-M "r:|/=* r:|=*" - "$linepath$tmp4${(@)^tmp1}"
|
||||
else
|
||||
compadd -Qf -p "$linepath$tmp4" -W "$prepath$realpath$testpath" \
|
||||
"$pfxsfx[@]" "$mopts[@]" -M "r:|/=* r:|=*" -a tmp1
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
# If we are configured to expand paths as far as possible and we collected
|
||||
# expanded paths that are different from the string on the line, we add
|
||||
# them as possible matches.
|
||||
|
||||
if zstyle -t ":completion:${curcontext}:paths" expand prefix &&
|
||||
[[ nm -eq compstate[nmatches] && $#exppaths -ne 0 &&
|
||||
"$exppaths" != "$eorig" ]]; then
|
||||
PREFIX="${opre}"
|
||||
SUFFIX="${osuf}"
|
||||
compadd -Q "$mopts[@]" -S '' -M "r:|/=* r:|=*" -p "$linepath" -a exppaths
|
||||
fi
|
||||
|
||||
[[ nm -ne compstate[nmatches] ]]
|
Loading…
Reference in New Issue
Block a user