about summary refs log tree commit diff
diff options
context:
space:
mode:
authorSven Wischnowsky <wischnow@users.sourceforge.net>2002-03-13 09:28:04 +0000
committerSven Wischnowsky <wischnow@users.sourceforge.net>2002-03-13 09:28:04 +0000
commit45f9a36216637075172d0bdf7ad8e18fad34c42e (patch)
tree8505f11011505b00e8cef1142b11c2b2e94e17e9
parent799b34d817a77244e9e371f6d5f1b01aa171214c (diff)
downloadzsh-45f9a36216637075172d0bdf7ad8e18fad34c42e.tar.gz
zsh-45f9a36216637075172d0bdf7ad8e18fad34c42e.tar.xz
zsh-45f9a36216637075172d0bdf7ad8e18fad34c42e.zip
remove that -T option to compdef again and instead use comma-separated sub-contexts both for function and style lookup (16819)
-rw-r--r--ChangeLog18
-rw-r--r--Completion/Base/Completer/_complete6
-rw-r--r--Completion/Base/Core/_dispatch49
-rw-r--r--Completion/Base/Core/_normal5
-rw-r--r--Completion/Base/Utility/_set_command14
-rw-r--r--Completion/Unix/Command/_gcc6
-rw-r--r--Completion/Unix/Command/_make3
-rw-r--r--Completion/Unix/Command/_su2
-rw-r--r--Completion/Unix/Type/_files2
-rw-r--r--Completion/Unix/Type/_locales11
-rw-r--r--Completion/Unix/Type/_printers2
-rw-r--r--Completion/Unix/Type/_terminals2
-rw-r--r--Completion/Unix/Type/_time_zone2
-rw-r--r--Completion/X/Type/_x_display2
-rw-r--r--Completion/Zsh/Command/_compdef54
-rw-r--r--Completion/Zsh/Context/_in_vared2
-rw-r--r--Completion/Zsh/Context/_redirect15
-rw-r--r--Completion/Zsh/Context/_subscript2
-rw-r--r--Completion/Zsh/Context/_value32
-rw-r--r--Completion/compdump55
-rw-r--r--Completion/compinit171
-rw-r--r--Doc/Zsh/compsys.yo149
-rw-r--r--Src/Zle/zle_tricky.c1
23 files changed, 293 insertions, 312 deletions
diff --git a/ChangeLog b/ChangeLog
index 75af6b705..5b6765055 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,21 @@
+2002-03-13  Sven Wischnowsky  <wischnow@zsh.org>
+
+	* 16819: Completion/compdump, Completion/compinit,
+	Completion/Base/Completer/_complete,
+	Completion/Base/Core/_dispatch, Completion/Base/Core/_normal,
+	Completion/Base/Utility/_set_command,
+	Completion/Unix/Command/_gcc, Completion/Unix/Command/_make,
+	Completion/Unix/Command/_su, Completion/Unix/Type/_files,
+	Completion/Unix/Type/_locales, Completion/Unix/Type/_printers,
+	Completion/Unix/Type/_terminals, Completion/Unix/Type/_time_zone,
+	Completion/X/Type/_x_display, Completion/Zsh/Command/_compdef,
+	Completion/Zsh/Context/_in_vared,
+	Completion/Zsh/Context/_redirect,
+	Completion/Zsh/Context/_subscript, Completion/Zsh/Context/_value,
+	Doc/Zsh/compsys.yo, Src/Zle/zle_tricky.c: remove that -T option
+	to compdef again and instead use comma-separated sub-contexts
+	both for function and style lookup
+
 2002-03-11  Oliver Kiddle  <opk@zsh.org>
 
 	* 16804: Completion/Unix/Command/_sccs,
diff --git a/Completion/Base/Completer/_complete b/Completion/Base/Completer/_complete
index 23670f7c0..743fd046b 100644
--- a/Completion/Base/Completer/_complete
+++ b/Completion/Base/Completer/_complete
@@ -95,7 +95,7 @@ fi
 
 comp="$_comps[-first-]"
 if [[ -n "$comp" ]]; then
-  service="${_servicecomps[-first-]:--first-}"
+  service="${_services[-first-]:--first-}"
   ccarray[3]=-first-
   eval "$comp" && ret=0
   if [[ "$_compskip" = all ]]; then
@@ -124,7 +124,7 @@ else
   ccarray[3]="$cname"
 
   comp="$_comps[$cname]"
-  service="${_servicecomps[$cname]:-$cname}"
+  service="${_services[$cname]:-$cname}"
 
   # If not, we use default completion, if any.
 
@@ -134,7 +134,7 @@ else
       return 1
     fi
     comp="$_comps[-default-]"
-    service="${_servicecomps[-default-]:--default-}"
+    service="${_services[-default-]:--default-}"
   fi
   [[ -n "$comp" ]] && eval "$comp" && ret=0
 fi
diff --git a/Completion/Base/Core/_dispatch b/Completion/Base/Core/_dispatch
index 124aea112..cd6a87171 100644
--- a/Completion/Base/Core/_dispatch
+++ b/Completion/Base/Core/_dispatch
@@ -1,31 +1,17 @@
 #autoload
 
 local comp pat val name i ret=1 _compskip="$_compskip"
-local curcontext="$curcontext" service str comptype noskip def
-local __comps __patcomps __postpatcomps __services
+local curcontext="$curcontext" service str noskip
 
 # If we get the option `-s', we don't reset `_compskip'.
 
-while [[ "$1" = -[sd] ]]; do
-  if [[ "$1" = -s ]]; then
-    noskip=yes
-  else
-    def=yes
-  fi
-  shift
-done
+if [[ "$1" = -s ]]; then
+  noskip=yes
+fi
 
 [[ -z "$noskip" ]] && _compskip=
 
