mirror of
				git://git.code.sf.net/p/zsh/code
				synced 2025-11-04 07:21:06 +01:00 
			
		
		
		
	_call_program and '_arguments --' will call _comp_locale before calling external command for easier analysis of the output. This is disabled by passing an option '-l'.
		
			
				
	
	
		
			587 lines
		
	
	
	
		
			17 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
			
		
		
	
	
			587 lines
		
	
	
	
		
			17 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
#autoload
 | 
						|
 | 
						|
# Complete the arguments of the current command according to the
 | 
						|
# descriptions given as arguments to this function.
 | 
						|
 | 
						|
local long cmd="$words[1]" descr odescr mesg subopts opt opt2 usecc autod
 | 
						|
local oldcontext="$curcontext" hasopts rawret optarg singopt alwopt
 | 
						|
local setnormarg start rest
 | 
						|
local -a match mbegin mend
 | 
						|
 | 
						|
subopts=()
 | 
						|
singopt=()
 | 
						|
while [[ "$1" = -([AMO]*|[CRSWnsw]) ]]; 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;;
 | 
						|
  -n)  setnormarg=yes; NORMARG=-1; shift;;
 | 
						|
  -w)  optarg=yes; shift;;
 | 
						|
  -W)  alwopt=arg; shift;;
 | 
						|
  -[Ss])  singopt+=( $1 ); shift;;
 | 
						|
  -[AM])  singopt+=( $1 $2 ); shift 2 ;;
 | 
						|
  -[AM]*) singopt+=( $1 ); shift ;;
 | 
						|
  esac
 | 
						|
done
 | 
						|
 | 
						|
[[ $1 = ':' ]] && shift
 | 
						|
singopt+=( ':' )  # always end with ':' to indicate the end of options
 | 
						|
 | 
						|
[[ "$PREFIX" = [-+] ]] && alwopt=arg
 | 
						|
 | 
						|
long=$argv[(I)--]
 | 
						|
