about summary refs log tree commit diff
path: root/Completion/Core
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 /Completion/Core
parent95af0ef9c4639763c8094d6e8cd5d8ec01a32f96 (diff)
downloadzsh-c615397157e5efd7a81c8ce11b3f77fd7ccb5a19.tar.gz
zsh-c615397157e5efd7a81c8ce11b3f77fd7ccb5a19.tar.xz
zsh-c615397157e5efd7a81c8ce11b3f77fd7ccb5a19.zip
zsh-workers/8603
Diffstat (limited to 'Completion/Core')
-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
7 files changed, 336 insertions, 29 deletions
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> ... ]