about summary refs log tree commit diff
diff options
context:
space:
mode:
authorTanaka Akira <akr@users.sourceforge.net>1999-11-09 13:14:59 +0000
committerTanaka Akira <akr@users.sourceforge.net>1999-11-09 13:14:59 +0000
commitc615397157e5efd7a81c8ce11b3f77fd7ccb5a19 (patch)
tree9f6e9081024370574ae18b5808ebedf6d653d672
parent95af0ef9c4639763c8094d6e8cd5d8ec01a32f96 (diff)
downloadzsh-c615397157e5efd7a81c8ce11b3f77fd7ccb5a19.tar.gz
zsh-c615397157e5efd7a81c8ce11b3f77fd7ccb5a19.tar.xz
zsh-c615397157e5efd7a81c8ce11b3f77fd7ccb5a19.zip
zsh-workers/8603
-rw-r--r--Completion/Base/_arguments26
-rw-r--r--Completion/Base/_describe15
-rw-r--r--Completion/Base/_values10
-rw-r--r--Completion/Builtins/_kill16
-rw-r--r--Completion/Builtins/_wait12
-rw-r--r--Completion/Core/_alternative70
-rw-r--r--Completion/Core/_files23
-rw-r--r--Completion/Core/_main_complete4
-rw-r--r--Completion/Core/_requested9
-rw-r--r--Completion/Core/_style45
-rw-r--r--Completion/Core/_tags43
-rw-r--r--Completion/Core/compinit171
12 files changed, 364 insertions, 80 deletions
diff --git a/Completion/Base/_arguments b/Completion/Base/_arguments
index 31713750f..68b52eef4 100644
--- a/Completion/Base/_arguments
+++ b/Completion/Base/_arguments
@@ -154,14 +154,14 @@ fi
 if comparguments -i "$compconfig[autodescribe_options]" "$@"; then
   local nm="$compstate[nmatches]" action noargs aret expl local
   local next direct odirect equal single match matched ws tmp1 tmp2
-  local tags opts
+  local opts
 
   if comparguments -D descr action; then
     if comparguments -O next direct odirect equal; then
       opts=yes
-      _tags -f "$funcstack[2]" argument option
+      _tags argument option
     else
-      _tags -f "$funcstack[2]" argument
+      _tags argument
     fi
   else
     if comparguments -a; then
@@ -172,12 +172,12 @@ if comparguments -i "$compconfig[autodescribe_options]" "$@"; then
     comparguments -O next direct odirect equal || return 1
 
     opts=yes
-    _tags -f "$funcstack[2]" option
+    _tags option
   fi
 
   while _tags; do
     while true; do
-      if [[ "$tags" = *:argument* ]]; then
+      if [[ -n "$matched" ]] || _requested argument; then
         _description expl "$descr"
 
         if [[ "$action" = -\>* ]]; then
@@ -207,7 +207,7 @@ if comparguments -i "$compconfig[autodescribe_options]" "$@"; then
 
             eval ws\=\( "${action[3,-3]}" \)
 
-            _describe -c "$cmd" -f "$funcstack[2]" "$descr" ws -M "$match"
+            _describe -c "$cmd" "$descr" ws -M "$match"
 
           elif [[ "$action" = \(*\) ]]; then
 
@@ -234,8 +234,8 @@ if comparguments -i "$compconfig[autodescribe_options]" "$@"; then
           fi
         fi
       fi
-      if [[ "$tags" = *:option* &&
-            ( "$tags" != *\[*prefix*\]* || "$PREFIX" = [-+]* ) ]]; then
+      if [[ -z "$matched" ]] && _requested option &&
+          { ! _style option prefix || [[ "$PREFIX" = [-+]* ]] } ; then
         comparguments -M match
 
         if comparguments -s single; then
@@ -253,20 +253,21 @@ if comparguments -i "$compconfig[autodescribe_options]" "$@"; then
 	    tmp1=( "${(M@)tmp1:#[-+]?(|:*)}" )
 	    tmp2=( "${PREFIX}${(@M)^${(@)${(@)tmp1%%:*}#[-+]}:#?}" )
 