if (( long )); then
 | 
						|
  local name tmp tmpargv
 | 
						|
 | 
						|
  tmpargv=( "${(@)argv[1,long-1]}" )  # optspec's before --, if any
 | 
						|
 | 
						|
  name=${~words[1]} 2>/dev/null
 | 
						|
  [[ "$name" = [^/]*/* ]] && name="$PWD/$name"
 | 
						|
 | 
						|
  name="_args_cache_${name}"
 | 
						|
  name="${name//[^a-zA-Z0-9_]/_}"
 | 
						|
 | 
						|
  if (( ! ${(P)+name} )); then
 | 
						|
    local iopts sopts lflag pattern tmpo dir cur cache
 | 
						|
    typeset -Ua 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" = -[lis]* ]]; do
 | 
						|
      if [[ "$1" = -l ]]; then
 | 
						|
	lflag='-l'
 | 
						|
	shift
 | 
						|
	continue
 | 
						|
      fi
 | 
						|
      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+=( "$tmp[@]" )
 | 
						|
      else
 | 
						|
        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.
 | 
						|
 | 
						|
   tmp=()
 | 
						|
   _call_program $lflag options ${~words[1]} --help 2>&1 |
 | 
						|
     while IFS= read -r opt; do
 | 
						|
     if (( ${#tmp} )); then
 | 
						|
       # Previous line had no comment.  Is the current one suitable?
 | 
						|
       # It's hard to be sure, but if it there was nothing on the
 | 
						|
       # previous line and the current one is indented more than
 | 
						|
       # a couple of spaces (and isn't completely whitespace or punctuation)
 | 
						|
       # there's a pretty good chance.
 | 
						|
       if [[ $opt = [[:space:]][[:space:]][[:space:]]*[[:alpha:]]* ]]; then
 | 
						|
	 # Assume so.
 | 
						|
	 opt=${opt##[[:space:]]##}
 | 
						|
	 # Same substitution as below.
 | 
						|
	 lopts+=("${^tmp[@]}":${${${opt//:/-}//\[/(}//\]/)})
 | 
						|
	 tmp=()
 | 
						|
	 # Finished with this line.
 | 
						|
	 continue
 | 
						|
       else
 | 
						|
	 # Still no comment, add the previous options anyway.
 | 
						|
         # Add a ':' after the option anyways, to make the matching of
 | 
						|
         # the options lateron work as intended.
 | 
						|
         # It will be removed again later.
 | 
						|
	 lopts+=("${^tmp[@]}":)
 | 
						|
	 tmp=()
 | 
						|
       fi
 | 
						|
     fi
 | 
						|
     while [[ $opt = [,[:space:]]#(#b)(-[^,[:space:]]#)(*) ]]; do
 | 
						|
       # We used to remove the brackets from "[=STUFF]",
 | 
						|
       # but later the code appears to handle it with the brackets
 | 
						|
       # present.  Maybe the problem was that the intervening code
 | 
						|
       # didn't.  If it's buggy without removing them, the problem
 | 
						|
       # probably is later, not here.
 | 
						|
       start=${match[1]}
 | 
						|
       rest=${match[2]}
 | 
						|
       if [[ -z ${tmp[(r)${start%%[^a-zA-Z0-9_-]#}]} ]]; then
 | 
						|
	 # variant syntax seen in fetchmail:
 | 
						|
	 # --[fetch]all  means --fetchall or --all.
 | 
						|
	 # maybe needs to be more general
 | 
						|
	 if [[ $start = (#b)(*)\[(*)\](*) ]]; then
 | 
						|
	   tmp+=("${match[1]}${match[2]}${match[3]}" "${match[1]}${match[3]}")
 | 
						|
	 else
 | 
						|
	   tmp+=($start)
 | 
						|
	 fi
 | 
						|
       fi
 | 
						|
       opt=$rest
 | 
						|
     done
 | 
						|
     # If there's left over text, assume it's a description; it
 | 
						|
     # may be truncated but if it's too long it's no use anyway.
 | 
						|
     # There's one hiccup: we sometimes get descriptions like
 | 
						|
     # --foo fooarg   Do some foo stuff with foo arg
 | 
						|
     # and we need to remove fooarg.  Use whitespace for hints.
 | 
						|
     opt=${opt## [^[:space:]]##  }
 | 
						|
     opt=${opt##[[:space:]]##}
 | 
						|
     if [[ -n $opt ]]; then
 | 
						|
       # Add description after a ":", converting any : in the description
 | 
						|
       # to a -.  Use RCQUOTES to append this to all versions of the option.
 | 
						|
       lopts+=("${^tmp[@]}":${${${opt//:/-}//\[/(}//\]/)})
 | 
						|
       tmp=()
 | 
						|
       # If there's no comment, we'll see if there's one on the
 | 
						|
       # next line.
 | 
						|
     fi
 | 
						|
   done
 | 
						|
   # Tidy up any remaining uncommented options.
 | 
						|
   if (( ${#tmp} )); then
 | 
						|
     lopts+=("${^tmp[@]}":)
 | 
						|
   fi
 | 
						|
 | 
						|
    # Remove options also described by user-defined specs.
 | 
						|
 | 
						|
    tmp=()
 | 
						|
    # Ignore any argument and description information when searching
 | 
						|
    # the long options array here and below.
 | 
						|
    for opt in "${(@)${(@)lopts:#--}%%[\[:=]*}"; do
 | 
						|
 | 
						|
      # Using (( ... )) gives a parse error.
 | 
						|
 | 
						|
      let "$tmpargv[(I)(|\([^\)]#\))(|\*)${opt}(|[-+]|=(|-))(|\[*\])(|:*)]" ||
 | 
						|
          tmp+=( "$lopts[(r)$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
 | 
						|
      # This implements adding things like --disable-* based
 | 
						|
      # on the existence of --enable-*.
 | 
						|
      # TODO: there's no anchoring here, is that correct?
 | 
						|
      # If it's not, careful with the [\[:=]* stuff.
 | 
						|
      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.
 | 
						|
 | 
						|
    argv+=(
 | 
						|
      '*=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.
 | 
						|
 | 
						|
      # This is the first bit of the arguments in the special form
 | 
						|
      # for converting --help texts, taking account of any quoting
 | 
						|
      # of colons.
 | 
						|
      pattern="${${${(M)1#*[^\\]:}[1,-2]}//\\\\:/:}"
 | 
						|
      # Any action specifications that go with it.
 | 
						|
      descr="${1#${pattern}}"
 | 
						|
      if [[ "$pattern" = *\(-\) ]]; then
 | 
						|
	# This is the special form to disallow arguments
 | 
						|
	# in the next word.
 | 
						|
        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.
 | 
						|
 | 
						|
      # Ignore :descriptions at the ends of lopts for matching this;
 | 
						|
      # they aren't in the patterns.
 | 
						|
      tmp=("${(@M)lopts:##$~pattern:*}")
 | 
						|
      lopts=("${(@)lopts:##$~pattern:*}")
 | 
						|
 | 
						|
      (( $#tmp )) || continue
 | 
						|
 | 
						|
      opt=''
 | 
						|
 | 
						|
      # Clean suffix ':' added earlier
 | 
						|
      tmp=("${(@)tmp%:}")
 | 
						|
 | 
						|
      # If there are option strings with a `[=', we take these to get an
 | 
						|
      # optional argument.
 | 
						|
 | 
						|
      tmpo=("${(@M)tmp:#[^:]##\[\=*}")
 | 
						|
      if (( $#tmpo )); then
 | 
						|
        tmp=("${(@)tmp:#[^:]##\[\=*}")
 | 
						|
 | 
						|
	for opt in "$tmpo[@]"; do
 | 
						|
	  # Look for --option:description and turn it into
 | 
						|
	  # --option[description].  We didn't do that above
 | 
						|
	  # since it could get confused with the [=ARG] stuff.
 | 
						|
	  if [[ $opt = (#b)(*):([^:]#) ]]; then
 | 
						|
	    opt=$match[1]
 | 
						|
	    odescr="[${match[2]}]"
 | 
						|
	  else
 | 
						|
	    odescr=
 | 
						|
	  fi
 | 
						|
	  if [[ $opt = (#b)(*)\[\=* ]]; then
 | 
						|
	    opt2=${${match[1]}//[^a-zA-Z0-9_-]}=-${dir}${odescr}
 | 
						|
	  else
 | 
						|
	    opt2=${${opt}//[^a-zA-Z0-9_-]}=${dir}${odescr}
 | 
						|
	  fi
 | 
						|
	  if [[ "$descr" = :\=* ]]; then
 | 
						|
	    cache+=( "${opt2}::${(L)${opt%\]}#*\=}: " )
 | 
						|
	  elif [[ "$descr" = ::* ]]; then
 | 
						|
	    cache+=( "${opt2}${descr}" )
 | 
						|
	  else
 | 
						|
	    cache+=( "${opt2}:${descr}" )
 | 
						|
	  fi
 | 
						|
	done
 | 
						|
      fi
 | 
						|
 | 
						|
      # Descriptions with `=': mandatory argument.
 | 
						|
      # Basically the same as the foregoing.
 | 
						|
      # TODO: could they be combined?
 | 
						|
 | 
						|
      tmpo=("${(@M)tmp:#[^:]##\=*}")
 | 
						|
      if (( $#tmpo )); then
 | 
						|
        tmp=("${(@)tmp:#[^:]##\=*}")
 | 
						|
 | 
						|
	for opt in "$tmpo[@]"; do
 | 
						|
	  if [[ $opt = (#b)(*):([^:]#) ]]; then
 | 
						|
	    opt=$match[1]
 | 
						|
	    odescr="[${match[2]}]"
 | 
						|
	  else
 | 
						|
	    odescr=
 | 
						|
	  fi
 | 
						|
	  opt2="${${opt%%\=*}//[^a-zA-Z0-9_-]}=${dir}${odescr}"
 | 
						|
	  if [[ "$descr" = :\=* ]]; then
 | 
						|
	    cache+=( "${opt2}:${(L)${opt%\]}#*\=}: " )
 | 
						|
	  else
 | 
						|
	    cache+=( "${opt2}${descr}" )
 | 
						|
	  fi
 | 
						|
	done
 | 
						|
      fi
 | 
						|
 | 
						|
      # Everything else is just added as an option without arguments or
 | 
						|
      # as described by $descr.
 | 
						|
 | 
						|
      if (( $#tmp )); then
 | 
						|
        tmp=(
 | 
						|
	  # commands with a description of the option (as opposed
 | 
						|
	  # to the argument, which is what descr contains): needs to be
 | 
						|
	  # "option[description]".
 | 
						|
	  # Careful: \[ on RHS of substitution keeps the backslash,
 | 
						|
	  # I discovered after about half an hour, so don't do that.
 | 
						|
	  "${(@)^${(@)tmp:#^*:*}//:/[}]"
 | 
						|
	  # commands with no description
 | 
						|
	  "${(@)${(@)tmp:#*:*}//[^a-zA-Z0-9_-]}")
 | 
						|
        if [[ -n "$descr" && "$descr" != ': :  ' ]]; then
 | 
						|
	  cache+=( "${(@)^tmp}${descr}" )
 | 
						|
        else
 | 
						|
	  cache+=( "$tmp[@]" )
 | 
						|
        fi
 | 
						|
      fi
 | 
						|
    done
 | 
						|
    set -A "$name" "${(@)cache:# #}"
 | 
						|
  fi
 | 
						|
  set -- "$tmpargv[@]" "${(@P)name}"
 | 
						|
fi
 | 
						|
 | 
						|
zstyle -s ":completion:${curcontext}:options" auto-description autod
 | 
						|
 | 
						|
if (( $# )) && comparguments -i "$autod" "$singopt[@]" "$@"; then
 | 
						|
  local action noargs aret expl local tried ret=1
 | 
						|
  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=()
 | 
						|
  state_descr=()
 | 
						|
 | 
						|
  while true; do
 | 
						|
    while _tags; do
 | 
						|
      anum=1
 | 
						|
      if [[ -z "$tried" ]]; then
 | 
						|
        while [[ anum -le  $#descrs ]]; do
 | 
						|
 | 
						|
	  action="$actions[anum]"
 | 
						|
	  descr="$descrs[anum]"
 | 
						|
	  subc="$subcs[anum++]"
 | 
						|
 | 
						|
	  if [[ $subc = argument* && -n $setnormarg ]]; then
 | 
						|
	    comparguments -n NORMARG
 | 
						|
	  fi
 | 
						|
 | 
						|
          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+=( "$action" )
 | 
						|
                state_descr+=( "$descr" )
 | 
						|
	        if [[ -n "$usecc" ]]; then
 | 
						|
	          curcontext="${oldcontext%:*}:$subc"
 | 
						|
	        else
 | 
						|
	          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 -e "$subc" "$descr"
 | 
						|
	        mesg=yes
 | 
						|
	        tried=yes
 | 
						|
                alwopt=${alwopt:-yes}
 | 
						|
              elif [[ "$action" = \(\(*\)\) ]]; then
 | 
						|
 | 
						|
                # ((...)) contains literal strings with descriptions.
 | 
						|
 | 
						|
                eval ws\=\( "${action[3,-3]}" \)
 | 
						|
 | 
						|
                _describe -t "$subc" "$descr" ws -M "$matcher" "$subopts[@]" ||
 | 
						|
                    alwopt=${alwopt:-yes}
 | 
						|
	        tried=yes
 | 
						|
 | 
						|
              elif [[ "$action" = \(*\) ]]; then
 | 
						|
 | 
						|
                # Anything inside `(...)' is added directly.
 | 
						|
 | 
						|
                eval ws\=\( "${action[2,-2]}" \)
 | 
						|
 | 
						|
                _all_labels "$subc" expl "$descr" compadd "$subopts[@]" -a - ws ||
 | 
						|
                    alwopt=${alwopt:-yes}
 | 
						|
	        tried=yes
 | 
						|
              elif [[ "$action" = \{*\} ]]; then
 | 
						|
 | 
						|
                # A string in braces is evaluated.
 | 
						|
 | 
						|
                while _next_label "$subc" expl "$descr"; do
 | 
						|
                  eval "$action[2,-2]" && ret=0
 | 
						|
                done
 | 
						|
                (( ret )) && alwopt=${alwopt:-yes}
 | 
						|
	        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[@]" && ret=0
 | 
						|
                done
 | 
						|
                (( ret )) && alwopt=${alwopt:-yes}
 | 
						|
	        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]}" && ret=0
 | 
						|
	        done
 | 
						|
                (( ret )) && alwopt=${alwopt:-yes}
 | 
						|
	        tried=yes
 | 
						|
              fi
 | 
						|
            fi
 | 
						|
          fi
 | 
						|
        done
 | 
						|
      fi
 | 
						|
      if _requested options &&
 | 
						|
         [[ -z "$hasopts" &&
 | 
						|
            -z "$matched" &&
 | 
						|
            ( -z "$aret" || "$PREFIX" = "$origpre" ) ]] &&
 | 
						|
          { ! zstyle -T ":completion:${oldcontext%:*}:options" prefix-needed ||
 | 
						|
            [[ "$origpre" = [-+]* || -z "$aret$mesg$tried" ]] } ; then
 | 
						|
	local prevpre="$PREFIX" previpre="$IPREFIX" prevcontext="$curcontext"
 | 
						|
 | 
						|
        curcontext="${oldcontext%:*}:options"
 | 
						|
 | 
						|
	hasopts=yes
 | 
						|
 | 
						|
	PREFIX="$origpre"
 | 
						|
	IPREFIX="$origipre"
 | 
						|
 | 
						|
        if [[ -z "$alwopt" || -z "$tried" || "$alwopt" = arg ]] &&
 | 
						|
           comparguments -s single; then
 | 
						|
 | 
						|
          if [[ "$single" = direct ]]; then
 | 
						|
            _all_labels options expl option \
 | 
						|
	        compadd -QS '' - "${PREFIX}${SUFFIX}"
 | 
						|
          elif [[ -z "$optarg" && "$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=( "${(@M)tmp1:#${PREFIX[1]}*}" )
 | 
						|
 | 
						|
            [[ "$single" = next ]] &&
 | 
						|
                tmp1=( "${(@)tmp1:#[-+]${PREFIX[-1]}((#e)|:*)}" )
 | 
						|
 | 
						|
	    [[ "$PREFIX" != --* ]] && tmp1=( "${(@)tmp1:#--*}" )
 | 
						|
	    tmp3=( "${(M@)tmp1:#[-+]?[^:]*}" )
 | 
						|
	    tmp1=( "${(M@)tmp1:#[-+]?(|:*)}" )
 | 
						|
	    tmp2=( "${PREFIX}${(@M)^${(@)${(@)tmp1%%:*}#[-+]}:#?}" )
 | 
						|
 | 
						|
            _describe -O option \
 | 
						|
                      tmp1 tmp2 -Q -S '' -- \
 | 
						|
		      tmp3 -Q
 | 
						|
 | 
						|
            [[ -n "$optarg" && "$single" = next && nm -eq $compstate[nmatches] ]] &&
 | 
						|
                _all_labels options expl option \
 | 
						|
	            compadd -Q - "${PREFIX}${SUFFIX}"
 | 
						|
 | 
						|
          fi
 | 
						|
          single=yes
 | 
						|
        else
 | 
						|
          next+=( "$odirect[@]" )
 | 
						|
          _describe -O option \
 | 
						|
                    next -Q -M "$matcher" -- \
 | 
						|
                    direct -QS '' -M "$matcher" -- \
 | 
						|
                    equal -QqS= -M "$matcher"
 | 
						|
        fi
 | 
						|
	PREFIX="$prevpre"
 | 
						|
	IPREFIX="$previpre"
 | 
						|
        curcontext="$prevcontext"
 | 
						|
      fi
 | 
						|
      [[ -n "$tried" && "${${alwopt:+$origpre}:-$PREFIX}" != [-+]* ]] && break
 | 
						|
    done
 | 
						|
    if [[ -n "$opts" && -z "$aret" &&
 | 
						|
          -z "$matched" &&
 | 
						|
          ( -z "$tried" || -n "$alwopt" ) &&
 | 
						|
          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
 | 
						|
 | 
						|
### Returning non-zero would allow the calling function to add its own
 | 
						|
### completions if we generated only options and have to use a ->state
 | 
						|
### action.  But if that then doesn't generate matches, the calling
 | 
						|
### function's return value would be wrong unless it compares
 | 
						|
### $compstate[nmatches] to its previous value.  Ugly.
 | 
						|
###
 | 
						|
###    return 1
 | 
						|
  else
 | 
						|
    [[ -n "$noargs" && nm -eq "$compstate[nmatches]" ]] && _message "$noargs"
 | 
						|
  fi
 | 
						|
  # Set the return value.
 | 
						|
 | 
						|
  [[ nm -ne "$compstate[nmatches]" ]]
 | 
						|
else
 | 
						|
  return 1
 | 
						|
fi
 |