diff options
Diffstat (limited to 'Completion/Base/Utility')
| -rw-r--r-- | Completion/Base/Utility/_arg_compile | 199 | ||||
| -rw-r--r-- | Completion/Base/Utility/_call_program | 41 | ||||
| -rw-r--r-- | Completion/Base/Utility/_numbers | 17 | ||||
| -rw-r--r-- | Completion/Base/Utility/_phony | 51 | ||||
| -rw-r--r-- | Completion/Base/Utility/_values | 4 |
5 files changed, 90 insertions, 222 deletions
diff --git a/Completion/Base/Utility/_arg_compile b/Completion/Base/Utility/_arg_compile deleted file mode 100644 index e37c869ee..000000000 --- a/Completion/Base/Utility/_arg_compile +++ /dev/null @@ -1,199 +0,0 @@ -#autoload - -# A simple compiler for _arguments descriptions. The first argument of -# _arg_compile is the name of an array parameter in which the parse is -# returned. The remaining arguments form a series of `phrases'. Each -# `phrase' begins with one of the keywords "argument", "option", or "help" -# and consists of a series of keywords and/or values. The syntax is as -# free-form as possible, but "argument" phrases generally must appear in -# the same relative position as the corresponding argument on the command -# line to be completed, and there are some restrictions on ordering of -# keywords and values within each phrase. -# -# Anything appearing before the first phrase or after the last is passed -# through verbatim. (See TODO.) If more detailed mixing of compiled and -# uncompiled fragments is necessary, use two or more calls, either with -# different array names or by passing the output of each previous call -# through the next. -# -# In the documentation below, brackets [ ] indicate optional elements and -# braces { } indicate elements that may be repeated zero or more times. -# Except as noted, bracketed or braced elements may appear in any order -# relative to each other, but tokens within each element are ordered. -# -# argument [POS] [means MSG] [action ACT] -# -# POS may be an integer N for the Nth argument or "*" for all, and -# must appear first if it appears at all. -# MSG is a string to be displayed above the matches in a listing. -# ACT is (currently) as described in the compsys manual. -# -# option OPT [follow HOW] [explain STR] {unless XOR} \ -# {[means MSG] [action ACT]} [through PAT [means MSG] [action ACT]] -# -# OPT is the option, prefixed with "*" if it may appear more than once. -# HOW refers to a following argument, and may be one of: -# "close" must appear in the same word (synonyms "join" or "-") -# "next" the argument must appear in the next word (aka "split") -# "loose" the argument may appear in the same or the next word ("+") -# "assign" as loose, but must follow an "=" in the same word ("=") -# HOW should be suffixed with a colon if the following argument is -# _not_ required to appear. -# STR is to be displayed based on style `description' -# XOR is another option in combination with which OPT may not appear. -# It may be ":" to disable non-option completions when OPT is present. -# MSG is a string to be displayed above the matches in a listing. -# ACT is (currently) as described in the compsys manual. -# PAT is either "*" for "all remaining words on the line" or a pattern -# that, if matched, marks the end of the arguments of this option. -# The "through PAT ..." description must be the last. -# PAT may be suffixed with one colon to narrow the $words array to -# the remainder of the command line, or with two colons to narrow -# to the words before (not including) the next that matches PAT. -# -# help PAT [means MSG] action ACT -# -# ACT is applied to any option output by --help that matches PAT. -# Do not use "help" with commands that do not support --help. -# PAT may be suffixed with a colon if the following argument is -# _not_ required to appear (this is usually inferred from --help). -# MSG is a string to be displayed above the matches in a listing. - -# EXAMPLE: -# This is from _gprof in the standard distribution. Note that because of -# the brace expansion trick used in the "function name" case, no attempt -# is made to use `phrase' form; that part gets passed through unchanged. -# It could simply be moved to the _arguments call ahead of "$args[@]". -# -# _arg_compile args -s -{a,b,c,D,h,i,l,L,s,T,v,w,x,y,z} \ -# -{A,C,e,E,f,F,J,n,N,O,p,P,q,Q,Z}:'function name:->funcs' \ -# option -I means directory action _dir_list \ -# option -d follow close means "debug level" \ -# option -k means "function names" action '->pair' \ -# option -m means "minimum execution count" \ -# argument means executable action '_files -g \*\(-\*\)' \ -# argument means "profile file" action '_files -g gmon.\*' \ -# help '*=name*' means "function name" action '->funcs' \ -# help '*=dirs*' means "directory" action _dir_list -# _arguments "$args[@]" - -# TODO: -# Verbose forms of various actions, e.g. (but not exactly) -# "state foo" becomes "->foo" -# "completion X explain Y ..." becomes "((X\:Y ...))" -# etc. -# Represent leading "*" in OPT some other way. -# Represent trailing colons in HOW and PAT some other way. -# Stricter syntax checking on HOW, sanity checks on XOR. -# Something less obscure than "unless :" would be nice. -# Warning or other syntax check for stuff after the last phrase. - -emulate -L zsh -local -h argspec dspec helpspec prelude xor -local -h -A amap dmap safe - -[[ -n "$1" ]] || return 1 -[[ ${(tP)${1}} = *-local ]] && { print -R NAME CONFLICT: $1 1>&2; return 1 } -safe[reply]="$1"; shift - -# First consume and save anything before the argument phrases - -helpspec=() -prelude=() - -while (($#)) -do - case $1 in - (argument|help|option) break;; - (*) prelude=("$prelude[@]" "$1"); shift;; - esac -done - -# Consume all the argument phrases and build the argspec array - -while (($#)) -do - amap=() - dspec=() - case $1 in - - # argument [POS] [means MSG] [action ACT] - (argument) - shift - while (($#)) - do - case $1 in - (<1->|\*) amap[position]="$1"; shift;; - (means|action) amap[$1]="$2"; shift 2;; - (argument|option|help) break;; - (*) print -R SYNTAX ERROR at "$@" 1>&2; return 1;; - esac - done - if (( $#amap )) - then - argspec=("$argspec[@]" "${amap[position]}:${amap[means]}:${amap[action]}") - fi;; - - # option OPT [follow HOW] [explain STR] {unless XOR} \ - # {[through PAT] [means MSG] [action ACT]} - (option) - amap[option]="$2"; shift 2 - dmap=() - xor=() - while (( $# )) - do - (( ${+amap[$1]} || ${+dmap[through]} )) && break; - case $1 in - (follow) - amap[follow]="${2:s/join/-/:s/close/-/:s/next//:s/split//:s/loose/+/:s/assign/=/:s/none//}" - shift 2;; - (explain) amap[explain]="[$2]" ; shift 2;; - (unless) xor=("$xor[@]" "${(@)=2}"); shift 2;; - (through|means|action) - while (( $# )) - do - (( ${+dmap[$1]} )) && break 2 - case $1 in - (through|means|action) dmap[$1]=":${2}"; shift 2;; - (argument|option|help|follow|explain|unless) break;; - (*) print -R SYNTAX ERROR at "$@" 1>&2; return 1;; - esac - done;; - (argument|option|help) break;; - (*) print -R SYNTAX ERROR at "$@" 1>&2; return 1;; - esac - if (( $#dmap )) - then - dspec=("$dspec[@]" "${dmap[through]}${dmap[means]:-:}${dmap[action]:-:}") - fi - done - if (( $#amap )) - then - argspec=("$argspec[@]" "${xor:+($xor)}${amap[option]}${amap[follow]}${amap[explain]}${dspec}") - fi;; - - # help PAT [means MSG] action ACT - (help) - amap[pattern]="$2"; shift 2 - while (($#)) - do - (( ${+amap[$1]} )) && break; - case $1 in - (means|action) amap[$1]="$2"; shift 2;; - (argument|option|help) break;; - (*) print -R SYNTAX ERROR at "$@" 1>&2; return 1;; - esac - done - if (( $#amap )) - then - helpspec=("$helpspec[@]" "${amap[pattern]}:${amap[means]}:${amap[action]}") - fi;; - (*) break;; - esac -done - -eval $safe[reply]'=( "${prelude[@]}" "${argspec[@]}" ${helpspec:+"-- ${helpspec[@]}"} "$@" )' - -# print -R _arguments "${prelude[@]:q}" "${argspec[@]:q}" ${helpspec:+"-- ${helpspec[@]:q}"} "$@:q" - -return 0 diff --git a/Completion/Base/Utility/_call_program b/Completion/Base/Utility/_call_program index 55712b04b..38bcede0b 100644 --- a/Completion/Base/Utility/_call_program +++ b/Completion/Base/Utility/_call_program @@ -1,19 +1,30 @@ #autoload +X local -xi COLUMNS=999 -local curcontext="${curcontext}" tmp err_fd=-1 clocale='_comp_locale;' -local -a prefix +local curcontext="${curcontext}" tmp ssb sse err_fd=-1 clocale='_comp_locale;' +local -a prefix args +local -A opth -if [[ "$1" = -p ]]; then - shift - if (( $#_comp_priv_prefix )); then - curcontext="${curcontext%:*}/${${(@M)_comp_priv_prefix:#^*[^\\]=*}[1]}:" - zstyle -t ":completion:${curcontext}:${1}" gain-privileges && - prefix=( $_comp_priv_prefix ) - fi -elif [[ "$1" = -l ]]; then - shift - clocale='' +zparseopts -A opth -D -F - l p q Q || return + +(( $+opth[-l] )) && clocale= + +# function authors might be tempted to run this in ${ ... }. but doing so will +# wreck the user's locale. force a sub-shell if necessary to avoid this +(( $+opth[-l] || ZSH_SUBSHELL )) || ssb='(' sse=')' + +(( $+opth[-p] && $#_comp_priv_prefix )) && { + curcontext="${curcontext%:*}/${${(@M)_comp_priv_prefix:#^*[^\\]=*}[1]}:" + zstyle -t ":completion:${curcontext}:${1}" gain-privileges && + prefix=( $_comp_priv_prefix ) +} + +if (( $+opth[-q] )); then + args=( "${(@q+)argv[2,-1]}" ) +elif (( $+opth[-Q] )); then + args=( "$2" "${(@q+)argv[3,-1]}" ) +else + args=( "${(@)argv[2,-1]}" ) fi if (( ${debug_fd:--1} > 2 )) || [[ ! -t 2 ]] @@ -25,12 +36,12 @@ fi if zstyle -s ":completion:${curcontext}:${1}" command tmp; then if [[ "$tmp" = -* ]]; then - eval $clocale "$tmp[2,-1]" "$argv[2,-1]" + eval $ssb $clocale "$tmp[2,-1]" "${(@)args}" $sse else - eval $clocale $prefix "$tmp" + eval $ssb $clocale $prefix "$tmp" $sse fi else - eval $clocale $prefix "$argv[2,-1]" + eval $ssb $clocale $prefix "${(@)args}" $sse fi 2>&$err_fd } always { diff --git a/Completion/Base/Utility/_numbers b/Completion/Base/Utility/_numbers index 069fc75a4..8fd2e1d7e 100644 --- a/Completion/Base/Utility/_numbers +++ b/Completion/Base/Utility/_numbers @@ -37,13 +37,15 @@ # _description is called with the x token set to make the completed # list of suffixes available to the normal format style -local desc tag range suffixes suffix suffixfmt pat='<->' partial='' +local MATCH MBEGIN MEND +local desc tag range suffixes suffix suffixfmt pad pat='<->' partial='' local -a expl formats local -a default max min keep tags units local -i i local -A opts -zparseopts -K -D -A opts M+:=keep q:=keep s+:=keep S+:=keep J+: V+: 1 2 o+: n F: x+: X+: \ +zparseopts -K -D -A opts \ + {M+:,q+,r+:,R+:,s+:,S+:}=keep J+: V+: 1 2 o+: n F: x+: X+: \ t:=tags u:=units l:=min m:=max d:=default f=type e=type N=type desc="${1:-number}" tag="${tags[2]:-numbers}" @@ -56,7 +58,9 @@ desc="${1:-number}" tag="${tags[2]:-numbers}" if (( $#argv )) && compset -P "$pat"; then zstyle -s ":completion:${curcontext}:units" list-separator sep || sep=-- _description -V units expl unit - disp=( ${${argv#:}/:/ $sep } ) + pad=${#${(O)${${argv%%:*}//?/.}}[1]} # length of longest suffix + disp=( ${${argv#:}/(#m)[^:]##/${(pr<$pad>< >)MATCH}} ) # pad suffixes + disp=( ${disp/:/ $sep } ) compadd -M 'r:|/=* r:|=*' -d disp "$keep[@]" "$expl[@]" - ${${argv#:}%%:*} return elif [[ -prefix $~pat || $PREFIX = $~partial ]]; then @@ -70,12 +74,13 @@ elif [[ -prefix $~pat || $PREFIX = $~partial ]]; then zstyle -s ":completion:${curcontext}:unit-suffixes" format suffixfmt || \ suffixfmt='%(d.%U.)%x%(d.%u.)%(r..|)' for ((i=0;i<$#;i++)); do - zformat -f suffix "$suffixfmt" "x:${${argv[i+1]#:}%%:*}" \ + zformat -fq suffix "$suffixfmt" "x:${${argv[i+1]#:}%%:*}" \ "X:${${argv[i+1]#:}#*:}" "d:${#${argv[i+1]}[1]#:}" \ i:i r:$(( $# - i - 1)) - suffixes+="${suffix//\%/%%}" + suffixes+=$suffix done - [[ -n $suffixes ]] && formats+=( x:$suffixes ) + # don't quote %x so we can pass formatting through + [[ -n $suffixes ]] && formats+=( %%x:$suffixes ) _comp_mesg=yes _description -x $tag expl "$desc" $formats diff --git a/Completion/Base/Utility/_phony b/Completion/Base/Utility/_phony new file mode 100644 index 000000000..1d53a2ecf --- /dev/null +++ b/Completion/Base/Utility/_phony @@ -0,0 +1,51 @@ +#autoload + +# Mix literal matches in with those produced by another function. +# This is useful where certain phony values, like "all", "any" or +# "none" are permitted alongside the real matches. + +# _phony [compadd options] [word] [words... --] [ _function [args] ] +# -a, -k, -l and -d options are the same as for compadd but are not +# passed on to the child function +# -E is only used once (last) +# -A and -O results merged as if compadd was used once only + +local curcontext="$curcontext" minus +local -i minus strip nm skip ret=1 +local -a phony opts cont amerge omerge phony_amat phony_omat last + +zparseopts -D -a opts a=phony k=phony d:=phony l=phony \ + n F: p: i: P: I: e f s: S: q r: R: M+: J+: V+: 1 2 o+: X+: x+: D: \ + A+:=amerge O+:=omerge \ + E:=last + +if (( $argv[(I)--] )); then + (( strip = $argv[(i)--] )) + phony+=( "${(@)argv[1,strip-1]}" ) + shift $strip +else + phony+=( "$argv[1]" ) + shift +fi + +if (( ! $# )); then # no function passed + opts=( ${opts:/-X/-x} ) + skip=1 +else + (( minus = argv[(ib:2:)-] )) + (( minus > $# )) && minus=2 && argv[1]+=( - ) + argv[minus]=( "$opts[@]" ${=amerge:+-A phony_amat} ${=omerge:+-O phony_omat} "$last[@]" ) +fi + +compadd "$opts[@]" "$amerge[@]" "$omerge[@]" "$phony[@]" && ret=0 +nm=$compstate[nmatches] +if (( skip )) || "$@" || [[ -n "$_comp_mesg" ]]; then + [[ ret -eq 0 && compstate[nmatches] -eq nm && -z "$PREFIX$SUFFIX" ]] && + compstate[insert]='' + ret=0 +fi + +(( $+amerge[2] )) && set -A ${amerge[2]} "${(@P)amerge[2]}" "$phony_amat[@]" +(( $+omerge[2] )) && set -A ${omerge[2]} "${(@P)omerge[2]}" "$phony_omat[@]" + +return ret diff --git a/Completion/Base/Utility/_values b/Completion/Base/Utility/_values index 5ed79e890..a8a14c73f 100644 --- a/Completion/Base/Utility/_values +++ b/Completion/Base/Utility/_values @@ -59,8 +59,8 @@ if compvalues -i "$keep[@]" "$@"; then _describe "$descr" \ noargs "$sep[@]" -M 'r:|[_-]=* r:|=*' -- \ - args -S "${argsep}" -M 'r:|[_-]=* r:|=*' -- \ - opts -qS "${argsep}" -r "${argsep}${sep[2]} \\t\\n\\-" -M 'r:|[_-]=* r:|=*' + args -S "${argsep}" -r "${argsep}${sep[2]}" -M 'r:|[_-]=* r:|=*' -- \ + opts -S "${argsep}" -r "${argsep}${sep[2]} \\t\\n\\-" -M 'r:|[_-]=* r:|=*' curcontext="$oldcontext" |
