1
0
mirror of git://git.code.sf.net/p/zsh/code synced 2024-09-21 19:31:50 +02:00

49597: add a helper for completing numbers with unit suffixes and separate out defaults, ranges and units in completion descriptions

This commit is contained in:
Oliver Kiddle 2021-11-24 23:07:18 +01:00
parent 138f5bf144
commit 16d5d6a9da
18 changed files with 258 additions and 90 deletions

View File

@ -1,3 +1,17 @@
2021-11-24 Oliver Kiddle <opk@zsh.org>
* 49597: Completion/Base/Core/_description, Doc/Zsh/compsys.yo,
Completion/Base/Utility/_numbers, Completion/BSD/Command/_ipfw,
Completion/Linux/Command/_btrfs, Completion/Unix/Command/_dd,
Completion/Unix/Command/_git, Completion/Unix/Command/_head,
Completion/Unix/Command/_killall, Completion/Unix/Command/_pv,
Completion/Unix/Command/_rclone, Completion/Unix/Command/_rsync,
Completion/Unix/Command/_stdbuf, Completion/Unix/Command/_tail,
Completion/Unix/Command/_timeout, Completion/Unix/Command/_zfs,
Completion/X/Command/_xset: add a helper for completing numbers
with unit suffixes and separate out defaults, ranges and units
in completion descriptions
2021-11-22 Jun-ichi Takimoto <takimoto-j@kba.biglobe.ne.jp>
* 49586: Src/hist.c: fix :a and :A modifiers (with PWD="/") on

View File

