about summary refs log tree commit diff
path: root/Completion
diff options
context:
space:
mode:
Diffstat (limited to 'Completion')
-rw-r--r--Completion/Base/.distfiles7
-rw-r--r--Completion/Base/_argument_sets56
-rw-r--r--Completion/Base/_arguments152
-rw-r--r--Completion/Base/_describe6
-rw-r--r--Completion/Builtins/_bindkey2
-rw-r--r--Completion/Builtins/_compdef18
-rw-r--r--Completion/Builtins/_emulate2
-rw-r--r--Completion/Builtins/_zpty2
-rw-r--r--Completion/Core/_tags2
9 files changed, 170 insertions, 77 deletions
diff --git a/Completion/Base/.distfiles b/Completion/Base/.distfiles
index 7e7635fa6..377a56c82 100644
--- a/Completion/Base/.distfiles
+++ b/Completion/Base/.distfiles
@@ -1,6 +1,7 @@
 DISTFILES_SRC='
     .distfiles 
-    _brace_parameter _command_names _condition _default _equal
-    _long_options _match_pattern _match_pattern.orig _match_test _parameter
-    _precommand _redirect _subscript _tilde _vars 
+    _arg_compile _argument_sets _arguments _brace_parameter _combination
+    _command_names _condition _default _describe _equal _first _jobs _math
+    _parameter _precommand _redirect _regex_arguments _subscript _tilde
+    _value _values
 '
diff --git a/Completion/Base/_argument_sets b/Completion/Base/_argument_sets
new file mode 100644
index 000000000..ad59effdc
--- /dev/null
+++ b/Completion/Base/_argument_sets
@@ -0,0 +1,56 @@
+#autoload
+
+local all ret=1 end xor has_args had_args ostate ocontext oopt_args r
+local opre="$PREFIX" oipre="$IPREFIX" ocur="$CURRENT"
+local osuf="$SUFFIX" oisuf="$ISUFFIX" owords
+
+owords="$words[@]"
+
+end=$argv[(i)-]
+[[ end -gt $# ]] && return 1
+
+all=( "${(@)argv[1,end]}" )
+
+shift end
+
+xor=()
+ostate=()
+ocontext=()
+
+while true; do
+  end=$argv[(i)-]
+
+  _arguments -M xor "$1" "$all[@]" "${(@)argv[2,end-1]}"
+  r=$?
+
+  oopt_args=( "$oopt_args[@]" "${(kv)opt_args}" )
+  if [[ r -eq 300 ]]; then
+    ret=300
+    ostate=( "$ostate[@]" "$state[@]" )
+    ocontext=( "$ocontext[@]" "$context[@]" )
+    PREFIX="$opre"   SUFFIX="$osuf"
+    IPREFIX="$oipre" ISUFFIX="$oisuf"
+    CURRENT="$ocur"  words=( "$owords[@]" )
+  elif [[ "$r$ret" = 01 ]]; then
+    ret=0
+  fi
+  
+  [[ end -gt $# ]] && break
+
+  shift end
+done
+
+opt_args=( "$oopt_args[@]" )
+
+if [[ ret -eq 300 ]]; then
+  state=( "$ostate[@]" )
+  context=( "$ocontext[@]" )
+elif [[ -z "$has_args" ]]; then
+  if [[ -n "$had_args" ]]; then
+    _message "no more arguments"
+  else
+    _message "no arguments"
+  fi
+fi
+
+return ret
diff --git a/Completion/Base/_arguments b/Completion/Base/_arguments
index f633b7cf5..9308bce71 100644
--- a/Completion/Base/_arguments
+++ b/Completion/Base/_arguments
@@ -4,7 +4,7 @@
 # descriptions given as arguments to this function.
 
 local long cmd="$words[1]" descr mesg subopts opt usecc autod
-local oldcontext="$curcontext" hasopts
+local oldcontext="$curcontext" hasopts multi ismulti
 
 long=$argv[(I)--]
 if (( long )); then
@@ -148,36 +148,37 @@ if (( long )); then
   set -- "$tmpargv[@]" "${(@P)name}"
 fi
 
+multi=(-i)
 subopts=()
-while [[ "$1" = -(O*|C) ]]; do
+while [[ "$1" = -(O*|C|M*) ]]; do
   case "$1" in
   -C) usecc=yes; shift ;;
   -O) subopts=( "${(@P)2}" ); shift 2 ;;
-  *)  subopts=( "${(@P)1[3,-1]}" ); shift ;;
+  -O*)  subopts=( "${(@P)1[3,-1]}" ); shift ;;
+  -M) ismulti=yes multi=(-I "$2" "$3"); shift 3 ;;
+  -M*) ismulti=yes multi=(-I "${1[3,-1]}" "$2"); shift 2 ;;
   esac
 done
 
 zstyle -s ":completion:${curcontext}:options" auto-description autod
 
