From 1939db10afe726c5e44ff88a6bd396a396eaa1f6 Mon Sep 17 00:00:00 2001 From: Frederick Zhang Date: Wed, 17 Jun 2020 09:59:58 -0400 Subject: 45982: _zfs: add space property --- Completion/Unix/Command/_zfs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Completion/Unix/Command/_zfs') diff --git a/Completion/Unix/Command/_zfs b/Completion/Unix/Command/_zfs index 814358bc7..452e1160d 100644 --- a/Completion/Unix/Command/_zfs +++ b/Completion/Unix/Command/_zfs @@ -133,7 +133,7 @@ _zfs() { # TODO: userused@ and groupused@ could have more extensive handling ro_properties=( - "name" "type" "creation" "used" "available" "referenced" + "name" "type" "creation" "space" "used" "available" "referenced" "compressratio" "mounted" "origin" "usedbychildren" "usedbydataset" "usedbyrefreservation" "usedbysnapshots" "defer_destroy" "userused@" "userrefs" "groupused@" -- cgit v1.2.3 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 --- ChangeLog | 14 +++++++ Completion/BSD/Command/_ipfw | 4 +- Completion/Base/Core/_description | 8 ++++ Completion/Base/Utility/_numbers | 87 +++++++++++++++++++++++++++++++++++++++ Completion/Linux/Command/_btrfs | 8 ++-- Completion/Unix/Command/_dd | 14 ++++--- Completion/Unix/Command/_git | 6 +-- Completion/Unix/Command/_head | 22 ++++------ Completion/Unix/Command/_killall | 12 ++---- Completion/Unix/Command/_pv | 18 ++------ Completion/Unix/Command/_rclone | 10 ++--- Completion/Unix/Command/_rsync | 10 ++--- Completion/Unix/Command/_stdbuf | 6 ++- Completion/Unix/Command/_tail | 22 ++++------ Completion/Unix/Command/_timeout | 2 +- Completion/Unix/Command/_zfs | 20 ++++++--- Completion/X/Command/_xset | 4 +- Doc/Zsh/compsys.yo | 81 +++++++++++++++++++++++++++++++++++- 18 files changed, 258 insertions(+), 90 deletions(-) create mode 100644 Completion/Base/Utility/_numbers (limited to 'Completion/Unix/Command/_zfs') diff --git a/ChangeLog b/ChangeLog index bb8b73085..d7b225d42 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +2021-11-24 Oliver Kiddle + + * 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 * 49586: Src/hist.c: fix :a and :A modifiers (with PWD="/") on diff --git a/Completion/BSD/Command/_ipfw b/Completion/BSD/Command/_ipfw index 2354a70fe..49d0ef1e8 100644 --- a/Completion/BSD/Command/_ipfw +++ b/Completion/BSD/Command/_ipfw @@ -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)"' 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 diff --git a/Completion/Linux/Command/_btrfs b/Completion/Linux/Command/_btrfs index bb0f724e6..65cf067aa 100644 --- a/Completion/Linux/Command/_btrfs +++ b/Completion/Linux/Command/_btrfs @@ -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' ) ;; 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"' ;; diff --git a/Completion/X/Command/_xset b/Completion/X/Command/_xset index b35a6466b..adda47f01 100644 --- a/Completion/X/Command/_xset +++ b/Completion/X/Command/_xset @@ -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" \ diff --git a/Doc/Zsh/compsys.yo b/Doc/Zsh/compsys.yo index 8c6bf9c40..40238c4b9 100644 --- a/Doc/Zsh/compsys.yo +++ b/Doc/Zsh/compsys.yo @@ -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 -- cgit v1.2.3 From 85bf9740a01e168b7b814469892d97fdabc67144 Mon Sep 17 00:00:00 2001 From: Oliver Kiddle Date: Wed, 29 Dec 2021 00:22:33 +0100 Subject: 49668: update zfs completion --- ChangeLog | 7 +- Completion/Unix/Command/_zfs | 1911 ++++++++++++++++++++--------- Completion/Unix/Command/_zpool | 311 ----- Completion/Unix/Type/_zfs_dataset | 15 +- Completion/Unix/Type/_zfs_keysource_props | 15 - 5 files changed, 1365 insertions(+), 894 deletions(-) delete mode 100644 Completion/Unix/Command/_zpool delete mode 100644 Completion/Unix/Type/_zfs_keysource_props (limited to 'Completion/Unix/Command/_zfs') diff --git a/ChangeLog b/ChangeLog index f65822e88..9a79ff2d9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,9 @@ - 2021-12-24 Bart Schaefer +2021-12-29 Oliver Kiddle + + * 49668: Completion/Unix/Command/_zfs, + Completion/Unix/Type/_zfs_dataset: update zfs completion + +2021-12-24 Bart Schaefer * m0viefreak: 38150: Src/Zle/compmatch.c: fix off-by-one error in matcher spec parsing diff --git a/Completion/Unix/Command/_zfs b/Completion/Unix/Command/_zfs index 51da9170b..be4a64b33 100644 --- a/Completion/Unix/Command/_zfs +++ b/Completion/Unix/Command/_zfs @@ -1,561 +1,1350 @@ -#compdef zfs -# Synced with the S11U1 man page - -_zfs() { - local context state line expl implementation - typeset -A opt_args - local -a subcmds rw_properties rw_propnames ro_properties create_properties - local -a share_nfs_ro_properties share_nfs_rw_properties - local -a share_smb_ro_properties share_smb_rw_properties - local -a share_ro_properties share_rw_properties - local -a difffields delegatable_perms - - _pick_variant -r implementation -c 'zpool upgrade -v' openzfs='This system supports ZFS pool feature flags' solaris - - subcmds=( - "create" "destroy" "clone" "promote" "rename" "snapshot" - "rollback" "list" "set" "get" "inherit" "mount" "unmount" - "share" "unshare" "send" "receive" "allow" "unallow" - "upgrade" "userspace" "groupspace" "hold" "holds" "release" - "diff" "key" "help" - ) - - [[ $OSTYPE == freebsd<7->.* ]] && subcmds+=(jail unjail) - - share_nfs_ro_properties=( - "share.nfs.all" - ) - - share_nfs_rw_properties=( - "share.nfs:value:(on off)" - "share.nfs.aclok:value:(on off)" - "share.nfs.acflfab:value:(on off)" - "share.nfs.anon:uid:" - "share.nfs.charset.euc-cn:access-list:" - "share.nfs.charset.euc-jpms:access-list:" - "share.nfs.charset.euc-kr:access-list:" - "share.nfs.charset.euc-tw:access-list:" - "share.nfs.charset.iso8859-1:access-list:" - "share.nfs.charset.iso8859-2:access-list:" - "share.nfs.charset.iso8859-5:access-list:" - "share.nfs.charset.iso8859-6:access-list:" - "share.nfs.charset.iso8859-7:access-list:" - "share.nfs.charset.iso8859-8:access-list:" - "share.nfs.charset.iso8859-9:access-list:" - "share.nfs.charset.iso8859-13:access-list:" - "share.nfs.charset.iso8859-15:access-list:" - "share.nfs.charset.koi8-r:access-list:" - "share.nfs.index:file:_files" - "share.nfs.log:nfslog.conf tag:" - "share.nfs.nosub:value:(on off)" - "share.nfs.nosuid:value:(on off)" - "share.nfs.public:value:(on off)" - "share.nfs.sec:security-mode-list:" - "share.nfs.sec.default.none:access-list:" - "share.nfs.sec.default.ro:access-list:" - "share.nfs.sec.default.root:access-list:" - "share.nfs.sec.default.root_mapping:uid:" - "share.nfs.sec.default.rw:access-list:" - "share.nfs.sec.default.window:seconds" - "share.nfs.sec.dh.none:access-list:" - "share.nfs.sec.dh.ro:access-list:" - "share.nfs.sec.dh.root:access-list:" - "share.nfs.sec.dh.root_mapping:uid:" - "share.nfs.sec.dh.rw:access-list:" - "share.nfs.sec.dh.window:seconds" - "share.nfs.sec.krb5.none:access-list:" - "share.nfs.sec.krb5.ro:access-list:" - "share.nfs.sec.krb5.root:access-list:" - "share.nfs.sec.krb5.root_mapping:uid:" - "share.nfs.sec.krb5.rw:access-list:" - "share.nfs.sec.krb5.window:seconds" - "share.nfs.sec.krb5i.none:access-list:" - "share.nfs.sec.krb5i.ro:access-list:" - "share.nfs.sec.krb5i.root:access-list:" - "share.nfs.sec.krb5i.root_mapping:uid:" - "share.nfs.sec.krb5i.rw:access-list:" - "share.nfs.sec.krb5i.window:seconds" - "share.nfs.sec.krb5p.none:access-list:" - "share.nfs.sec.krb5p.ro:access-list:" - "share.nfs.sec.krb5p.root:access-list:" - "share.nfs.sec.krb5p.root_mapping:uid:" - "share.nfs.sec.krb5p.rw:access-list:" - "share.nfs.sec.krb5p.window:seconds" - "share.nfs.sec.none.none:access-list:" - "share.nfs.sec.none.ro:access-list:" - "share.nfs.sec.none.root:access-list:" - "share.nfs.sec.none.root_mapping:uid:" - "share.nfs.sec.none.rw:access-list:" - "share.nfs.sec.none.window:seconds" - "share.nfs.sec.sys.none:access-list:" - "share.nfs.sec.sys.ro:access-list:" - "share.nfs.sec.sys.root:access-list:" - "share.nfs.sec.sys.root_mapping:uid:" - "share.nfs.sec.sys.rw:access-list:" - "share.nfs.sec.sys.window:seconds" - ) - - share_smb_ro_properties=( - "share.smb.all" - ) - - share_smb_rw_properties=( - "share.smb:value:(on off)" - "share.smb.ad-container" - "share.smb.abe" - "share.smb.csc:value:(disabled manual auto vdo)" - "share.smb.catia:value:(on off)" - "share.smb.dfsroot:value:(on off)" - "share.smb.guestok:value:(on off)" - "share.smb.ro:access-list:" - "share.smb.rw:access-list:" - "share.smb.none:access-list:" - ) - - share_ro_properties=( - "share.all" - "share.fs" - "share.name" - "share.point" - "share.protocols" - "share.state" - $share_nfs_ro_properties - $share_smb_ro_properties - ) - - share_rw_properties=( - "share.desc:description:" - "share.noauto:value:(on off)" - "share.path:path:" - $share_nfs_rw_properties - $share_smb_rw_properties - ) - - # TODO: userused@ and groupused@ could have more extensive handling - ro_properties=( - "name" "type" "creation" "space" "used" "available" "referenced" - "compressratio" "mounted" "origin" "usedbychildren" - "usedbydataset" "usedbyrefreservation" "usedbysnapshots" - "defer_destroy" "userused@" "userrefs" "groupused@" - "keychangedate" "keystatus" "rekeydate" - $share_ro_properties - ) - - # TODO: Be cleverer about what values can be set. Is there any way to - # set the sorting for *size properties to false by default? - rw_properties=( - "aclinherit:value:(discard noallow restricted passthrough passthrough-x)" - "atime:value:(on off)" - "canmount:value:(on off noauto)" - "checksum:value:(on off fletcher2 fletcher4 sha256 sha256+mac)" - "compression:value:(on off lzjb lz4 gzip gzip-{1..9} zle)" - "copies:value:(1 2 3)" - "dedup:value:(on off verify sha256 sha256,verify)" - "devices:value:(on off)" - "encryption:value:(off on aes128-ccm aes-192-ccm aes-256-ccm aes-128-gcm aes-192-gcm aes-256-gcm)" - "exec:value:(on off)" - "groupquota@:value:" # TODO: complete group=size|none - "keysource:value:_zfs_keysource_props" - "logbias:value:(latency throughput)" - "mlslabel:value:(none)" # TODO: list sensitivity labels - "mountpoint:path, 'legacy', or 'none':{if [[ -prefix /* ]]; then _path_files -/; else _wanted mountpoints expl 'mountpoint (type \"/\" to start completing paths)' compadd legacy none; fi}" - "multilevel:value:(on off)" - "nbmand:value:(on off)" - "primarycache:value:(all none metadata)" - "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: : _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)" - "shadow:value:" # TODO: complete URI|none - "share:share properties:" - "snapdir:value:(hidden visible)" - "sync:value:(standard always disabled)" - "userquota@:value:" # TODO: complete user=size|none - "version:value:(1 2 3 4 current)" - "volsize:value:" # - "vscan:value:(on off)" - "xattr:value:(on off)" - "zoned:value:(on off)" - $share_rw_properties - ) - - if [[ "$OSTYPE" == "linux-gnu" ]]; then - rw_properties+=("acltype:value:(off noacl posixacl)") - elif [[ "$implementation" == "solaris" ]]; then - rw_properties+=("aclmode:value:(discard mask passthrough)") - else - rw_properties+=("aclmode:value:(discard groupmask passthrough restricted)") - fi - - - create_properties=( - $rw_properties - "casesensitivity:value:(sensitive insensitive mixed)" - "normalization:value:(none formC formD formKC formKD)" - "utf8only:value:(on off)" - "volblocksize:value:(512 1K 2K 4K 8K 16K 32K 64K 128K 256K 512K 1M)" - ) - - delegatable_perms=( - "allow" "clone" "create" "destroy" "diff" "hold" "key" - "keychange" "mount" "promote" "receive" "release" "rename" - "rollback" "send" "share" "snapshot" - "groupused" "userused" "userprop" - ${create_properties%%:*} - ) - - rw_propnames=( ${rw_properties%%:*} ) - - difffields=( - object parent size links linkschange name oldname user group - ctime mtime atime crtime - ) - - if [[ $service == "zfs" ]]; then - _arguments -C -A "-*" \ - '-\?[Help]' \ - '*::command:->subcmd' && return 0 - - if (( CURRENT == 1 )); then - _wanted commands expl "zfs subcommand" compadd -a subcmds - return - fi - service="$words[1]" - curcontext="${curcontext%:*}=$service:" - fi - - case $service in - ("create") - _arguments -A "-*" \ - '-p[Create parent datasets]' \ - '*-o[Set initial properties]:property:_values -s , "property" $create_properties' \ - - set1 \ - ':filesystem:_zfs_dataset -t fs -e "parent dataset"' \ - - set2 \ - '-s[Create sparse volume]' \ - '-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"' - ;; - - ("destroy") - _arguments -A "-*" \ - '-r[Recursively destroy all children]' \ - '-R[Recursively destroy all dependents]' \ - - set1 \ - '-d[delete or mark deferred]' \ - ':snapshot:_zfs_dataset -t snap' \ - - set2 \ - '-f[Force unmounts]' \ - ':filesystem/volume/snapshot:_zfs_dataset -t fs -t vol' - ;; - - (snap(|shot)) - _arguments -A "-*" \ - '-r[Recursively snapshot all descendant datasets]' \ - '*-o[Set property]:property:_values -s , "property" $create_properties' \ - ':filesystem/volume:_zfs_dataset -t fs -t vol -S@' - ;; - - ("rollback") - _arguments -A "-*" \ - '-r[Recursively destroy more recent snapshots]' \ - '-R[Recursively destroy more recent snapshots and clones]' \ - '-f[Force unmounts]' \ - ':snapshot:_zfs_dataset -t snap' - ;; - - ("clone") - # XXX needs to bail if there are no snapshots - _arguments -A "-*" \ - '-p[Create parent datasets]' \ - '-K[Create encryption key]' \ - '*-o[Set property]:property:_values -s , "property" $create_properties' \ - ':snapshot:_zfs_dataset -t snap' \ - ':filesystem/volume:_zfs_dataset -t fs -e "parent dataset"' - ;; - - ("promote") - _arguments \ - ':filesystem:_zfs_dataset -t clone' \ - ;; - - ("rename") - _arguments -A "-*" \ - '(-r)-p[Create parent datasets]' \ - '(-p)-r[Recursively rename snapshots of all descendent datasets]' \ - ':dataset:_zfs_dataset -r1' \ - ':dataset:_zfs_dataset -r2' - ;; - - ("list") - _arguments -A "-*" \ - '-r[Recursively display children]' \ - '-H[Scripting mode]' \ - '-d[Depth]:value:' \ - '-o[Properties to list]:property:_values -s , "property" $ro_properties $rw_propnames' \ - '*-s[Sort key (ascending)]:property:_values "property" $ro_properties $rw_propnames' \ - '*-S[Sort key (descending)]:property:_values "property" $ro_properties $rw_propnames' \ - '-t[Dataset types to list]:dataset type:_values -s , "dataset type" all filesystem snapshot volume' \ - '*:filesystem/volume/snapshot/path:_zfs_dataset -p' - ;; - - ("set") - _arguments \ - '-r[Recursively apply value]' \ - ':property:_values -s , "property" $rw_properties' \ - '*:filesystem/volume:_zfs_dataset -t fs -t vol' - ;; - - ("get") - _arguments -A "-*" \ - "-r[Recursively display children's properties]" \ - '-d[Depth]:value:' \ - '-H[Scripting mode]' \ - '-p[Display numbers exactly]' \ - '-s[Specify sources]:source:_values -s , "source" local default inherited temporary none' \ - '-o[Specify fields]:field:_values -s , "field" name property value source' \ - ':property:_values -s , "property" $ro_properties $rw_propnames all' \ - '*:filesystem/volume/snapshot:_zfs_dataset' - ;; - - ("inherit") - _arguments -A "-*" \ - '-r[Recursively inherit property for all children]' \ - '-S[Revert to received property value]' \ - ':property:_values -s , "property" $ro_properties $rw_properties' \ - '*:filesystem/volume:_zfs_dataset -t fs -t vol' - ;; - - ("userspace"|"groupspace") - _arguments -A "-*" \ - '-n[Print numeric ID]' \ - '-i[Translate SID to POSIX ID]' \ - '-H[Tab-delimited output with no headers]' \ - '-p[Parseable mode]' \ - '-o[Properties to list]:property:_values -s , "property" type name used quota' \ - '*-s[Sort key (ascending)]:property:_values "property" type name used quota' \ - '*-S[Sort key (descending)]:property:_values "property" type name used quota' \ - '-t[Types to list]:type:_values -s , "type" all posixuser smbuser posixgroup smbgroup' \ - '*:filesystem/volume/snapshot:_zfs_dataset' - ;; - - ("mount") - _arguments -A "-*" \ - '-o[Mount options]:mount options:_values -s , "option" {,no}{devices,exec,setuid} ro rw' \ - '-O[Overlay mount]' \ - '-v[Report mount progress]' \ - - set1 \ - ':filesystem:_zfs_dataset -t fs' \ - - set2 \ - '-a[Mount all available ZFS filesystems]' - ;; - - ("unmount") - _arguments -A "-*" \ - - set1 \ - '-f[Force unmount]' \ - ':filesystem:_zfs_dataset -t fs -t mtpt' \ - - set2 \ - '-a[Unmount all ZFS filesystems]' - ;; - - ("share") - _arguments -A "-*" \ - - set1 \ - '-a[Share all available ZFS filesystems]' \ - - set2 \ - '-r[Share filesystems recursively]' \ - ':filesystem:_zfs_dataset -t fs' \ - - set3 \ - '*-o[Create a share with these properties]:property:_values -w "share properties" $share_rw_properties' \ - '-u[Create a share without sharing it]' \ - ':filesystem:_zfs_dataset -t fs' \ - - set4 \ - ':filesystem:_zfs_dataset -t fs -t mtpt -t share' - ;; - - ("unshare") - _arguments -A "-*" \ - - set1 \ - '-a[Unshare all shared ZFS filesystems]' \ - - set2 \ - '-r[Unshare filesystems recursively]' \ - ':filesystem:_zfs_dataset -t fs' \ - - set3 \ - ':filesystem:_zfs_dataset -t fs -t mtpt -t share' - ;; - - ("send") - _arguments -A "-*" \ - '-b' \ - '-i[Generate an incremental stream]:snapshot:_zfs_dataset -t snap' \ - '-D[Perform dedup processing]' \ - '-p[Send properties]' \ - '-v[Verbose]' \ - - set1 \ - '-I[Generate an incremental stream with intermediary snapshots]:snapshot:_zfs_dataset -t snap' \ - '-R[Generate a replication stream package]' \ - ':snapshot:_zfs_dataset -t snap' \ - - set2 \ - '-c[Create a self-contained stream]' \ - '-r[Generate a recursive stream package]' \ - ':snapshot:_zfs_dataset -t snap' - ;; - - ("receive") - _arguments -A "-*" \ - '-v[Verbose]' \ - '-n[Do not receive the stream]' \ - '-F[Force a rollback if necessary]' \ - '-u[Filesystem is not mounted]' \ - '-o[Include property change in the stream]::' \ - '-x[Exclude property change from the stream]:property:' \ - - set1 \ - ':filesystem/volume/snapshot:_zfs_dataset' \ - - set2 \ - '(-e)-d[Set path prefix from stream, excluding only pool name]' \ - '(-d)-e[Set path prefix from stream, using last path element]' \ - '-:filesystem:_zfs_dataset -t fs' - ;; - - ("allow") - _arguments -A "-*" \ - '(1 -g -e -c -s)-u[delegate to user]:user:_users' \ - '(1 -u -e -c -s)-g[delegate to group]:group:_groups' \ - '(1 -g -u -c -s)-e[delegate to everyone]' \ - '(1 -u -g -e -l -d -s)-c[set permissions for newly-created descendant filesystems]' \ - '(1 -u -g -e -l -d -c)-s[define or modify permission sets]:permission set' \ - '(1 -c -s)-l[allow for named dataset]' \ - '(1 -c -s)-d[allow for descendent datasets]' \ - '1::filesystem/volume:_zfs_dataset -t fs -t vol' \ - ':permissions or sets:_values -s , "permission or set" $delegatable_perms' \ - ':filesystem/volume:_zfs_dataset -t fs -t vol' \ - ;; - - ("unallow") - _arguments -A "-*" \ - '-r[Recursive removal]' \ - - set1 \ - '-s[Remove permissions from or delete a permission set]:permission set:' \ - ':permissions or sets:_values -s , "permission or set" $delegatable_perms' \ - ':filesystem/volume:_zfs_dataset -t fs -t vol' \ - - set2 \ - '(-g)-u[User]:user:_users' \ - '(-u)-g[Group]:group:_groups' \ - '-l[Allow for named dataset]' \ - '-d[Allow for descendent datasets]' \ - ':permissions or sets:_values -s , "permission or set" $delegatable_perms' \ - ':filesystem/volume:_zfs_dataset -t fs -t vol' \ - - set3 \ - '-e[Everyone]' \ - '-l[Allow for named dataset]' \ - '-d[Allow for descendent datasets]' \ - ':permissions or sets:_values -s , "permission or set" $delegatable_perms' \ - ':filesystem/volume:_zfs_dataset -t fs -t vol' \ - - set4 \ - '-c[Create-time permissions]' \ - ':permissions or sets:_values -s , "permission or set" $delegatable_perms' \ - ':filesystem/volume:_zfs_dataset -t fs -t vol' - ;; - - ("upgrade") - _arguments -A "-*" \ - - set1 \ - '-v[Verbose]' \ - - set2 \ - '-a[Upgrade all filesystems on all pools]' \ - '-r[Upgrade descendent filesystems, too]' \ - '-V[Upgrade to specified version]:version:(1 2)' \ - - set3 \ - '-r[Upgrade descendent filesystems, too]' \ - '-V[Upgrade to specified version]:version:(1 2)' \ - ':filesystem:_zfs_dataset -t fs' - ;; - - ("hold") - _arguments -A "-*" \ - '-r[Apply hold recursively]' \ - ':tag:' \ - ':snapshot:_zfs_dataset -t snap' - ;; - - ("holds") - _arguments -A "-*" \ - '-r[List holds recursively]' \ - ':snapshot:_zfs_dataset -t snap' - ;; - - ("release") - _arguments -A "-*" \ - '-r[Release holds recursively]' \ - ':tag:' \ - ':snapshot:_zfs_dataset -t snap' - ;; - - ("diff") - _arguments -A "-*" \ - '-F[Add column for filetype character]' \ - '-H[Parseable output]' \ - '-e[Only show new and changed files]' \ - '*-o[Show fields]:field:_values "field" $difffields' \ - '-t[Add column for ctime]' \ - - set1 \ - ':snapshot:_zfs_dataset -t snap' \ - ':snapshot or filesystem:_zfs_dataset -t snap -t fs' \ - - set2 \ - '-E[Show difference from empty]' \ - ':snapshot or filesystem:_zfs_dataset -t snap -t fs' - ;; - - ("key") - _arguments -A "-*" \ - - set1 \ - '-a[Apply to all datasets in all pools]' \ - '(-u -K -f)-l[Load the encryption key]' \ - '(-l -K)-u[Unload the encryption key]' \ - '(-l -u -f)-K[Create a new data encryption key]' \ - '(-l -K)-f[Unmount the dataset before unloading the encryption key]' \ - '-r[Apply recursively]' \ - ':filesystem or volume:_zfs_dataset -t fs -t vol' \ - - set2 \ - '-c[Change the encryption key]' \ - '-o[Change a property]:property:_zfs_keysource_props' \ - ':filesystem or volume:_zfs_dataset -t fs -t vol' - ;; - - ("jail"|"unjail") - _arguments \ - '1: : _jails' \ - '2:filesystem:_zfs_dataset -t fs' - ;; - - ("help") - _arguments -A "-*" \ - - set1 \ - ':command:($subcmds $delegatable_perms $ro_properties ${rw_properties%%:*} properties)' \ - - set2 \ - '-l[Display property information]' \ - ': :(properties)' - ;; - - (*) - _message "unknown zfs subcommand: $service" - ;; - esac -} - -_zfs "$@" +#compdef zfs zdb zpool + +local curcontext="$curcontext" implementation nm="$compstate[nmatches]" +local -a state curstate line state_descr expl alts args +typeset -A opt_args val_args +local MATCH MBEGIN MEND +local -a subcmds +local -a share_nfs_ro_properties share_nfs_rw_properties +local -a share_smb_ro_properties share_smb_rw_properties +local -a share_ro_properties share_rw_properties +local -a difffields delegatable_perms key_properties +local -a ds_types sum_algorithms comp_algorithms dedup_algorithms + +local -a ds_propnames ro_ds_props rw_ds_props ci_ds_props # dataset properties +local -a po_propnames ro_po_props rw_po_props ci_po_props # pool properties + +_pick_variant -r implementation -c 'zpool upgrade -v' openzfs='This system supports ZFS pool feature flags' solaris + +ds_types=( filesystem snapshot volume all ) +sum_algorithms=( on off fletcher2 fletcher4 sha256 ) +comp_algorithms=( on off lzjb lz4 gzip gzip-{1..9} zle ) +dedup_algorithms=( on off verify sha256 sha256,verify ) + +ro_po_props=( # readonly + 'all[all properties]' + 'allocated[space allocated]' + 'capacity[space used (percentage)]' + 'dedupratio[deduplication ratio]' + 'free[space unallocated]' + 'health[health status]' + 'size[total size]' +) +ci_po_props=( # only set at create or import + 'altroot[alternate root directory]:path:_directories' + 'guid[unique identifier]:identifier' + 'readonly[whether the pool can be modified]:value:(on off)' +) +rw_po_props=( + 'autoexpand[automatic pool expansion]:value:(on off)' + 'autoreplace[automatic device replacement]:value:(on off)' + 'bootfs[default bootable dataset]:dataset:_zfs_dataset' + 'cachefile[pool configuration cache file location]:value' + 'dedupditto[threshold for number of copies]:value [0]' + 'delegation[delegated administration]:value:(on off)' + 'failmode[failure-mode behavior]:value:(wait continue panic)' + "listshares[show shares in 'zfs list']:value:(on off)" + "listsnaps[show snapshots in 'zfs list']:value:(on off)" + 'version[pool version]:version' +) + +# TODO: userused@ and groupused@ could have more extensive handling +ro_ds_props=( + name type creation space used available referenced compressratio mounted + origin usedbychildren usedbydataset usedbyrefreservation usedbysnapshots + defer_destroy userused@ userrefs groupused@ keystatus +) +ci_ds_props=( + 'casesensitivity:value:(sensitive insensitive mixed)' + 'normalization:value:(none formC formD formKC formKD)' + 'utf8only:value:(on off)' +) +rw_ds_props=( + 'aclinherit:value:(discard noallow restricted passthrough passthrough-x)' + 'atime:value:(on off)' + 'canmount:value:(on off noauto)' + "checksum:value:($sum_algorithms)" + "compression:value:($comp_algorithms)" + 'copies:value:(1 2 3)' + "dedup:value:($dedup_algorithms)" + 'devices:value:(on off)' + 'encryption:value:(off on aes128-ccm aes-192-ccm aes-256-ccm aes-128-gcm aes-192-gcm aes-256-gcm)' + 'exec:value:(on off)' + 'groupquota@' + 'logbias:value:(latency throughput)' + "mountpoint: : _alternative \ + 'properties:property:(none legacy)' \ + 'paths:mountpoint:_directories -W / -P /'" + 'multilevel:value:(on off)' + 'nbmand:value:(on off)' + 'primarycache:value:(all none metadata)' + 'quota: :->quotas' + 'readonly:value:(on off)' + 'recordsize:value:(512 1K 2K 4K 8K 16K 32K 64K 128K 256K 512K 1M)' + 'refquota: :->quotas' + "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: :->quotas' + 'rstchown:value:(on off)' + 'secondarycache:value:(all none metadata)' + 'setuid:value:(on off)' + 'shadow:value' # TODO: complete URI|none + 'share:share properties' + 'snapdir:value:(hidden visible)' + 'sync:value:(standard always disabled)' + 'userquota@' + 'version:value' + 'volsize:size:_numbers -M "m:{a-zA-Z}={A-Za-z}" -u bytes size :B {k,M,G,T,P,E,Z}{,B}' +) + +case $service:$implementation in + *:openzfs) + ds_types+=( bookmark ) + sum_algorithms+=( noparity sha512 skein edonr ) + comp_algorithms+=( zstd zstd-{1..19} zstd-fast zstd-fast-{{1..9}{,0},100,500,1000} ) + dedup_algorithms+=( {sha512,skein}{,\,verify} edonr,verify ) + share_rw_properties=( sharesmb:option sharenfs:option ) + ro_po_props+=( + 'expandsize[uninitialized space within the pool]' + 'fragmentation[amount of fragmentation in the pool]' + 'freeing[amount of space remaining to be reclaimed]' + 'used[amount of storage space used within the pool]' + 'load_guid[unique identifier generated when pool is loaded]' + ) + ci_po_props+=( + 'ashift[pool sector size exponent]:exponent:((9\:512 10\:1024 11\:2048 12\:4096 13\:8192 14\:16384 15\:32768 16\:65536))' + ) + rw_po_props+=( + 'autotrim[periodically trim recently freed space]:value:(on off)' + 'comment[text string that is available even if the pool becomes faulted]:value' + 'multihost[perform pool activity check during import]:value:(on off)' + ) + rw_ds_props+=( + 'aclmode:value:(discard groupmask passthrough restricted)' + 'acltype:value:(off noacl nfsv4 posix posixacl)' + 'mlslabel:value:(none)' # TODO: list sensitivity labels + 'redundant_metadata:value:(all most)' + 'vscan:value:(on off)' + 'xattr:value:(on off dir sa)' + "filesystem_limit: :{if [[ -prefix [0-9]## ]]; then _message -e 'number'; elif [[ -prefix n ]]; then compadd none; else _message -e limits 'number or none'; fi}" + "snapshot_limit: :{if [[ -prefix [0-9]## ]]; then _message -e 'number'; elif [[ -prefix n ]]; then compadd none; else _message -e limits 'number or none'; fi}" + 'volmode:mode:(( + default\:use\ system-wide\ tunable + full\:expose\ as\ block\ devices + geom\:expose\ as\ block\ devices + dev\:hide\ partitions + none\:not\ exposed\ outside\ zfs + ))' + ) + ro_ds_props+=( + createtxg clones filesystem_count guid logicalreferenced logicalused + receive_resume_token refcompressratio snapshot_count volblocksize written + ) + delegatable_perms=( + bookmark load-key change-key userobjquota userobjused groupobjquota + groupobjused projectused projectquota projectobjused projectobjquota + ) + ;| + *:solaris) + ds_types+=( share ) + sum_algorithms+=( sha256+mac ) + share_nfs_ro_properties=( share.nfs.all ) + share_nfs_rw_properties=( + 'share.nfs:value:(on off)' + 'share.nfs.aclok:value:(on off)' + 'share.nfs.aclfab:value:(on off)' + 'share.nfs.anon:uid' + 'share.nfs.charset.'{cp932,euc-{cn,jpns,kr,tw},iso8859-{1,2,5,6,7,8,9,13,15},koi8-r,shift_jis}':access-list' + 'share.nfs.index:file:_files' + 'share.nfs.labeled:value:(on off)' + 'share.nfs.noaclfab:value:(on off)' + 'share.nfs.log:nfslog.conf tag' + 'share.nfs.nosub:value:(on off)' + 'share.nfs.nosuid:value:(on off)' + 'share.nfs.public:value:(on off)' + 'share.nfs.sec:security-mode-list' + 'share.nfs.sec.'{default,dh,krb5{,i,p},none,sys}.{ro,root,rw}':access-list' + 'share.nfs.sec.'{default,dh,krb5{,i,p},none,sys}.root_mapping':uid' + 'share.nfs.sec.'{default,dh,krb5{,i,p},none,sys}.window':credential lifetime (seconds)' + 'share.nfs.sec.sys.resvport:value:(on off)' + ) + share_smb_ro_properties=( share.smb.all ) + share_smb_rw_properties=( + 'share.smb:value:(on off)' + 'share.smb.abe' + 'share.smb.ad-container' + 'share.smb.catia:value:(on off)' + 'share.smb.csc:value:(disabled manual auto vdo)' + 'share.smb.dfsroot:value:(on off)' + 'share.smb.encrypt:value:(on off)' + 'share.smb.guestok:value:(on off)' + 'share.smb.oplocks:value:(disabled enabled)' + 'share.smb.cont_avail:value:(on off)' + 'share.smb.'{none,ro,rw}':access-list' + ) + share_ro_properties=( + share.all share.fs share.name share.point share.protocols share.state + $share_nfs_ro_properties $share_smb_ro_properties + ) + share_rw_properties=( + 'share.desc:description' + 'share.auto:value:(on off)' + 'share.autoname:value' + 'share.nfs.cksum:value' + 'share.path:path' + $share_nfs_rw_properties $share_smb_rw_properties + ) + ro_po_props+=( + 'lastscrub[start time of the last successful scrub]' + ) + rw_po_props+=( + 'clustered[pool is imported as a global pool in Oracle Solaris Cluster]:value:(on off)' + 'scrubinternal[time interval between scheduled scrubs]:interval' + ) + ro_ds_props+=( keychangedate rekeydate effective{read,write}limit ) + rw_ds_props+=( + 'aclmode:value:(discard mask passthrough)' + "defaultreadlimit: : _alternative \ + 'sizes: :_guard \[0-9\]\#\(\|\[BKMGTPEZ\]\) size\ \(bytes\ per\ second\)' \ + 'properties:property:(none)'" + "defaultwritelimit: : _alternative \ + 'sizes: :_guard \[0-9\]\#\(\|\[BKMGTPEZ\]\) size\ \(bytes\ per\ second\)' \ + 'properties:property:(none)'" + 'defaultuserquota:->quotas' + 'defaultgroupquota: :->quotas' + 'keysource:value:->keysources' + ) + ci_ds_props+=( + 'volblocksize:value:compadd -o nosort 512 1K 2K 4K 8K 16K 32K 64K 128K 256K 512K 1M' + ) + difffields=( + object parent size links linkschange name oldname user group + ctime mtime atime crtime mountpoint dataset_name + ) + delegatable_perms=( key keychange ) + ;| + zfs:openzfs) + subcmds+=( + bookmark change-key load-key program project projectspace redact + unload-key wait + ) + ;| + zpool:openzfs) + subcmds+=( + checkpoint events labelclear initialize reopen resilver sync trim wait + version + ) + ;| + zfs:solaris) + subcmds+=( key help ) + ;| + zpool:solaris) + subcmds+=( help label monitor ) + ;| + + zfs:*) + subcmds+=( + create destroy clone promote rename snapshot rollback list set get + inherit mount unmount share unshare send receive allow unallow upgrade + userspace groupspace hold holds release diff + ) + [[ $OSTYPE = freebsd<7->.* ]] && subcmds+=( jail unjail ) + ;; + zpool:*) + subcmds+=( + add attach clear create destroy detach export get history import iostat + list offline online reguid remove replace scrub set split status upgrade + ) + ;; +esac + +case $OSTYPE in + solaris*) + rw_ds_props+=( 'zoned:value:(on off)' ) + ;; + freebsd*) + [[ $OSTYPE = freebsd<-12>.* ]] && subcmds+=( remap ) + rw_ds_props+=( 'jailed:value:(on off)' ) + ;; + linux-gnu) + rw_ds_props+=( 'relatime:value:(on off)' ) + ci_ds_props+=( + {,fs,def,root}'context:SELinux context:_selinux_contexts' + ) + ;; +esac + +delegatable_perms+=( + allow clone create destroy diff hold key keychange mount promote receive + release rename rollback send share snapshot groupquota groupused userprop + userused ${ci_ds_props%%:*} +) + +key_properties=( + 'keylocation:location [prompt]:_files -P file\:// -W /' + 'keyformat:format:(raw hex passphrase)' + 'pbkdf2iters:iterations [350000]' +) + +ro_ds_props+=( $share_ro_properties ) +rw_ds_props+=( $share_rw_properties ) +ci_ds_props+=( $rw_ds_props ) + +ds_propnames=( ${rw_ds_props%%:*} ) +po_propnames=( ${ro_po_props%%:*} ${ci_po_props%%:*} ${rw_po_props%%:*} ) + + +case $service in + zfs|zpool) + _arguments -C -A "-*" \ + '-?[display usage information]' \ + '*::command:->subcmd' && return 0 + + if (( CURRENT == 1 )); then + _wanted commands expl "subcommand" compadd -a subcmds + return + fi + curcontext="${curcontext%:*}-$words[1]:" + ;; + zdb) + if [[ $implementation = openzfs ]]; then + args=( + '-mm[also display free space histogram associated with each metaslab]' + {-mmm,-MM}'[display more free space information]' + {-mmmm,-MMM}'[display every spacemap record]' + '-DD[display a histogram of deduplication statistics]' + '-DDD[display deduplication statistics independently for each table]' + '-DDDD[dump the contents of the deduplication tables describing duplicate blocks]' + '-DDDDD[also dump the contents of the deduplication tables describing unique blocks]' + '-E+[decode and display block from a given embedded block pointer]:word' + '(-l)-ll+[like -l but display L2ARC log blocks]:device:_files' + '(-l -ll)-lll+[like -l but display every configuration, unique or not]:device:_files' + "-q[don't print labels (with -l)]" + '-k[examine the checkpointed state of the pool]' + '-M[display the offset, spacemap, and free space of each metaslab]' \ + '-O+[look up the specified path inside of the dataset]:dataset:_zfs_dataset:path:_files' + '-o+[set the given global libzpool variable]:variable' + '-r+[copy the specified path inside of the dataset to the specified destination]:dataset:_zfs_dataset:path:_files:destination:_files' + '-x+[copy all blocks accessed to files in the specified directory]:directory:_directories' + '-V[attempt verbatim import]' + '-Y[attempt all possible combinations when reconstructing indirect split blocks]' + '-y[perform validation for livelists that are being deleted]' + ) + else + args=( + '-?[display usage information]' + '-M+[dump MOS contents]:contents: _values -s , raw_config all objset dir pool_props metaslab sync_bplist dtl config spares l2cache history errlog_scrub errlog_last bpmap-vdev bpmap_defer_obj dtl-scan ddt2' + '-r[dump datasets recursively]' + '-z[report zombies only]' + '-V[verify DDT xtree block data]' + "-a[don't import l2arc cache data]" + '-f[attempt to force import (with -e)]' + '-w+[specify directory to save shadow copy of all accessed disk locations]: :_directories' + '-x+[set kernel tunable]:tunable' + '-G[dump the contents of the zfs_dbgmsg buffer before exiting]' + '-I[limit the number of outstanding checksum I/Os to the specified value]' + ) + fi + _arguments -A "-*" -S $args \ + '(-C)-b[display block statistics]' \ + '(-C)*-c[verify checksum of metadata blocks]' \ + '(-b -c -d)-C[display configuration information]' \ + '(-C)*-d[display dataset information]' \ + '-h[display pool history]' \ + '-i[display intent log (ZIL) information]' \ + '-l+[read the vdev labels from the specified device]:device:_files' \ + '-m[display the offset, spacemap, and free space of each metaslab]' \ + '-s[report statistics on zdb I/O]' \ + '*-u[also display the uberblocks on the device (with -l)]' \ + '*-v[enable verbose output]' \ + '-D[display deduplication statistics]' \ + '-S[simulate the effects of deduplication, displaying constructed DDT as with -DD]' \ + '-L[disable leak detection and the loading of space maps]' \ + '-R+[read and display a block from the specified device]:device' \ + "-A[don't abort should any assertion fail]" \ + "-AA[enable panic recovery]" \ + '-F[try progressively older transactions until pool is readable]' \ + '-U+[specify cache file to use]:cache file [/etc/zfs/zpool.cache]:_files' \ + '-X[attempt "extreme" transaction rewind]' \ + '-e[operate on an exported pool]' \ + '-p[specify path under which to search for devices (with -e)]:path:_files' \ + '-P[use exact (parsable) numeric output]' \ + '-t+[specify the highest transaction to use when searching for uberblocks]:transaction' \ + '1:pool:_zfs_pool' + return + ;; +esac + +case $service:$words[1] in + zfs:create) + [[ $implementation = openzfs ]] && args=( + '-P[print machine-parsable verbose information about the created dataset]' + '-n[do a dry-run, no dataset will be created]' + '-v[print verbose information about the created dataset]' + ) + _arguments -C -A "-*" -S $args \ + '-p[create parent datasets]' \ + '*-o+[set initial propertyvalue]:property:->create-properties' \ + - set1 \ + ':filesystem:_zfs_dataset -t fs -e "parent dataset"' \ + - set2 \ + '-s[create sparse volume]' \ + '-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"' + ;; + + zfs:destroy) + if [[ $implementation = openzfs ]]; then + args=( + '-n[do a dry-run, no data will be deleted]' + '-p[print machine-parsable verbose information about the deleted data]' + '-v[print verbose information about the deleted data]' + ) + else + args=( '-s[destroy snapshots synchronously - only return when blocks freed]' ) + fi + _arguments -A "-*" -S $args \ + '-r[recursively destroy all children]' \ + '-R[recursively destroy all dependents]' \ + '(-f)-d[delete or mark deferred]' \ + '(-d)-f[force unmounts]' \ + ':dataset:_zfs_dataset -t fs -t vol ${=${opt_args[(i)-f]:--t snap}:/-f/} ${=${opt_args[(i)-*]:--t bookmark}:/-?/}' + ;; + + zfs:snap(|shot)) + _arguments -C -A "-*" -S \ + '-r[recursively snapshot all descendant datasets]' \ + '*-o+[set property]:property:->create-properties' \ + ':filesystem/volume:_zfs_dataset -t fs -t vol -S@' + ;; + + zfs:rollback) + _arguments -A "-*" -S \ + '-r[recursively destroy more recent snapshots]' \ + '-R[recursively destroy more recent snapshots and clones]' \ + '-f[force unmounts]' \ + ':snapshot:_zfs_dataset -t snap' + ;; + + zfs:clone) + [[ $implementation = solaris ]] && args+=( + '-K[create encryption key]' + ) + _arguments -C -A "-*" -S $args \ + '-p[create parent datasets]' \ + '*-o+[set property]:property:->create-properties' \ + ':snapshot:_zfs_dataset -t snap' \ + ':filesystem/volume:_zfs_dataset -t fs -e "parent dataset"' + ;; + + zfs:promote) + _arguments \ + ':filesystem:_zfs_dataset -t clone' \ + ;; + + zfs:rename) + [[ $implementation = openzfs ]] && args=( + '(-r -u)-f[force unmount any filesystems]' + "(-r -f)-u[don't remount file systems during rename]" + ) + _arguments -A "-*" -S $args \ + '(-r)-p[create parent datasets]' \ + '(-p -u -f)-r[recursively rename snapshots of all descendent datasets]' \ + ':dataset:_zfs_dataset -r1' \ + ':dataset:_zfs_dataset -r2' + ;; + + zfs:bookmark) + _arguments \ + ':snapshot or bookmark:_zfs_dataset -t snap -t bookmark' \ + ':bookmark' + ;; + + zfs:program) + _arguments -A "-*" -S \ + '-j[display channel program output in JSON format]' \ + '-n[execute a read-only channel program]' \ + '-t+[limit the number of Lua instructions to execute]:instruction limit' \ + '-m+[specify memory limit]:memory limit (bytes) [10MB]' \ + ':pool:_zfs_pool' \ + ':script:_files' \ + '*: :_default' + ;; + + zfs:list) + if [[ $implementation = solaris ]]; then + args=( '-I+[specify dataset states to display instead of normal datasets]:dataset state:_sequence compadd - receiving resumable hidden all' ) + else + args=( '-p[use exact (parsable) numeric output]' ) + fi + _arguments -A "-*" -S $args \ + '(-d)-r[recursively display children]' \ + '-H[suppress printing of headers]' \ + '(-r)-d+[depth]:value' \ + '-o+[specify properties to list]: :_values -s , "property" $ro_ds_props $ds_propnames' \ + '*-s+[specify sort key (ascending)]: :_values "property" $ro_ds_props $ds_propnames' \ + '*-S+[specify sort key (descending)]: :_values "property" $ro_ds_props $ds_propnames' \ + '-t+[specify dataset types to list]: :_values -s , "dataset type" $ds_types' \ + '*:filesystem/volume/snapshot/path:_zfs_dataset -p' + ;; + + zfs:set) + [[ $implementation = solaris ]] && args=( + '-r[recursively apply value]' \ + ) + _arguments -C -A "-*" -S $args \ + ':property:->set-properties' \ + '*:filesystem/volume:_zfs_dataset -t fs -t vol' + ;; + + zfs:get) + if [[ $implementation == openzfs ]]; then + args=( '-t+[specify dataset types to display]: :_values -s , "dataset type" $ds_types' ) + else + args=( '-e[expand property sublists to any depth]' ) + fi + _arguments -A "-*" -S $args \ + "(-d)-r[recursively display children's properties]" \ + '(-r)-d+[depth]:value' \ + '-H[suppress printing of headers]' \ + '-p[use exact (parsable) numeric output]' \ + '-s+[specify sources]: :_values -s , "source" local default inherited received temporary none' \ + '-o+[specify fields]: :_values -s , "field" name property received value source' \ + ':property:_values -s , "property" $ro_ds_props $ds_propnames all' \ + '*:filesystem/volume/snapshot:_zfs_dataset' + ;; + + zfs:inherit) + _arguments -C -A "-*" -S \ + '-r[recursively inherit property for all children]' \ + '-S[revert to received property value]' \ + ':property:_values "property" $ro_ds_props ${rw_ds_props%%:*}' \ + '*:filesystem/volume:_zfs_dataset -t fs -t vol' + ;; + + zfs:remap) + _arguments \ + ':filesystem or volume:_zfs_dataset -t fs -t vol' + ;; + + zfs:upgrade) + _arguments -A "-*" -S \ + '(- :)-v[display supported ZFS versions]' \ + '(-v :)-a[upgrade all filesystems on all pools]' \ + '(-v)-r[upgrade descendent filesystems, too]' \ + '(-v)-V+[upgrade to specified version]:version' \ + '(-a -v):filesystem:_zfs_dataset -t fs' + ;; + + zfs:(user|group)space) + args=( + '-n[print numeric ID]' + '-i[translate SID to POSIX ID]' + ) + ;& # fall-through + zfs:projectspace) + [[ $implementation = solaris ]] && args+=( + '(- *)'{-h,--help}'[display usage information]' + ) + _arguments -A "-*" -S $args \ + '-H[suppress printing of headers, tab-delimit columns]' \ + '-p[use exact (parsable) numeric output]' \ + '-o+[specify properties to list]:property:_values -s , "property" type name used quota' \ + '*-s+[specify sort key (ascending)]: :_values "property" type name used quota' \ + '*-S+[specify sort key (descending)]: :_values "property" type name used quota' \ + '-t+[specify types to list]:type:_values -s , "type" all posixuser smbuser posixgroup smbgroup' \ + '*:filesystem/volume/snapshot:_zfs_dataset' + ;; + + zfs:project) + _arguments -A "-*" -S \ + '(-r -C -k -p -s)-d[act on the directory project ID and inherit flag, not its children]' \ + '(-d)-r[act on subdirectories recursively]' \ + '(-0 -c -d -s)-C[clear project inherit flag and/or ID on the file(s) or directories]' \ + '(-0 -c -d -p -s)-k[keep the project ID unchanged]' \ + '(-k -C -s)-c[check project ID and inherit flag on the file(s) or directories]' \ + '(-k -C -s)-0[print file name with a trailing NUL instead of newline]' \ + '(-k)-p+[specify project ID]:project ID' \ + '(-0 -c -k -C)-s[set project inherit flag on the given file(s) or directories]' \ + '*:file:_files' + ;; + + zfs:mount) + [[ $OSTYPE != freebsd* ]] && args=( '-O[overlay mount]' ) + [[ $implementation = openzfs ]] && args+=( + '-l[load keys for encrypted filesystems as they are being mounted]' + ) + _arguments -A "-*" -S $args \ + '-o+[specify temporary file system options]: :_values -s , "option" {,no}{atime,dev,exec,relatime,suid,xattr} ro rw' \ + '-v[report mount progress]' \ + '-f[force mount]' \ + '(:)-a[mount all available ZFS filesystems]' \ + '(-a):filesystem:_zfs_dataset -t fs' + ;; + + zfs:u(|n)mount) + [[ $implementation = openzfs ]] && args+=( + '-u[unload keys for any unmounted encryption roots]' + ) + _arguments -A "-*" -S $args \ + '-f[force unmount]' \ + '(:)-a[unmount all ZFS filesystems]' \ + '(-a):dataset or mountpoint:_zfs_dataset -t fs -t mtpt' + ;; + + zfs:share) + [[ $implementation = solaris ]] && args=( + - set2 \ + '-r[share filesystems recursively]' \ + ':dataset:_zfs_dataset -t fs' \ + - set3 \ + '*-o+[create a share with specified properties]: :_values -w "share properties" $share_rw_properties' \ + '-u[create a share without sharing it]' \ + ':dataset:_zfs_dataset -t fs' \ + ) + _arguments -A "-*" -S \ + - set1 \ + '-a[share all available ZFS filesystems]' \ + $args \ + - set4 \ + ':dataset or mountpoint:_zfs_dataset -t fs -t mtpt -t share' + ;; + + zfs:unshare) + [[ $implementation = solaris ]] && args=( + - set2 + '-r[unshare filesystems recursively]' + ':filesystem:_zfs_dataset -t fs' + ) + _arguments -A "-*" -S $args \ + - set1 \ + '-a[unshare all shared ZFS filesystems]' \ + - set3 \ + ':filesystem:_zfs_dataset -t fs -t mtpt -t share' + ;; + + zfs:send) + if [[ $implementation = openzfs ]]; then + args=( + '(-L --large-block)'{-L,--large-block}'[generate a stream which may contain blocks larger than 128KB]' + '(-P --parsable)'{-P,--parsable}'[print machine-parsable verbose information about the stream generated]' + '(-e --embed)'{-e,--embed}'[more compact stream for blocks stored with the embedded_data feature]' + '(-c --compressed)'{-c,--compressed}'[more compact stream for compressed blocks]' + '(-h --holds)'{-h,--holds}'[send snapshot holds]' + '-V[set the process title to a per-second report of how much data has been send]' + '-t[create a send stream that resumes an interrupted receive]:resume token' + '(-w --raw)'{-w,--raw}'[keep encrypted data exactly as it exists on disk]' + - redact + '(-h -V -t -w --raw)--redact[generate a redacted send stream]' + - saved + '(-S --saved)'{-S,--saved}'[generate stream from partially received dataset]' + ) + else + args=( + '-w+[send compressed filesystem blocks as compressed in the stream]:compression:(compress none)' + '-m+[limit amount of memory used by deduplication processing]: :_numbers -u bytes "memory size" K M G' + '-s+[set stream options]:token:(streamsize check nocheck memsize)' + '-C[read a receive checkpoint from stdin]' + '-c[create a self-contained stream]' + '(-R)-r[generate a recursive stream package]' + ) + fi + _arguments -A "-*" -S \ + '-b[send only received property values]' \ + '(-I)-i[generate an incremental stream]:snapshot:_zfs_dataset -t snap' \ + '-D[perform dedup processing]' \ + "-n[don't send the stream]" \ + '-p[send properties]' \ + '-v[verbose]' \ + '(-i)-I[generate an incremental stream with intermediary snapshots]:snapshot:_zfs_dataset -t snap' \ + '(-r)-R[generate a replication stream package]' \ + ':snapshot:_zfs_dataset -t snap -t bookmark' \ + $args + ;; + + zfs:redact) + _arguments \ + ':snapshot:_zfs_dataset -t snap' \ + ':bookmark:_zfs_dataset -t bookmark' \ + ':redaction snapshot:_zfs_dataset -t snap' + ;; + + zfs:(receive|recv)) + if [[ $implementation = openzfs ]]; then + args=( + '-h[skip the receive of holds]' + '-s[if the receive is interrupted, save the partially received state]' + '(- set2)-A[abort an interrupted zfs recv -s, deleting its saved partially received state]' + ) + [[ $OSTYPE != linux* ]] && args+=( + '-M[force an unmount of the file system while receiving a snapshot]' + ) + else + args=( '(-)-C[write a receive checkpoint to stdout]' ) + fi + _arguments -A "-*" -S $args \ + '-v[verbose]' \ + "-n[don't receive the stream]" \ + '-F[force a rollback if necessary]' \ + '-u[filesystem is not mounted]' \ + '-o[include property change in the stream]:property' \ + '-x[exclude property change from the stream]:property' \ + - set1 \ + ':filesystem/volume/snapshot:_zfs_dataset' \ + - set2 \ + '(-e)-d[set path prefix from stream, excluding only pool name]' \ + '(-d)-e[set path prefix from stream, using last path element]' \ + ':filesystem:_zfs_dataset -t fs' + ;; + + zfs:allow) + _arguments -C -A "-*" -S \ + '(-g -e -c -s)-u[delegate to user]' \ + '(-u -e -c -s)-g[delegate to group]' \ + '(1 -g -u -c -s)-e[delegate to everyone]' \ + '(1 -u -g -e -l -d -s)-c[set permissions for newly-created descendant filesystems]' \ + '(-u -g -e -l -d -c)-s[define or modify permission sets]:permission set' \ + '(-c -s)-l[allow for named dataset]' \ + '(-c -s)-d[allow for descendent datasets]' \ + '1: :->first' \ + ':permission list:_values -s , "permission or set" $delegatable_perms' \ + ':filesystem/volume:_zfs_dataset -t fs -t vol' + + if [[ -n $state ]]; then + case $opt_args[(I)-[ugs]] in + ^-[ug]) alts+=( 'permission-sets: :_guard "(|@*)" "permission set"' ) ;| + ^-[gs]) alts+=( 'users:user:_users' ) ;| + ^-[us]) alts+=( 'groups:group:_groups' ) ;| + '') + alts+=( + 'all:everyone:(everyone)' + 'filesystems:filesystem/volume:_zfs_dataset -t fs -t vol' + ) + ;; + esac + _alternative $alts + fi + ;; + + zfs:unallow) + _arguments -A "-*" -S \ + '-r[recursive removal]' \ + '(-e -g -s -c)-u[user]' \ + '(-e -u -s -c)-g[group]' \ + '(1 -g -u -s -c)-e[everyone]' \ + '(1 -u -g -e -s -l -d)-c[create-time permissions]' \ + '(-e -u -g -c)-s[remove permissions from or delete a permission set]:permission set' \ + '(-c -s)-l[allow for named dataset]' \ + '(-c -s)-d[allow for descendent datasets]' \ + '1: :->first' \ + '::permissions or sets:_values -s , "permission or set" $delegatable_perms' \ + ':filesystem/volume:_zfs_dataset -t fs -t vol' + + if [[ -n $state ]]; then + case $opt_args[(I)-[ugs]] in + ^-[ug]) alts+=( 'permission-sets: :_guard "(|@*)" "permission set"' ) ;| + ^-[gs]) alts+=( 'users:user:_users' ) ;| + ^-[us]) alts+=( 'groups:group:_groups' ) ;| + '') alts+=( 'all:everyone:(everyone)' ) ;; + esac + _alternative $alts + fi + ;; + + zfs:hold) + _arguments -A "-*" -S \ + '-r[apply hold recursively]' \ + ':tag' \ + ':snapshot:_zfs_dataset -t snap' + ;; + + zfs:holds) + [[ $implementation = openzfs ]] && args=( + '-H[suppress printing of headers, tab-delimit columns]' + ) + [[ $OSTYPE = freebsd<-12>.* ]] && args+=( + # features were lost with the openzfs rebase + '-p[use exact (parsable) numeric output]' + '(-r)-d+[depth]:value' + ) + _arguments -A "-*" -S $args \ + '(-d)-r[list holds recursively]' \ + ':snapshot:_zfs_dataset -t snap' + ;; + + zfs:release) + _arguments -A "-*" -S \ + '-r[release holds recursively]' \ + ':tag' \ + ':snapshot:_zfs_dataset -t snap' + ;; + + zfs:diff) + [[ $implementation = solaris ]] && args=( + '(-E)-e[only show new and changed files, no deleted]' + '*-o+[show specified fields]:field:_values "field" $difffields' + '-q[silence warnings for missing snapshots on recursive datasets]' + '-N[enumerate new child datasets (with -r)]' + '(1 -e)-E[show difference from empty]' + ) + _arguments -A "-*" -S $args \ + '-F[add column for filetype character, similar to ls(1)]' \ + '-H[suppress printing of headers and arrows, tab-delimit columns]' \ + '-t[add column for ctime]' \ + '(-E)1:snapshot:_zfs_dataset -t snap' \ + '2:snapshot or filesystem:_zfs_dataset -t snap -t fs' + ;; + + zfs:wait) + _arguments -A "-*" -S \ + '-t[specify background activity]:activity:(deleteq)' \ + ':filesystem:_zfs_dataset' + ;; + + zfs:key) + _arguments -C -A "-*" -S \ + '-t+[only apply to given dataset type]: :_values -s , "dataset type" $ds_types' \ + '(-u -c -K -f -o)-l[load the encryption key]' \ + "(-u -c -K -f -o)-M[don't mount file systems after loading their keys]" \ + "(-u -c -K -f -o)-S[don't share file systems after loading their keys]" \ + '(-l -c -K -o -M -S)-u[unload the encryption key]' \ + '(-l -c -K -o -M -S)-f[force unmount the dataset before unloading the encryption key]' \ + '(-l -u -K -f -M -S)-c[change the encryption key]' \ + '(-l -u -K -f -M -S)-o+[change a property]:property:->keysources' \ + '(-l -c -u -f -o -M -S)-K[create a new data encryption key]' \ + '(1 -r)-a[apply to all datasets in all pools]' \ + '(-a)-r[apply recursively]' \ + ':filesystem or volume:_zfs_dataset -t fs -t vol' + ;; + + zfs:load-key) + _arguments -A "-*" -S \ + "-L+[specify location of user's encryption key]:key location [prompt]:_files -P file\:// -W /" \ + '(:)-a[load keys for all encryption roots in all imported pools]' \ + '-n[do a dry-run, simply check that the provided key is correct]' \ + '-r[load keys for datasets recursively]' \ + '(-a):filesystem or volume:_zfs_dataset -t fs -t vol' + ;; + + zfs:unload-key) + _arguments -A "-*" -S \ + '(:)-a[unload keys for all encryption roots in all imported pools]' \ + '-r[unload keys for datasets recursively]' \ + '(-a):filesystem or volume:_zfs_dataset -t fs -t vol' + ;; + + zfs:change-key) + _arguments -A "-*" -S \ + '(-o)-i[make filesystem inherit key from its parent]' \ + '-l[ensure key is loaded before attempting to change it]' \ + '(-i)*-o+[change encryption key property]: :_values -s , "property" $key_properties' \ + ':filesystem or volume:_zfs_dataset -t fs -t vol' + ;; + + zfs:jail|zfs:unjail) + _arguments \ + '1: : _jails' \ + '2:filesystem:_zfs_dataset -t fs' + ;; + + zfs:help) + _arguments -A "-*" -S \ + - set1 \ + ':command:($subcmds $delegatable_perms $ro_ds_props ${rw_ds_props%%:*} properties)' \ + - set2 \ + '(2)-l[display property information]' \ + ':help topic:(property)' \ + ':property:($delegatable_perms $ro_ds_props ${rw_ds_props%%:*})' + ;; + + zpool:help) + _arguments -A "-*" -S \ + - commands \ + ':command:($subcmds)' \ + - properties \ + '(2)-l[display property information]' \ + ':help topic:(property)' \ + ':property:(${po_propnames%%\[*})' + ;; + + zpool:add) + if [[ $implementation = openzfs ]]; then + args=( + '-g[display vdev, GUIDs instead of the normal device names]' + '-L[display real paths for vdevs resolving all symbolic links]' + '-o+[set given pool properties]: :_values -s , "property" "${(@M)ci_po_props\:#ashift*}"' \ + '-P[display real paths for vdevs instead of only the last component of the path]' + ) + elif [[ $implementation = solaris ]]; then + args=( '-l[display configuration in /dev/chassis location form]' ) + fi + _arguments -A "-*" -S $args \ + '-f[force use of in-use devices]' \ + '-n[display configuration without modifying pool]' \ + ':pool:_zfs_pool' \ + '*:virtual device:->virtual-devices' + ;; + + zpool:attach) + if [[ $implementation = openzfs ]]; then + args=( + '-w[wait until new device has finished resilvering before returning]' + '-s[reconstruct sequentially to restore redundancy as quickly as possible]' + '-o+[set given pool properties]: :_values -s , "property" "${(@M)ci_po_props\:#ashift*}"' + ) + fi + _arguments -A "-*" -S $args \ + '-f[force attach, even if in use]' \ + ':pool:_zfs_pool' \ + ':virtual device:->pool-devices' \ + ':virtual device:->disk-devices' + ;; + + zpool:checkpoint) + _arguments -A "-*" -S \ + '(-d --discard)'{-d,--discard}'[discard an existing checkpoint from the pool]' \ + '(-w --wait)'{-w,--wait}'[wait until the checkpoint has finished being discarded before returning]' \ + ':pool:_zfs_pool' + ;; + + zpool:clear) + [[ $implementation = solaris ]] && args=( + '-f[ignore fmadm acquit and fmadm repair failures]' + ) + _arguments -C -A "-*" -S $args \ + '-F[discard transactions to allow pool opening]' \ + '-n[with -F, check if discarding transactions would work]' \ + '-X[(undocumented) extreme rewind of transactions]' \ + ':pool:_zfs_pool' \ + '*:virtual device:->pool-devices' + ;; + + zpool:create) + if [[ $implementation = openzfs ]]; then + args=( + "-d[don't enable any features on the new pool]" + ) + else + args=( + '-B[create EFI boot partition on whole disks]' + '-l[display configuration in /dev/chassis location form]' + "-N[create pool but don't mount or share]" + ) + fi + _arguments -C -A "-*" -S $args \ + '-o+[set pool property at creation time]:property:->newpool-properties' \ + '-O+[set dataset property at creation time]:property:->create-properties' \ + '-f[force use of in-use devices]' \ + '-n[display configuration without creating pool]' \ + '-R+[use alternate root]:alternate root:_directories' \ + '-m+[set mountpoint for root dataset]:mountpoint' \ + '-t+[use a temporary pool name]:pool name' \ + ':pool :_guard "^-*" "pool name"' \ + '*: :->virtual-devices' + ;; + + zpool:destroy) + _arguments -A "-*" -S \ + '-f[force active datasets to be unmounted]' \ + ':pool:_zfs_pool' + ;; + + zpool:detach) + _arguments -C \ + ':pool:_zfs_pool' \ + ':virtual device:->pool-devices' + ;; + + zpool:events) + _arguments -A "-*" -S \ + '(- 1)-c[clear all previous events]' \ + '-f[follow mode - continue running, showing new events]' \ + '-H[suppress headers and tab-delimit fields]' \ + '-v[print the entire payload for each event]' \ + '(-c)1:pool:_zfs_pool' + ;; + + zpool:export) + [[ $implementation = openzfs ]] && args=( '(*)-a[export all pools]' ) + _arguments -A "-*" -S $args \ + '-f[forcefully unmount all datasets]' \ + '*:pool:_zfs_pool' + ;; + + zpool:get) + [[ $implementation = solaris ]] && args=( + '-s+[specify sources to display]: :_values -s "source" local default none' + ) + _arguments -A "-*" -S $args \ + '-H[suppress headers and tab-delimit fields]' \ + '-p[display numbers in parseable (exact) values]' \ + '-o+[specify fields to display]: : _values -s , field name property value source' \ + ':property:_values -s , "property" $po_propnames' \ + '*:pool:_zfs_pool' + ;; + + zpool:history) + _arguments -A "-*" -S \ + '-i[display internal events]' \ + '-l[long format]' \ + '*:pool:_zfs_pool' + ;; + + zpool:import) + # TODO: -o should complete mount options, too + if [[ $implementation = openzfs ]]; then + args=( + '-t[new pool name is temporary]' + '-l[request encryption keys for all encrypted datasets]' + '--rewind-to-checkpoint[rewind pool to the checkpointed state]' + '-s[scan using the default search path]' + '(-F -X)-T[specify the txg to use for rollback]' + ) + else + args=( + '(-a)-t+[use a temporary pool name]:pool name' + '-l[display configuration in /dev/chassis location form]' + ) + fi + _arguments -C -A "-*" -S $args \ + '(1 2 -t)-a[search for and import all pools found]' \ + '-D[destroyed pools only]' \ + '(-d)*-c+[use cache file]:cache file:_files' \ + '(-c -D)*-d+[search for devices or files in directory]:directory:_files -/' \ + '-F[recovery mode: discard transactions if required]' \ + '-X[(undocumented) extreme rewind of transactions]' \ + '!-V' \ + '-f[force import]' \ + '-m[ignore missing log devices]' \ + '-N[import pool without mounting any filesystems]' \ + "-n[with -F; don't perform input]" \ + '-R+[specify alternate root]:alternate root:_files -/' \ + '-o+[set pool or dataset property]:property:->import-properties' \ + '1:pool name or id:_zfs_pool' \ + '2::new pool name' + ;; + + zpool:initialize) + _arguments -A "-*" -S \ + '(-s --suspend -c --cancel)'{-c,--cancel}'[cancel initializing on specified devices]' \ + '(-s --suspend -c --cancel)'{-s,--suspend}'[suspend initializing on specified devices]' \ + '(-w --wait)'{-w,--wait}'[wait until devices have finished initializing before returning]' \ + ':pool:_zfs_pool' \ + '*:device:pool-devices' + ;; + + zpool:iostat) + if [[ $implementation = openzfs ]]; then + args=( + '-c[run scripts on each vdev]:script:_files -W "($ZPOOL_SCRIPTS_PATH /etc/zfs/zpool.d ~/.zpool.d)"' + '-g[display vdev GUIDs instead of normal device names]' + '-H[suppress headers and tab-delimit fields]' + '-L[display real paths for vdevs resolving all symbolic links]' + '-n[print headers only once]' + '-p[display numbers in parsable (exact) values and times in nanoseconds]' + '-P[display full paths for vdevs instead of only the last component of the path]' + "-r[print request size histograms for the leaf vdev's IO]" + '-y[omit statistics since boot]' + '-w[display latency histograms]' + '-l[include average latency statistics]' + '-q[include active queue statistics]' + ) + else + args=( '-l[display configuration in /dev/chassis location form]' ) + fi + _arguments -A "-*" -S $args \ + '-T+[display a timestamp]:format:((d\:standard u\:internal))' \ + '-v[verbose statistics]' \ + '*::pool:_zfs_pool' \ + '::interval' \ + '::count' + ;; + + zpool:label) + _arguments -C -A "-*" -S \ + '(-c)*-d+[specify path in which to search for devices or files]:path:_directories' \ + '(-d)-c+[read configuration from specified cache file]:cache file:_files' \ + '(-R)-C[clear ZFS metadata on an inactive pool or device]' \ + '(-C)-R[recover ZFS metadata for a pool]' \ + '1::pool:_zfs_pool' \ + '2:device:->pool-devices' + ;; + + zpool:labelclear) + _arguments -A "-*" -S \ + '-f[treat exported or foreign devices as inactive]' \ + '*:virtual device:_files' + ;; + + zpool:list) + [[ $implementation = openzfs ]] && args=( + '-g[display vdev GUIDs instead of normal device names]' + '-L[display real paths for vdevs resolving all symbolic links]' + '-p[display numbers in parsable (exact) values]' + '-P[display full paths for vdevs instead of only the last component of the path]' + '-v[report usage statistics for individual vdevs within the pool]' + ) + _arguments -A "-*" -S $args \ + '-H[suppress headers and tab-delimit fields]' \ + '-T+[display a timestamp]:format:((d\:standard u\:internal))' \ + '-o+[specify fields to list]: :_values -s , "field" $po_propnames' \ + '::pool:_zfs_pool' + ;; + + zpool:monitor) + _arguments -A "-*" -S \ + '-t+[specify provider]:provider:(send receive scrub resilver ddtmigrate destroy)' \ + '-o+[specify fields]: :_values -s , field done other pctdone pool provider speed starttime tag timeleft timestmp total' \ + '-T+[display a timestamp]:format:((d\:standard u\:internal))' \ + '-p[use machine-parseable output format]' \ + '1:pool:_zfs_pool' \ + '2:interval' \ + '3:count' + ;; + + zpool:offline) + [[ $implementation = openzfs ]] && args=( + '-f[force disk into faulted state]' + ) + _arguments -C -A "-*" -S $args \ + '-t[offline until next reboot]' \ + ':pool:_zfs_pool' \ + '*:virtual device:->pool-devices' + ;; + + zpool:online) + _arguments -C -A "-*" -S \ + '-e[expand device to use all available space]' \ + ':pool:_zfs_pool' \ + '*:virtual device:->pool-devices' + ;; + + zpool:reopen) + _arguments -A "-*" -S \ + "-n[don't restart an in-progress scrub operation]" \ + '1:pool:_zfs_pool' + ;; + + zpool:reguid) + _zfs_pool + ;; + + zpool:remove) + [[ $implementation = openzfs ]] && args=( + '(-s)-w[wait until removal has completed before returning]' + ) + _arguments -C -A "-*" -S $args \ + "(-s)-n[don't perform the removal, display mapping table memory use]" \ + '(-s)-p[with -n, display numbers in parseable (exact) values]' \ + '(- *)-s[stop and cancel an in-progress removal]' \ + '1:pool:_zfs_pool' \ + '*:device:->pool-devices' + ;; + + zpool:replace) + [[ $implementation = openzfs ]] && args=( + '-w[wait until replacement has completed before returning]' + '-s[reconstruct sequentially to restore redundancy as quickly as possible]' + '-o+[set given pool properties]: :_values -s , "property" "${(@M)ci_po_props\:#ashift*}"' + ) + _arguments -A "-*" -S $args \ + '-f[force attach, even if in use]' \ + ':pool:_zfs_pool' \ + ':virtual device:_files' \ + '::virtual device:_files' + ;; + + zpool:(resilver|sync)) + _arguments \ + '*:pool:_zfs_pool' + ;; + + zpool:scrub) + [[ $implementation = openzfs ]] && args=( + '(-s)-p[pause scrubbing]' + '-w[wait until scrub has completed before returning]' + ) + _arguments -A "-*" -S $args \ + '(-p)-s[stop scrubbing]' \ + '*:pool:_zfs_pool' + ;; + + zpool:set) + _arguments -C -A "-*" -S \ + ':property:->set-pool-properties' \ + '*:pool:_zfs_pool' + ;; + + zpool:split) + if [[ $implementation = solaris ]]; then + args=( '-l[display configuration in /dev/chassis location form]' ) + else + args=( + '-g[display vdev GUIDs instead of normal device names]' + '-L[display real paths for vdevs resolving all symbolic links]' + '-l[request encryption keys for encrypted datasets]' + '-P[display full paths for vdevs instead of only the last component of the path]' + ) + fi + _arguments -C -A "-*" -S $args \ + '-R+[specify alternate root]:alternate root:_files -/' \ + '-n[display configuration without splitting]' \ + '-o+[set pool or dataset property]:property:->import-properties' \ + ':pool name or id:_zfs_pool' \ + ':new pool name' \ + '*:virtual device:->pool-devices' + ;; + + zpool:status) + if [[ $implementation = openzfs ]]; then + args=( + '-D[display a histogram of deduplication statistics]' + '-c[run scripts on each vdev]:script:_files -W "($ZPOOL_SCRIPTS_PATH /etc/zfs/zpool.d ~/.zpool.d)"' + '-i[display vdev initialization status]' + '-g[display vdev GUIDs instead of the normal device names]' + '-L[display real paths for vdevs resolving all symbolic links]' + '-p[display numbers in parsable (exact) values and times in nanoseconds]' + '-P[display full paths for vdevs instead of only the last component of the path]' + '-s[display the number of leaf VDEV slow IOs]' + '-t[display vdev TRIM status]' + ) + else + args=( '-l[display configuration in /dev/chassis location form]' ) + fi + _arguments -A "-*" -S $args\ + '-v[verbose information]' \ + '-x[show only unhealthy pools]' \ + '-T+[display a timestamp]:format:((d\:standard u\:internal))' \ + '*::pool:_zfs_pool' \ + ':: :_guard "[0-9]#" interval' \ + ':: :_guard "[0-9]#" count' + ;; + + zpool:trim) + _arguments -C -A "-*" -S \ + '(-d --secure)'{-d,--secure}'[initiate a secure TRIM]' \ + '(-r --rate)'{-r,--rate}'[set rate at which the TRIM operation progresses]:rate (bytes per second)' \ + '(-c --cancel)'{-c,--cancel}'[cancel trimming]' \ + '(-s --suspend)'{-s,--suspend}'[suspend trimming]' \ + '(-w --wait)'{-w,--wait}'[wait until devices are done being trimmed]' \ + '1:pool:_zfs_pool' \ + '*:device:->pool-devices' + ;; + + zpool:upgrade) + _arguments -A "-*" -S \ + '(- *)-v[display ZFS versions and descriptions]' + "(-v)-V+[upgrade to given version]:version" \ + '(-v *)-a[upgrade all pools]' \ + '(-a -v)*:pool:_zfs_pool' + ;; + + zpool:wait) + _arguments -A "-*" -S \ + '-H[suppress printing of headers, tab-delimit columns]' \ + '-P[use exact (parsable) numeric output]' \ + '-t+[specify background activity]: : _values -s , activity discard free initialize replace remove resilver scrub trim' \ + '-T+[display a timestamp]:format:((d\:standard u\:internal))' \ + ':pool:_zfs_pool' \ + ':interval' + ;; + + *) + _default + ;; +esac + +while (( $#state )); do + curstate=$state + state=() + case $curstate in + virtual-devices) + local -a vdevtypes + vdevtypes=( mirror raidz{,1,2,3} spare log cache ) + if [[ $implementation = openzfs ]]; then + vdevtypes+=( draid{,1,2,3} dedup special ) + else + vdevtypes+=( meta ) + fi + # cache can't be a mirror + [[ $words[CURRENT-1] != cache ]] && alts=( + 'vdev-types:vdev type:compadd -a vdevtypes' + ) + [[ -prefix / ]] || alts+=( + 'disk-vdevs:disk vdev:_files -g "*(-%)" -W /dev' + ) + _alternative $alts 'file-vdevs:file vdev:_files -W / -P /' + ;; + + pool-devices) + local -a devices + devices=( ${${${(M)${(f)"$(_call_program devices zpool status $line[1])"}:#$'\t' *}##[[:blank:]]#}%%[[:blank:]]*} ) + if (( $#devices )); then + _description devices expl "$state_descr" + compadd "$expl[@]" -a devices + break + fi + ;& # fall-through if we found none + + disk-devices) + [[ -prefix / ]] || alts=( + 'disk-vdevs:disk vdev:_files -g "*(-%)" -W /dev' + ) + _alternative $alts 'file-vdevs:file vdev:_files -W / -P /' + ;; + + keysources) + local -a suf + + compset -S ",*" || suf=(-S ,) + if compset -P 1 "*,"; then + _alternative \ + 'zfs-keylocator-prompt:"prompt" locator:(prompt)' \ + 'zfs-keylocator-file:file locator:_files' \ + 'zfs-keylocator-pkcs11: : _message -e zfs-keylocator-pkcs11 "PKCS#11 locator"' \ + 'zfs-keylocator-https: : _message -e zfs-keylocator-https "HTTPS URL locator"' + else + _description keysource-formats expl "keysource format" + compadd $suf -q "$expl[@]" "$@" raw hex passphrase + fi + ;; + + quotas) + _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)' + ;; + + import-properties) args=( $ci_ds_props $rw_ds_props $ci_po_props ) ;| + create-properties) args=( $ci_ds_props ) ;| + set-properties) args=( $rw_ds_props ) ;| + newpool-properties) args=( $rw_po_props $ci_po_props ) ;| + set-pool-properties) args=( $rw_po_props ) ;| + + *-properties) + if compset -P 1 '(#m)*@'; then + if compset -P 1 '*='; then + case $MATCH in + *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)' + ;; + esac + else + case $MATCH in + user*@) _users -S = ;; + group*@) _groups -S = ;; + project*@) _message -e projects project ;; + esac + fi + else + _wanted values expl "$state_descr" compadd -S@ ${${(M)args:#*@}%@} + _values -C "$state_descr" ${args:#*@} + fi + ;; + esac +done + +[[ nm -ne "$compstate[nmatches]" ]] diff --git a/Completion/Unix/Command/_zpool b/Completion/Unix/Command/_zpool deleted file mode 100644 index d9c2caa52..000000000 --- a/Completion/Unix/Command/_zpool +++ /dev/null @@ -1,311 +0,0 @@ -#compdef zpool -# Synced with the S11U1 man page - -_zpool() { - local context state line expl implementation - local -a subcmds fields ro_props rw_props versions create_properties_dataset - - _pick_variant -r implementation -c 'zpool upgrade -v' openzfs='This system supports ZFS pool feature flags' solaris - - subcmds=( - create destroy add remove list iostat status online - offline clear attach detach replace scrub import export - upgrade history get set split help - ) - - if [[ $implementation = openzfs ]] && [[ $OSTYPE != solaris* ]]; then - subcmds+=( labelclear initialize ) - fi - - versions=( - ${${${(M)"${(f)$(_call_program versions zpool upgrade -v)}":#[[:space:]]#<->*}##[[:space:]]}%%[[:space:]]*} - ) - - ro_props=( - "all[All properties]" - "allocated[Space allocated]" - "capacity[Space used (percentage)]" - "dedupratio[Deduplication ratio]" - "free[Space unallocated]" - "guid[Unique identifier]" - "health[Health status]" - "size[Total size]" - ) - - rw_props=( - "altroot[Alternate root directory]:value:" - "autoexpand[Automatic pool expansion]:value:(on off)" - "autoreplace[Automatic device replacement]:value:(on off)" - "bootfs[Default bootable dataset]:value:" - "cachefile[Pool configuration cache file location]:value:" - "dedupditto[Threshold for number of copies]:value:" - "delegation[Delegated administration]:value:(on off)" - "failmode[Failure-mode behavior]:value:(wait continue panic)" - "listshares[Show shares in 'zfs list']:value:(on off)" - "listsnaps[Show snapshots in 'zfs list']:value:(on off)" - "readonly[Controls whether the pool can be modified]:value:(on off)" - "version[Pool version]:version:($versions)" - ) - - fields=( ${ro_props%%:*} ${rw_props%%:*} ) - - create_properties_dataset=( - "aclinherit:value:(discard noallow restricted passthrough passthrough-x)" - "aclmode:value:(discard mask passthrough)" - "atime:value:(on off)" - "canmount:value:(on off noauto)" - "checksum:value:(on off fletcher2 fletcher4 sha256 sha256+mac)" - "compression:value:(on off lzjb gzip gzip-{1..9} zle)" - "copies:value:(1 2 3)" - "dedup:value:(on off verify sha256 sha256,verify)" - "devices:value:(on off)" - "encryption:value:(off on aes128-ccm aes-192-ccm aes-256-ccm aes-128-gcm aes-192-gcm aes-256-gcm)" - "exec:value:(on off)" - "groupquota@:value:" # TODO: complete group=size|none - "keysource:value:_zfs_keysource_props" - "logbias:value:(latency throughput)" - "mlslabel:value:(none)" # TODO: list sensitivity labels - "mountpoint:path, 'legacy', or 'none':{if [[ -prefix /* ]]; then _path_files -/; else _wanted mountpoints expl 'mountpoint (type \"/\" to start completing paths)' compadd legacy none; fi}" - "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}" - "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}" - "rstchown:value:(on off)" - "secondarycache:value:(all none metadata)" - "setuid:value:(on off)" - "shadow:value:" # TODO: complete URI|none - "share:share properties:" - "sharenfs:value:(on off)" - "sharesmb:value:(on off)" - "snapdir:value:(hidden visible)" - "sync:value:(standard always disabled)" - "userquota@:value:" # TODO: complete user=size|none - "version:value:(1 2 3 4 current)" - "volsize:value:" # - "vscan:value:(on off)" - "xattr:value:(on off)" - "zoned:value:(on off)" - ) - - if [[ $service == "zpool" ]]; then - _arguments -C \ - '-\?[show help information]' \ - '1:subcommand:compadd -a subcmds' \ - '*:: :->subcmd' && return - - service="$words[1]" - curcontext="${curcontext%:*}-$service:" - fi - - case $service in - (help) - _arguments -A "-*" \ - - set1 \ - ':command/property:($subcmds ${fields%%\[*} properties)' \ - - set2 \ - '-l[Display property information]' \ - ': :(properties)' - ;; - - (clear) - _arguments -A "-*" \ - '-F[Discard transactions to allow pool opening]' \ - '-f[Ignore fmadm acquit and fmadm repair failures]' \ - '-n[With -F, check if discarding transactions would work]' \ - ':pool name:_zfs_pool' \ - '*:virtual device:_files' - ;; - - (create) - # TODO: investigate better vdev handling - _arguments -A "-*" \ - '-B[Create EFI boot partition on whole disks]' \ - '-o[Set pool property at creation time]:property:_values -s , "property" $rw_props' \ - '-O[Set dataset property at creation time]:property:_values -s , "property" $create_properties_dataset' \ - '-f[Force use of in-use devices]' \ - '-l[Display configuration in /dev/chassis location form]' \ - '-n[Display configuration without creating pool]' \ - '-R[Use alternate root]:alternate root:_files -/' \ - '-m[Set mountpoint for root dataset]:mountpoint:' \ - ':pool name:' \ - '*:virtual device:_files' - ;; - - (destroy) - _arguments -A "-*" \ - '-f[Force active datasets to be unmounted]' \ - ':pool name:_zfs_pool' - ;; - - (add) - _arguments -A "-*" \ - '-f[Force use of in-use devices]' \ - '-l[Display configuration in /dev/chassis location form]' \ - '-n[Display configuration without modifying pool]' \ - ':pool name:_zfs_pool' \ - '*:virtual device:_files' - ;; - - (list) - _arguments \ - '-H[Scripted mode]' \ - '-T[timestamp]:value:(u d)' \ - '-o[Fields to list]:field:_values -s , "field" $fields' \ - '::pool name:_zfs_pool' - ;; - - (initialize) - _arguments -A "-*" \ - '(-c --cancel)'{-c,--cancel}'[cancel initializing on specified devices]' \ - '(-s --suspend)'{-s,--suspend}'[suspend initializing on specified devices]' \ - ':pool name:_zfs_pool' \ - '*:device:_files' - ;; - - (iostat) - _arguments -A "-*" \ - '-l[Display configuration in /dev/chassis location form]' \ - '-T[timestamp]:value:(u d)' \ - '-v[Verbose statistics]' \ - '*::pool name:_zfs_pool' \ - '::interval:' \ - '::count:' - ;; - - (labelclear) - _arguments -A "-*" \ - '-f[treat exported or foreign devices as inactive]' \ - '*:virtual device:_files' - ;; - - (status) - _arguments -A "-*" \ - '-l[Display configuration in /dev/chassis location form]' \ - '-v[Verbose information]' \ - '-x[Show only unhealthy pools]' \ - '-T[timestamp]:value:(u d)' \ - '*::pool name:_zfs_pool' - ;; - - (offline) - _arguments -A "-*" \ - '-t[Offline until next reboot]' \ - ':pool name:_zfs_pool' \ - '*:virtual device:_files' - ;; - - (online) - _arguments \ - '-e[Expand device to use all available space]' \ - ':pool name:_zfs_pool' \ - '*:virtual device:_files' - ;; - - (attach) - # TODO: first device should choose first from existing. - _arguments \ - '-f[Force attach, even if in use]' \ - ':pool name:_zfs_pool' \ - ':virtual device:_files' \ - ':virtual device:_files' - ;; - - (detach) - _arguments \ - ':pool name:_zfs_pool' \ - ':virtual device:_files' - ;; - - (replace) - _arguments -A "-*" \ - '-f[Force attach, even if in use]' \ - ':pool name:_zfs_pool' \ - ':virtual device:_files' \ - '::virtual device:_files' - ;; - - (scrub) - _arguments -A "-*" \ - '-s[Stop scrubbing]' \ - '*:pool name:_zfs_pool' - ;; - - (export) - _arguments -A "-*" \ - '-f[Forcefully unmount all datasets]' \ - '*:pool name:_zfs_pool' - ;; - - (import) - # TODO: -o should complete mount options, too - _arguments -A "-*" \ - '-D[Destroyed pools]' \ - '(-d)*-c[Use cache file]:cache file:_files' \ - '(-c -D)*-d[Search for devices or files in directory]:directory:_files -/' \ - '-F[Recovery mode: discard transactions if required]' \ - '-f[Force import]' \ - '-l[Display configuration in /dev/chassis location form]' \ - '-m[Ignore missing log devices]' \ - '-N[Import pool without mounting any filesystems]' \ - '-n[With -F; do not perform input]' \ - '-R[Alternate root]:alternate root:_files -/' \ - '-o[Set pool or dataset property]:property:_values -s , "property" $create_properties_dataset $rw_props' \ - - set1 \ - '*:pool name or id:_zfs_pool' \ - '::new pool name:' \ - - set2 \ - '-N[Do not mount any filesystems]' \ - '-a[All pools]' - ;; - - (get) - _arguments -A "-*" \ - ':property:_values -s , "property" $fields' \ - '*:pool name:_zfs_pool' - ;; - - (set) - _arguments -A "-*" \ - ':property:_values -s , "property" $rw_props' \ - '*:pool name:_zfs_pool' - ;; - - (split) - _arguments -A "-*" \ - '-R[Alternate root]:alternate root:_files -/' \ - '-l[Display configuration in /dev/chassis location form]' \ - '-n[Display configuration without splitting]' \ - '-o[Set pool or dataset property]:property:_values -s , "property" $create_properties_dataset $rw_props' \ - ':pool name or id:_zfs_pool' \ - ':new pool name:' \ - '*::virtual device:_files -/' - ;; - - (upgrade) - _arguments -A "-*" \ - - set1 \ - '-v[Display ZFS versions and descriptions]' \ - - set2 \ - "-V[Upgrade to given version]:version:($versions)" \ - '-a[Upgrade all pools]' \ - '*:pool name:_zfs_pool' - ;; - - (history) - _arguments -A "-*" \ - '-i[Display internal events]' \ - '-l[Long format]' \ - '*:pool name:_zfs_pool' - ;; - - (*) - _message "unknown zpool subcommand: $service" - ;; - esac -} - -_zpool "$@" diff --git a/Completion/Unix/Type/_zfs_dataset b/Completion/Unix/Type/_zfs_dataset index 63384afc6..7edcfd5d7 100644 --- a/Completion/Unix/Type/_zfs_dataset +++ b/Completion/Unix/Type/_zfs_dataset @@ -11,10 +11,12 @@ local expl_type # -t takes arguments (what kinds of datasets) and can appear multiple times zparseopts -D -E e:=expl_type_arr p=paths_allowed r1=rsrc r2=rdst t+:=type -[[ -n $type[(r)fs] ]] && typearg=( filesystem ) -[[ -n $type[(r)vol] ]] && typearg=( $typearg volume ) -[[ -n $type[(r)snap] ]] && typearg=( $typearg snapshot ) -[[ -n $type[(r)share] ]] && typearg=( $typearg share ) +[[ -n $type[(r)fs] ]] && typearg=( filesystem ) +[[ -n $type[(r)vol] ]] && typearg+=( volume ) +[[ -n $type[(r)snap] ]] && typearg+=( snapshot ) +[[ -n $type[(r)share] && $implementation = solaris ]] && typearg+=( share ) +[[ -n $type[(r)bookmark] && $implementation = openzfs ]] && + typearg+=( bookmark ) if [[ -n $typearg ]]; then typearg=( -t ${(j:,:)typearg} ) # We know we're in zfs list if paths_allowed is non-empty. @@ -58,7 +60,7 @@ if [[ ${#rdst} -gt 0 ]]; then fi if [[ -n $type[(r)clone] ]]; then - datasetlist=( ${(f)"$(zfs list -H -o name,origin -t filesystem 2>/dev/null | awk -F $'\t' "\$2 != \"-\" {print \$1}")":#no cloned filesystems available} ) + datasetlist=( ${(f)"$(zfs list -H -o name,origin -t filesystem 2>/dev/null | awk -F$'\t' "\$2 != \"-\" {print \$1}")":#no cloned filesystems available} ) else datasetlist=( ${(f)"$(zfs list -H -o name $typearg 2>/dev/null)":#no datasets available} ) fi @@ -74,4 +76,5 @@ if [[ -n $expl_type_arr[2] ]]; then expl_type=$expl_type_arr[2] fi -_wanted dataset expl "$expl_type" _multi_parts "$@" -q / datasetlist +_description datasets expl "$expl_type" +_multi_parts "$@" "$expl[@]" -q / datasetlist diff --git a/Completion/Unix/Type/_zfs_keysource_props b/Completion/Unix/Type/_zfs_keysource_props deleted file mode 100644 index 01f63257a..000000000 --- a/Completion/Unix/Type/_zfs_keysource_props +++ /dev/null @@ -1,15 +0,0 @@ -#autoload - -local -a suf -local expl - -compset -S ",*" || suf=(-S ,) -if compset -P 1 "*,"; then - _alternative "zfs-keylocator-prompt:\"prompt\" locator:(prompt)" \ - "zfs-keylocator-file:file locator:_path_files" \ - "zfs-keylocator-pkcs11:PKCS#11 locator: " \ - "zfs-keylocator-https:HTTPS URL locator: " -else - _description format expl "keysource format" - compadd $suf -q "$expl[@]" "$@" raw hex passphrase -fi -- cgit v1.2.3