@ -249,8 +249,8 @@ actions=(
$'/(pipe|queue|sched)[ \t\0]/' -'pqs=${match%?}' ':dummynet-commands:dummynet configuration:$ca pipe queue sched'
$word ': _message -e numbers number'
$word ':options:config:$ca config'
\( $'/bw[ \t\0]/' \( $'/<->/' ': _guard "[0-9]#" bandwidth'
$word ':units:unit:compadd -M "m:{a-z}={A-Z}" {K,M,G}{bit,Byte}/s'
\( $'/bw[ \t\0]/'
\( $word ':bandwidths: :_numbers -M "m:{a-z}={A-Z}" bandwidth {K,M,G}{bit,Byte}/s'
\| $word ':devices:device:_net_interfaces -qS " "' \)
\| $'/delay[ \t\0]/' $word ': _message -e numbers "propagation delay (ms)"'
\| $'/burst[ \t\0]/' $word ': _message -e numbers "size (bytes)"'

View File

@ -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

View File

@ -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

View File

@ -147,16 +147,16 @@ while (( $#state )); do
'--tbytes[show sizes in TiB, or TB with --si]'
)
;|
filesystem:resize) args+=( '1:size:_guard "(|+|-)[0-9]#[GKM]"' '2:path:->mounts' );;
filesystem:resize) args+=( '1: :_numbers -u bytes -N size K M G T P E' '2:path:->mounts' );;
filesystem:defragment)
args+=( '!-v'
'-r[defragment files recursively]'
'-c+[compress files while defragmenting]::compression algorithm:(zlib lzo zstd)'
'-r[defragment files recursively]'
'-f[flush after defragmenting]'
'-s[start position]:byte position'
'-l[defragment limited number of bytes]:length (bytes)'
'-t[defragment only files over a certain size]:minimum size (bytes) [32M]'
'-s[start position]: :_numbers -u bytes -d "beginning of file" offset K M G T P E'
'-l[defragment limited number of bytes]: :_numbers -u bytes length K M G T P E'
'-t[defragment only extents up to a certain size]: :_numbers -u bytes -d 32M "maximum extent size" K M G T P E'
'*:file:_files'
)
;;

View File

@ -1,18 +1,19 @@
#compdef dd gdd
local -a vals conv flags
local -a vals conv flags units
local variant
units=( w:word b:block k:1024 m g t )
_pick_variant -r variant gnu=GNU $OSTYPE --version
vals=(
'(ibs obs)bs[block size]:block size (bytes)'
'cbs[conversion buffer size]:buffer size (bytes)'
'(ibs obs)bs[block size]: :_numbers -u bytes "block size" $units'
'cbs[conversion buffer size]: :_numbers -u bytes "buffer size" $units'
'conv[specify conversions to apply]: :_values -s , conversion $conv'
'count[number of input blocks to copy]:blocks'
'(bs)ibs[input block size]:block size (bytes)'
'(bs)ibs[input block size]: :_numbers -u bytes -d 512 "block size" $units'
'if[specify input file]:input file:_tilde_files'
'(bs)obs[output block size]:block size (bytes)'
'(bs)obs[output block size]: :_numbers -u bytes -d 512 "block size" $units'
'of[specify output file]:output file:_tilde_files'
'seek[output blocks initially skipped]:blocks'
'skip[input blocks initially skipped]:blocks'
@ -63,7 +64,7 @@ case $variant in
freebsd*)
vals+=(
'fillchar[specify padding character]:character'
'speed[limit copying speed]:speed (bytes/second)'
'speed[limit copying speed]: :_numbers -u bytes/second speed $units'
)
conv+=(
'(pareven parnone parodd parset)'{pareven,parnone,parodd,parset}
@ -75,6 +76,7 @@ case $variant in
)
flags+=( fullblock noatime nocache count_bytes skip_bytes seek_bytes )
conv+=( excl nocreat fdatasync fsync )
units=( c:1 w:2 b:512 kB:1000 K:1024 MB:1000^2 M:1024\^2 GB G TB T PB P EB E ZB Z YB Y )
;;
netbsd*)
vals+=(

View File

@ -3720,8 +3720,8 @@ _git-fast-import () {
now\:"use current time and timezone"' \
'--done[terminate with error if there is no "done" command at the end of the stream]' \
'--force[force updating modified existing branches]' \
'--max-pack-size=-[maximum size of each packfile]: : __git_guard_bytes' \
'--big-file-threshold=-[maximum size of blob to create deltas for]: : __git_guard_bytes' \
'--max-pack-size=-[maximum size of each packfile]: : __git_guard_bytes -d unlimited size' \
'--big-file-threshold=-[maximum size of blob to create deltas for]: : __git_guard_bytes -d 512m size' \
'--depth=-[maximum delta depth for blob and tree deltification]: :__git_guard_number "maximum delta depth"' \
'--active-branches=-[maximum number of branches to maintain active at once]: :__git_guard_number "maximum number of branches"' \
'--export-marks=-[dump internal marks table when complete]: :_files' \
@ -7506,7 +7506,7 @@ __git_guard_number () {
(( $+functions[__git_guard_bytes] )) ||
__git_guard_bytes () {
_guard '[[:digit:]]#([kKmMgG]|)' ${*:-size}
_numbers -u bytes ${*:-size} k m g
}
(( $+functions[__git_datetimes] )) ||

View File

@ -32,20 +32,14 @@ _arguments -C -s -S $opts : $args '*:file:_files' && return 0
case $state in
(number)
local mlt sign digit
mlt='multiplier:multiplier:((b\:512 K\:1024 KB\:1000 M\:1024\^2'
mlt+=' MB\:1000\^2 G\:1024\^3 GB\:1000\^3 T\:1024\^4 TB\:1000\^4))'
sign='sign:sign:((-\:"print all but the last specified bytes/lines"'
sign+=' +\:"print the first specified bytes/lines (default)"))'
digit='digits:digit:(0 1 2 3 4 5 6 7 8 9)'
if compset -P '(-|+|)[0-9]##'; then
_alternative $mlt $digit && ret=0
elif [[ -z $PREFIX ]]; then
_alternative $sign $digit && ret=0
elif compset -P '(+|-)'; then
_alternative $digit && ret=0
fi
;;
local alts
[[ -z $PREFIX ]] && alts=(
'sign:sign:((-\:"print all but the last specified bytes/lines" +\:"print the first specified bytes/lines (default)"))'
)
compset -P '+'
alts+=( 'numbers: :_numbers -N $state_descr b\:512 K\:1024 KB\:1000 M\:1024\^2 MB\:1000\^2 G\:1024\^3 GB\:1000\^3 T\:1024\^4 TB\:1000\^4' )
_alternative $alts && ret=0
;;
esac
return ret

View File

@ -38,15 +38,9 @@ if _pick_variant psmisc=PSmisc unix --version; then
case $state in
(time)
local -a units=( 's:seconds' 'm:minutes' 'h:hours' 'd:days'
'w:weeks' 'M:months' 'y:years' )
if compset -P '[0-9]##(|.[0-9]#)'; then
_alternative 'float-numbers:: _message "float number"' \
'units:: _describe unit units' && ret=0
else
_message 'float number and unit' && ret=0
fi
;;
_numbers -fN age 's:seconds' 'm:minutes' 'h:hours' 'd:days' \
'w:weeks' 'M:months' 'y:years'
;;
esac
return ret

View File

@ -25,7 +25,7 @@ _arguments -s -S $args \
'(-q --quiet)'{-q,--quiet}"[don't output any transfer information at all, useful with -L]" \
'(-W --wait)'{-W,--wait}'[display nothing until first byte transferred]' \
'(-D --delay-start -R --remote)'{-D+,--delay-start=}'[display nothing until delay has passed]:delay (seconds)' \
'(-s --size)'{-s+,--size=}'[set estimated data size]:size (bytes):->size-unit' \
'(-s --size)'{-s+,--size=}'[set estimated data size]: :_numbers -u bytes size K M G T' \
'(-l --line-mode -R --remote)'{-l,--line-mode}'[count lines instead of bytes]' \
'(-0 --null -l --line-mode)'{-0,--null}'[lines are null-terminated]' \
'(-i --interval)'{-i+,--interval=}'[update every after specified interval]:interval (seconds) [1]' \
@ -34,8 +34,8 @@ _arguments -s -S $args \
'(-N --name)'{-N+,--name=}'[prefix visual information with given name]:name' \
'(-f --force -R --remote)'{-f,--force}'[output even if standard error is not a terminal]' \
'(-c --cursor -R --remote)'{-c,--cursor}'[use cursor positioning escape sequences]' \
'(-L --rate-limit)'{-L+,--rate-limit=}'[limit transfer rate]:rate (bytes per second):->size-unit' \
'(-B --buffer-size)'{-B+,--buffer-size=}'[use a buffer size of given size]:size (bytes):->size-unit' \
'(-L --rate-limit)'{-L+,--rate-limit=}'[limit transfer rate]: :_numbers -u "bytes per second" rate K M G T' \
'(-B --buffer-size)'{-B+,--buffer-size=}'[use a buffer size of given size]: :_numbers -u bytes size K M G T' \
'(-C --no-splice)'{-C,--no-splice}'[never use splice(), always use read/write]' \
'(-R --remote)*'{-E,--skip-errors}"[skip read errors in input${Edesc}]" \
'(-S --stop-at-size -R --remote)'{-S,--stop-at-size}'[stop after --size bytes have been transferred]' \
@ -70,18 +70,6 @@ case $state in
_pids $suf && ret=0
fi
;;
size-unit)
if compset -P '<->'; then
_tags values units
else
_tags values
fi
while _tags; do
_requested values && _message -e values "$state_descr" && ret=0
_requested units expl unit compadd -o nosort - K M G T && ret=0
(( ret )) || break
done
;;
esac
return ret

View File

@ -62,7 +62,7 @@ _arguments -C \
'--backup-dir[make backups into hierarchy based at specified directory]:directory:_directories' \
'--bind[specify socal address to bind to for outgoing connections]:IPv4, IPv6 or name' \
'--buffer-size[specify in memory buffer size when reading files for each --transfer]:size [16M]' \
'--bwlimit[specify bandwidth limit]:BwTimetable (kBytes/s or b|k|M|G suffix)' \
'--bwlimit[specify bandwidth limit]: :_numbers -u kBytes/s limit b k M G' \
'--cache-dir[specify directory rclone will use for caching]:directory [~/.cache/rclone]:_directories' \
'--checkers[specify number of checkers to run in parallel]:number [8]': \
'(-c --checksum)'{-c,--checksum}'[skip based on checksum & size, not mod-time & size]' \
@ -99,15 +99,15 @@ _arguments -C \
'--log-format[specify comma separated list of log format options]:string ["date,time"]' \
'--log-level[specify log level]:string [NOTICE]:(DEBUG INFO NOTICE ERROR)' \
'--low-level-retries[number of low level retries to do]:int [10]' \
'--max-age[only transfer files younger than this in s or suffix ms|s|m|h|d|w|M|y]:duration [default off]' \
'--max-age[only transfer files younger than specified age]: :_numbers -u seconds age ms\:milliseconds \:s\:seconds m\:minutes h\:hours d\:days w\:weeks M\:months y\:years' \
'--max-backlog[maximum number of objects in sync or check backlog]:int [10000]' \
'--max-delete[when synchronizing, limit the number of deletes]:delete limit [-1]' \
'--max-depth[limit the recursion depth]:depth [-1]' \
'--max-size[only transfer files smaller than this in k or suffix b|k|M|G]:int [default off]' \
'--max-size[only transfer files smaller than specified size]: :_numbers -u kBytes size \:k M G' \
'--max-transfer[maximum size of data to transfer]:int [default off]' \
'--memprofile[write memory profile to file]:file:_files' \
'--min-age[only transfer files older than this in s or suffix ms|s|m|h|d|w|M|y]:duration [default off]' \
'--min-size[only transfer files bigger than this in k or suffix b|k|M|G]:int [default off]' \
'--min-age[only transfer files older than specified age]: :_numbers -u seconds age ms\:milliseconds \:s\:seconds m\:minutes h\:hours d\:days w\:weeks M\:months y\:years' \
'--min-size[only transfer files bigger than specified size]: :_numbers -u kBytes size \:k M G' \
'--modify-window[specify max time delta to be considered the same]:duration [1ns]' \
'--multi-thread-cutoff[use multi-threaded downloads for files above specified size]:size (250M)' \
'--multi-thread-streams[specify max number of streams to use for multi-threaded downloads]:number (4)' \

View File

@ -99,7 +99,7 @@ _rsync() {
_arguments -s \
'*'{-v,--verbose}'[increase verbosity]' \
{--no-v,--no-verbose}'[turn off --verbose]' \
'--bwlimit=[limit I/O bandwidth]:limit (KiB per second)' \
'--bwlimit=[limit I/O bandwidth]: :_numbers -f -u "KiB per second" -d 1g limit B K M G T P' \
'--outbuf=[set output buffering]:buffering:(none line block)' \
'--port=[specify alternate port number]:port:(873)' \
'--address=[bind to the specified address]:bind address:_bind_addresses' \
@ -181,7 +181,7 @@ _rsync() {
{--no-W,--no-whole-file}'[turn off --whole-file]' \
'(--cc --checksum-choice)'{--cc,--checksum-choice}'=[choose the checksum algorithms]:algorithm:_sequence -n 2 compadd - auto md4 md5 none' \
'(-x --one-file-system)'{-x,--one-file-system}"[don't cross filesystem boundaries]" \
'(-B --block-size)'{-B+,--block-size=}'[force a fixed checksum block-size]:block size (bytes)' \
'(-B --block-size)'{-B+,--block-size=}'[force a fixed checksum block-size]: :_numbers -f -u bytes -d 1g "block size" B K M G T P' \
'(-e --rsh)'{-e+,--rsh=}'[specify the remote shell to use]:remote-shell command:(rsh ssh)' \
'--rsync-path=[specify path to rsync on the remote machine]:remote command' \
'--ignore-existing[ignore files that already exist on receiving side]' \
@ -199,10 +199,10 @@ _rsync() {
'--force-change[affect user-/system-immutable files/dirs]' \
'--force-uchange[affect user-immutable files/dirs]' \
'--force-schange[affect system-immutable files/dirs]' \
'--max-delete=[do not delete more than NUM files]:number' \
'--max-size=[do not transfer any file larger than specified size]:number' \
"--max-delete=[don't delete more than NUM files]: :_numbers -f -u bytes size B K M G T P" \
"--max-size=[don't transfer any file larger than specified size]: :_numbers -f -u bytes size B K M G T P" \
'--min-size=[do not transfer any file smaller than specified size]:number' \
'--max-alloc=[set limit to individual memory allocation]:size (bytes) [1g]' \
'--max-alloc=[set limit to individual memory allocation]: :_numbers -f -u bytes -d 1g size B K M G T P' \
'(-P)--partial[keep partially transferred files]' \
'--no-partial[turn off --partial]' \
'--partial-dir=[put a partially transferred file into specified directory]:directory:_directories' \

View File

@ -7,7 +7,9 @@ short=( -e -i -o )
long=( --error --input --output )
buf=( err in out )
opt='[set initial buffering for std${buf[i]}]:mode or size:((0\:unbuffered L\:line\ buffered'
opt='[set initial buffering for std${buf[i]}]: : _alternative
"sizes\: \: _numbers -u bytes size k M G"
"modes\:mode\:((0\:unbuffered L\:line\ buffered'
if _pick_variant gnu=GNU freebsd --version; then
gnu=1
args=(
@ -17,7 +19,7 @@ if _pick_variant gnu=GNU freebsd --version; then
else
opt+=' B\:fully\ buffered'
fi
opt+='))'
opt+='))"'
for ((i=1;i<=3;i++)); do
args+=( "(${long[i]})${short[i]}+${(e)opt}" )

View File

@ -53,20 +53,14 @@ _arguments -C -s -S $opts : $args '*:file:_files' && return
case $state in
(number)
local mlt sign digit
mlt='multipliers:multiplier:((b\:512 K\:1024 KB\:1000 M\:1024\^2'
mlt+=' MB\:1000\^2 G\:1024\^3 GB\:1000\^3 T\:1024\^4 TB\:1000\^4))'
sign='signs:sign:((+\:"start at the specified byte/line"'
sign+=' -\:"output the last specified bytes/lines (default)"))'
digit='digits:digit:(0 1 2 3 4 5 6 7 8 9)'
if compset -P '(-|+|)[0-9]##'; then
_alternative $mlt $digit && ret=0
elif [[ -z $PREFIX ]]; then
_alternative $sign $digit && ret=0
elif compset -P '(+|-)'; then
_alternative $digit && ret=0
fi
;;
local alts
[[ -z $PREFIX ]] && alts=(
'sign:sign:((-\:"print all but the last specified bytes/lines" +\:"print the first specified bytes/lines (default)"))'
)
compset -P '+'
alts+=( 'numbers: :_numbers -N $state_descr b\:512 K\:1024 KB\:1000 M\:1024\^2 MB\:1000\^2 G\:1024\^3 GB\:1000\^3 T\:1024\^4 TB\:1000\^4' )
_alternative $alts && ret=0
;;
esac
return ret

View File

@ -16,5 +16,5 @@ _arguments -S -A "-" $args \
"--foreground[don't propagate timeout to the command children]" \
'(-s --signal)'{-s,--signal}'[specify the signal to send on timeout]:signal:_signals' \
'(-k --kill-after)'{-k,--kill-after}'[followup first signal with SIGKILL if command persists after specified time]:time' \
'1: :_guard "[0-9.]#([smhd]|)" duration' \
'1: :_numbers -f -u seconds duration :s:seconds m:minutes h:hours d:days' \
'*:::command:_normal'

View File

@ -162,12 +162,20 @@ _zfs() {
"multilevel:value:(on off)"
"nbmand:value:(on off)"
"primarycache:value:(all none metadata)"
"quota:number or 'none':{if [[ -prefix [0-9]## ]]; then _message -e 'number'; elif [[ $PREFIX == quota= ]]; then _wanted none expl 'number or none' compadd none; else _wanted none expl 'quota' compadd none; fi}"
"quota: : _alternative \
'sizes: :_numbers -M "m\:{a-zA-Z}={A-Za-z}" -u bytes size :B {k,M,G,T,P,E,Z}{,B}' \
'properties:property:(none)'"
"readonly:value:(on off)"
"recordsize:value:(512 1K 2K 4K 8K 16K 32K 64K 128K 256K 512K 1M)"
"refquota:number or 'none':{if [[ -prefix [0-9]## ]]; then _message -e 'number'; elif [[ $PREFIX == refquota= ]]; then _wanted none expl 'number or none' compadd none; else _wanted none expl 'refquota' compadd none; fi}"
"refreservation:number or 'none':{if [[ -prefix [0-9]## ]]; then _message -e 'number'; elif [[ $PREFIX == refreservation= ]]; then _wanted none expl 'number or none' compadd none; else _wanted none expl 'refreservation' compadd none; fi}"
"reservation:value:{if [[ -prefix [0-9]## ]]; then _message -e 'number'; elif [[ $PREFIX == reservation= ]]; then _wanted none expl 'number or none' compadd none; else _wanted none expl 'reservation' compadd none; fi}"
"refquota: : _alternative \
'sizes: :_numbers -M "m\:{a-zA-Z}={A-Za-z}" -u bytes size :B {k,M,G,T,P,E,Z}{,B}' \
'properties:property:(none)'"
"refreservation: : _alternative \
'sizes: :_numbers -M "m\:{a-zA-Z}={A-Za-z}" -u bytes size :B {k,M,G,T,P,E,Z}{,B}' \
'properties:property:(auto none)'"
"reservation: : _alternative \
'sizes: :_numbers -M "m\:{a-zA-Z}={A-Za-z}" -u bytes size :B {k,M,G,T,P,E,Z}{,B}' \
'properties:property:(none)'"
"rstchown:value:(on off)"
"secondarycache:value:(all none metadata)"
"setuid:value:(on off)"
@ -238,8 +246,8 @@ _zfs() {
':filesystem:_zfs_dataset -t fs -e "parent dataset"' \
- set2 \
'-s[Create sparse volume]' \
'-b[Set volblocksize]:blocksize:' \
'-V[Set size]:size:' \
'-b+[set volblocksize]: :_numbers -M "m\:{a-zA-Z}={A-Za-z}" -u bytes blocksize :B {k,M,G,T,P,E,Z}{,B}' \
'-V+[set size]: :_numbers -M "m\:{a-zA-Z}={A-Za-z}" -u bytes size :B {k,M,G,T,P,E,Z}{,B}' \
':volume:_zfs_dataset -t fs -e "parent dataset"'
;;

View File

@ -91,8 +91,8 @@ _regex_arguments _xset_parse \
\( "/(blank|noblank|expose|noexpose|default|on|activate|reset)$nul/" \
':option-s:screen saver:(blank noblank expose noexpose default on activate reset off)' \
\| "/off$nul/" \( "/off$nul/" ':option-s-off-period:period off:(off)' \| \) \
\| "/[0-9]##$nul/" ':option-s-timeout:length:' \
\( "/[0-9]##$nul/" ':option-s-period:period:' \
\| "/[0-9]##$nul/" ':option-s-timeout: :_numbers -u seconds length' \
\( "/[0-9]##$nul/" ':option-s-period: :_numbers -u seconds period' \
\| \) \
\| \) \
\| "/-r$nul/" "$guard" \

View File

@ -4496,8 +4496,22 @@ not contain an explanation string to be displayed above the matches.
If tt(_description) is called with more than three arguments,
the additional var(spec)s should be of the form `var(char)tt(:)var(str)'.
These supply escape sequence replacements for the tt(format) style:
every appearance of `tt(%)var(char)' will be
replaced by var(string).
every appearance of `tt(%)var(char)' will be replaced by var(string).
If no additional var(spec)s are given but the description in var(descr)
conforms to a common form then further escape sequences are set for
elements of that description. These elements correspond to a default
value (`tt(%o)'), the units (`tt(%m)') range of acceptable values
(`tt(%r)') and the remaining initial part of the description (`tt(%h)').
The form the description takes consists of specifying the units and
range in parentheses and the default value in square brackets, for
example:
example(_description times expl 'timeout (seconds) (0-60) [20]')
It is possible to use tt(zformat) conditional expressions when styling
these elements. So, for example, to add `tt(default:)' as a tag but only
when there is a default value to show, the tt(format) style might
include `tt(%(o.default: %o.))'.
If the tt(-x) option is given, the description will be passed to
tt(compadd) using the tt(-x) option instead of the default tt(-X). This
@ -4773,6 +4787,69 @@ checked. If it is set completion is terminated at that point even if
no matches have been found. This is the same effect as in the
tt(-first-) context.
)
findex(_numbers)
item(tt(_numbers) [ var(option) ... ] [ var(description) ] [ var(suffix) ... ])(
This can be used where a number is followed by a suffix to indicate the units.
The unit suffixes are completed and can also be included in the description
used when completion is invoked for the preceding number.
In addition to common tt(compadd) options, tt(_numbers) accepts the following
options:
startitem()
item(tt(-t) var(tag))(
Specify a tag to use instead of the default of tt(numbers).
)
item(tt(-u) var(units))(
Indicate the default units for the number, e.g. tt(bytes).
)
item(tt(-l) var(min))(
Specify the lowest possible value for the number.
)
item(tt(-m) var(max))(
Specify the highest possible value for the number.
)
item(tt(-d) var(default))(
Specify the default value.
)
item(tt(-N))(
Allow negative numbers. This is implied if the range includes a negative.
)
item(tt(-f))(
Allow decimal numbers.
)
enditem()
Where a particular suffix represents the default units for a number, it
should be prefixed with a colon. Additionally, suffixes can be followed
by a colon and a description. So for example, the following allows the
age of something to be specified, either in seconds or with an optional
suffix with a longer unit of time:
example(_numbers -u seconds age :s:seconds m:minutes h:hours d:days)
It is typically helpful for units to be presented in order of magnitude
when completed. To facilitate this, the order in which they are given
is preserved.
When the tt(format) style is looked up with the tt(descriptions) tag or
the tag specified with tt(-t), the list of suffixes is available as a
`tt(%x)' escape sequence. This is in addition to the usual sequences
documented under the tt(format) style. The form this list takes can also
be configured. To this end, the tt(format) style is first looked up with
the tag tt(unit-suffixes). The retrieved format is applied to each
suffix in turn and the results are then concatenated to form the
completed list. For the tt(unit-suffixes) format, `tt(%x)' expands to
the individual suffix and `tt(%X)' to its description. tt(%d)' indicates
a default suffix and can be used in a condition. The index and reverse
index are set in `tt(%i)' and `tt(%r)' respectively and are useful for
text included only with the first and last suffixes in the list. So for
example, the following joins the suffixes together as a comma-separated
list:
example(zstyle ':completion:*:unit-suffixes' format '%x%(r::,)')
)
findex(_options)
item(tt(_options))(
This can be used to complete the names of shell options. It provides a