-            _describe -o -c "$cmd" -f "$funcstack[2]" option \
+            _describe -o -c "$cmd" option \
                       tmp1 tmp2 -Q -S ''
           fi
           single=yes
         else
           next=( "$next[@]" "$odirect[@]" )
-          _describe -o -c "$cmd" -f "$funcstack[2]" option \
+          _describe -o -c "$cmd" option \
             next -Q -M "$match" -- \
             direct -QS '' -M "$match" -- \
             equal -QqS= -M "$match"
         fi
       fi
-      if [[ -n "$opts" && -z "$aret$matched" && nm -ne compstate[nmatches] &&
-            "$tags" = *:argument* ]]; then
+      if [[ -n "$opts" && -z "$aret$matched" &&
+            nm -ne compstate[nmatches] ]] &&
+          _requested argument; then
 
         local prefix suffix
 
@@ -282,7 +283,6 @@ if comparguments -i "$compconfig[autodescribe_options]" "$@"; then
 	  IPREFIX="${IPREFIX}${equal[1]%%:*}="
 	  matched=yes
 	  comparguments -L "$equal[1]" descr action
-	  tags=argument
 	  continue
         fi
       fi
diff --git a/Completion/Base/_describe b/Completion/Base/_describe
index ddd35f0e7..41c2ba8e5 100644
--- a/Completion/Base/_describe
+++ b/Completion/Base/_describe
@@ -2,19 +2,16 @@
 
 # This can be used to add options or values with descriptions as matches.
 
-local cmd func opt expl tmps tmpd tmpmd tmpms ret=1 showd _nm hide
-local tags type=value
+local cmd opt expl tmps tmpd tmpmd tmpms ret=1 showd _nm hide
+local type=value
 
 cmd="$words[1]"
-func="$funcstack[2]"
 
 # Get the options.
 
-while getopts 'oc:f:' opt; do
+while getopts 'oc:' opt; do
   if [[ "$opt" = o ]]; then
     type=option
-  elif [[ "$opt" = f ]]; then
-    func="$OPTARG"
   else
     cmd="$OPTARG"
   fi
@@ -23,9 +20,9 @@ shift OPTIND-1
 
 # Do the tests. `showd' is set if the descriptions should be shown.
 
-_tags -i -c "$cmd" -f "$func" "$type" || return 1
+_tags -c "$cmd" "$type" || return 1
 
-[[ "$tags" = *:${type}\[*describe*\]* ]] && showd=yes
+_style "$type" describe && showd=yes
 
 _description expl "$1"
 shift
@@ -36,7 +33,7 @@ else
   compdescribe -i "$@"
 fi
 
-[[ "$type" = option && "$tags" = *:option\[*hide*\]* ]] && hide=yes
+[[ "$type" = option ]] && _style option hide && hide=yes
 
 while compdescribe -g args tmpd tmpmd tmps tmpms; do
 
diff --git a/Completion/Base/_values b/Completion/Base/_values
index 9d89c7ea9..aac8b392d 100644
--- a/Completion/Base/_values
+++ b/Completion/Base/_values
@@ -2,11 +2,11 @@
 
 if compvalues -i "$@"; then
 
-  local tags noargs args opts descr action expl sep
+  local noargs args opts descr action expl sep
 
   if ! compvalues -D descr action; then
 
-    _tags -i value || return 1
+    _tags value || return 1
 
     compvalues -V noargs args opts
 
@@ -42,7 +42,7 @@ if compvalues -i "$@"; then
         sep=()
       fi
 
-      _describe -f "$funcstack[2]" "$descr" \
+      _describe "$descr" \
         noargs "$sep[@]" -M 'r:|[_-]=* r:|=*' -- \
         args -S= -M 'r:|[_-]=* r:|=*' -- \
         opts -qS= -M 'r:|[_-]=* r:|=*'
