summary refs log tree commit diff
path: root/Completion/Base/Utility
diff options
context:
space:
mode:
authorSven Wischnowsky <wischnow@users.sourceforge.net>2001-04-02 11:09:34 +0000
committerSven Wischnowsky <wischnow@users.sourceforge.net>2001-04-02 11:09:34 +0000
commit3a6cc96ce6045ca82af881df34177592c28ead3e (patch)
tree7e60f8da48eabef3fb80fcb505a70f5281ca7591 /Completion/Base/Utility
parentfd0f0d45988c1a8fb5c87952d50b5d353f1e4426 (diff)
downloadzsh-3a6cc96ce6045ca82af881df34177592c28ead3e.tar.gz
zsh-3a6cc96ce6045ca82af881df34177592c28ead3e.tar.xz
zsh-3a6cc96ce6045ca82af881df34177592c28ead3e.zip
moved from Completion/Base/_arguments
Diffstat (limited to 'Completion/Base/Utility')
-rw-r--r--Completion/Base/Utility/_arguments409
1 files changed, 409 insertions, 0 deletions
diff --git a/Completion/Base/Utility/_arguments b/Completion/Base/Utility/_arguments
new file mode 100644
index 000000000..e947dc8ad
--- /dev/null
+++ b/Completion/Base/Utility/_arguments
@@ -0,0 +1,409 @@
+#autoload
+
+# Complete the arguments of the current command according to the
+# descriptions given as arguments to this function.
+
+local long cmd="$words[1]" descr mesg subopts opt usecc autod
+local oldcontext="$curcontext" hasopts rawret
+
+long=$argv[(I)--]
+if (( long )); then
+  local name tmp tmpargv
+
+  if [[ long -eq 1 ]]; then
+    tmpargv=()
+  else
+    tmpargv=( "${(@)argv[1,long-1]}" )
+  fi
+
+  name=${~words[1]}
+  [[ "$name" = [^/]*/* ]] && name="$PWD/$name"
+
+  name="_args_cache_${name}"
+  name="${name//[^a-zA-Z0-9_]/_}"
+
+  if (( ! ${(P)+name} )); then
+    local iopts sopts pattern tmpo dir cur cache
+    typeset -U lopts
+
+    cache=()
+
+    # We have to build a new long-option cache, get the `-i' and
+    # `-s' options.
+
+    set -- "${(@)argv[long+1,-1]}"
+
+    iopts=()
+    sopts=()
+    while [[ "$1" = -[is]* ]]; do
+      if [[ "$1" = -??* ]]; then
+        tmp="${1[3,-1]}"
+        cur=1
+      else
+        tmp="$2"
+	cur=2
+      fi
+      if [[ "$tmp[1]" = '(' ]]; then
+	tmp=( ${=tmp[2,-2]} )
+      else
+	tmp=( "${(@P)tmp}" )
+      fi
+      if [[ "$1" = -i* ]]; then
+        iopts=( "$iopts[@]" "$tmp[@]" )
+      else
+        sopts=( "$sopts[@]" "$tmp[@]" )
+      fi
+      shift cur
+    done
+
+    # Now get the long option names by calling the command with `--help'.
+    # The parameter expansion trickery first gets the lines as separate
+    # array elements. Then we select all lines whose first non-blank
+    # character is a hyphen. Since some commands document more than one
+    # option per line, separated by commas, we convert commas into
+    # newlines and then split the result again at newlines after joining 
+    # the old array elements with newlines between them. Then we select
+    # those elements that start with two hyphens, remove anything up to
+    # those hyphens and anything from the space or tab after the
+    # option up to the end.
+
+    lopts=("--${(@)^${(@)${(@)${(@M)${(@ps:\n:j:\n:)${(@)${(@M)${(@f)$(_call_program options ${~words[1]} --help 2>&1)//\[--/
+--}:#[ 	]#-*}//,/
+}}:#[ 	]#--*}#*--}%%[]	 ]*}:#}")
+
+    # Remove options also described by user-defined specs.
+
+    tmp=()
+    for opt in "${(@)lopts:#--}"; do
+
+      # Using (( ... )) gives a parse error.
+
+      let "$tmpargv[(I)(|\([^\)]#\))(|\*)${opt}(|[-+=])(|\[*\])(|:*)]" ||
+          tmp=( "$tmp[@]" "$opt" )
+    done
+    lopts=( "$tmp[@]" )
+
+    # Now remove all ignored options ...
+
+    while (( $#iopts )); do
+      lopts=( ${lopts:#$~iopts[1]} )
+      shift iopts
+    done
+
+    # ... and add "same" options
+
+    while (( $#sopts )); do
+      lopts=( $lopts ${lopts/$~sopts[1]/$sopts[2]} )
+      shift 2 sopts
+    done
+
+    # Then we walk through the descriptions plus a few builtin ones.
+    # The last one matches all options; the `special' description and action
+    # makes those options be completed without an argument description.
+
+    set -- "$@" '*=FILE*:file:_files' \
+           '*=(DIR|PATH)*:directory:_files -/' '*: :  '
+
+    while (( $# )); do
+
+      # First, we get the pattern and the action to use and take them
+      # from the positional parameters.
+
+      pattern="${${${(M)1#*[^\\]:}[1,-2]}//\\\\:/:}"
+      descr="${1#${pattern}}"
+      if [[ "$pattern" = *\(-\) ]]; then
+        pattern="$pattern[1,-4]"
+	dir=-
+      else
+        dir=
+      fi
+      shift
+
+      # We get all options matching the pattern and take them from the
+      # list we have built. If no option matches the pattern, we
+      # continue with the next.
+
+      tmp=("${(@M)lopts:##$~pattern}")
+      lopts=("${(@)lopts:##$~pattern}")
+
+      (( $#tmp )) || continue
+
+      opt=''
+
+      # If there are option strings with a `[=', we take these to get an
+      # optional argument.
+
+      tmpo=("${(@M)tmp:#*\[\=*}")
+      if (( $#tmpo )); then
+        tmp=("${(@)tmp:#*\[\=*}")
+        tmpo=("${(@)${(@)tmpo%%\=*}//[^a-z0-9-]}")
+
+        if [[ "$descr" = ::* ]]; then
+	  cache=( "$cache[@]" "${(@)^tmpo}=${dir}${descr}" )
+        else
+	  cache=( "$cache[@]" "${(@)^tmpo}=${dir}:${descr}" )
+        fi
+      fi
+
+      # Descriptions with `=': mandatory argument.
+
+      tmpo=("${(@M)tmp:#*\=*}")
+      if (( $#tmpo )); then
+        tmp=("${(@)tmp:#*\=*}")
+        tmpo=("${(@)${(@)tmpo%%\=*}//[^a-z0-9-]}")
+
+	cache=( "$cache[@]" "${(@)^tmpo}=${dir}${descr}" )
+      fi
+
+      # Everything else is just added as an option without arguments or
+      # as described by $descr.
+
+      if (( $#tmp )); then
+        tmp=("${(@)tmp//[^a-zA-Z0-9-]}")
+        if [[ -n "$descr" && "$descr" != ': :  ' ]]; then
+	  cache=( "$cache[@]" "${(@)^tmp}${descr}" )
+        else
+	  cache=( "$cache[@]" "$tmp[@]" )
+        fi
+      fi
+    done
+    set -A "$name" "${(@)cache:# #}"
+  fi
+  set -- "$tmpargv[@]" "${(@P)name}"
+fi
+
+subopts=()
+while [[ "$1" = -(O*|[CR]) ]]; do
+  case "$1" in
+  -C)  usecc=yes; shift ;;
+  -O)  subopts=( "${(@P)2}" ); shift 2 ;;
+  -O*) subopts=( "${(@P)1[3,-1]}" ); shift ;;
+  -R)  rawret=yes; shift;;
+  esac
+done
+
+zstyle -s ":completion:${curcontext}:options" auto-description autod
+
+if (( $# )) && comparguments -i "$autod" "$@"; then
+  local action noargs aret expl local tried
+  local next direct odirect equal single matcher matched ws tmp1 tmp2 tmp3
+  local opts subc tc prefix suffix descrs actions subcs anum
+  local origpre="$PREFIX" origipre="$IPREFIX" nm="$compstate[nmatches]"
+
+  if comparguments -D descrs actions subcs; then
+    if comparguments -O next direct odirect equal; then
+      opts=yes
+      _tags "$subcs[@]" options
+    else
+      _tags "$subcs[@]"
+    fi
+  else
+    if comparguments -a; then
+      noargs='no more arguments'
+    else
+      noargs='no arguments'
+    fi
+    if comparguments -O next direct odirect equal; then
+      opts=yes
+      _tags options
+    elif [[ $? -eq 2 ]]; then
+        compadd -Q - "${PREFIX}${SUFFIX}"
+        return 0
+    else
+      _message "$noargs"
+      return 1
+    fi
+  fi
+
+  comparguments -M matcher
+
+  context=()
+  state=()
+
+  while true; do
+    while _tags; do
+      anum=1
+      while [[ anum -le  $#descrs ]]; do
+
+	action="$actions[anum]"
+	descr="$descrs[anum]"
+	subc="$subcs[anum++]"
+
+        if [[ -n "$matched" ]] || _requested "$subc"; then
+
+          curcontext="${oldcontext%:*}:$subc"
+
+          _description "$subc" expl "$descr"
+
+          if [[ "$action" = \=\ * ]]; then
+            action="$action[3,-1]"
+            words=( "$subc" "$words[@]" )
+	    (( CURRENT++ ))
+          fi
+
+          if [[ "$action" = -\>* ]]; then
+	    action="${${action[3,-1]##[ 	]#}%%[ 	]#}"
+	    if (( ! $state[(I)$action] )); then
+              comparguments -W line opt_args
+              state=( "$state[@]" "$action" )
+	      if [[ -n "$usecc" ]]; then
+	        curcontext="${oldcontext%:*}:$subc"
+	      else
+	        context=( "$context[@]" "$subc" )
+	      fi
+              compstate[restore]=''
+              aret=yes
+            fi
+          else
+            if [[ -z "$local" ]]; then
+              local line
+              typeset -A opt_args
+              local=yes
+            fi
+
+            comparguments -W line opt_args
+
+            if [[ "$action" = \ # ]]; then
+
+              # An empty action means that we should just display a message.
+
+	      _message "$descr"
+	      mesg=yes
+	      tried=yes
+
+            elif [[ "$action" = \(\(*\)\) ]]; then
+
+              # ((...)) contains literal strings with descriptions.
+
+              eval ws\=\( "${action[3,-3]}" \)
+
+              _describe -t "$subc" "$descr" ws -M "$matcher" "$subopts[@]"
+	      tried=yes
+
+            elif [[ "$action" = \(*\) ]]; then
+
+              # Anything inside `(...)' is added directly.
+
+              eval ws\=\( "${action[2,-2]}" \)
+
+              _all_labels "$subc" expl "$descr" compadd "$subopts[@]" -a - ws
+	      tried=yes
+            elif [[ "$action" = \{*\} ]]; then
+
+              # A string in braces is evaluated.
+
+              while _next_label "$subc" expl "$descr"; do
+                eval "$action[2,-2]"
+              done
+	      tried=yes
+            elif [[ "$action" = \ * ]]; then
+
+              # If the action starts with a space, we just call it.
+
+	      eval "action=( $action )"
+              while _next_label "$subc" expl "$descr"; do
+                "$action[@]"
+              done
+	      tried=yes
+            else
+
+              # Otherwise we call it with the description-arguments.
+
+	      eval "action=( $action )"
+              while _next_label "$subc" expl "$descr"; do
+                "$action[1]" "$subopts[@]" "$expl[@]" "${(@)action[2,-1]}"
+	      done
+	      tried=yes
+            fi
+          fi
+        fi
+      done
+
+      if [[ -z "$matched$hasopts" && ( -z "$aret" || "$PREFIX" = "$origpre" ) ]] &&
+          _requested options &&
+          { ! zstyle -T ":completion:${curcontext}:options" prefix-needed ||
+            [[ "$origpre" = [-+]* || -z "$aret$mesg$tried" ]] } ; then
+	local prevpre="$PREFIX" previpre="$IPREFIX"
+
+	hasopts=yes
+
+	PREFIX="$origpre"
+	IPREFIX="$origipre"
+
+        if comparguments -s single; then
+
+          if [[ "$single" = direct ]]; then
+            _all_labels options expl option \
+	        compadd -QS '' - "${PREFIX}${SUFFIX}"
+          elif [[ "$single" = next ]]; then
+            _all_labels options expl option \
+	        compadd -Q - "${PREFIX}${SUFFIX}"
+          elif [[ "$single" = equal ]]; then
+            _all_labels options expl option \
+	        compadd -QqS= - "${PREFIX}${SUFFIX}"
+          else
+	    tmp1=( "$next[@]" "$direct[@]" "$odirect[@]" "$equal[@]" )
+	    [[ "$PREFIX" != --* ]] && tmp1=( "${(@)tmp1:#--*}" )
+	    tmp3=( "${(M@)tmp1:#[-+]?[^:]*}" )
+	    tmp1=( "${(M@)tmp1:#[-+]?(|:*)}" )
+	    tmp2=( "${PREFIX}${(@M)^${(@)${(@)tmp1%%:*}#[-+]}:#?}" )
+
+            _describe -o option \
+                      tmp1 tmp2 -Q -S '' -- \
+		      tmp3 -Q
+          fi
+          single=yes
+        else
+          next=( "$next[@]" "$odirect[@]" )
+          _describe -o option \
+                    next -Q -M "$matcher" -- \
+                    direct -QS '' -M "$matcher" -- \
+                    equal -QqS= -M "$matcher"
+        fi
+	PREFIX="$prevpre"
+	IPREFIX="$previpre"
+      fi
+      [[ -n "$tried" && "$PREFIX" != [-+]* ]] && break
+    done
+    if [[ -n "$opts" && -z "$aret$matched$mesg" &&
+          nm -eq compstate[nmatches] ]]; then
+
+      PREFIX="$origpre"
+      IPREFIX="$origipre"
+
+      prefix="${PREFIX#*\=}"
+      suffix="$SUFFIX"
+      PREFIX="${PREFIX%%\=*}"
+      SUFFIX=''
+
+      compadd -M "$matcher" -D equal - "${(@)equal%%:*}"
+
+      if [[ $#equal -eq 1 ]]; then
+        PREFIX="$prefix"
+	SUFFIX="$suffix"
+	IPREFIX="${IPREFIX}${equal[1]%%:*}="
+	matched=yes
+
+	comparguments -L "${equal[1]%%:*}" descrs actions subcs
+
+	_tags "$subcs[@]"
+
+	continue
+      fi
+    fi
+    break
+  done
+
+  [[ -z "$aret" || -z "$usecc" ]] && curcontext="$oldcontext"
+
+  if [[ -n "$aret" ]]; then
+    [[ -n $rawret ]] && return 300
+  else
+    [[ -n "$noargs" && nm -eq "$compstate[nmatches]" ]] && _message "$noargs"
+  fi
+  # Set the return value.
+
+  [[ nm -ne "$compstate[nmatches]" ]]
+else
+  return 1
+fi