about summary refs log tree commit diff
path: root/Completion/Base/Utility
diff options
context:
space:
mode:
Diffstat (limited to 'Completion/Base/Utility')
-rw-r--r--Completion/Base/Utility/_arguments14
-rw-r--r--Completion/Base/Utility/_numbers87
-rw-r--r--Completion/Base/Utility/_shadow97
-rw-r--r--Completion/Base/Utility/_values2
4 files changed, 192 insertions, 8 deletions
diff --git a/Completion/Base/Utility/_arguments b/Completion/Base/Utility/_arguments
index 3f1b39304..5ff34ff47 100644
--- a/Completion/Base/Utility/_arguments
+++ b/Completion/Base/Utility/_arguments
@@ -132,8 +132,8 @@ if (( long )); then
 	 # variant syntax seen in fetchmail:
 	 # --[fetch]all  means --fetchall or --all.
 	 # maybe needs to be more general
-	 if [[ $start = (#b)(*)\[(*)\](*) ]]; then
-	   tmp+=("${match[1]}${match[2]}${match[3]}" "${match[1]}${match[3]}")
+	 if [[ $start = (#b)--\[(*)\](*) ]]; then
+	   tmp+=("--${match[1]}${match[2]}" "--${match[2]}")
 	 else
 	   tmp+=($start)
 	 fi
@@ -513,8 +513,8 @@ if (( $# )) && comparguments -i "$autod" "$singopt[@]" "$@"; then
 	    tmp2=( "${PREFIX}${(@M)^${(@)${(@)tmp1%%:*}#[-+]}:#?}" )
 
             _describe -O option \
-                      tmp1 tmp2 -Q -S '' -- \
-		      tmp3 -Q
+                tmp1 tmp2 -S '' -- \
+                tmp3
 
             [[ -n "$optarg" && "$single" = next && nm -eq $compstate[nmatches] ]] &&
                 _all_labels options expl option \
@@ -525,9 +525,9 @@ if (( $# )) && comparguments -i "$autod" "$singopt[@]" "$@"; then
         else
           next+=( "$odirect[@]" )
           _describe -O option \
-                    next -Q -M "$matcher" -- \
-                    direct -QS '' -M "$matcher" -- \
-                    equal -QqS= -M "$matcher"
+              next -M "$matcher" -- \
+              direct -S '' -M "$matcher" -- \
+              equal -qS= -M "$matcher"
         fi
 	PREFIX="$prevpre"
 	IPREFIX="$previpre"
diff --git a/Completion/Base/Utility/_numbers b/Completion/Base/Utility/_numbers
new file mode 100644
index 000000000..069fc75a4
--- /dev/null
+++ b/Completion/Base/Utility/_numbers
@@ -0,0 +1,87 @@
+#autoload
+
+# Usage: _numbers [compadd options] [-t tag] [-f|-N] [-u units] [-l min] [-m max] \
+#                 [-d default] ["description"] [unit-suffix...]
+
+#   -t : specify a tag (defaults to 'numbers')
+#   -u : indicate the units, e.g. seconds
+#   -l : lowest possible value
+#   -m : maximum possible value
+#   -d : default value
+#   -N : allow negative numbers (implied by range including a negative)
+#   -f : allow decimals (float)
+
+# For a unit-suffix, an initial colon indicates a unit that asserts the default
+# otherwise, colons allow for descriptions, e.g:
+
+#   :s:seconds m:minutes h:hours
+
+# unit-suffixes are not sorted by the completion system when listed
+# Specify them in order of magnitude, this tends to be ascending unless
+# the default is of a higher magnitude, in which case, descending.
+# So for, example
+#   bytes kB MB GB
+#   s ms us ns
+# Where the compadd options include matching control or suffixes, these
+# are applied to the units
+
+# For each unit-suffix, the format style is looked up with the
+# unit-suffixes tag and the results concatenated. Specs used are:
+#   x : the suffix
+#   X : suffix description
+#   d : indicate suffix is for the default unit
+#   i : list index
+#   r : reverse list index
+# The latter three of these are useful with ternary expressions.
+
+# _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 -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+: \
+  t:=tags u:=units l:=min m:=max d:=default f=type e=type N=type
+
+desc="${1:-number}" tag="${tags[2]:-numbers}"
+(( $# )) && shift
+
+[[ -n ${(M)type:#-f} ]] && pat='(<->.[0-9]#|[0-9]#.<->|<->)' partial='(|.)'
+[[ -n ${(M)type:#-N} || $min[2] = -* || $max[2] = -* ]] && \
+    pat="(|-)$pat" partial="(|-)$partial"
+
+if (( $#argv )) && compset -P "$pat"; then
+  zstyle -s ":completion:${curcontext}:units" list-separator sep || sep=--
+  _description -V units expl unit
+  disp=( ${${argv#:}/:/ $sep } )
+  compadd -M 'r:|/=* r:|=*' -d disp "$keep[@]" "$expl[@]" - ${${argv#:}%%:*}
+  return
+elif [[ -prefix $~pat || $PREFIX = $~partial ]]; then
+  formats=( "h:$desc" )
+  (( $#units )) && formats+=( m:${units[2]} ) desc+=" ($units[2])"
+  (( $#min )) && range="$min[2]-"
+  (( $#max )) && range="${range:--}$max[2]"
+  [[ -n $range ]] && formats+=( r:$range ) desc+=" ($range)"
+  (( $#default )) && formats+=( o:${default[2]} ) desc+=" [$default[2]]"
+
+  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]#:}%%:*}" \
+        "X:${${argv[i+1]#:}#*:}" "d:${#${argv[i+1]}[1]#:}" \
+	i:i r:$(( $# - i - 1))
+    suffixes+="${suffix//\%/%%}"
+  done
+  [[ -n $suffixes ]] && formats+=( x:$suffixes )
+
+  _comp_mesg=yes
+  _description -x $tag expl "$desc" $formats
+  [[ $compstate[insert] = *unambiguous* ]] && compstate[insert]=
+  compadd "$expl[@]"
+  return 0
+fi
+
+return 1
diff --git a/Completion/Base/Utility/_shadow b/Completion/Base/Utility/_shadow
new file mode 100644
index 000000000..9e78af38f
--- /dev/null
+++ b/Completion/Base/Utility/_shadow
@@ -0,0 +1,97 @@
+#autoload
+
+## Recommended usage:
+#  {
+#    _shadow fname
+#    function fname {
+#      # Do your new thing
+#    }
+#    # Invoke callers of fname
+#  } always {
+#    _unshadow
+#  }
+## Alternate usage:
+# {
+#   _shadow -s suffix fname
+#   function fname {
+#     # Do other stuff
+#     fname@suffix new args for fname
+#   }
+#   # Invoke callers of fname
+# } always {
+#   _unshadow
+# }
+##
+
+# BUGS:
+# * `functions -c` acts like `autoload +X`
+# * name collisions are possible in alternate usage
+# * functions that examine $0 probably misfire
+
+zmodload zsh/parameter # Or what?
+
+# This probably never comes up, but protect ourself from recursive call
+# chains that may duplicate the top elements of $funcstack by creating
+# a counter of _shadow calls and using it to make shadow names unique.
+builtin typeset -gHi .shadow.depth=0
+builtin typeset -gHa .shadow.stack
+
+# Create a copy of each fname so that a caller may redefine
+_shadow() {
+  emulate -L zsh
+  local -A fsfx=( -s ${funcstack[2]}:${functrace[2]}:$((.shadow.depth+1)) )
+  local fname shadowname
+  local -a fnames
+  zparseopts -K -A fsfx -D s:
+  for fname; do
+    shadowname=${fname}@${fsfx[-s]}
+    if (( ${+functions[$shadowname]} ))
+    then
+      # Called again with the same -s, just ignore it
+      continue
+    elif (( ${+functions[$fname]} ))
+    then
+      builtin functions -c -- $fname $shadowname
+      fnames+=(f@$fname)
+    elif (( ${+builtins[$fname]} ))
+    then
+      eval "function -- ${(q-)shadowname} { builtin ${(q-)fname} \"\$@\" }"
+      fnames+=(b@$fname)
+    else
+      eval "function -- ${(q-)shadowname} { command ${(q-)fname} \"\$@\" }"
+      fnames+=(c@$fname)
+    fi
+  done
+  [[ -z $REPLY ]] && REPLY=${fsfx[-s]}
+  builtin set -A .shadow.stack ${fsfx[-s]} $fnames -- ${.shadow.stack}
+  ((.shadow.depth++))
+}
+
+# Remove the redefined function and shadowing name
+_unshadow() {
+  emulate -L zsh
+  local fname shadowname fsfx=${.shadow.stack[1]}
+  local -a fnames
+  [[ -n $fsfx ]] || return 1
+  shift .shadow.stack
+  while [[ ${.shadow.stack[1]?no shadows} != -- ]]; do
+    fname=${.shadow.stack[1]#?@}
+    shadowname=${fname}@${fsfx}
+    if (( ${+functions[$fname]} )); then
+      builtin unfunction -- $fname
+    fi
+    case ${.shadow.stack[1]} in
+      (f@*) builtin functions -c -- $shadowname $fname ;&
+      ([bc]@*) builtin unfunction -- $shadowname ;;
+    esac
+    shift .shadow.stack
+  done
+  [[ -z $REPLY ]] && REPLY=$fsfx
+  shift .shadow.stack
+  ((.shadow.depth--))
+}
+
+# This is tricky.  When we call _shadow recursively from autoload,
+# there's an extra level of stack in $functrace that will confuse
+# the later call to _unshadow.  Fool ourself into working correctly.
+(( ARGC )) && _shadow -s ${funcstack[2]}:${functrace[2]}:1 "$@"
diff --git a/Completion/Base/Utility/_values b/Completion/Base/Utility/_values
index 688ada848..5ed79e890 100644
--- a/Completion/Base/Utility/_values
+++ b/Completion/Base/Utility/_values
@@ -60,7 +60,7 @@ if compvalues -i "$keep[@]" "$@"; then
       _describe "$descr" \
         noargs "$sep[@]" -M 'r:|[_-]=* r:|=*' -- \
         args -S "${argsep}" -M 'r:|[_-]=* r:|=*' -- \
-        opts -qS "${argsep}" -r "${argsep}${sep} \\t\\n\\-" -M 'r:|[_-]=* r:|=*'
+        opts -qS "${argsep}" -r "${argsep}${sep[2]} \\t\\n\\-" -M 'r:|[_-]=* r:|=*'
 
       curcontext="$oldcontext"