-comptype=$1
-
-__comps=_$1
-
-(( ${(P)+__comps} )) || return 1
-
-__patcomps=_pat$1
-__postpatcomps=_postpat$1
-__services=_service$1
+curcontext="${curcontext%:*:*}:${1}:"
 
 shift
 
@@ -35,9 +21,9 @@ if [[ "$_compskip" != (all|*patterns*) ]]; then
 
   for str in "$@"; do
     [[ -n "$str" ]] || continue
-    service="${${(e):-\$${__services}[\$str]}:-$str}"
-    for i in "${(@e):-\$${__patcomps}[(K)\$str]}"; do
-      "$i" && ret=0
+    service="${_services[$str]:-$str}"
+    for i in "${(@)_patcomps[(K)$str]}"; do
+      eval "$i" && ret=0
       if [[ "$_compskip" = *patterns* ]]; then
         break
       elif [[ "$_compskip" = all ]]; then
@@ -54,30 +40,27 @@ ret=1
 for str in "$@"; do
   [[ -n "$str" ]] || continue
   name="$str"
-  comp="${(e):-\$${__comps}[\$str]}"
-  service="${${(e):-\$${__services}[\$str]}:-$str}"
+  comp="${_comps[$str]}"
+  service="${_services[$str]:-$str}"
 
   [[ -z "$comp" ]] || break
 done
 
 # And generate the matches, probably using default completion.
 
-if [[ -n "$comp" ]]; then
+if [[ -n "$comp" && "$name" != "${argv[-1]}" ]]; then
   _compskip=patterns
   eval "$comp" && ret=0
   [[ "$_compskip" = (all|*patterns*) ]] && return ret
-elif [[ "$_compskip" != *default* ]]; then
-  name=-default-
-  comp="${(e):-\$${__comps}[-default-]}"
 fi
 
 if [[ "$_compskip" != (all|*patterns*) ]]; then
   for str; do
     [[ -n "$str" ]] || continue
-    service="${${(e):-\$${__services}[\$str]}:-$str}"
-    for i in "${(@e):-\$${__postpatcomps}[(K)\$str]}"; do
+    service="${_services[$str]:-$str}"
+    for i in "${(@)_postpatcomps[(K)$str]}"; do
       _compskip=default
-      "$i" && ret=0
+      eval "$i" && ret=0
       if [[ "$_compskip" = *patterns* ]]; then
         break
       elif [[ "$_compskip" = all ]]; then
@@ -88,9 +71,9 @@ if [[ "$_compskip" != (all|*patterns*) ]]; then
   done
 fi
 
