about summary refs log tree commit diff
path: root/Completion/Unix/Command
diff options
context:
space:
mode:
authorOliver Kiddle <opk@zsh.org>2021-11-24 23:07:18 +0100
committerOliver Kiddle <opk@zsh.org>2021-11-24 23:09:38 +0100
commit16d5d6a9dae526355caf16f2de9d57d84b5d9993 (patch)
tree6ab30a2ad2596523b85aa553ffa8a4544632fd7a /Completion/Unix/Command
parent138f5bf144589a59ef009f26332652291cd0a944 (diff)
downloadzsh-16d5d6a9dae526355caf16f2de9d57d84b5d9993.tar.gz
zsh-16d5d6a9dae526355caf16f2de9d57d84b5d9993.tar.xz
zsh-16d5d6a9dae526355caf16f2de9d57d84b5d9993.zip
49597: add a helper for completing numbers with unit suffixes and separate out defaults, ranges and units in completion descriptions
Diffstat (limited to 'Completion/Unix/Command')
-rw-r--r--Completion/Unix/Command/_dd14
-rw-r--r--Completion/Unix/Command/_git6
-rw-r--r--Completion/Unix/Command/_head22
-rw-r--r--Completion/Unix/Command/_killall12
-rw-r--r--Completion/Unix/Command/_pv18
-rw-r--r--Completion/Unix/Command/_rclone10
-rw-r--r--Completion/Unix/Command/_rsync10
-rw-r--r--Completion/Unix/Command/_stdbuf6
-rw-r--r--Completion/Unix/Command/_tail22
-rw-r--r--Completion/Unix/Command/_timeout2
-rw-r--r--Completion/Unix/Command/_zfs20
11 files changed, 62 insertions, 80 deletions
diff --git a/Completion/Unix/Command/_dd b/Completion/Unix/Command/_dd
index e5c5e63ce..10682bc8e 100644
--- a/Completion/Unix/Command/_dd
+++ b/Completion/Unix/Command/_dd
@@ -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+=(
diff --git a/Completion/Unix/Command/_git b/Completion/Unix/Command/_git
index 7c7fb22bc..c757376b0 100644
--- a/Completion/Unix/Command/_git
+++ b/Completion/Unix/Command/_git
@@ -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] )) ||
diff --git a/Completion/Unix/Command/_head b/Completion/Unix/Command/_head
index f25c97c83..0771b1e4d 100644
--- a/Completion/Unix/Command/_head
+++ b/Completion/Unix/Command/_head
@@ -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
diff --git a/Completion/Unix/Command/_killall b/Completion/Unix/Command/_killall
index 36accb2e0..3ddd36341 100644
--- a/Completion/Unix/Command/_killall
+++ b/Completion/Unix/Command/_killall
@@ -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
diff --git a/Completion/Unix/Command/_pv b/Completion/Unix/Command/_pv
index 68f8e8586..d02d3a35d 100644
--- a/Completion/Unix/Command/_pv
+++ b/Completion/Unix/Command/_pv
@@ -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
diff --git a/Completion/Unix/Command/_rclone b/Completion/Unix/Command/_rclone
index 27b4dd926..a2e3429f5 100644
--- a/Completion/Unix/Command/_rclone
+++ b/Completion/Unix/Command/_rclone
@@ -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)' \
diff --git a/Completion/Unix/Command/_rsync b/Completion/Unix/Command/_rsync
index b1a4f6046..eb906e974 100644
--- a/Completion/Unix/Command/_rsync
+++ b/Completion/Unix/Command/_rsync
@@ -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' \
diff --git a/Completion/Unix/Command/_stdbuf b/Completion/Unix/Command/_stdbuf
index a18938ee1..4b7d98ba0 100644
--- a/Completion/Unix/Command/_stdbuf
+++ b/Completion/Unix/Command/_stdbuf
@@ -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}" )
diff --git a/Completion/Unix/Command/_tail b/Completion/Unix/Command/_tail
index 6d6e9b2d5..e54a0b06e 100644
--- a/Completion/Unix/Command/_tail
+++ b/Completion/Unix/Command/_tail
@@ -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
diff --git a/Completion/Unix/Command/_timeout b/Completion/Unix/Command/_timeout
index 2235fa5ec..c041283ac 100644
--- a/Completion/Unix/Command/_timeout
+++ b/Completion/Unix/Command/_timeout
@@ -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'
diff --git a/Completion/Unix/Command/_zfs b/Completion/Unix/Command/_zfs
index 452e1160d..51da9170b 100644
--- a/Completion/Unix/Command/_zfs
+++ b/Completion/Unix/Command/_zfs
@@ -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"'
 		;;