-if (( $# )) && comparguments -i "$autod" "$@"; then
+if (( $# )) && comparguments "$multi[@]" "$autod" "$@"; then
   local nm="$compstate[nmatches]" action noargs aret expl local
   local next direct odirect equal single match matched ws tmp1 tmp2 tmp3
-  local opts subc prefix suffix
+  local opts subc tc prefix suffix descrs actions subcs
   local origpre="$PREFIX" origipre="$IPREFIX"
 
-  if comparguments -D descr action; then
-    comparguments -C subc
-    curcontext="${oldcontext%:*}:$subc"
-
+  if comparguments -D descrs actions subcs; then
     if comparguments -O next direct odirect equal; then
       opts=yes
-      _tags arguments options
+      _tags "$subcs[@]" options
     else
-      _tags arguments
+      _tags "$subcs[@]"
     fi
   else
     if comparguments -a; then
       noargs='no more arguments'
+      had_args=yes
     else
       noargs='no arguments'
     fi
@@ -187,83 +188,100 @@ if (( $# )) && comparguments -i "$autod" "$@"; then
     _tags options
   fi
 
+  context=()
+  state=()
+
   while true; do
     while _tags; do
-      if [[ -n "$matched" ]] || _requested arguments; then
-        _description arguments expl "$descr"
+      while (( $#descrs )); do
 
-        if [[ "$action" = \=\ * ]]; then
-          action="$action[3,-1]"
-          words=( "$subc" "$words[@]" )
-	  (( CURRENT++ ))
-        fi
+	action="$actions[1]"
+	descr="$descrs[1]"
+	subc="$subcs[1]"
 
-        if [[ "$action" = -\>* ]]; then
-          comparguments -W line opt_args
-          state="${${action[3,-1]##[ 	]#}%%[ 	]#}"
-	  if [[ -n "$usecc" ]]; then
-	    curcontext="${oldcontext%:*}:$subc"
-	  else
-	    context="$subc"
-	  fi
-          compstate[restore]=''
-          aret=yes
-        else
-          if [[ -z "$local" ]]; then
-            local line
-            typeset -A opt_args
-            local=yes
+        if [[ -n "$matched" ]] || _requested "$subc"; then
+
+          curcontext="${oldcontext%:*}:$subc"
+
+          _description "$subc" expl "$descr"
+
+          if [[ "$action" = \=\ * ]]; then
+            action="$action[3,-1]"
+            words=( "$subc" "$words[@]" )
+	    (( CURRENT++ ))
           fi
 
-          comparguments -W line opt_args
+          if [[ "$action" = -\>* ]]; then
+            comparguments -W line opt_args
+            state=( "$state[@]" "${${action[3,-1]##[ 	]#}%%[ 	]#}" )
+	    if [[ -n "$usecc" ]]; then
+	      curcontext="${oldcontext%:*}:$subc"
+	    else
+	      context=( "$context[@]" "$subc" )
+	    fi
+            compstate[restore]=''
+            aret=yes
+          else
+            if [[ -z "$local" ]]; then
+              local line
+              typeset -A opt_args
+              local=yes
+            fi
 
-          if [[ "$action" = \ # ]]; then
+            comparguments -W line opt_args
 
-            # An empty action means that we should just display a message.
+            if [[ "$action" = \ # ]]; then
 
-            [[ -n "$matched" ]] && compadd -n -Q -S '' -s "$SUFFIX" - "$PREFIX"
-            mesg="$descr"
+              # An empty action means that we should just display a message.
 
-          elif [[ "$action" = \(\(*\)\) ]]; then
+              [[ -n "$matched" ]] &&
+                  compadd -n -Q -S '' -s "$SUFFIX" - "$PREFIX"
+              mesg="$descr"
 
-            # ((...)) contains literal strings with descriptions.
+            elif [[ "$action" = \(\(*\)\) ]]; then
 
-            eval ws\=\( "${action[3,-3]}" \)
+              # ((...)) contains literal strings with descriptions.
 
-            _describe "$descr" ws -M "$match" "$subopts[@]"
+              eval ws\=\( "${action[3,-3]}" \)
 
-          elif [[ "$action" = \(*\) ]]; then
+              _describe -t "$subc" "$descr" ws -M "$match" "$subopts[@]"
 
-            # Anything inside `(...)' is added directly.
+            elif [[ "$action" = \(*\) ]]; then
 
-            _all_labels arguments expl "$descr" \
-                compadd "$subopts[@]" - ${=action[2,-2]}
-          elif [[ "$action" = \{*\} ]]; then
+              # Anything inside `(...)' is added directly.
 
-            # A string in braces is evaluated.
+              _all_labels "$subc" expl "$descr" \
+                  compadd "$subopts[@]" - ${=action[2,-2]}
+            elif [[ "$action" = \{*\} ]]; then
 
-            while _next_label arguments expl "$descr"; do
-              eval "$action[2,-2]"
-            done
-          elif [[ "$action" = \ * ]]; then
+              # A string in braces is evaluated.
 
-            # If the action starts with a space, we just call it.
+              while _next_label "$subc" expl "$descr"; do
+                eval "$action[2,-2]"
+              done
+            elif [[ "$action" = \ * ]]; then
 
-	    eval "action=( $action )"
-            while _next_label arguments expl "$descr"; do
-              "$action[@]"
-            done
-          else
+              # If the action starts with a space, we just call it.
+
+	      eval "action=( $action )"
+              while _next_label "$subc" expl "$descr"; do
+                "$action[@]"
+              done
+            else
 
-            # Otherwise we call it with the description-arguments.
+              # Otherwise we call it with the description-arguments.
 
-            eval "action=( $action )"
-            while _next_label arguments expl "$descr"; do
-              "$action[1]" "$subopts[@]" "$expl[@]" "${(@)action[2,-1]}"
-	    done
+              eval "action=( $action )"
+              while _next_label "$subc" expl "$descr"; do
+                "$action[1]" "$subopts[@]" "$expl[@]" "${(@)action[2,-1]}"
+	      done
+            fi
           fi
         fi
-      fi
+        shift 1 descrs
+        shift 1 actions
+        shift 1 subcs
+      done
 
       if [[ -z "$matched$hasopts" ]] && _requested options &&
           { ! zstyle -T ":completion:${curcontext}:options" prefix-needed ||
@@ -344,7 +362,11 @@ if (( $# )) && comparguments -i "$autod" "$@"; then
   [[ -n "$aret" ]] && return 300
 
   [[ -n "$mesg" ]] && _message "$mesg"
-  [[ -n "$noargs" ]] && _message "$noargs"
+  if [[ -n "$noargs" ]]; then
+    [[ -z "$ismulti" ]] && _message "$noargs"
+  else
+    has_args=yes
+  fi
 
   # Set the return value.
 
diff --git a/Completion/Base/_describe b/Completion/Base/_describe
index ca2d3e4cf..5aeeadf10 100644
--- a/Completion/Base/_describe
+++ b/Completion/Base/_describe
@@ -10,6 +10,12 @@ local _type=values _descr
 if [[ "$1" = -o ]]; then
   _type=options
   shift
+elif [[ "$1" = -t ]]; then
+  _type="$2"
+  shift 2
+elif [[ "$1" = -t* ]]; then
+  _type="${1[3,-1]}"
+  shift
 fi
 
 # Do the tests. `showd' is set if the descriptions should be shown.
diff --git a/Completion/Builtins/_bindkey b/Completion/Builtins/_bindkey
index 6f6677b59..d1e1f8ab1 100644
--- a/Completion/Builtins/_bindkey
+++ b/Completion/Builtins/_bindkey
@@ -24,7 +24,7 @@ _arguments -C -s \
   '(-l -L -d -D -A -N -m -s *)-r[unbind specified in-strings]:*:in-string' \
   '(-l -L -d -D -A -N -m -r *)-s[bind each in-string to each out-string]:*:key string' \
   '(-e -v -a -M -l -L -d -D -A -N -m)-R[interpret in-strings as ranges]' \
-  '(-l -L -d -A -N -m -r -s)*::widgets:->widget'
+  '(-l -L -d -A -N -m -r -s)*::widgets:->widget' && return 0
 
 case $state in
   keymap)
diff --git a/Completion/Builtins/_compdef b/Completion/Builtins/_compdef
index 6287810e5..649daa6dc 100644
--- a/Completion/Builtins/_compdef
+++ b/Completion/Builtins/_compdef
@@ -8,11 +8,19 @@ _arguments -C -s \
   '(-a -n -p -P -k -K)-d[delete]:*:completed command:->ccom' \
   '(-n -d -P -k -K)-p[completion for command matching pattern]:completion function:->cfun:pattern' \
   '(-n -d -p -k -K)-P[as -p for commands without own completion]:completion function:->cfun:pattern' \
-  '(-d -p -P -K)-k[define widget and key binding]:completion function:->cfun:widget name::style:->style:*:key' \
-  '(-d -p -P -k)-K[define multiple widgets based on function]:completion function:->cfun:widget name::style:->style:*:key' \
-  '1:completion function:->cfun' \
-  '2:commands:_command_names'
-  
+  '(-d -p -P -K)-k[define widget and key binding]:completion function:->cfun:style:->style:*:key' \
+  '(-d -p -P -k)-K[define multiple widgets based on function]:*::: :->multi' \
+  ':completion function:->cfun' \
+  '*:commands: _command_names' && return 0
+
+if [[ $state = multi ]]; then
+  case $(( CURRENT % 3 )) in
+  0) _message key
+     return 1;;
+  1) state=cfun;;
+  2) state=style;;
+  esac
+fi
 
 case $state in
   ccom)
diff --git a/Completion/Builtins/_emulate b/Completion/Builtins/_emulate
index 82096a77e..1c1f63cde 100644
--- a/Completion/Builtins/_emulate
+++ b/Completion/Builtins/_emulate
@@ -3,4 +3,4 @@
 _arguments -C -s \
   '-L[set local_options and local_traps as well]' \
   '-R[reset all options instead of only those needed for script portability]' \
-  '1::shell to emulate:(zsh sh ksh csh)'
+  '::shell to emulate:(zsh sh ksh csh)'
diff --git a/Completion/Builtins/_zpty b/Completion/Builtins/_zpty
index ac631baf4..e766e509e 100644
--- a/Completion/Builtins/_zpty
+++ b/Completion/Builtins/_zpty
@@ -9,7 +9,7 @@ _arguments -C -s \
   '(-e -b -d -r -L)-w[send string to command]:name:->name:*:strings to write' \
   '(-e -b -d -w -L *)-r[read string from command]:name:->name:param:_parameters' \
   '(-e -b -d -w -r)-L[list defined commands as calls]' \
-  '(-r)*::args:_normal'
+  '(-r)*::args:_normal' && return 0
 
 if [[ $state = name ]]; then
   list=( ${${(f)"$(zpty)"}#*\) } )
diff --git a/Completion/Core/_tags b/Completion/Core/_tags
index 496f5b7e0..c98990cec 100644
--- a/Completion/Core/_tags
+++ b/Completion/Core/_tags
@@ -53,7 +53,7 @@ if (( $# )); then
     "$_sort_tags" "$@"
   else
     zstyle -a ":completion:${curcontext}:" tag-order order ||
-        order=('arguments values' options)
+        order=('(|*-)argument-* (|*-)option-* values' options)
 
     for tag in $order; do
       case $tag in