-[[ "$name" = -default- && -n "$comp" &&
+[[ "$name" = "${argv[-1]}" && -n "$comp" &&
    "$_compskip" != (all|*default*) ]] &&
-  service="${${(e):-\$${__services}[-default-]}:--default-}" &&
+  service="${_services[$name]:-$name}" &&
    eval "$comp" && ret=0
 
 _compskip=''
diff --git a/Completion/Base/Core/_normal b/Completion/Base/Core/_normal
index 028687fd1..36ecb225d 100644
--- a/Completion/Base/Core/_normal
+++ b/Completion/Base/Core/_normal
@@ -1,6 +1,6 @@
 #compdef -command-line-
 
-local _comp_command1 _comp_command2 skip
+local _comp_command1 _comp_command2 _comp_command skip
 
 if [[ "$1" = -s ]]; then
   skip=(-s)
@@ -22,4 +22,5 @@ fi
 
 _set_command
 
-_dispatch -d "$skip[@]" comps "$_comp_command1" "$_comp_command2"
+_dispatch "$skip[@]" "$_comp_command" \
+          "$_comp_command1" "$_comp_command2" -default-
diff --git a/Completion/Base/Utility/_set_command b/Completion/Base/Utility/_set_command
index daf532686..6b4910889 100644
--- a/Completion/Base/Utility/_set_command
+++ b/Completion/Base/Utility/_set_command
@@ -1,7 +1,7 @@
 #autoload
 
-# This sets the parameters _comp_command1 and _comp_command2 in the
-# calling function.
+# This sets the parameters _comp_command1, _comp_command2 and _comp_command
+# in the calling function.
 
 local command
 
@@ -11,21 +11,21 @@ command="$words[1]"
 
 if (( $+builtins[$command] + $+functions[$command] )); then
   _comp_command1="$command"
-  curcontext="${curcontext%:*:*}:${_comp_command1}:"
+  _comp_command="$_comp_command1"
 elif [[ "$command[1]" = '=' ]]; then
   eval _comp_command2\=$command
   _comp_command1="$command[2,-1]"
-  curcontext="${curcontext%:*:*}:${_comp_command2}:"
+  _comp_command="$_comp_command2"
 elif [[ "$command" = ..#/* ]]; then
   _comp_command1="${PWD}/$command"
   _comp_command2="${command:t}"
-  curcontext="${curcontext%:*:*}:${_comp_command2}:"
+  _comp_command="$_comp_command2"
 elif [[ "$command" = */* ]]; then
   _comp_command1="$command"
   _comp_command2="${command:t}"
-  curcontext="${curcontext%:*:*}:${_comp_command2}:"
+  _comp_command="$_comp_command2"
 else
   _comp_command1="$command"
   _comp_command2="$commands[$command]"
-  curcontext="${curcontext%:*:*}:${_comp_command1}:"
+  _comp_command="$_comp_command1"
 fi
diff --git a/Completion/Unix/Command/_gcc b/Completion/Unix/Command/_gcc
index e218a4414..6f105155d 100644
--- a/Completion/Unix/Command/_gcc
+++ b/Completion/Unix/Command/_gcc
@@ -1,13 +1,13 @@
-#compdef gcc g++ -T values LDFLAGS CFLAGS CPPFLAGS
+#compdef gcc g++ -value-,LDFLAGS,-default- -value-,CFLAGS,-default- -value-,CPPFLAGS,-default-
 
 local curcontext="$curcontext" state line ret=1 expl args args2
 typeset -A opt_args
 
-if [[ "$comptype" = values ]]; then
+if [[ "$service" = -value-* ]]; then
   compset -q
   words=( fake "$words[@]" )
   (( CURRENT++ ))
-  if [[ "$service" = LDFLAGS ]]; then
+  if [[ "$service" = *LDFLAGS ]]; then
     args2=( '-R:runtime path:->rundir' )
   else
     args2=()
diff --git a/Completion/Unix/Command/_make b/Completion/Unix/Command/_make
index 3402eb172..df28eac60 100644
--- a/Completion/Unix/Command/_make
+++ b/Completion/Unix/Command/_make
@@ -45,6 +45,7 @@ else
     fi
     _wanted targets expl 'make target' compadd -a tmp && return 0
   fi
+  compstate[parameter]="${PREFIX%%\=*}"
   compset -P 1 '*='
-  _files
+  _value "$@"
 fi
diff --git a/Completion/Unix/Command/_su b/Completion/Unix/Command/_su
index a1dd69db8..24fb5932e 100644
--- a/Completion/Unix/Command/_su
+++ b/Completion/Unix/Command/_su
@@ -17,4 +17,4 @@ fi
 shell="${${(M@)${(@f)$(</etc/passwd)}:#$usr*}##*:}"
 compset -n $base
 
-_dispatch comps $shell $shell:t -default-
+_dispatch $shell:t $shell $shell:t -default-
diff --git a/Completion/Unix/Type/_files b/Completion/Unix/Type/_files
index 4a57cdbc7..add41dbbe 100644
--- a/Completion/Unix/Type/_files
+++ b/Completion/Unix/Type/_files
@@ -1,4 +1,4 @@
-#compdef -T redirs -default-
+#compdef -redirect-,-default-,-default-
 
 local opts tmp glob pat pats expl tag i def descr end ign ret=1 match tried
 local type sdef
diff --git a/Completion/Unix/Type/_locales b/Completion/Unix/Type/_locales
new file mode 100644
index 000000000..ad5741c8a
--- /dev/null
+++ b/Completion/Unix/Type/_locales
@@ -0,0 +1,11 @@
+#compdef -value-,LANG,-default- -P -value-,LC_*,-default-
+
+local locales
+
+if (( $+commands[locale] )); then
+  locales=( $(_call_program locales locale -a) )
+else
+  locales=( /usr/lib/locale/*(:t) )
+fi
+
+_wanted locales expl locale compadd "$@" -a locales
diff --git a/Completion/Unix/Type/_printers b/Completion/Unix/Type/_printers
index 7229c1dc6..d736dd51d 100644
--- a/Completion/Unix/Type/_printers
+++ b/Completion/Unix/Type/_printers
@@ -1,4 +1,4 @@
-#compdef -T values PRINTER LPDEST
+#compdef -value-,PRINTER,-default- -value-,LPDEST,-default-
 
 local expl ret=1 list disp sep
 
diff --git a/Completion/Unix/Type/_terminals b/Completion/Unix/Type/_terminals
index 039430ad5..59f8d4d87 100644
--- a/Completion/Unix/Type/_terminals
+++ b/Completion/Unix/Type/_terminals
@@ -1,4 +1,4 @@
-#compdef infocmp -T values TERM
+#compdef infocmp -value-,TERM,-default-
 
 local desc expl
 
diff --git a/Completion/Unix/Type/_time_zone b/Completion/Unix/Type/_time_zone
index 215d8bd4a..5bad7329b 100644
--- a/Completion/Unix/Type/_time_zone
+++ b/Completion/Unix/Type/_time_zone
@@ -1,4 +1,4 @@
-#compdef -T values TZ
+#compdef -value-,TZ,-default-
 
 local expl
 
diff --git a/Completion/X/Type/_x_display b/Completion/X/Type/_x_display
index 647ff1f5a..c093ac943 100644
--- a/Completion/X/Type/_x_display
+++ b/Completion/X/Type/_x_display
@@ -1,3 +1,3 @@
-#compdef -T values DISPLAY
+#compdef -value-,DISPLAY,-default-
 
 _tags displays && _hosts -S ':0 ' -r :
diff --git a/Completion/Zsh/Command/_compdef b/Completion/Zsh/Command/_compdef
index db4309642..48daa9e53 100644
--- a/Completion/Zsh/Command/_compdef
+++ b/Completion/Zsh/Command/_compdef
@@ -1,24 +1,37 @@
 #compdef compdef
 
-local state line expl list disp curcontext="$curcontext"
+local state line expl list disp curcontext="$curcontext" pat normal ret=1
+local args1 args2
 typeset -A opt_args
 
-_arguments -C -s -A "-*" -S \
-  '(-d)-a[make function autoloadable]' \
-  '(-d -p -P)-n[leave existing definitions intact]' \
-  "*-T[select type of completion function]:completion function type:($_comp_assocs)" \
+args2=()
+if (( ! ${words[2,-1][(I)[^-]*]} || ${words[(I)-[kK]]} )); then
+  args1=(
+    -A '-*'
+    '(-d)-a[make function autoloadable]'
+    '(-d)-n[leave existing definitions intact]'
+  )
+  args2=(
+     - d
+      '(-a -n)-d[delete]:*:completed command:->ccom'
+     - k
+      '-k[define widget and key binding]:completion function:->cfun:style:->style:*:key'
+     - K
+      '-K[define multiple widgets based on function]:*::: :->multi'
+  )
+else
+  args1=(
+    '-N[completion for named command]'
+  )
+fi
+
+_arguments -C -s -S \
+  "$args1[@]" \
+  '-p[completion for command matching pattern]' \
+  '-P[completion for command matching pattern]' \
   ':completion function:->cfun' \
-  '*:commands: _command_names' \
- - d \
-  '(-a -n)-d[delete]:*:completed command:->ccom' \
- - p \
-  '(-n)-p[completion for command matching pattern]:completion function:->cfun:pattern' \
- - P \
-  '(-n)-P[as -p for commands without own completion]:completion function:->cfun:pattern' \
- - k \
-  '-k[define widget and key binding]:completion function:->cfun:style:->style:*:key' \
- - K \
-  '-K[define multiple widgets based on function]:*::: :->multi' && return 0
+  '*:commands:->com' \
+  "$args2[@]" && return 0
 
 if [[ $state = multi ]]; then
   case $(( CURRENT % 3 )) in
@@ -30,6 +43,15 @@ if [[ $state = multi ]]; then
 fi
 
 case $state in
+  com)
+    pat="${words[(I)-[pP]]}"
+    normal="${words[(I)-N]}"
+    if (( pat && pat > normal )); then
+      _message -e patterns 'pattern'
+    else
+      _command_names
+    fi
+  ;;
   ccom)
     _wanted commands expl 'completed command' compadd -k _comps
   ;;
diff --git a/Completion/Zsh/Context/_in_vared b/Completion/Zsh/Context/_in_vared
index 03f6d404e..c3c8a20e2 100644
--- a/Completion/Zsh/Context/_in_vared
+++ b/Completion/Zsh/Context/_in_vared
@@ -32,4 +32,4 @@ fi
 
 compstate[insert]="${compstate[insert]//tab /}"
 
-_dispatch comps "$also"
+_dispatch "$also" "$also"
diff --git a/Completion/Zsh/Context/_redirect b/Completion/Zsh/Context/_redirect
index 5e454014b..b33e785ee 100644
--- a/Completion/Zsh/Context/_redirect
+++ b/Completion/Zsh/Context/_redirect
@@ -1,17 +1,16 @@
 #compdef -redirect-
 
-# This searches for `<command-name>:<redir-op>' and `<redir-op>', where
-# `<redir-op>' is something like `<' or `2>'.
-
-local strs _comp_command1 _comp_command2
+local strs _comp_command1 _comp_command2 _comp_command
 
 _set_command
 
-strs=( "$compstate[redirect]" )
+strs=( -default- )
 
 if [[ -n "$_comp_command1" ]]; then
-  strs=( "${_comp_command1}:$strs[-1]" "$strs[@]" )
-  [[ -n "$_comp_command2" ]] && strs=( "${_comp_command2}:$strs[1]" "$strs[@]" )
+  strs=( "${_comp_command1}" "$strs[@]" )
+  [[ -n "$_comp_command2" ]] &&
+      strs=( "${_comp_command2}" "$strs[@]" )
 fi
 
-_dispatch -d redirs "$strs[@]"
+_dispatch -redirect-,${compstate[redirect]},${_comp_command} \
+          -redirect-,{${compstate[redirect]},-default-},${^strs}
diff --git a/Completion/Zsh/Context/_subscript b/Completion/Zsh/Context/_subscript
index 0f1138e1a..052848ffe 100644
--- a/Completion/Zsh/Context/_subscript
+++ b/Completion/Zsh/Context/_subscript
@@ -113,5 +113,5 @@ elif [[ ${(Pt)${compstate[parameter]}} = array* ]]; then
 
   return 1
 else
-  _dispatch comps -math-
+  _dispatch -math- -math-
 fi
diff --git a/Completion/Zsh/Context/_value b/Completion/Zsh/Context/_value
index 9d0acaa0e..15732f22c 100644
--- a/Completion/Zsh/Context/_value
+++ b/Completion/Zsh/Context/_value
@@ -1,4 +1,4 @@
-#compdef -value- -array-value- -T values -default-
+#compdef -value- -array-value- -value-,-default-,-default-
 
 # You can customize completion for different parameters by writing
 # functions with the tag-line `#compdef -T value <name>'.
@@ -6,30 +6,20 @@
 # and `<param-name>'. If the line contains a command (as in `make foo=<TAB>')
 # the string `<command>:<param-name>:<param-type>' is also searched for.
 
-if [[ "$service" != -default- ]]; then
-  local strs type
+if [[ "$service" != -value-,* ]]; then
+  local strs ctx=
 
-  type="${(Pt)compstate[parameter]}"
-
-  if [[ -z "$type" ]]; then
-    if [[ "$compstate[parameter]" = *-* ]]; then
-      type=association-value
-    elif [[ "$compstate[context]" = value ]]; then
-      type=scalar
-    else
-      type=array
-    fi
-  fi
-
-  strs=( "${compstate[parameter]}:$type" "$compstate[parameter]" )
+  strs=( -default- )
 
   if [[ "$compstate[context]" != *value && -n "$_comp_command1" ]]; then
-    strs=( "${_comp_command1}:$^strs[@]" "$strs[@]" )
+    ctx="${_comp_command}"
+    strs=( "${_comp_command1}" "$strs[@]" )
     [[ -n "$_comp_command2" ]] &&
-        strs=( "${_comp_command2}:${(@)^strs[-2,-1]}" "$strs[@]" )
+        strs=( "${_comp_command2}" "$strs[@]" )
   fi
 
-  _dispatch -d values "$strs[@]"
+  _dispatch -value-,${compstate[parameter]},$ctx \
+            -value-,{${compstate[parameter]},-default-},${^strs}
 else
   if [[ "$compstate[parameter]" != *-* &&
         "$compstate[context]" = *value &&
@@ -39,7 +29,9 @@ else
           compadd -k "$compstate[parameter]"
     else
       compstate[parameter]="${compstate[parameter]}-${words[CURRENT-1]}"
-      _value "$@"
+
+      _dispatch -value-,${compstate[parameter]}, \
+                -value-,{${compstate[parameter]},-default-},-default-
     fi
   else
     local pats
diff --git a/Completion/compdump b/Completion/compdump
index 194fcf07b..630d96c63 100644
--- a/Completion/compdump
+++ b/Completion/compdump
@@ -35,43 +35,34 @@ fi
 
 print "#files: $#_d_files" > $_d_file
 
-# First dump the arrays _comps, _servicecomps and _patcomps.  The quoting
+# Dump the arrays _comps, _services and _patcomps.  The quoting
 # hieroglyphics ensure that a single quote inside a variable is itself
 # correctly quoted.
 
-for _d_name in $_comp_assocs; do
-
-  print "\n\ntypeset -gA _$_d_name _service$_d_name _pat$_d_name _postpat$_d_name"
-
-  _d_tmp="_${_d_name}"
-  print "\n_${_d_name}=("
-  for _d_f in ${(Pok)_d_tmp}; do
-    print -r - "${(q)_d_f}" "${(q)${(e):-\$${_d_tmp}[$_d_f]}}"
-  done
-  print ")"
-
-  _d_tmp="_service${_d_name}"
-  print "\n_service${_d_name}=("
-  for _d_f in ${(Pok)_d_tmp}; do
-    print -r - "${(q)_d_f}" "${(q)${(e):-\$${_d_tmp}[$_d_f]}}"
-  done
-  print ")"
-
-  _d_tmp="_pat${_d_name}"
-  print "\n_pat${_d_name}=("
-  for _d_f in ${(Pok)_d_tmp}; do
-    print -r - "${(q)_d_f}" "${(q)${(e):-\$${_d_tmp}[$_d_f]}}"
-  done
-  print ")"
-
-  _d_tmp="_postpat${_d_name}"
-  print "\n_postpat${_d_name}=("
-  for _d_f in ${(Pok)_d_tmp}; do
-    print -r - "${(q)_d_f}" "${(q)${(e):-\$${_d_tmp}[$_d_f]}}"
-  done
-  print ")"
+print "\n_comps=(" >> $_d_file
+for _d_f in ${(ok)_comps}; do
+  print -r - "${(q)_d_f}" "${(q)_comps[$_d_f]}"
+done >> $_d_file
+print ")" >> $_d_file
+
+print "\n_services=(" >> $_d_file
+for _d_f in ${(ok)_services}; do
+  print -r - "${(q)_d_f}" "${(q)_services[$_d_f]}"
+done >> $_d_file
+print ")" >> $_d_file
 
+print "\n_patcomps=(" >> $_d_file
+for _d_f in ${(ok)_patcomps}; do
+  print -r - "${(q)_d_f}" "${(q)_patcomps[$_d_f]}"
 done >> $_d_file
+print ")" >> $_d_file
+
+_d_tmp="_postpatcomps"
+print "\n_postpatcomps=(" >> $_d_file
+for _d_f in ${(ok)_postpatcomps}; do
+  print -r - "${(q)_d_f}" "${(q)_postpatcomps[$_d_f]}"
+done >> $_d_file
+print ")" >> $_d_file
 
 print "\n_compautos=(" >> $_d_file
 for _d_f in "${(ok@)_compautos}"; do
diff --git a/Completion/compinit b/Completion/compinit
index 94f5f7091..8e04af36d 100644
--- a/Completion/compinit
+++ b/Completion/compinit
@@ -102,21 +102,10 @@ while [[ $# -gt 0 && $1 = -[dDiuC] ]]; do
   esac
 done
 
-# The name suffixes for the associative arrays containing the functions
-# to call.
-
-typeset -gUa _comp_assocs
-
-_comp_assocs=(comps)
-
 # The associative arrays containing the definitions for the commands and
 # services.
-# Definitions for patterns will be stored in the associations `_pat*'
-# and `_postpat*'.
-# The assocs for the other function types are created automatically by
-# compdef.
 
-typeset -gA _comps _servicecomps _patcomps _postpatcomps
+typeset -gA _comps _services _patcomps _postpatcomps
 
 # `_compautos' contains the names and options for autoloaded functions
 # that get options.
@@ -191,9 +180,6 @@ comppostfuncs=()
 # The option `-P' is like `-p', but the function will be called after
 # trying to find a function defined for the command on the line if no
 # such function could be found.
-# In each of these cases the argument list may also contain `-T assoc'
-# options to specify the associactive arrays to which the following
-# definitions should be added.
 # With the `-k' option a function for a special completion keys is 
 # defined and immediately bound to those keys. Here, the extra arguments
 # are the name of one of the builtin completion widgets and any number
@@ -209,8 +195,7 @@ comppostfuncs=()
 # whose names are given as arguments. If combined with the `-p' option
 # it deletes the definitions for the patterns given as argument.
 # The `-d' option may not be combined with the `-k' option, i.e.
-# definitions for key function can not be removed. But one `-T assoc'
-# option may follow the `-d' to say which definitions should be removed.
+# definitions for key function can not be removed.
 #
 # Examples:
 #
@@ -232,7 +217,7 @@ comppostfuncs=()
 #   delete the definitions for the command names `bar' and `baz'
 
 compdef() {
-  local opt autol type func delete new i ret=0 cmd svc assoc=comps
+  local opt autol type func delete new i ret=0 cmd svc
 
   # Get the options.
 
@@ -277,38 +262,26 @@ compdef() {
 
     if [[ "$1" = *\=* ]]; then
       while (( $# )); do
-        if [[ $1 = -T ]]; then
-          shift
-          if (( ! $# )); then
-            echo "$0: missing type"
-            return 1
-          fi
-          _comp_assocs=( "$_comp_assocs[@]" "$1" )
-          typeset -gA _$1 _service$1 _pat$1 _postpat$1
-          assoc="$1"
-          shift
-        else
-          if [[ "$1" = *\=* ]]; then
-	    cmd="${1%%\=*}"
-	    svc="${1#*\=}"
-            func="$_comps[${(e):-\${(k)_service${assoc}[(R)$svc]:-$svc}}]"
-            [[ -n ${(e):-\$_service${assoc}[$svc]} ]] &&
-                svc=${(e):-\$_service${assoc}[$svc]}
-	    [[ -z "$func" ]] &&
-	        func="${${(e):-\$_pat${assoc}[(K)$svc][1]}:-${(e):-\$_postpat${assoc}[(K)$svc][1]}}"
-            if [[ -n "$func" ]]; then
-	      eval "_${assoc}"'[$cmd]="$func"'
-	      eval "_service${assoc}"'[$cmd]="$svc"'
-	    else
-	      echo "$0: unknown command or service: $svc"
-	      ret=1
-	    fi
+        if [[ "$1" = *\=* ]]; then
+	  cmd="${1%%\=*}"
+	  svc="${1#*\=}"
+          func="$_comps[${_services[(R)$svc]:-$svc}]"
+          [[ -n ${_services[$svc]} ]] &&
+              svc=${_services[$svc]}
+	  [[ -z "$func" ]] &&
+	      func="${${_patcomps[(K)$svc][1]}:-${_postpatcomps[(K)$svc][1]}}"
+          if [[ -n "$func" ]]; then
+	    _comps[$cmd]="$func"
+	    _services[$cmd]="$svc"
 	  else
-	    echo "$0: invalid argument: $1"
+	    echo "$0: unknown command or service: $svc"
 	    ret=1
 	  fi
-          shift
-        fi
+	else
+	  echo "$0: invalid argument: $1"
+	  ret=1
+	fi
+        shift
       done
 
       return ret
@@ -322,42 +295,6 @@ compdef() {
     shift
 
     case "$type" in
-    pattern)
-      while (( $# )); do
-        if [[ $1 = -T ]]; then
-          shift
-          if (( ! $# )); then
-            echo "$0: missing type"
-            return 1
-          fi
-          _comp_assocs=( "$_comp_assocs[@]" "$1" )
-          typeset -gA _$1 _service$1 _pat$1 _postpat$1
-          assoc="$1"
-          shift
-        else
-          eval "_pat${assoc}"'[$1]="$func"'
-          shift
-        fi
-      done
-      ;;
-    postpattern)
-      while (( $# )); do
-        if [[ $1 = -T ]]; then
-          shift
-          if (( ! $# )); then
-            echo "$0: missing type"
-            return 1
-          fi
-          _comp_assocs=( "$_comp_assocs[@]" "$1" )
-          typeset -gA _$1 _service$1 _pat$1 _postpat$1
-          assoc="$1"
-          shift
-        else
-          eval "_postpat${assoc}"'[$1]="$func"'
-          shift
-        fi
-      done
-      ;;
     widgetkey)
       while [[ -n $1 ]]; do
 	if [[ $# -lt 3 ]]; then
@@ -406,54 +343,48 @@ compdef() {
       # For commands store the function name in the
       # associative array, command names as keys.
       while (( $# )); do
-        if [[ $1 = -T ]]; then
-          shift
-          if (( ! $# )); then
-            echo "$0: missing type"
-            return 1
-          fi
-          _comp_assocs=( "$_comp_assocs[@]" "$1" )
-          typeset -gA _$1 _service$1 _pat$1 _postpat$1
-          assoc="$1"
-          shift
+        if [[ "$1" = -N ]]; then
+          type=normal
+        elif [[ "$1" = -p ]]; then
+          type=pattern
+        elif [[ "$1" = -P ]]; then
+          type=postpattern
         else
-          if [[ "$1" = *\=* ]]; then
-	    cmd="${1%%\=*}"
-	    svc=yes
-          else
-	    cmd="$1"
-	    svc=
-          fi
-          if [[ -z "$new" || -z "${(e):-\$_${assoc}[$1]}" ]]; then
-            eval "_${assoc}"'[$cmd]="$func"'
-	    [[ -n "$svc" ]] && eval "_service${assoc}"'[$cmd]="${1#*\=}"'
-	  fi
-          shift
+          case "$type" in
+          pattern)
+            _patcomps[$1]="$func"
+            ;;
+          postpattern)
+            _postpatcomps[$1]="$func"
+            ;;
+          *)
+            if [[ "$1" = *\=* ]]; then
+	      cmd="${1%%\=*}"
+	      svc=yes
+            else
+	      cmd="$1"
+	      svc=
+            fi
+            if [[ -z "$new" || -z "${_comps[$1]}" ]]; then
+              _comps[$cmd]="$func"
+	      [[ -n "$svc" ]] && _services[$cmd]="${1#*\=}"
+	    fi
+            ;;
+          esac
         fi
+        shift
       done
       ;;
     esac
   else
     # Handle the `-d' option, deleting.
 
-    if [[ $1 = -T ]]; then
-      shift
-      if (( ! $# )); then
-        echo "$0: missing type"
-        return 1
-      fi
-      _comp_assocs=( "$_comp_assocs[@]" "$1" )
-      typeset -gA _$1 _service$1 _pat$1 _postpat$1
-      assoc="$1"
-      shift
-    fi
-
     case "$type" in
     pattern)
-      unset "_pat${assoc}[$^@]"
+      unset "_patcomps[$^@]"
       ;;
     postpattern)
-      unset "_postpat${assoc}[$^@]"
+      unset "_postpatcomps[$^@]"
       ;;
     key)
       # Oops, cannot do that yet.
@@ -462,7 +393,7 @@ compdef() {
       return 1
       ;;
     *)
-      unset "_${assoc}[$^@]"
+      unset "_comps[$^@]"
     esac
   fi
 }
diff --git a/Doc/Zsh/compsys.yo b/Doc/Zsh/compsys.yo
index 1fb337329..48acd9bfe 100644
--- a/Doc/Zsh/compsys.yo
+++ b/Doc/Zsh/compsys.yo
@@ -159,7 +159,8 @@ completion system and will not be treated specially.
 The tags are:
 
 startitem()
-item(tt(#compdef) var(names...))(
+item(tt(#compdef) var(names...) [ tt(-[pP]) var(patterns...) [ tt(-N)
+var(names...) ] ])(
 The file will be made autoloadable and the function defined 
 in it will be called when completing var(names), each of which is
 either the name of a command whose arguments are to be completed or one of
@@ -174,33 +175,18 @@ arguments for the command `tt(cmd)', setting the parameter tt($service)
 to the string `tt(service)'.  The function can then use that parameter 
 to decide what to complete.
 
-Finally, the list of var(names) may contain tt(-T) options, each
-followed by a type name.  These type names describe in which set of
-completion function definitions the function is to be stored.  The
-default without a tt(-T) option is `tt(comps)', saying that the
-function is a normal completion function.  Other type names currently
-understood by the completion system are tt(redirs) and tt(values).
-The first is used to define specialised completion functions for
-use after redirection operators for certain commands and the latter is
-used to define functions used when completing values of parameters.
-For example, to define the function that should be used when
-completing after `tt(foo=<TAB>)' one would use the tag line:
-
-example(#compdef -T values foo)
-
-When the function is called, the parameter tt($comptype) will be set
-to the type name, making it easy to distinguish what should be
-completed.
-)
-item(tt(#compdef -p) var(patterns...))(
-The file will be made autoloadable and the function defined in it will be
-called when completing for a command whose name matches the given
-var(pattern) (a standard globbing pattern).  As in the first case, the
-list of var(patterns) may contain tt(-T) options.
-)
-item(tt(#compdef -P) var(patterns...))(
-Like the previous one, but the function will be called only if no
-completion function for the command on the line could be found.
+If the list of var(names) contains a tt(-p) or tt(-P) option, the
+following words are taken to be patterns.  When completing for a
+command or context whose name matches one of the patterns, the
+function will be called.  In the case of tt(-P), this will only be
+done if no other completion function for the command or context could
+be found (i.e. this can be used to define default completion for
+commands or contexts matching one of the patterns which don't have a
+completion function specifically defined for them).
+
+If the list contains the tt(-N) option, the following words are used
+as in the normal case again.  Another tt(-p) or tt(-P) option can be
+usedto toggle back to defining patterns again. 
 )
 item(tt(#compdef -k) var(style key-sequences...))(
 This can be used to bind special completion functions to the
@@ -272,10 +258,8 @@ also be called directly by the user.
 findex(compdef)
 cindex(completion system, adding definitions)
 startitem()
-xitem(tt(compdef) [ tt(-an) ] var(function names) [ tt(-T) var(type) ] ...))
-xitem(tt(compdef -d) [ tt(-T) var(type) ] var(names...))
-xitem(tt(compdef -p) [ tt(-a) ] var(function patterns) [ tt(-T) var(type) ] ...)
-xitem(tt(compdef -P) [ tt(-a) ] var(function patterns) [ tt(-T) var(type) ] ...)
+xitem(tt(compdef) [ tt(-an) ] var(function names...) [ tt(-[pP]) var(patterns...) ])
+xitem(tt(compdef -d) var(names...))
 xitem(tt(compdef -k) [ tt(-an) ] var(function style key-sequences...))
 item(tt(compdef -K) [ tt(-an) ] var(function name style key-sequences ...))(
 The first form tells the completion system to call the given
@@ -297,27 +281,25 @@ arguments to the command tt(foo), one would use:
 
 example(compdef '_files -g "*.h"' foo)
 
-The tt(-T) options in the list of var(names) define for which type of
-completions the function is to be used, i.e. in which set of
-completion functions definitions it should be added.  Currently used
-tt(type)s are tt(comps) (the default, for normal completion functions
-for command completion), tt(values) for completion of parameter values
-in assignments and tt(redirs) for completion after redirection
-operators.
-
 If the
 tt(-n) option is given, any existing completion behaviour for particular
 contexts or commands will not be altered.  These definitions can be deleted
 by giving the tt(-d) option as in the second form.
 
-The form with tt(-p) is similar to the first, but var(function) will be
-called for all commands whose name matches the var(pattern); this is like
-the tt(#compdef -p) function tag.
-
-The form with tt(-P) is like the third, but the var(function) will be
-called only if no function for the command itself was found or if one
-was found and it set the tt(_compskip) parameter to a value em(not)
-containing the substring tt(patterns).
+In both of the first two cases forms and as for the tt(#compdef) tag
+described above, the var(names) may also contain tt(-p), tt(-P) and
+tt(-N) options.  The first two make the following arguments be used as
+patterns and the var(function) will be called for all commands and
+contexts matching one of the patterns.  Wtih tt(-P) this will only
+happen if no specific function is defined for the command or context.
+The tt(-N) option toggles back to using the var(names) as described
+above.
+
+Inside functions defined for patterns, the parameter tt($_compskip)
+may be used.  If it is set to a value containing the substring
+`tt(patterns)' none of the pattern-functions will be called.  If it is
+set to a value containing the substring `tt(all)', no other function
+will be called.
 
 The form with tt(-k) defines a widget with the same name as the var(function)
 which will be called for each of the var(key-sequences); this is like the
@@ -2566,6 +2548,56 @@ contexts, in most cases named after the context itself
 (e.g. completion for the `tt(-tilde-)' context is done by the function 
 named `tt(_tilde)').
 
+The functions for some contexts re-dispatch by calling the function
+tt(_dispatch) to offer more specific context information.  This is
+done by appending the parts of extra information to the name of the
+context, separated by commas.  Currently, only the function
+completing redirection arguments (tt(_redirect)) and the function
+completing values in parameter assignments (tt(_value)) use this
+feature.  The former uses contexts of the form
+`tt(-redirect-,)var(op)tt(,)var(command)', where var(op) is the
+redirection operator and var(command) is the name of the command on
+the line.  If there isn't a command yet, the var(command) field will
+be empty.  The function completing values uses contexts of the form
+`tt(-value-,)var(name)tt(,)var(command)', where var(name) is the name
+of the parameter (or `var(name)tt(-)var(key)' when completing a
+value of an associative array in an assignment like
+`tt(assoc=LPAR()key <TAB>)').  The var(command) part is the name of
+the command from the line again in completions like `tt(make
+CFLAGS=<TAB>)' and is empty for normal assignments.
+
+To simplify defining functions for multiple cases, the functions
+tt(_redirect) and tt(_value) will make tt(_dispatch) try these context
+names more than once with each of the parts once set to the string
+tt(-default-).  For example, when completing after `tt(foo=<TAB>)',
+tt(_value) will try the names `tt(-value-,foo,)' (note the empty
+var(command) part), `tt(-value-,foo,-default-)' and
+`tt(-value-,-default-,-default-)'.  Also note the order in which the
+contexts are tried.
+
+As an example:
+
+example(compdef '_files -g "*.log"' '-redirect-,2>,-default-')
+
+could be used to complete files matching `tt(*.log)' when completing
+after `tt(2> <TAB>)'.
+
+And:
+
+example(compdef _foo -value-,-default-,-default-)
+
+says that the function tt(_foo) is to be called to provide completion
+for the values of parameters for which no special function has been
+defined.
+
+In any case the most specific context name will be used inside the
+context string used for looking up styles.  For example:
+
+example(zstyle ':completion:*:*:-redirect-,2>,*:*' file-patterns '*.log')
+
+is another way to make completion after `tt(2> <TAB>)' complete files
+matching `tt(*.log)'.
+
 Before trying to find a function for a specific context, tt(_complete) 
 checks if the parameter `tt(compcontext)' is set.  If it is set to an
 array, the elements are taken to be the possible matches which will be
@@ -3657,17 +3689,16 @@ a similar format; this ensures that user-specified styles are correctly
 passed down to the builtins which implement the internals of completion.
 )
 findex(_dispatch)
-item(tt(_dispatch) [ tt(-d) ] var(type strings ...))(
-This function looks up the function defined for the first var(string)
-in the set of definitions named var(type) (these are those definitions
-defined with `tt(-T )var(type)').  If one is found, it is called to
-generate completions.  Otherwise the definition for the second
-var(string) is looked up and so on.  If none is found and the tt(-d)
-option is given, the definition for the special name tt(-default-) is
-used.
-
-This function is the one responsible for setting the parameters
-tt($service) and tt($comptype).
+item(tt(_dispatch) var(context strings ...))(
+This looks up the functions defined for the var(strings) one after
+another until it finds one that is defined. That function is then
+called to generate the matches.  Normally, the last var(string) is the
+one used to look up the default completion.
+
+This function is the one responsible for setting the parameter
+tt($service) (to the var(strings) as they are tried) and for setting
+the var(context/command) field of the tt($curcontext) parameter (to
+the var(context) given as the first argument).
 )
 findex(_files)
 item(tt(_files))(
diff --git a/Src/Zle/zle_tricky.c b/Src/Zle/zle_tricky.c
index 43d234843..083a0968b 100644
--- a/Src/Zle/zle_tricky.c
+++ b/Src/Zle/zle_tricky.c
@@ -856,6 +856,7 @@ addx(char **ptmp)
 	(iblank(line[cs]) && (!cs || line[cs-1] != '\\')) ||
 	line[cs] == ')' || line[cs] == '`' || line[cs] == '}' ||
 	line[cs] == ';' || line[cs] == '|' || line[cs] == '&' ||
+	line[cs] == '>' || line[cs] == '<' ||
 	(instring && (line[cs] == '"' || line[cs] == '\'')) ||
 	(addspace = (comppref && !iblank(line[cs])))) {
 	*ptmp = (char *)line;