mirror of
				git://git.code.sf.net/p/zsh/code
				synced 2025-10-31 06:00:54 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			160 lines
		
	
	
	
		
			3.7 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
			
		
		
	
	
			160 lines
		
	
	
	
		
			3.7 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
| #autoload
 | |
| 
 | |
| local subopts opt usecc garbage keep
 | |
| 
 | |
| subopts=()
 | |
| zparseopts -D -a garbage s+:=keep S+:=keep w+=keep C=usecc O:=subopts \
 | |
|     M: J: V: 1 2 n F: X:
 | |
| 
 | |
| (( $#subopts )) && subopts=( "${(@P)subopts[2]}" )
 | |
| 
 | |
| if compvalues -i "$keep[@]" "$@"; then
 | |
| 
 | |
|   local noargs args opts descr action expl sep argsep subc test='*'
 | |
|   local oldcontext="$curcontext"
 | |
| 
 | |
|   compvalues -S argsep
 | |
|   compvalues -s sep && [[ -n "$sep" ]] && test="[^${(q)sep}]#"
 | |
| 
 | |
|   if ! compvalues -D descr action; then
 | |
| 
 | |
|     _tags values || return 1
 | |
| 
 | |
|     curcontext="${oldcontext%:*}:values"
 | |
| 
 | |
|     compvalues -V noargs args opts
 | |
| 
 | |
|     if [[ -n "$argsep" && "$PREFIX" = *${argsep}${~test} ]]; then
 | |
|       local name
 | |
| 
 | |
|       name="${PREFIX%%${argsep}*}"
 | |
|       if compvalues -L "$name" descr action; then
 | |
|         IPREFIX="${IPREFIX}${name}${argsep}"
 | |
|         PREFIX="${PREFIX#*${argsep}}"
 | |
|       else
 | |
|         local prefix suffix
 | |
| 
 | |
| 	prefix="${PREFIX#*${argsep}}"
 | |
| 	suffix="$SUFFIX"
 | |
| 	PREFIX="$name"
 | |
| 	SUFFIX=''
 | |
| 	args=( "$args[@]" "$opts[@]" )
 | |
| 	compadd -M 'r:|[_-]=* r:|=*' -D args - "${(@)args[@]%%:*}"
 | |
| 
 | |
| 	[[ $#args -ne 1 ]] && return 1
 | |
| 
 | |
|         PREFIX="$prefix"
 | |
| 	SUFFIX="$suffix"
 | |
|         IPREFIX="${IPREFIX}${args[1]%%:*}${argsep}"
 | |
| 	compvalues -L "${args[1]%%:*}" descr action subc
 | |
| 	curcontext="${oldcontext%:*}:$subc"
 | |
|       fi
 | |
|     else
 | |
|       compvalues -d descr
 | |
|       if compvalues -s sep; then
 | |
|         sep=( "-qS" "$sep" )
 | |
|       else
 | |
|         sep=()
 | |
|       fi
 | |
| 
 | |
|       _describe "$descr" \
 | |
|         noargs "$sep[@]" -M 'r:|[_-]=* r:|=*' -- \
 | |
|         args -S "${argsep}" -M 'r:|[_-]=* r:|=*' -- \
 | |
|         opts -qS "${argsep}" -r "${argsep}${sep} \\t\\n\\-" -M 'r:|[_-]=* r:|=*'
 | |
| 
 | |
|       curcontext="$oldcontext"
 | |
| 
 | |
|       return
 | |
|     fi
 | |
|   else
 | |
|     compvalues -C subc
 | |
|     curcontext="${oldcontext%:*}:$subc"
 | |
|   fi
 | |
| 
 | |
|   if ! _tags arguments; then
 | |
|     curcontext="$oldcontext"
 | |
|     return 1
 | |
|   fi
 | |
| 
 | |
|   _description arguments expl "$descr"
 | |
| 
 | |
|   # We add the separator character as a autoremovable suffix unless
 | |
|   # we have only one possible value left.
 | |
| 
 | |
|   sep=()
 | |
|   [[ ${#snames}+${#names}+${#onames} -ne 1 ]] && compvalues -s sep &&
 | |
|       expl=( "-qS$sep" "$expl[@]" ) sep=( "-qS$sep" )
 | |
| 
 | |
|   if [[ "$action" = -\>* ]]; then
 | |
|     compvalues -v val_args
 | |
|     state="${${action[3,-1]##[ 	]#}%%[ 	]#}"
 | |
|     state_descr="$descr"
 | |
|     if [[ -n "$usecc" ]]; then
 | |
|       curcontext="${oldcontext%:*}:$subc"
 | |
|     else
 | |
|       context="$subc"
 | |
|     fi
 | |
|     compstate[restore]=''
 | |
|     return 1
 | |
|   else
 | |
|     typeset -A val_args
 | |
| 
 | |
|     compvalues -v val_args
 | |
| 
 | |
|     if [[ "$action" = \ # ]]; then
 | |
| 
 | |
|       # An empty action means that we should just display a message.
 | |
| 
 | |
|       _message -e arguments "$descr"
 | |
|       return 1
 | |
| 
 | |
|     elif [[ "$action" = \(\(*\)\) ]]; then
 | |
|       local ws
 | |
| 
 | |
|       # ((...)) contains literal strings with descriptions.
 | |
| 
 | |
|       eval ws\=\( "${action[3,-3]}" \)
 | |
| 
 | |
|       _describe "$descr" ws -M 'r:|[_-]=* r:|=*' "$subopts[@]" "$sep[@]"
 | |
| 
 | |
|     elif [[ "$action" = \(*\) ]]; then
 | |
| 
 | |
|       # Anything inside `(...)' is added directly.
 | |
| 
 | |
|       eval ws\=\( "${action[2,-2]}" \)
 | |
| 
 | |
|       _all_labels arguments expl "$descr" compadd "$subopts[@]" "$sep[@]" -a - ws
 | |
|     elif [[ "$action" = \{*\} ]]; then
 | |
| 
 | |
|       # A string in braces is evaluated.
 | |
| 
 | |
|       while _next_label arguments expl "$descr"; do
 | |
|         eval "$action[2,-2]"
 | |
|       done
 | |
|     elif [[ "$action" = \ * ]]; then
 | |
| 
 | |
|       # If the action starts with a space, we just call it.
 | |
| 
 | |
|       eval "action=( $action )"
 | |
|       while _next_label arguments expl "$descr"; do
 | |
|         "$action[@]"
 | |
|       done
 | |
|     else
 | |
| 
 | |
|       # Otherwise we call it with the description-arguments built above.
 | |
| 
 | |
|       eval "action=( $action )"
 | |
|       while _next_label arguments expl "$descr"; do
 | |
|         "$action[1]" "$subopts[@]" "$expl[@]" "${(@)action[2,-1]}"
 | |
|       done
 | |
|     fi
 | |
|   fi
 | |
| 
 | |
|   curcontext="$oldcontext"
 | |
| 
 | |
|   [[ nm -ne "$compstate[nmatches]" ]]
 | |
| else
 | |
|   curcontext="$oldcontext"
 | |
| 
 | |
|   return 1;
 | |
| fi
 |