about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--Completion/Base/_describe155
1 files changed, 155 insertions, 0 deletions
diff --git a/Completion/Base/_describe b/Completion/Base/_describe
new file mode 100644
index 000000000..e01c77509
--- /dev/null
+++ b/Completion/Base/_describe
@@ -0,0 +1,155 @@
+#autoload
+
+# This can be used to add options or values with descriptions as matches.
+
+setopt localoptions extendedglob
+
+local gdescr isopt cmd opt nsets tmp descr match descrs matches adescr i
+local disps disp expl tmps tmpd tmpmd tmpms name ret=1 showd _nm
+
+cmd="$words[1]"
+
+# Get the options.
+
+while getopts 'oc:' opt; do
+  if [[ "$opt" = o ]]; then
+    isopt=yes
+  else
+    cmd="$OPTARG"
+  fi
+done
+shift OPTIND-1
+
+# Do the tests. `showd' is set if the descriptions should be shown.
+
+if [[ -n "$isopt" ]]; then
+
+  # We take the value to test the number of patches from a non-local
+  # parameter `nm' if that exists and contains only digits. It's a hack.
+
+  if [[ "$nm" = [0-9]## ]]; then
+    _nm="$nm"
+  else
+    _nm=0
+  fi
+  [[ -n "$compconfig[option_prefix]" &&
+     "$compconfig[option_prefix]" != *\!${cmd}* &&
+     "$PREFIX" != [-+]* &&
+     ( "$compconfig[option_prefix]" = *nodefault* ||
+       _nm -ne compstate[nmatches] ) ]] && return 1
+
+  [[ -n "$compconfig[describe_options]" &&
+     "$compconfig[describe_options]" != *\!${cmd}* ]] && showd=yes
+else
+  [[ -n "$compconfig[describe_values]" &&
+     "$compconfig[describe_values]" != *\!${cmd}* ]] && showd=yes
+fi
+
+gdescr="$1"
+shift
+
+# Now interpret the arguments.
+
+nsets=0
+adescr=()
+descrs=()
+matches=()
+while (( $# )); do
+  (( nsets++ ))
+  descr="$1"
+  [[ -n "$showd" ]] && adescr=( "$adescr[@]" "${(@PM)^descr:#*:?*},$nsets" )
+  if [[ "$2" = -* ]]; then
+    match=''
+    shift
+  else
+    match="$2"
+    shift 2
+  fi
+  tmp=$argv[(i)--]
+  if [[ tmp -eq 1 ]]; then
+    opt=()
+  else
+    opt=( "${(@)argv[1,tmp-1]}" )
+  fi
+  if [[ tmp -gt $# ]]; then
+    argv=()
+  else
+    shift tmp
+  fi
+
+  # `descr' and `matches' collect the names of the arrays containing the
+  # possible matches with descriptions and the matches to add.
+  # The options to give to `compadd' are stored in local arrays.
+
+  descrs[nsets]="$descr"
+  matches[nsets]="$match"
+  typeset -a _descr_opts_$nsets
+  eval "_descr_opts_${nsets}=( \"\$opt[@]\" )"
+done
+
+(( nsets )) || return 1
+
+# Build the display strings if needed.
+
+[[ -n "$showd" ]] && _display disps "$adescr[@]"
+_description expl "$gdescr"
+
+# Loop through the array/option sets we have.
+
+i=0
+while [[ ++i -le nsets ]]; do
+  name=_descr_opts_$i
+  [[ -n "$showd" ]] && disp=( "${(@)${(@M)disps:#*,${i}}%,*}" )
+  descr=( "${(@P)descrs[i]}" )
+
+  # We collect the strings to display in `tmpd' (one string per line)
+  # and `tmps' (in columns) and the matches to add in `tmpmd' and `tmpms'.
+
+  tmpd=()
+  tmps=()
+  tmpmd=()
+  tmpms=()
+  if [[ -n "$matches[i]" ]]; then
+    match=( "${(@P)matches[i]}" )
+    while (( $#match )); do
+      if [[ -n "$showd" && "$descr[1]" = *:?* ]]; then
+	tmpd=( "$tmpd[@]" "$disp[1]" )
+        tmpmd=( "$tmpmd[@]" "$match[1]" )
+        shift 1 disp
+      else
+        tmps=( "$tmps[@]" "${descr[1]%%:*}" )
+        tmpms=( "$tmpms[@]" "$match[1]" )
+      fi
+      shift 1 match
+      shift 1 descr
+    done
+  else
+    while (( $#descr )); do
+      if [[ -n "$showd" && "$descr[1]" = *:?* ]]; then
+	tmpd=( "$tmpd[@]" "$disp[1]" )
+        tmpmd=( "$tmpmd[@]" "${descr[1]%%:*}" )
+        shift 1 disp
+      else
+        tmps=( "$tmps[@]" "${descr[1]%%:*}" )
+        tmpms=( "$tmpms[@]" "${descr[1]%%:*}" )
+      fi
+      shift 1 descr
+    done
+  fi
+
+  # See if we should remove the option prefix characters.
+
+  if [[ -n "$isopt" && "$compconfig[option_prefix]" = hide* ]]; then
+    if [[ "$PREFIX" = --* ]]; then
+      tmpd=( "${(@)tmpd#--}" )
+      tmps=( "${(@)tmps#--}" )
+    elif [[ "$PREFIX" = [-+]* ]]; then
+      tmpd=( "${(@)tmpd#[-+]}" )
+      tmps=( "${(@)tmps#[-+]}" )
+    fi
+  fi
+  compadd "${(@P)name}" "$expl[@]" -ld tmpd - "$tmpmd[@]" && ret=0
+  compadd "${(@P)name}" "$expl[@]" -d tmps - "$tmpms[@]" && ret=0
+done
+
+return ret