1 #compdef -redirect-,-default-,-default-
3 local opts tmp glob pat pats expl tag i def descr end ign ret=1 match tried
7 '/=tmp' 'f=tmp' 'g+:-=tmp' q n 1 2 P: S: r: R: W: X+: M+: F: J+: V+:
9 type="${(@j::M)${(@)tmp#-}#?}"
10 if (( $tmp[(I)-g*] )); then
11 glob="${${${${(@M)tmp:#-g*}#-g}##[[:blank:]]#}%%[[:blank:]]#}"
12 [[ "$glob" = *[^\\][[:blank:]]* ]] &&
13 glob="{${glob//(#b)([^\\])[[:blank:]]##/${match[1]},}}"
15 # add `#q' to the beginning of any glob qualifier if not there already
16 [[ "$glob" = (#b)(*\()([^\|\~]##\)) && $match[2] != \#q* ]] &&
17 glob="${match[1]}#q${match[2]}"
22 if [[ $ign = _comp_ignore ]]; then
25 opts[tmp+1]=_comp_ignore
31 if zstyle -a ":completion:${curcontext}:" file-patterns tmp; then
32 [[ "$type" = */* ]] && glob="$glob,*(-/)"
35 for i in ${tmp//\%p/${${glob:-\*}//:/\\:}}; do
36 if [[ $i = *[^\\]:* ]]; then
37 pats=( "$pats[@]" " $i " )
39 pats=( "$pats[@]" " ${i}:files " )
42 elif zstyle -t ":completion:${curcontext}:" list-dirs-first; then
43 if [[ "$type" = *g* ]]; then
45 # add `^-/' after `#q' glob qualifier if not there already
46 if [[ "$glob" = (#b)(*\(\#q)(*\)) ]]; then
47 [[ $match[2] != \^-/* ]] &&
48 glob="${match[1]}^-/,${match[2]}"
53 pats=( " *(-/):directories:directories ${glob//:/\\:}:globbed-files" )
54 elif [[ "$type" = */* ]] then
55 pats=( '*(-/):directories ' '*:all-files ' )
57 pats=( '*(-/):directories:directories *(^-/):other-files ' )
60 if [[ "$type" = *g* ]]; then
62 # People prefer to have directories shown on first try as default.
63 # Even if the calling function didn't use -/.
65 # if [[ "$type" = */* ]]; then
67 pats=( " ${glob//:/\\:}:globbed-files *(-/):directories" '*:all-files '
69 ### We could allow _next_tags to offer only globbed-files or directories
71 ### " ${glob//:/\\:}:only-globbed-files " ' *(-/):only-directories '
76 # pats=( " ${glob//:/\\:}:globbed-files "
77 # '*(-/):directories ' '*:all-files ' )
80 elif [[ "$type" = */* ]]; then
81 pats=( '*(-/):directories ' '*:all-files ' )
83 pats=( '*:all-files ' )
88 for def in "$pats[@]"; do
89 eval "def=( ${${def:gs/\\:/\\\\\\\\\\\\:}//(#b)([][()|*?^#~<>])/\\${match[1]}} )"
91 tmp="${(@M)def#*[^\\]:}"
92 (( $tried[(I)${(q)tmp}] )) && continue
93 tried=( "$tried[@]" "$tmp" )
95 for sdef in "$def[@]"; do
97 tag="${${sdef#*[^\\]:}%%:*}"
98 pat="${${sdef%%:${tag}*}//\\:/:}"
100 if [[ "$sdef" = *:${tag}:* ]]; then
101 descr="${(Q)sdef#*:${tag}:}"
103 if (( $opts[(I)-X] )); then
114 while _next_label "$tag" expl "$descr"; do
115 _comp_ignore=( $_comp_ignore $ign )
116 if [[ -n "$end" ]]; then
117 _path_files -g "$pat" "$opts[@]" "$expl[@]" && ret=0
119 _path_files "$expl[@]" -g "$pat" "$opts[@]" && ret=0
125 ### For that _next_tags change mentioned above we would have to
126 ### comment out the following line. (Or not, depending on the order
127 ### of the patterns.)
129 [[ "$pat" = '*' ]] && return ret
132 (( ret )) || return 0