mirror of
				git://git.code.sf.net/p/zsh/code
				synced 2025-10-31 18:10:56 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			155 lines
		
	
	
	
		
			3.7 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
			
		
		
	
	
			155 lines
		
	
	
	
		
			3.7 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
| #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 [[ $# = 1 || "$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
 |