@@ -51,7 +51,7 @@ if compvalues -i "$@"; then
     fi
   fi
 
-  _tags -i argument || return 1
+  _tags argument || return 1
 
   _description expl "$descr"
 
@@ -85,7 +85,7 @@ if compvalues -i "$@"; then
 
       eval ws\=\( "${action[3,-3]}" \)
 
-      _describe -f "$funcstack[2]" "$descr" ws -M 'r:|[_-]=* r:|=*'
+      _describe "$descr" ws -M 'r:|[_-]=* r:|=*'
 
     elif [[ "$action" = \(*\) ]]; then
 
diff --git a/Completion/Builtins/_kill b/Completion/Builtins/_kill
index bb198b7a4..43ff40838 100644
--- a/Completion/Builtins/_kill
+++ b/Completion/Builtins/_kill
@@ -1,23 +1,13 @@
 #compdef kill
 
-local tags list expl
+local list expl
 
 if compset -P 1 -; then
 
-  _tags -i signal || return 1
+  _tags signal || return 1
 
   _description expl signal
   compadd "$expl[@]" $signals[1,-3]
 else
-  local ret=1
-  
-  _tags job process
-  
-  while _tags; do
-    [[ "$tags" = *:job:*     ]] && _jobs && ret=0
-    [[ "$tags" = *:process:* ]] && _pids && ret=0
-    (( ret )) || break
-  done
-
-  return ret
+  _alternative 'job:: _jobs' 'process:: _pids'
 fi
diff --git a/Completion/Builtins/_wait b/Completion/Builtins/_wait
index b03aac6e0..c1022a25f 100644
--- a/Completion/Builtins/_wait
+++ b/Completion/Builtins/_wait
@@ -1,13 +1,3 @@
 #compdef wait
 
-local tags ret=1
-  
-_tags job process
-  
-while _tags; do
-  [[ "$tags" = *:job:*     ]] && _jobs && ret=0
-  [[ "$tags" = *:process:* ]] && _pids && ret=0
-  (( ret )) || break
-done
-
-return ret
+_alternative 'job:: _jobs' 'process:: _pids'
diff --git a/Completion/Core/_alternative b/Completion/Core/_alternative
new file mode 100644
index 000000000..158f3a07a
--- /dev/null
+++ b/Completion/Core/_alternative
@@ -0,0 +1,70 @@
+#autoload
+
+local tags def expl descr action mesgs nm="$compstack[nmatches]"
+local context
+
+if [[ "$1" = -C?* ]]; then
+  context="${1[3,-1]}"
+  shift
+elif [[ "$1" = -C ]]; then
+  context="$2"
+  shift 2
+fi
+
+mesgs=()
+
+_tags -C "$context" "${(@)argv%%:*}"
+
+while _tags; do
+  for def; do
+    if _requested "${def%%:*}"; then
+      descr="${${def#*:}%%:*}"
+      action="${def#*:*:}"
+
+      _description expl "$descr"
+
+      if [[ "$action" = \ # ]]; then
+
+        # An empty action means that we should just display a message.
+
+        mesgs=( "$mesgs[@]" "$descr")
+      elif [[ "$action" = \(\(*\)\) ]]; then
+        local ws
+
+        # ((...)) contains literal strings with descriptions.
+
+        eval ws\=\( "${action[3,-3]}" \)
+
+        _describe "$descr" ws -M 'r:|[_-]=* r:|=*'
+      elif [[ "$action" = \(*\) ]]; then
+
+        # Anything inside `(...)' is added directly.
+
+        compadd "$expl[@]" - ${=action[2,-2]}
+      elif [[ "$action" = \{*\} ]]; then
+
+        # A string in braces is evaluated.
+
+        eval "$action[2,-2]"
+      elif [[ "$action" = \ * ]]; then
+
+        # If the action starts with a space, we just call it.
+
+        ${(e)=~action}
+      else
+
+        # Otherwise we call it with the description-arguments built above.
+
+        action=( $=action )
+        ${(e)action[1]} "$expl[@]" ${(e)~action[2,-1]}
+      fi
+    fi
+  done
+  [[ nm -ne compstate[nmatches] ]] && return 0
+done
+
+for descr in "$mesgs[@]"; do
+  _message "$descr"
+done
+
+return 1
diff --git a/Completion/Core/_files b/Completion/Core/_files
index 4adae0f73..eb1ec3559 100644
--- a/Completion/Core/_files
+++ b/Completion/Core/_files
@@ -1,6 +1,6 @@
 #autoload
 
-local opts opt type=file tags
+local opts opt type=file
 
 opts=()
 while getopts "P:S:qr:R:W:F:J:V:X:f/g:M:" opt; do
@@ -13,15 +13,24 @@ while getopts "P:S:qr:R:W:F:J:V:X:f/g:M:" opt; do
 done
 
 case "$type" in
-file) _tags -f "$funcstack[2]" file           ;;
-dir)  _tags -f "$funcstack[2]" path file      ;;
-*)    _tags -f "$funcstack[2]" glob path file ;;
+file) _tags file           ;;
+dir)  _tags path file      ;;
+*)    _tags glob path file ;;
 esac
 
 while _tags; do
