mirror of
git://git.code.sf.net/p/zsh/code
synced 2024-11-20 05:53:52 +01:00
156 lines
3.7 KiB
Plaintext
156 lines
3.7 KiB
Plaintext
|
#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
|