From 16d5d6a9dae526355caf16f2de9d57d84b5d9993 Mon Sep 17 00:00:00 2001 From: Oliver Kiddle Date: Wed, 24 Nov 2021 23:07:18 +0100 Subject: 49597: add a helper for completing numbers with unit suffixes and separate out defaults, ranges and units in completion descriptions --- Completion/Base/Core/_description | 8 ++++ Completion/Base/Utility/_numbers | 87 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 95 insertions(+) create mode 100644 Completion/Base/Utility/_numbers (limited to 'Completion/Base') diff --git a/Completion/Base/Core/_description b/Completion/Base/Core/_description index 5b54484c7..368b41ee2 100644 --- a/Completion/Base/Core/_description +++ b/Completion/Base/Core/_description @@ -2,6 +2,7 @@ local name nopt xopt format gname hidden hide match opts tag local -a ign gropt sort +local -a match mbegin mend opts=() @@ -78,6 +79,13 @@ shift 2 if [[ -z "$1" && $# -eq 1 ]]; then format= elif [[ -n "$format" ]]; then + if [[ -z $2 ]]; then + argv+=( h:${1%%( ##\((#b)([^\)]#[^0-9-][^\)]#)(#B)\)|)( ##\((#b)([0-9-]##)(#B)\)|)( ##\[(#b)([^\]]##)(#B)\]|)} ) + [[ -n $match[1] ]] && argv+=( m:$match[1] ) + [[ -n $match[2] ]] && argv+=( r:$match[2] ) + [[ -n $match[3] ]] && argv+=( o:$match[3] ) + fi + zformat -F format "$format" "d:$1" "${(@)argv[2,-1]}" fi diff --git a/Completion/Base/Utility/_numbers b/Completion/Base/Utility/_numbers new file mode 100644 index 000000000..97bb8b4c8 --- /dev/null +++ b/Completion/Base/Utility/_numbers @@ -0,0 +1,87 @@ +#autoload + +# Usage: _numbers [compadd options] [-t tag] [-f|-N] [-u units] [-l min] [-m max] \ +# [-d default] ["description"] [unit-suffix...] + +# -t : specify a tag (defaults to 'numbers') +# -u : indicate the units, e.g. seconds +# -l : lowest possible value +# -m : maximum possible value +# -d : default value +# -N : allow negative numbers (implied by range including a negative) +# -f : allow decimals (float) + +# For a unit-suffix, an initial colon indicates a unit that asserts the default +# otherwise, colons allow for descriptions, e.g: + +# :s:seconds m:minutes h:hours + +# unit-suffixes are not sorted by the completion system when listed +# Specify them in order of magnitude, this tends to be ascending unless +# the default is of a higher magnitude, in which case, descending. +# So for, example +# bytes kB MB GB +# s ms us ns +# Where the compadd options include matching control or suffixes, these +# are applied to the units + +# For each unit-suffix, the format style is looked up with the +# unit-suffixes tag and the results concatenated. Specs used are: +# x : the suffix +# X : suffix description +# d : indicate suffix is for the default unit +# i : list index +# r : reverse list index +# The latter three of these are useful with ternary expressions. + +# _description is called with the x token set to make the completed +# list of suffixes available to the normal format style + +local desc tag range suffixes suffix suffixfmt pat='<->' partial='' +local -a expl formats +local -a default max min keep tags units +local -i i +local -A opts + +zparseopts -K -D -A opts M+:=keep q:=keep s+:=keep S+:=keep J+: V+: 1 2 o+: n F: x+: X+: \ + t:=tags u:=units l:=min m:=max d:=default f=type e=type N=type + +desc="${1:-number}" tag="${tags[2]:-numbers}" +(( $# )) && shift + +[[ -n ${(M)type:#-f} ]] && pat='(<->.[0-9]#|[0-9]#.<->|<->)' partial='(|.)' +[[ -n ${(M)type:#-N} || $min[2] = -* || $max[2] = -* ]] && \ + pat="(|-)$pat" partial="(|-)$partial" + +if (( $#argv )) && compset -P "$pat"; then + zstyle -s ":completion:${curcontext}:units" list-separator sep || sep=-- + _description -V units expl unit + disp=( ${${argv#:}/:/ $sep } ) + compadd -M 'r:|/=* r:|=*' -d disp "$keep[@]" "$expl[@]" - ${${argv#:}%%:*} + return +elif [[ -prefix $~pat || $PREFIX = $~partial ]]; then + formats=( "h:$desc" ) + (( $#units )) && formats+=( m:${units[2]} ) desc+=" ($units[2])" + (( $#min )) && range="$min[2]-" + (( $#max )) && range="${range:--}$max[2]" + [[ -n $range ]] && formats+=( r:$range ) desc+=" ($range)" + (( $#default )) && formats+=( o:${default[2]} ) desc+=" [$default[2]]" + + zstyle -s ":completion:${curcontext}:unit-suffixes" format suffixfmt || \ + suffixfmt='%(d.%U.)%x%(d.%u.)%(r..|)' + for ((i=0;i<$#;i++)); do + zformat -f suffix "$suffixfmt" "x:${${argv[i+1]#:}%%:*}" \ + "X:${${argv[i+1]#:}#*:}" "d:${#${argv[i+1]}[1]#:}" \ + i:i r:$(( $# - i - 1)) + suffixes+="$suffix" + done + [[ -n $suffixes ]] && formats+=( x:$suffixes ) + + _comp_mesg=yes + _description -x $tag expl "$desc" $formats + [[ $compstate[insert] = *unambiguous* ]] && compstate[insert]= + compadd "$expl[@]" + return 0 +fi + +return 1 -- cgit 1.4.1