-  [[ "$tags" = *:file:* ]] && { _path_files "$opts[@]" -f         ;  return   }
-  [[ "$tags" = *:path:* ]] &&   _path_files "$opts[@]" -/         && return 0
-  [[ "$tags" = *:glob:* ]] &&   _path_files "$opts[@]" -g "$type" && return 0
+  if _requested file; then
+    _path_files "$opts[@]" -f
+    return
+  elif _requested path; then
+    if _requested glob; then
+      _path_files "$opts[@]" -/g "$type" && return 0
+    else
+      _path_files "$opts[@]" -/g "$type" && return 0
+    fi
+  elif _requested glob; then
+    _path_files "$opts[@]" -g "$type" && return 0
+  fi
 done
 
 return 1
diff --git a/Completion/Core/_main_complete b/Completion/Core/_main_complete
index d1d75de7f..e4ee2879b 100644
--- a/Completion/Core/_main_complete
+++ b/Completion/Core/_main_complete
@@ -17,9 +17,9 @@
 # state than the global one for which you are completing.
 
 
-local comp post ret=1 _compskip tags _prio_num=1
+local comp post ret=1 _compskip _prio_num=1
 typeset -U _offered_tags _tried_tags _failed_tags _used_tags _unused_tags
-typeset -A _prio_names
+typeset -A _prio_names _cur_tags
 
 _offered_tags=()
 _tried_tags=()
