From 45f9a36216637075172d0bdf7ad8e18fad34c42e Mon Sep 17 00:00:00 2001 From: Sven Wischnowsky Date: Wed, 13 Mar 2002 09:28:04 +0000 Subject: remove that -T option to compdef again and instead use comma-separated sub-contexts both for function and style lookup (16819) --- ChangeLog | 18 ++++ Completion/Base/Completer/_complete | 6 +- Completion/Base/Core/_dispatch | 49 ++++------ Completion/Base/Core/_normal | 5 +- Completion/Base/Utility/_set_command | 14 +-- Completion/Unix/Command/_gcc | 6 +- Completion/Unix/Command/_make | 3 +- Completion/Unix/Command/_su | 2 +- Completion/Unix/Type/_files | 2 +- Completion/Unix/Type/_locales | 11 +++ Completion/Unix/Type/_printers | 2 +- Completion/Unix/Type/_terminals | 2 +- Completion/Unix/Type/_time_zone | 2 +- Completion/X/Type/_x_display | 2 +- Completion/Zsh/Command/_compdef | 54 +++++++---- Completion/Zsh/Context/_in_vared | 2 +- Completion/Zsh/Context/_redirect | 15 ++- Completion/Zsh/Context/_subscript | 2 +- Completion/Zsh/Context/_value | 32 +++---- Completion/compdump | 55 +++++------ Completion/compinit | 171 +++++++++++------------------------ Doc/Zsh/compsys.yo | 149 ++++++++++++++++++------------ Src/Zle/zle_tricky.c | 1 + 23 files changed, 293 insertions(+), 312 deletions(-) create mode 100644 Completion/Unix/Type/_locales diff --git a/ChangeLog b/ChangeLog index 75af6b705..5b6765055 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,21 @@ +2002-03-13 Sven Wischnowsky + + * 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 * 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)$(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 `:' and `', where -# `' 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 '. @@ -6,30 +6,20 @@ # and `'. If the line contains a command (as in `make foo=') # the string `::' 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=)' 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 )'). The var(command) part is the name of +the command from the line again in completions like `tt(make +CFLAGS=)' 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=)', +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> )'. + +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> )' 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; -- cgit 1.4.1