diff --git a/Completion/Core/_requested b/Completion/Core/_requested
new file mode 100644
index 000000000..082c45820
--- /dev/null
+++ b/Completion/Core/_requested
@@ -0,0 +1,9 @@
+#autoload
+
+local tag tname="$funcstack[2,-1]"
+
+for tag; do
+  [[ "${_cur_tags[${tname}]}" = *:${tag}(:|\[*\]:)* ]] && return 0
+done
+
+return 1
diff --git a/Completion/Core/_style b/Completion/Core/_style
new file mode 100644
index 000000000..b0cbd7b00
--- /dev/null
+++ b/Completion/Core/_style
@@ -0,0 +1,45 @@
+#autoload
+
+local tags get i
+
+if [[ "$1" = -g ]]; then
+  get=yes
+  shift
+fi
+
+if (( ${+_cur_tags[${funcstack[2,-1]}]} )); then
+  tags="${_cur_tags[${funcstack[2,-1]}]}"
+else
+  tags="${_cur_tags[${funcstack[3,-1]}]}"
+fi
+
+if [[ "$tags" = *:${1}\[*\]:* ]]; then
+
+  tags="${${tags#*:${1}\[}%%\]*}"
+
+  if [[ $# -eq 2 ]]; then
+    if [[ -n "$get" ]]; then
+      eval "${2}=\"$tags\""
+      return 0
+    fi
+
+    [[ "$tags" = (|*,)${2}(|,*) ]]
+    return
+  fi
+
+  [[ "$tags" = (|*,)${2}(|(\=|,)*) ]] || return 1
+
+  if [[ -n "$get" ]]; then
+    if [[ "$tags" = (|*,)${2}\=* ]]; then
+      eval "${3}=\"${${tags#(|*,)${2}\=}%%,*}\""
+    else
+      eval "${3}=''"
+    fi
+    return 0
+  fi
+
+  [[ "$tags" = (|*,)${2}\=(|[^,]#,)${3}(|,*) ]] 
+  return
+fi
+
+return 1
diff --git a/Completion/Core/_tags b/Completion/Core/_tags
index 9b9ce96b4..7b1254325 100644
--- a/Completion/Core/_tags
+++ b/Completion/Core/_tags
@@ -1,19 +1,21 @@
 #autoload
 
+local tname="$funcstack[2,-1]"
+
 if (( $# )); then
-  local cmd="$words[1]" func="$funcstack[2]" defs i ttags tag pat style prio
-  local trynow
-
-  while getopts 'c:f:i' i; do
-    case "$i" in
-    c) cmd="$OPTARG"  ;;
-    f) func="$OPTARG" ;;
-    i) trynow=yes     ;;
-    esac
-  done
+  local cmd="$words[1]" defs i ttags tag pat style prio context opt
 
+  while getopts 'c:C:' opt; do
+    if [[ "$opt" = c ]]; then
+      cmd="$OPTARG"
+    else
+      context="$OPTARG"
+    fi
+  done
   shift OPTIND-1
 
+  [[ -n "$context" ]] && context="/$context"
+
   defs=( "${(@M)argv:#${(kj:|:)~override_tags[(R)(|+*)]}}" )
   (( $#defs )) && set -- "$defs[@]"
 
@@ -42,8 +44,7 @@ if (( $# )); then
   for i in "$defs[@]"; do
     tag="${i%%:*}"
     for pat in "${(s.:.)i#*:}"; do
-      if [[ ( "$pat" = _* && "$func" = ${~pat%%\=*} ) ||
-            "$cmd" = ${~pat%%\=*} ]]; then
+      if [[ "$cmd$context" = ${~pat%%\=*} ]]; then
         prio="${pat#*\=}"
 	[[ "$prio" = -* ]] && continue 2
 
@@ -65,22 +66,24 @@ if (( $# )); then
   done
 
   prio="_prio_arr$(( _prio_num++ ))"
-  _prio_names[$funcstack]="$prio"
-  eval "${prio}=( \"\${(@)ttags:#}\" )"
+  _prio_names[$tname]="$prio"
+  ttags=( "${(@)ttags:#}" )
+  eval "${prio}=( \"\$ttags[@]\" )"
 
-  [[ -z "$trynow" ]] && return 0
+  return \!$#ttags
 fi
 
-local prios="$_prio_names[$funcstack]"
+local prios="$_prio_names[$tname]"
 
-_failed_tags=( "$_failed_tags[@]" "$_last_tags[@]" )
+_failed_tags=( "$_failed_tags[@]" "$_last_tags" )
 
 (( ${(P)#prios} )) || return 1
 
-tags="${${(@P)prios}[1]}:"
-shift 1 "$prios"
+_cur_tags[$tname]="${(@)${(@P)prios}[1]}:"
 
-_last_tags=( "${(@s.:.)${${tags#:}%:}}" )
+_last_tags=( "${(@)${(@s.:.)${(@P)prios}[1]}:#}" )
 _tried_tags=( "$_tried_tags[@]" "$_last_tags[@]" )
 
+shift 1 "$prios"
+
 return 0
diff --git a/Completion/Core/compinit b/Completion/Core/compinit
index 3d316fac8..1b88cc8f0 100644
--- a/Completion/Core/compinit
+++ b/Completion/Core/compinit
@@ -446,6 +446,177 @@ comptag() {
   fi
 }
 
+# First suggested function for new configuration interface.
+#
+# Example:
+#
+#   conf1 \
+#     argument = 1 \
+#     value    = 1 with describe \
+#     option   = 2 with describe and hide \
+#     file     = 3 \
+#     path in   '*dvi*' = 1 \
+#          else         = 2 \
+#     glob     = 1 \
+#     job      = never
+
+conf1() {
+  local tag pat prio
+
+  while (( $# )); do
+
+    tag="$1"
+    shift
+
+    while (( $# )); do
+
+      if [[ "$1" = in ]]; then
+        pat="$2"
+	shift 2
+      else
+        pat='*'
+	[[ "$1" = else ]] && shift
+      fi
+
+      style=''
+
+      if [[ "$1" = is ]]; then
+        prio=0
+	style="[${2}]"
+	shift 2
+      elif [[ "$1" = \= ]]; then
+        if [[ "$2" = n(o|ever) ]]; then
+          prio=-1
+	  shift 2
+        else
+          prio="$2"
+	  shift 2
+
+	  if [[ "$1" = with ]]; then
+	    while [[ "$1" = (with|and) ]]; do
+	      style="${style},${2}"
+	      shift 2
+            done
+            style="[${style[2,-1]}]"
+          fi
+        fi
+      else
+        echo "$0: missing priority: $1"
+	return 1
+      fi
+      if [[ -n "$comptags[$tag]" ]]; then
+        comptags[$tag]="${comptags[$tag]}:${pat}=${prio}${style}"
+      else
+        comptags[$tag]="${pat}=${prio}${style}"
+      fi
+
+      [[ "$1" = (in|else|\=) ]] || break
+
+    done
+  done
+
+  return 0
+}
+
+# Second suggested function for new configuration interface.
+#
+# Example:
+#
+#   conf2 \
+#     for '*dvi*' do \
+#       glob and path or \
+#       file \
+#     else do \
+#       glob or \
+#       path or \
+#       file \
+#     for '*p[bgpn]m*' do \
+#       argument and option with describe and with hide \
+#     else do \
+#       argument or \
+#       value with describe or \
+#       option with describe \
+#     for 'kill' do \
+#       no job but \
+#       process \
+#     else do \
+#       process and job
+
+conf2() {
+  local pat prio tag style
+
+  while (( $# )); do
+
+    if [[ "$1" = for ]]; then
+      pat="$2"
+      shift 2
+    elif [[ "$1" = (else|always) ]]; then
+      pat="*"
+      shift
+    else
+      echo "$0: missing context: $1"
+      return 1
+    fi
+
+    shift 1
+
+    prio=1
+
+    while (( $# )); do
+
+      if [[ "$1" = no ]]; then
+        while [[ "$1" != (but|for|else|always) ]]; do
+	  if [[ -n "$comptags[$2]" ]]; then
+	    comptags[$2]="${comptags[$2]}:${pat}=-1"
+          else
+	    comptags[$2]="${pat}=-1"
+	  fi
+
+	  shift 2
+	done
+
+	[[ "$1" != but ]] && break
+
+	shift
+      fi
+
+      while (( $# )); do
+
+        tag="$1"
+	shift
+
+	style=''
+	if [[ "$1" = with ]]; then
+	  shift
+	  while true; do
+	    style="${style},${1}"
+	    [[ "$2" != and || "$3" != with ]] && break
+	    shift 3
+          done
+	  shift
+        fi
+
+	[[ -n "$style" ]] && style="[${style[2,-1]}]"
+
+	if [[ -n "$comptags[$tag]" ]]; then
+	  comptags[$tag]="${comptags[$tag]}:${pat}=${prio}${style}"
+        else
+	  comptags[$tag]="${pat}=${prio}${style}"
+        fi
+
+	[[ "$1" != and ]] && break
+
+	shift
+      done
+
+      [[ "$1" != or ]] && break
+
+      (( prio++ ))
+      shift
+    done
+  done
+}
+
 # Utility function to call a function if it exists.
 #
 # Usage: funcall <return> <name> [ <args> ... ]