about summary refs log tree commit diff
path: root/Completion
diff options
context:
space:
mode:
Diffstat (limited to 'Completion')
-rw-r--r--Completion/BSD/Command/_bsd_pkg47
-rw-r--r--Completion/BSD/Command/_chflags25
-rw-r--r--Completion/BSD/Command/_freebsd-update1
-rw-r--r--Completion/BSD/Command/_fw_update6
-rw-r--r--Completion/BSD/Command/_ipfw137
-rw-r--r--Completion/BSD/Command/_jexec2
-rw-r--r--Completion/BSD/Command/_kdump2
-rw-r--r--Completion/BSD/Command/_ktrace2
-rw-r--r--Completion/BSD/Command/_ldap4
-rw-r--r--Completion/BSD/Command/_pfctl7
-rw-r--r--Completion/BSD/Command/_rcctl19
-rw-r--r--Completion/BSD/Command/_sockstat8
-rw-r--r--Completion/BSD/Command/_sysclean6
-rw-r--r--Completion/BSD/Command/_sysmerge6
-rw-r--r--Completion/BSD/Command/_syspatch7
-rw-r--r--Completion/BSD/Command/_sysupgrade9
-rw-r--r--Completion/BSD/Type/_login_classes9
-rw-r--r--Completion/BSD/Type/_routing_domains6
-rw-r--r--Completion/BSD/Type/_routing_tables6
-rw-r--r--Completion/Base/Completer/_approximate48
-rw-r--r--Completion/Base/Completer/_expand2
-rw-r--r--Completion/Base/Completer/_prefix9
-rw-r--r--Completion/Base/Core/_description10
-rw-r--r--Completion/Base/Core/_main_complete22
-rw-r--r--Completion/Base/Core/_message2
-rw-r--r--Completion/Base/Utility/_arguments14
-rw-r--r--Completion/Base/Utility/_numbers87
-rw-r--r--Completion/Base/Utility/_shadow97
-rw-r--r--Completion/Base/Utility/_values2
-rw-r--r--Completion/Base/Widget/_complete_debug2
-rw-r--r--Completion/Base/Widget/_complete_help3
-rw-r--r--Completion/Darwin/Command/_open8
-rw-r--r--Completion/Darwin/Command/_otool7
-rw-r--r--Completion/Darwin/Command/_qtplay2
-rw-r--r--Completion/Darwin/Command/_shortcuts88
-rw-r--r--Completion/Darwin/Command/_softwareupdate151
-rw-r--r--Completion/Darwin/Command/_sw_vers7
-rw-r--r--Completion/Darwin/Command/_system_profiler12
-rw-r--r--Completion/Darwin/Command/_trash22
-rw-r--r--Completion/Debian/Command/_apt14
-rw-r--r--Completion/Debian/Command/_aptitude2
-rw-r--r--Completion/Debian/Command/_sbuild2
-rw-r--r--Completion/Linux/Command/_basenc30
-rw-r--r--Completion/Linux/Command/_btrfs51
-rw-r--r--Completion/Linux/Command/_chcon24
-rw-r--r--Completion/Linux/Command/_chrt2
-rw-r--r--Completion/Linux/Command/_cpupower2
-rw-r--r--Completion/Linux/Command/_ethtool58
-rw-r--r--Completion/Linux/Command/_findmnt3
-rw-r--r--Completion/Linux/Command/_free1
-rw-r--r--Completion/Linux/Command/_fusermount4
-rw-r--r--Completion/Linux/Command/_gpasswd2
-rw-r--r--Completion/Linux/Command/_htop66
-rw-r--r--Completion/Linux/Command/_ionice2
-rw-r--r--Completion/Linux/Command/_iptables66
-rw-r--r--Completion/Linux/Command/_lsblk7
-rw-r--r--Completion/Linux/Command/_lsns18
-rw-r--r--Completion/Linux/Command/_modutils4
-rw-r--r--Completion/Linux/Command/_networkmanager20
-rw-r--r--Completion/Linux/Command/_perf809
-rw-r--r--Completion/Linux/Command/_pidof58
-rw-r--r--Completion/Linux/Command/_selinux796
-rw-r--r--Completion/Linux/Command/_setpriv4
-rw-r--r--Completion/Linux/Command/_strace15
-rw-r--r--Completion/Linux/Command/_sysstat8
-rw-r--r--Completion/Linux/Command/_valgrind4
-rw-r--r--Completion/Linux/Type/_selinux_contexts13
-rw-r--r--Completion/Linux/Type/_selinux_types16
-rw-r--r--Completion/Mandriva/Command/_urpmi2
-rw-r--r--Completion/Redhat/Command/_dnf4
-rw-r--r--Completion/Redhat/Command/_rpm13
-rw-r--r--Completion/Solaris/Command/_dumpadm2
-rw-r--r--Completion/Solaris/Command/_ipadm2
-rw-r--r--Completion/Solaris/Command/_pkg51
-rw-r--r--Completion/Unix/Command/_adb114
-rw-r--r--Completion/Unix/Command/_ansible116
-rw-r--r--Completion/Unix/Command/_ant19
-rw-r--r--Completion/Unix/Command/_arp2
-rw-r--r--Completion/Unix/Command/_awk1
-rw-r--r--Completion/Unix/Command/_cal129
-rw-r--r--Completion/Unix/Command/_cat3
-rw-r--r--Completion/Unix/Command/_chmod5
-rw-r--r--Completion/Unix/Command/_chown7
-rw-r--r--Completion/Unix/Command/_chroot2
-rw-r--r--Completion/Unix/Command/_cmp14
-rw-r--r--Completion/Unix/Command/_column16
-rw-r--r--Completion/Unix/Command/_cp10
-rw-r--r--Completion/Unix/Command/_csplit51
-rw-r--r--Completion/Unix/Command/_cut3
-rw-r--r--Completion/Unix/Command/_date23
-rw-r--r--Completion/Unix/Command/_dbus6
-rw-r--r--Completion/Unix/Command/_dd16
-rw-r--r--Completion/Unix/Command/_dig18
-rw-r--r--Completion/Unix/Command/_dmidecode1
-rw-r--r--Completion/Unix/Command/_du8
-rw-r--r--Completion/Unix/Command/_elfdump11
-rw-r--r--Completion/Unix/Command/_enscript2
-rw-r--r--Completion/Unix/Command/_env7
-rw-r--r--Completion/Unix/Command/_ffmpeg2
-rw-r--r--Completion/Unix/Command/_find18
-rw-r--r--Completion/Unix/Command/_flac1
-rw-r--r--Completion/Unix/Command/_gcc21
-rw-r--r--Completion/Unix/Command/_gcore1
-rw-r--r--Completion/Unix/Command/_gem39
-rw-r--r--Completion/Unix/Command/_getent3
-rw-r--r--Completion/Unix/Command/_getopt7
-rw-r--r--Completion/Unix/Command/_git992
-rw-r--r--Completion/Unix/Command/_global9
-rw-r--r--Completion/Unix/Command/_gnutls13
-rw-r--r--Completion/Unix/Command/_gpg5
-rw-r--r--Completion/Unix/Command/_gprof2
-rw-r--r--Completion/Unix/Command/_gradle96
-rw-r--r--Completion/Unix/Command/_grep3
-rw-r--r--Completion/Unix/Command/_head23
-rw-r--r--Completion/Unix/Command/_iconv2
-rw-r--r--Completion/Unix/Command/_id4
-rw-r--r--Completion/Unix/Command/_ifconfig31
-rw-r--r--Completion/Unix/Command/_imagemagick2
-rw-r--r--Completion/Unix/Command/_install3
-rw-r--r--Completion/Unix/Command/_iostat2
-rw-r--r--Completion/Unix/Command/_java9
-rw-r--r--Completion/Unix/Command/_killall12
-rw-r--r--Completion/Unix/Command/_ldd3
-rw-r--r--Completion/Unix/Command/_less31
-rw-r--r--Completion/Unix/Command/_libvirt1
-rw-r--r--Completion/Unix/Command/_ln12
-rw-r--r--Completion/Unix/Command/_logger80
-rw-r--r--Completion/Unix/Command/_ls46
-rw-r--r--Completion/Unix/Command/_lsof6
-rw-r--r--Completion/Unix/Command/_lua1
-rw-r--r--Completion/Unix/Command/_make42
-rw-r--r--Completion/Unix/Command/_man45
-rw-r--r--Completion/Unix/Command/_mktemp54
-rw-r--r--Completion/Unix/Command/_mosh4
-rw-r--r--Completion/Unix/Command/_mount14
-rw-r--r--Completion/Unix/Command/_mpc14
-rw-r--r--Completion/Unix/Command/_mutt9
-rw-r--r--Completion/Unix/Command/_mv12
-rw-r--r--Completion/Unix/Command/_mysql_utils1
-rw-r--r--Completion/Unix/Command/_netstat6
-rw-r--r--Completion/Unix/Command/_nice27
-rw-r--r--Completion/Unix/Command/_nkf8
-rw-r--r--Completion/Unix/Command/_nm18
-rw-r--r--Completion/Unix/Command/_objdump14
-rw-r--r--Completion/Unix/Command/_openldap222
-rw-r--r--Completion/Unix/Command/_pandoc68
-rw-r--r--Completion/Unix/Command/_perl1
-rw-r--r--Completion/Unix/Command/_perlbrew315
-rw-r--r--Completion/Unix/Command/_pgrep11
-rw-r--r--Completion/Unix/Command/_php2
-rw-r--r--Completion/Unix/Command/_ping4
-rw-r--r--Completion/Unix/Command/_pip213
-rw-r--r--Completion/Unix/Command/_pr103
-rw-r--r--Completion/Unix/Command/_ps4
-rw-r--r--Completion/Unix/Command/_ptx54
-rw-r--r--Completion/Unix/Command/_pv22
-rw-r--r--Completion/Unix/Command/_pydoc5
-rw-r--r--Completion/Unix/Command/_python8
-rw-r--r--Completion/Unix/Command/_qemu2
-rw-r--r--Completion/Unix/Command/_quilt2
-rw-r--r--Completion/Unix/Command/_rake17
-rw-r--r--Completion/Unix/Command/_rclone10
-rw-r--r--Completion/Unix/Command/_readelf13
-rw-r--r--Completion/Unix/Command/_ri46
-rw-r--r--Completion/Unix/Command/_rm6
-rw-r--r--Completion/Unix/Command/_route4
-rw-r--r--Completion/Unix/Command/_rsync25
-rw-r--r--Completion/Unix/Command/_ruby54
-rw-r--r--Completion/Unix/Command/_samba35
-rw-r--r--Completion/Unix/Command/_sccs2
-rw-r--r--Completion/Unix/Command/_scons4
-rw-r--r--Completion/Unix/Command/_screen2
-rw-r--r--Completion/Unix/Command/_script8
-rw-r--r--Completion/Unix/Command/_sed5
-rw-r--r--Completion/Unix/Command/_service5
-rw-r--r--Completion/Unix/Command/_split15
-rw-r--r--Completion/Unix/Command/_sqlite8
-rw-r--r--Completion/Unix/Command/_ssh209
-rw-r--r--Completion/Unix/Command/_stat2
-rw-r--r--Completion/Unix/Command/_stdbuf8
-rw-r--r--Completion/Unix/Command/_stgit52
-rw-r--r--Completion/Unix/Command/_strings2
-rw-r--r--Completion/Unix/Command/_strip102
-rw-r--r--Completion/Unix/Command/_subversion104
-rw-r--r--Completion/Unix/Command/_sudo56
-rw-r--r--Completion/Unix/Command/_sysctl8
-rw-r--r--Completion/Unix/Command/_tail23
-rw-r--r--Completion/Unix/Command/_tar2
-rw-r--r--Completion/Unix/Command/_tex4
-rw-r--r--Completion/Unix/Command/_texinfo9
-rw-r--r--Completion/Unix/Command/_tiff2
-rw-r--r--Completion/Unix/Command/_timeout8
-rw-r--r--Completion/Unix/Command/_tmux65
-rw-r--r--Completion/Unix/Command/_todo.sh8
-rw-r--r--Completion/Unix/Command/_top2
-rw-r--r--Completion/Unix/Command/_touch2
-rw-r--r--Completion/Unix/Command/_tr1
-rw-r--r--Completion/Unix/Command/_trash57
-rw-r--r--Completion/Unix/Command/_truncate69
-rw-r--r--Completion/Unix/Command/_truss6
-rw-r--r--Completion/Unix/Command/_uniq2
-rw-r--r--Completion/Unix/Command/_user_admin17
-rw-r--r--Completion/Unix/Command/_vmstat2
-rw-r--r--Completion/Unix/Command/_vorbis5
-rw-r--r--Completion/Unix/Command/_w4
-rw-r--r--Completion/Unix/Command/_watch5
-rw-r--r--Completion/Unix/Command/_wc1
-rw-r--r--Completion/Unix/Command/_wget3
-rw-r--r--Completion/Unix/Command/_xargs2
-rw-r--r--Completion/Unix/Command/_xfconf-query33
-rw-r--r--Completion/Unix/Command/_xmlsoft1
-rw-r--r--Completion/Unix/Command/_xxd14
-rw-r--r--Completion/Unix/Command/_xz17
-rw-r--r--Completion/Unix/Command/_zfs1980
-rw-r--r--Completion/Unix/Command/_zip2
-rw-r--r--Completion/Unix/Command/_zpool311
-rw-r--r--Completion/Unix/Type/_canonical_paths3
-rw-r--r--Completion/Unix/Type/_diff_options66
-rw-r--r--Completion/Unix/Type/_files45
-rw-r--r--Completion/Unix/Type/_ldap_attributes27
-rw-r--r--Completion/Unix/Type/_ldap_filters91
-rw-r--r--Completion/Unix/Type/_path_commands13
-rw-r--r--Completion/Unix/Type/_path_files2
-rw-r--r--Completion/Unix/Type/_remote_files5
-rw-r--r--Completion/Unix/Type/_ssh_hosts18
-rw-r--r--Completion/Unix/Type/_tar_archive2
-rw-r--r--Completion/Unix/Type/_time_zone3
-rw-r--r--Completion/Unix/Type/_umountable10
-rw-r--r--Completion/Unix/Type/_zfs_dataset15
-rw-r--r--Completion/Unix/Type/_zfs_keysource_props15
-rw-r--r--Completion/X/Command/_evince1
-rw-r--r--Completion/X/Command/_gnome-gv2
-rw-r--r--Completion/X/Command/_qiv6
-rw-r--r--Completion/X/Command/_xdvi18
-rw-r--r--Completion/X/Command/_xinput3
-rw-r--r--Completion/X/Command/_xset4
-rw-r--r--Completion/Zsh/Command/_cd11
-rw-r--r--Completion/Zsh/Command/_compadd2
-rw-r--r--Completion/Zsh/Command/_fc5
-rw-r--r--Completion/Zsh/Command/_kill8
-rw-r--r--Completion/Zsh/Command/_vared2
-rw-r--r--Completion/Zsh/Command/_zle1
-rw-r--r--Completion/Zsh/Context/_brace_parameter5
-rw-r--r--Completion/Zsh/Context/_dynamic_directory_name30
-rw-r--r--Completion/Zsh/Context/_parameter5
-rw-r--r--Completion/Zsh/Context/_redirect3
-rw-r--r--Completion/Zsh/Type/_command_names20
-rw-r--r--Completion/Zsh/Type/_globquals9
-rw-r--r--Completion/Zsh/Type/_parameters7
-rw-r--r--Completion/Zsh/Type/_ps123423
-rw-r--r--Completion/Zsh/Type/_suffix_alias_files1
-rw-r--r--Completion/bashcompinit5
-rw-r--r--Completion/compdump60
-rw-r--r--Completion/compinit22
254 files changed, 7854 insertions, 2570 deletions
diff --git a/Completion/BSD/Command/_bsd_pkg b/Completion/BSD/Command/_bsd_pkg
index 6bdce58e0..82cf6226c 100644
--- a/Completion/BSD/Command/_bsd_pkg
+++ b/Completion/BSD/Command/_bsd_pkg
@@ -78,12 +78,12 @@ _bsd_pkg() {
       ;;
     openbsd*)
       flags+=(
-        '-A[arch to assume for any package tests]:architecture:_obsd_architectures'
+        '-A+[arch to assume for any package tests]:architecture:_obsd_architectures'
         '-a[do not record packages as installed manually]'
         '-aa[force already installed packages to be tagged as installed automatically]'
-        '-B[specify destdir prefix]:destdir directory:_files -/'
+        '-B+[specify destdir prefix]:destdir directory:_files -/'
         '-c[while replacing packages, delete extra configuration file in the old package]'
-        '-D[specify failsafe to waive]:failsafe:((
+        '*-D+[specify failsafe to waive]:failsafe:((
           allversions\:"do not trim older p* variants of packages for updates"
           arch\:"architecture recorded in package may not match"
           checksum\:"verify checksums before deleting or tying old files"
@@ -91,9 +91,7 @@ _bsd_pkg() {
           donttie\:"do not try to find new files in old packages by comparing the stored sha256"
           downgrade\:"do not filter out package versions older than what is currently installed"
           installed\:"in update mode, reinstall an existing package with the same update signature"
-          libdepends\:"library specifications may not be fulfilled"
           nonroot\:"install even if not running as root"
-          paranoid\:"do not run any @exec/@unexec"
           repair\:"attempt to repair installed packages with missing registration data"
           scripts\:"external scripts may fail"
           SIGNER\:"list of trusted signers, separated by commas"
@@ -103,10 +101,10 @@ _bsd_pkg() {
         ))'
         '-I[force non-interactive mode]'
         '-i[force interactive mode]'
-        '-L[specify a localbase]:localbase:_files -/'
-        '-l[specify pkg_info output file to install]:pkg_info file:_files'
+        '-L+[specify a localbase]:localbase:_files -/'
+        '-l+[specify pkg_info output file to install]:pkg_info file:_files'
         '-m[always display progress meter]'
-        '-P[check distribution permissions]:permission type:(cdrom ftp)'
+        '-P+[check distribution permissions]:permission type:(ftp)'
         "-qq[don't check checksums]"
         '-r[replace existing packages]'
         "-s[don't install; just report disk size changes]"
@@ -143,26 +141,28 @@ _bsd_pkg() {
     case "$OSTYPE" in
     netbsd*)
       flags+=(
-        '(:)-a[delete all installed packages]'
         '(:)-A[remove automatically installed packages that are no longer required]'
         "-D[don't execute deinstallation scripts]"
         '-F[specify each package by an installed file]'
         '-f[force deinstallation]'
-        '-K[override PKG_DBDIR]:pkg_dbdir:_files -/'
+        '-ff[force deinstallation even if preserved]'
+        '-K+[override PKG_DBDIR]:pkg_dbdir:_files -/'
+        '-k[silently skip preserved packages]'
+        '-N[leave the files installed]'
         "-O[only delete the package's entries]"
-        '-P[specify destdir prefix]:destdir directory:_files -/'
-        '-p[specify prefix]:prefix directory:_files -/'
+        '-P+[specify destdir prefix]:destdir directory:_files -/'
+        '-p+[specify prefix]:prefix directory:_files -/'
         '-R[delete upward recursively]'
         '-r[delete recursively]'
         '-V[show version and exit]'
-        '(-a)*:package name:_bsd_pkg_pkgs_and_files'
+        '*:package name:_bsd_pkg_pkgs_and_files'
       )
       ;;
     openbsd*)
       flags+=(
         '-a[delete unused dependencies]'
-        '-B[specify destdir prefix]:destdir directory:_files -/'
-        '-D[specify failsafe to waive]:failsafe:((
+        '-B+[specify destdir prefix]:destdir directory:_files -/'
+        '*-D+[specify failsafe to waive]:failsafe:((
           baddepend\:"force deletion of packages even if they reference nonexistent dependencies"
           checksum\:"verify checksums before deleting or tying old files"
           dependencies\:"delete the set of packages that depend upon the requested packages"
@@ -190,11 +190,11 @@ _bsd_pkg() {
       '(:)-a[show all installed packages]'
       '-c[show comment fields]'
       '-d[show long descriptions]'
-      '-e[test if package is installed]:package name:_bsd_pkg_pkgs'
+      '-e+[test if package is installed]:package name:_bsd_pkg_pkgs'
       '-f[show packing list instructions]'
       '-I[show index lines]'
       '-L[show full pathnames of files]'
-      '-l[specify prefix string]:prefix string:'
+      '-l+[specify prefix string]:prefix string:'
       '-q[be quiet]'
       '-R[show list of installed requiring packages]'
       '-s[show total size occupied by each package]'
@@ -210,13 +210,13 @@ _bsd_pkg() {
         '-D[show install-message files]'
         '-F[specify each package by an installed file]'
         '-i[show install scripts]'
-        '-K[override PKG_DBDIR]:pkg_dbdir:_files -/'
+        '-K+[override PKG_DBDIR]:pkg_dbdir:_files -/'
         '-k[show deinstall scripts]'
         '-m[show mtree files]'
         '-N[show which packages each package was built with]'
         '-n[show which packages each package needs]'
         '-p[show installation prefixes]'
-        '-Q[show the definition of the specified variable from the build information]:variable:'
+        '-Q+[show the definition of the specified variable from the build information]:variable:'
         '-r[show list of installed requiring packages recursively]'
         '-S[show total size occupied by each package and its dependents]'
         '-u[show information for all user-installed packages]'
@@ -228,14 +228,19 @@ _bsd_pkg() {
       flags+=(
         '(:)-A[show all installed packages, including internal packages]'
         '-C[show certificate information]'
+        '*-D+[specify failsafe to waive]:failsafe:((
+          SIGNER\:"list of trusted signers, separated by commas"
+          snap\:"force %c and %m to expand to snapshots"
+          unsigned\:"allow the installation of unsigned packages without warnings/errors"
+        ))'
         '-E[show the package that contains the specified file]:file:_files'
         # XXX only with -L
         '-K[prefix filenames with category keywords]'
         '-M[show the install-message file]'
         '-m[only show manual installations]'
         '-P[show the pkgpath]'
-        '-Q[show packages matching the specified query]:query:'
-        '-r[check the list of packages for a specified pkgspec]:pkgspec:'
+        '-Q+[show packages matching the specified query]:query:'
+        '-r+[check the list of packages for a specified pkgspec]:pkgspec:'
         '-S[show the update signature]'
         '-t[show packages not required by any other]'
         '-U[show the deinstall-message file]'
diff --git a/Completion/BSD/Command/_chflags b/Completion/BSD/Command/_chflags
index 924b09acd..905aa0645 100644
--- a/Completion/BSD/Command/_chflags
+++ b/Completion/BSD/Command/_chflags
@@ -1,22 +1,31 @@
 #compdef chflags
 
-local args own='-g *(-u$EUID)'
+local own='-g *(-u$EUID)'
+local -a args recurse
 
 (( ! EUID || $+_comp_priv_prefix )) && own=
 
-if [[ $OSTYPE = (darwin|dragonfly|freebsd)* ]]; then
-  args=(
-    "-f[don't display diagnostic messages]"
-    '-v[verbose output]'
-  )
-fi
+case $OSTYPE in
+  (darwin|dragonfly|freebsd)*)
+    args=(
+      "-f[don't display diagnostic messages]"
+      '-v[verbose output]'
+    )
+  ;|
+  darwin*|freebsd*)
+    recurse=( "-x[don't cross mount points]" )
+  ;|
+  netbsd*)
+    args=( '-d[if the change requested would not alter the flags, attempt no change]' )
+  ;|
+esac
 
 _arguments -s -A "-*" : $args \
   ': :_file_flags' \
   '*:file:_files "$own"' \
   - opth \
   '-h[act on symlinks]' \
-  - optR \
+  - optR $recurse \
   '-R[recurse directories]' \
   '(-L -P)-H[follow symlinks on the command line (specify with -R)]' \
   '(-H -P)-L[follow all symlinks (specify with -R)]' \
diff --git a/Completion/BSD/Command/_freebsd-update b/Completion/BSD/Command/_freebsd-update
index 7dd907298..af37641e4 100644
--- a/Completion/BSD/Command/_freebsd-update
+++ b/Completion/BSD/Command/_freebsd-update
@@ -17,6 +17,7 @@ _arguments \
   '-d[store working files in workdir]:workdir:_files -/' \
   '-f[read configuration options from conffile]:conf file:_files' \
   '-F[force freebsd-update fetch to proceed where it normally would not]' \
+  '-j[operate on specified jail]: :_jails' \
   '-k[trust an RSA key with SHA256 of KEY]:RSA key' \
   '-r[specify the new release]:new release' \
   '-s[fetch files from the specified server or server pool]:server:_hosts' \
diff --git a/Completion/BSD/Command/_fw_update b/Completion/BSD/Command/_fw_update
index b01749f3f..84b5f808d 100644
--- a/Completion/BSD/Command/_fw_update
+++ b/Completion/BSD/Command/_fw_update
@@ -3,8 +3,10 @@
 _arguments -s -S -A "-*" \
   '(*)-a[install or update firmware for all drivers]' \
   '-d[delete drivers instead of adding them]' \
-  '-i[display information]' \
+  '-F[download firmware only]' \
   '-n[dry run]' \
-  '-p[use the firmware at specified path]:path:' \
+  '-p+[use the firmware at specified path]: : _alternative
+    "urls\:url\:_urls"
+    "directories\:path\:_directories"' \
   '*-v[verbose output]' \
   '(-a)*:driver:'
diff --git a/Completion/BSD/Command/_ipfw b/Completion/BSD/Command/_ipfw
index 2354a70fe..b910aa34d 100644
--- a/Completion/BSD/Command/_ipfw
+++ b/Completion/BSD/Command/_ipfw
@@ -1,7 +1,7 @@
-#compdef ipfw
+#compdef ipfw dnctl
 
 local word=$'/[^ \t\0]#[ \t\0]/' comma next pqs nat
-local -a actions address pathname ropts ca
+local -a actions address dummynet args ropts ca
 local -A opt_args nat_options
 
 _ipfw_tables() {
@@ -80,6 +80,46 @@ address=(
   \| \)
 )
 
+dummynet=(
+  $'/(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]/'
+    \( $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)"'
+  \| $'/profile[ \t\0]/' $word ':files:file:_files -qS " "'
+  \| $'/pipe[ \t\0]/' $word ': _message -e pipes pipe'
+  \| $'/weight[ \t\0]/' $word ': _message -e weights "weight (1-100) [1]"'
+  \| $'/type[ \t\0]/-'
+    \( $'/fq_(pie|codel)[ \t\0]/'
+      \( $'/limit[ \t\0]/' $word ': _message -e numbers "limit (packets) [10240]"'
+      \| $'/flows[ \t\0]/' $word ': _message -e numbers "flow queues [1024]"'
+      \| $'/quantum[ \t\0]/' ':parameters:parameter:$ca -F line quantum limit flows' \) \#
+      '/[]/'
+    \| $word ':types:scheduling algorithm:$ca fifo wf2q+ rr qfq fq_codel fq_pie fq_codel' \)
+  \| $'/buckets[ \t\0]/' $word ': _message -e sizes "hash table size (16-65536)"'
+  \| $'/mask[ \t\0]/' $word ':mask-specifiers:mask specifier:$ca dst-ip dst-ip6 src-ip src-ip6 dst-port src-port flow-id proto all'
+  \| $'/plr[ \t\0]/' $word ': _message -e numbers "packet loss rate (0.0-1.0)"'
+  \| $'/queue[ \t\0]/' $word ': _message -e sizes "queue size"'
+  \| $'/(red|gred)[ \t\0]/' $word ': _message -e thresholds thresholds'
+  \| $'/codel[ \t\0]/'
+    \( $'/(target|interval)[ \t\0]/' $word ': _message -e times "time (ms)"'
+    \| $'/(ecn|noecn)[ \t\0]/' ':options:option:$ca -F line target interval ecn noecn' \) \#
+    '/[]/'
+  \| $'/pie[ \t\0]/'
+    \( $'/(target|tupdate|max_burst)[ \t\0]/' $word ': _message -e times "time"'
+    \| $'/(alpha|beta)[ \t\0]/' $word ': _message -e weights weight'
+    \| $'/max_ecnth[ \t\0]/' $word ': _message -e probabilities probability'
+    \| $word ':options:option:$ca -F line alpha beta max_burst max_ecnth {,no}{ecn,capdrop,drand} onoff dre ts' \) \#
+    '/[]/'
+  \| // '-[[ $pqs = pipe ]]' $'/noerror[ \t\0]/' ':options:option:$ca -F line bw delay burst profile buckets mask noerror plr queue red gred codel pie'
+  \| // '-[[ $pqs = queue ]]' $'/noerror[ \t\0]/' ':options:option:$ca -F line pipe weight buckets mask noerror plr queue red gred codel pie'
+  \| // '-[[ $pqs = sched ]]' $'/[]/' ':options:option:$ca -F line type bw delay burst profile'
+  \) \#
+)
+
 actions=(
   $'/[^\0]##\0(-[a-zA-Z0-9]##[ \t]#)#/' # skip over options, completed by _arguments but can
   \(                                    # be quoted in one argument which that doesn't handle
@@ -241,48 +281,14 @@ actions=(
         \| $'/redirect_proto[ \t\0]/' $word ':protocols:protocol:$ca sctp tcp udp'
           $word ': _message -e ip-addresses "IP address"'
           $word ': _message -e ip-addresses "IP address"'
-        \| $word ':parameters:config parameter:$ca ip if log deny_in same_ports unreg_only unreg_cgn reset reverse proxy_only skip_global redirect_port redirect_addr redirect_proto'
+        \| $'/port_range[ \t\0]/'
+          '/[0-9]#-/' ': _message -e ports lower'
+          $word ': _message -e ports upper'
+        \| $word ':parameters:config parameter:$ca ip if log deny_in same_ports unreg_only unreg_cgn reset reverse proxy_only skip_global redirect_port redirect_addr redirect_proto port_range'
         \) \#
       \| $'/show[ \t\0]/' $word ':actions:action:(config log)'
       \| '/[]/' ':commands:command:$ca config show' \)
-  \| # dummynet configuration
-    $'/(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'
-      \| $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)"'
-    \| $'/profile[ \t\0]/' $word ':files:file:_files -qS " "'
-    \| $'/pipe[ \t\0]/' $word ': _message -e pipes pipe'
-    \| $'/weight[ \t\0]/' $word ': _message -e weights "weight (1-100) [1]"'
-    \| $'/type[ \t\0]/-'
-      \( $'/fq_(pie|codel)[ \t\0]/'
-        \( $'/limit[ \t\0]/' $word ': _message -e numbers "limit (packets) [10240]"'
-        \| $'/flows[ \t\0]/' $word ': _message -e numbers "flow queues [1024]"'
-        \| $'/quantum[ \t\0]/' ':parameters:parameter:$ca -F line quantum limit flows' \) \#
-        '/[]/'
-      \| $word ':types:scheduling algorithm:$ca fifo wf2q+ rr qfq fq_codel fq_pie fq_codel' \)
-    \| $'/buckets[ \t\0]/' $word ': _message -e sizes "hash table size (16-65536)"'
-    \| $'/mask[ \t\0]/' $word ':mask-specifiers:mask specifier:$ca dst-ip dst-ip6 src-ip src-ip6 dst-port src-port flow-id proto all'
-    \| $'/plr[ \t\0]/' $word ': _message -e numbers "packet loss rate (0.0-1.0)"'
-    \| $'/queue[ \t\0]/' $word ': _message -e sizes "queue size"'
-    \| $'/(red|gred)[ \t\0]/' $word ': _message -e thresholds thresholds'
-    \| $'/codel[ \t\0]/'
-      \( $'/(target|interval)[ \t\0]/' $word ': _message -e times "time (ms)"'
-      \| $'/(ecn|noecn)[ \t\0]/' ':options:option:$ca -F line target interval ecn noecn' \) \#
-      '/[]/'
-    \| $'/pie[ \t\0]/'
-      \( $'/(target|tupdate|max_burst)[ \t\0]/' $word ': _message -e times "time"'
-      \| $'/(alpha|beta)[ \t\0]/' $word ': _message -e weights weight'
-      \| $'/max_ecnth[ \t\0]/' $word ': _message -e probabilities probability'
-      \| $word ':options:option:$ca -F line alpha beta max_burst max_ecnth {,no}{ecn,capdrop,drand} onoff dre ts' \) \#
-      '/[]/'
-    \| // '-[[ $pqs = pipe ]]' $'/noerror[ \t\0]/' ':options:option:$ca -F line bw delay burst profile buckets mask noerror plr queue red gred codel pie'
-    \| // '-[[ $pqs = queue ]]' $'/noerror[ \t\0]/' ':options:option:$ca -F line pipe weight buckets mask noerror plr queue red gred codel pie'
-    \| // '-[[ $pqs = sched ]]' $'/[]/' ':options:option:$ca -F line type bw delay burst profile'
-    \) \#
+  \| $dummynet
   \| # sysctl shortcuts
     $'/(en|dis)able[ \t\0]/' ':sysctl-shortcuts:sysctl shortcut:$ca enable disable'
     $word ':values:value:(firewall altq one_pass debug verbose dyn_keepalive)'
@@ -292,11 +298,36 @@ actions=(
   \)
 )
 
-if (( $words[(I)-p*] )); then
-  pathname=( ':path:_files -P / -W /' )
-fi
+case $service in
+  ipfw)
+    _regex_arguments _ipfw_actions "$actions[@]"
+    args=(
+      '!-e' # nop for compatibility
+      '(-p)-a[show counter values when listing rules (implied by show)]'
+      '(-p)-b[show only the action and the comment]'
+      '-c[show rules in compact form]'
+      '(-p)-d[show dynamic rules in addition to static ones]'
+      '(-p)-D[act on dynamic states only]'
+      '-f[run without confirmation]'
+      '(-p)-i[format values as IP addresses in table listings]'
+      '-N[resolve addresses and service names in output]'
+      '-q[quiet output]'
+      '-S[show the set each rule belongs to]'
+      '(-p -T)-t[show timestamp of last match, ctime() format]'
+      '(-p -t)-T[show timestamp of last match as seconds since epoch]'
+      '(-a -b -d -D -i -s -t -T *)-p+[specify preprocessor]:preprocessor:_command_names -e'
+    )
+    if (( $words[(I)-p*] )); then
+      args+=( ':path:_files -P / -W /' )
+    fi
+  ;;
+  dnctl)
+    _regex_arguments _ipfw_actions \
+      $'/[^\0]##\0(-[a-zA-Z0-9]##[ \t]#)#/' \
+      "$dummynet[@]"
+  ;;
+esac
 
-_regex_arguments _ipfw_actions "$actions[@]"
 
 if [[ -prefix *[$' \t']* ]]; then
   # This allows from things like ipfw "-n add..."
@@ -304,22 +335,10 @@ if [[ -prefix *[$' \t']* ]]; then
   return
 fi
 
-_arguments -s $pathname \
-  '(-p)-a[show counter values when listing rules (implied by show)]' \
-  '(-p)-b[show only the action and the comment]' \
-  '-c[show rules in compact form]' \
-  '(-p)-d[show dynamic rules in addition to static ones]' \
-  '(-p)-D[act on dynamic states only]' \
-  '-f[run without confirmation]' \
+_arguments -s $args \
   '(- *)-h[display syntax summary]' \
-  '(-p)-i[format values as IP addresses in table listings]' \
   '-n[only check syntax, make no changes]' \
-  '-N[resolve addresses and service names in output]' \
-  '-q[quiet output]' \
-  '-S[show the set each rule belongs to]' \
   '(-p)-s+[sort pipes by field]:field (negative reverses):((0\:unsorted 1\:packets 2\:bytes 3\:total\ packets 4\:total\ bytes))' \
-  '(-p -T)-t[show timestamp of last match, ctime() format]' \
-  '(-p -t)-T[show timestamp of last match as seconds since epoch]' \
-  '(-a -b -d -D -i -s -t -T *)-p+[specify preprocessor]:preprocessor:_command_names -e' \
+  '-v[verbose]' \
   '*:::actions:= _ipfw_actions'
 
diff --git a/Completion/BSD/Command/_jexec b/Completion/BSD/Command/_jexec
index 6a2d05a81..cd99ebe91 100644
--- a/Completion/BSD/Command/_jexec
+++ b/Completion/BSD/Command/_jexec
@@ -6,7 +6,7 @@ _jexec_normal() {
   # relative paths are relative to the jail's root
   path=( "$(_call_program paths jls -j $words[1] path)"/$^path )
   shift 1 words; (( CURRENT-- ))
-  _normal
+  _normal -p $service
 }
 
 _jexec() {
diff --git a/Completion/BSD/Command/_kdump b/Completion/BSD/Command/_kdump
index 946296a75..e5c7c4cce 100644
--- a/Completion/BSD/Command/_kdump
+++ b/Completion/BSD/Command/_kdump
@@ -30,7 +30,7 @@ local args=(
   '-f+[use the specified file (- for stdin)]:dump file:_files'
   '-l[loop reading the trace file]'
   '-m+[maximum I/O bytes to display]:max data bytes:'
-  '-n[supress ad hoc translations]'
+  '-n[suppress ad hoc translations]'
   '-p+[show output only for the specified pid]: :_kdump_pid'
   '(-E    -T)-R[display relative timestamps]'
   '(-E -R   )-T[display absolute timestamps]'
diff --git a/Completion/BSD/Command/_ktrace b/Completion/BSD/Command/_ktrace
index 13c11f15d..9613ba2bf 100644
--- a/Completion/BSD/Command/_ktrace
+++ b/Completion/BSD/Command/_ktrace
@@ -4,7 +4,7 @@ local args=(
   '-a[append to the trace file]'
   '(*)-C[disable tracing on all user owned processes or all processes if executed by root]'
   '-c[clear the trace points]'
-  '-d[trace current decendants]'
+  '-d[trace current descendants]'
   '-f+[log trace to specified file]:trace file:_files'
   '(-p *)-g+[enable/disable tracing on specified process group]:pgid:_pgids'
   '-i[inherit trace flags on future children]'
diff --git a/Completion/BSD/Command/_ldap b/Completion/BSD/Command/_ldap
index 8fa17e2f8..181e6b0d0 100644
--- a/Completion/BSD/Command/_ldap
+++ b/Completion/BSD/Command/_ldap
@@ -80,8 +80,8 @@ else
         '-x[use simple authentication]' \
         '-Z[use StartTLS]' \
         '-z+[specify maximum number of results or 0 for no limit]:size limit [0]:' \
-        '::filter:' \
-        '*:attribute:'
+        '1: :_ldap_filters' \
+        '*: :_ldap_attributes'
       ;;
   esac
 fi
diff --git a/Completion/BSD/Command/_pfctl b/Completion/BSD/Command/_pfctl
index 23898882f..8063eb504 100644
--- a/Completion/BSD/Command/_pfctl
+++ b/Completion/BSD/Command/_pfctl
@@ -66,7 +66,7 @@ case $OSTYPE in
       "-N[don't perform domain name resolution]"
       '-P[display ports using service names]'
       '-S+[store pf state table in the specified file]:file:_files'
-      '-V+[select routing domain to be used to kill states]:routing domain'
+      '-V+[select routing domain to be used to kill states]:routing domain:_routing_domains'
     )
   ;;
   (free|net)bsd*)
@@ -91,7 +91,10 @@ case $OSTYPE in
     )
   ;|
   freebsd*)
-    args+=( '-P[display ports numerically]' )
+    args+=(
+      '-M[kill matching states in the opposite direction]'
+      '-P[display ports numerically]'
+    )
   ;;
 esac
 
diff --git a/Completion/BSD/Command/_rcctl b/Completion/BSD/Command/_rcctl
index 62cb8f634..457c3eb85 100644
--- a/Completion/BSD/Command/_rcctl
+++ b/Completion/BSD/Command/_rcctl
@@ -1,11 +1,20 @@
 #compdef rcctl
 
 local context state line
-local -a actions subcmds variables
+local -a actions lsarg subcmds variables
 
-actions=(check reload restart start stop)
+actions=(configtest check reload restart start stop)
 subcmds=(disable enable get getdef ls order set)
 variables=(class flags status timeout user)
+lsarg=(
+  'all:all services and daemons'
+  'failed:enabled but stopped daemons'
+  'off:disabled services and daemons'
+  'on:enabled services and daemons'
+  'rogue:daemons which are disabled but currently running'
+  'started:running daemons'
+  'stopped:stopped daemons'
+)
 
 if [[ $service == "rcctl" ]]; then
   _arguments -C \
@@ -23,11 +32,11 @@ case $service in
       ':variable:compadd -a variables'
     ;;
   ls)
-     _arguments ':display a list of services and daemons matching:(all failed off on started stopped)'
+    _arguments ':display a list of services and daemons matching:(($lsarg))'
     ;;
   order)
     _arguments \
-      ':service to start first:_services'
+      ':service to start first:_services' \
       '*:service to start next:_services'
     ;;
   set)
@@ -37,6 +46,6 @@ case $service in
       '*:argument:'
     ;;
   ${(~j:|:)actions}|disable|enable)
-    _arguments "*:service to $words[2]:_services"
+    _arguments "*:service to ${words[2]}:_services"
     ;;
 esac
diff --git a/Completion/BSD/Command/_sockstat b/Completion/BSD/Command/_sockstat
index 1d7973db7..f372fe1b3 100644
--- a/Completion/BSD/Command/_sockstat
+++ b/Completion/BSD/Command/_sockstat
@@ -21,6 +21,14 @@ case $OSTYPE in
       '-w[use wider field size for displaying addresses]'
     )
   ;|
+  freebsd<13->.*)
+    args+=(
+      '-C[display the congestion control module]'
+      '-i[display the inp_gencnt]'
+      "-n[don't resolve numeric UIDs to user names]"
+      '-q[quiet mode, do not print the header line]'
+    )
+  ;|
   freebsd*)
     for proto in ${${(M)${(f)"$(</etc/protocols)"}##[a-z0-9]*}}; do
       case $proto in
diff --git a/Completion/BSD/Command/_sysclean b/Completion/BSD/Command/_sysclean
new file mode 100644
index 000000000..755861644
--- /dev/null
+++ b/Completion/BSD/Command/_sysclean
@@ -0,0 +1,6 @@
+#compdef sysclean
+
+_arguments -s : \
+  '(-p)-a[include filenames used by installed packages]' \
+  '-i[include ignored filenames]' \
+  '(-a)-p[output package names that are using obsolete files]'
diff --git a/Completion/BSD/Command/_sysmerge b/Completion/BSD/Command/_sysmerge
new file mode 100644
index 000000000..00ee18299
--- /dev/null
+++ b/Completion/BSD/Command/_sysmerge
@@ -0,0 +1,6 @@
+#compdef sysmerge
+
+_arguments -s : \
+  '-b[run non-interactively]' \
+  '-d[do not take any automatic action]' \
+  '-p[only compare configuration of packages]'
diff --git a/Completion/BSD/Command/_syspatch b/Completion/BSD/Command/_syspatch
new file mode 100644
index 000000000..850636d09
--- /dev/null
+++ b/Completion/BSD/Command/_syspatch
@@ -0,0 +1,7 @@
+#compdef syspatch
+
+_arguments \
+  '(   -l -R -r)-c[list available patches]' \
+  '(-c    -R -r)-l[list installed patches]' \
+  '(-c -l    -r)-R[revert all patches]' \
+  '(-c -l -R   )-r[revert the most recently installed patch]'
diff --git a/Completion/BSD/Command/_sysupgrade b/Completion/BSD/Command/_sysupgrade
new file mode 100644
index 000000000..b1144b0d5
--- /dev/null
+++ b/Completion/BSD/Command/_sysupgrade
@@ -0,0 +1,9 @@
+#compdef sysupgrade
+
+_arguments -s -S -A '-*' : \
+  '-f[force an already applied upgrade]' \
+  '-k[keep the downloaded files]' \
+  '-n[do not reboot]' \
+  '(-s)-r[upgrade to the next release]' \
+  '(-r)-s[upgrade to a snapshot]' \
+  ':installurl:'
diff --git a/Completion/BSD/Type/_login_classes b/Completion/BSD/Type/_login_classes
index 227e3c748..a2e6983a9 100644
--- a/Completion/BSD/Type/_login_classes
+++ b/Completion/BSD/Type/_login_classes
@@ -1,4 +1,11 @@
 #autoload
 
+local expl login_classes
+
+login_classes=(${${(M)${(f)"$(</etc/login.conf)"}:#[^#[:blank:]]*}%%[:|]*})
+if [[ $OSTYPE = openbsd* ]]; then
+  login_classes+=(/etc/login.conf.d/*(N:t))
+fi
+
 _description login-classes expl 'login class'
-compadd "$@" "$expl[@]" - ${${(M)${(f)"$(</etc/login.conf)"}:#[^#[:blank:]]*}%%[:|]*}
+compadd "$@" "$expl[@]" - $login_classes
diff --git a/Completion/BSD/Type/_routing_domains b/Completion/BSD/Type/_routing_domains
new file mode 100644
index 000000000..4bb9f78b0
--- /dev/null
+++ b/Completion/BSD/Type/_routing_domains
@@ -0,0 +1,6 @@
+#autoload
+
+local expl
+
+_description routing-domains expl 'routing domain'
+compadd "$@" "$expl[@]" -  ${${(M)${(f)"$(_call_program routing-domains netstat -R)"}:#Rdomain *}#Rdomain }
diff --git a/Completion/BSD/Type/_routing_tables b/Completion/BSD/Type/_routing_tables
new file mode 100644
index 000000000..3ba1931fe
--- /dev/null
+++ b/Completion/BSD/Type/_routing_tables
@@ -0,0 +1,6 @@
+#autoload
+
+local expl
+
+_description routing-tables expl 'routing table'
+compadd "$@" "$expl[@]" -  ${(s: :)${${(M)${(f)"$(_call_program routing-tables netstat -R)"}:#  Routing tables#: *}#*: }}
diff --git a/Completion/Base/Completer/_approximate b/Completion/Base/Completer/_approximate
index dcd8b2776..96860b5a7 100644
--- a/Completion/Base/Completer/_approximate
+++ b/Completion/Base/Completer/_approximate
@@ -12,7 +12,6 @@
 
 local _comp_correct _correct_expl _correct_group comax cfgacc match
 local oldcontext="${curcontext}" opm="$compstate[pattern_match]"
-local dounfunction
 integer ret=1
 
 if [[ "$1" = -a* ]]; then
@@ -44,34 +43,31 @@ fi
 
 _tags corrections original
 
-# Otherwise temporarily define a function to use instead of
-# the builtin that adds matches. This is used to be able
-# to stick the `(#a...)' in the right place (after an
-# ignored prefix).
+# Otherwise temporarily define a function to use instead of the builtin that
+# adds matches. This is used to be able to stick the `(#a...)' in the right
+# place (after an ignored prefix).
 #
-# Current shell structure for use with "always", to make sure
-# we unfunction the compadd.
+# Current shell structure for use with "always", to make sure we unfunction our
+# compadd and restore any compadd function defined previously.
 {
-if (( ! $+functions[compadd] )); then
-  dounfunction=1
-  compadd() {
-    local ppre="$argv[(I)-p]"
-
-    [[ ${argv[(I)-[a-zA-Z]#U[a-zA-Z]#]} -eq 0 &&
-       "${#:-$PREFIX$SUFFIX}" -le _comp_correct ]] && return
-
-    if [[ "$PREFIX" = \~* && ( ppre -eq 0 || "$argv[ppre+1]" != \~* ) ]]; then
-      PREFIX="~(#a${_comp_correct})${PREFIX[2,-1]}"
-    else
-      PREFIX="(#a${_comp_correct})$PREFIX"
-    fi
+_shadow -s _approximate compadd
+compadd() {
+  local ppre="$argv[(I)-p]"
 
-    (( $_correct_group && ${${argv[1,(r)-(|-)]}[(I)-*[JV]]} )) &&
-        _correct_expl[_correct_group]=${argv[1,(r)-(-|)][(R)-*[JV]]}
+  [[ ${argv[(I)-[a-zA-Z]#U[a-zA-Z]#]} -eq 0 &&
+      "${#:-$PREFIX$SUFFIX}" -le _comp_correct ]] && return
 
-    builtin compadd "$_correct_expl[@]" "$@"
-  }
-fi
+  if [[ "$PREFIX" = \~* && ( ppre -eq 0 || "$argv[ppre+1]" != \~* ) ]]; then
+    PREFIX="~(#a${_comp_correct})${PREFIX[2,-1]}"
+  else
+    PREFIX="(#a${_comp_correct})$PREFIX"
+  fi
+
+  (( $_correct_group && ${${argv[1,(r)-(|-)]}[(I)-*[JV]]} )) &&
+      _correct_expl[_correct_group]=${argv[1,(r)-(-|)][(R)-*[JV]]}
+
+  compadd@_approximate "$_correct_expl[@]" "$@"
+}
 
 _comp_correct=1
 
@@ -115,7 +111,7 @@ while [[ _comp_correct -le comax ]]; do
 done
 
 } always {
-    [[ -n $dounfunction ]] && (( $+functions[compadd] )) && unfunction compadd
+  _unshadow
 }
 
 (( ret == 0 )) && return 0
diff --git a/Completion/Base/Completer/_expand b/Completion/Base/Completer/_expand
index 86b4ac6e4..e5e4f9b39 100644
--- a/Completion/Base/Completer/_expand
+++ b/Completion/Base/Completer/_expand
@@ -105,7 +105,7 @@ subd=("$exp[@]")
 
 # We need to come out of this with consistent quoting, by hook or by crook.
 integer done_quote
-local orig_exp=$exp
+local -a orig_exp=( $exp )
 if [[ "$force" = *g* ]] || zstyle -T ":completion:${curcontext}:" glob; then
   eval 'exp=( ${~exp//(#b)\\([ 	\"'"\'"'
 ])/$match[1]} ); exp=( ${(q)exp} )' 2>/dev/null && (( $#exp )) && done_quote=1
diff --git a/Completion/Base/Completer/_prefix b/Completion/Base/Completer/_prefix
index 74be5f47d..aea2f7863 100644
--- a/Completion/Base/Completer/_prefix
+++ b/Completion/Base/Completer/_prefix
@@ -49,13 +49,8 @@ for tmp in "$comp[@]"; do
     fi
 
     if [[ "$tmp" != _prefix ]] && "$tmp"; then
-      [[ compstate[nmatches] -gt 1 ]] && return 0
-      compadd -U -i "$IPREFIX" -I "$ISUFFIX" - "${compstate[unambiguous]%$suf}x"
-      compstate[list]=
-      if [[ -n $compstate[unambiguous] ]]; then
-        compstate[insert]=unambiguous
-      else
-        compstate[insert]=0
+      if [[ -n $compstate[old_list] || ${compstate[unambiguous]%$suf} == $PREFIX ]]; then
+        compstate[to_end]=match
       fi
       return 0
     fi
diff --git a/Completion/Base/Core/_description b/Completion/Base/Core/_description
index bdb4007a6..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,7 +79,14 @@ shift 2
 if [[ -z "$1" && $# -eq 1 ]]; then
   format=
 elif [[ -n "$format" ]]; then
-  zformat -f format "$format" "d:$1" "${(@)argv[2,-1]}"
+  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
 
 if [[ -n "$gname" ]]; then
diff --git a/Completion/Base/Core/_main_complete b/Completion/Base/Core/_main_complete
index 169ca1f40..408a66ee3 100644
--- a/Completion/Base/Core/_main_complete
+++ b/Completion/Base/Core/_main_complete
@@ -93,19 +93,15 @@ fi
 if [[ -z "$compstate[quote]" ]]; then
   if [[ -o equals ]] && compset -P 1 '='; then
     compstate[context]=equal
-  elif [[ "$PREFIX" != */* && "$PREFIX[1]" = '~' ]]; then
-    if [[ "$PREFIX" = '~['[^\]]# ]]; then
-      # Inside ~[...] should be treated as a subscript.
-      compset -p 2
-      # To be consistent, we ignore all but the contents of the square
-      # brackets.
-      compset -S '\]*'
-      compstate[context]=subscript
-      [[ -n $_comps[-subscript-] ]] && $_comps[-subscript-] && return
-    else
-      compset -p 1
-      compstate[context]=tilde
-    fi
+  elif [[ "$PREFIX" = \~\[[^]]# ]]; then
+    # Inside ~[...] should be treated as a subscript.
+    compset -p 2
+    # To be consistent, we ignore all but the contents of the square brackets.
+    compset -S '\]*'
+    compstate[context]=subscript
+  elif [[ "$PREFIX" = \~[^/]# ]]; then
+    compset -p 1
+    compstate[context]=tilde
   fi
 fi
 
diff --git a/Completion/Base/Core/_message b/Completion/Base/Core/_message
index 4d5645eaf..dbeed4a88 100644
--- a/Completion/Base/Core/_message
+++ b/Completion/Base/Core/_message
@@ -39,7 +39,7 @@ else
 fi
 
 if [[ -n "$format$raw" ]]; then
-  [[ -z "$raw" ]] && zformat -f format "$format" "d:$1" "${(@)argv[2,-1]}"
+  [[ -z "$raw" ]] && zformat -F format "$format" "d:$1" "${(@)argv[2,-1]}"
   builtin compadd "$gopt[@]" -x "$format"
   _comp_mesg=yes
 fi
diff --git a/Completion/Base/Utility/_arguments b/Completion/Base/Utility/_arguments
index 3f1b39304..5ff34ff47 100644
--- a/Completion/Base/Utility/_arguments
+++ b/Completion/Base/Utility/_arguments
@@ -132,8 +132,8 @@ if (( long )); then
 	 # variant syntax seen in fetchmail:
 	 # --[fetch]all  means --fetchall or --all.
 	 # maybe needs to be more general
-	 if [[ $start = (#b)(*)\[(*)\](*) ]]; then
-	   tmp+=("${match[1]}${match[2]}${match[3]}" "${match[1]}${match[3]}")
+	 if [[ $start = (#b)--\[(*)\](*) ]]; then
+	   tmp+=("--${match[1]}${match[2]}" "--${match[2]}")
 	 else
 	   tmp+=($start)
 	 fi
@@ -513,8 +513,8 @@ if (( $# )) && comparguments -i "$autod" "$singopt[@]" "$@"; then
 	    tmp2=( "${PREFIX}${(@M)^${(@)${(@)tmp1%%:*}#[-+]}:#?}" )
 
             _describe -O option \
-                      tmp1 tmp2 -Q -S '' -- \
-		      tmp3 -Q
+                tmp1 tmp2 -S '' -- \
+                tmp3
 
             [[ -n "$optarg" && "$single" = next && nm -eq $compstate[nmatches] ]] &&
                 _all_labels options expl option \
@@ -525,9 +525,9 @@ if (( $# )) && comparguments -i "$autod" "$singopt[@]" "$@"; then
         else
           next+=( "$odirect[@]" )
           _describe -O option \
-                    next -Q -M "$matcher" -- \
-                    direct -QS '' -M "$matcher" -- \
-                    equal -QqS= -M "$matcher"
+              next -M "$matcher" -- \
+              direct -S '' -M "$matcher" -- \
+              equal -qS= -M "$matcher"
         fi
 	PREFIX="$prevpre"
 	IPREFIX="$previpre"
diff --git a/Completion/Base/Utility/_numbers b/Completion/Base/Utility/_numbers
new file mode 100644
index 000000000..069fc75a4
--- /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/Base/Utility/_shadow b/Completion/Base/Utility/_shadow
new file mode 100644
index 000000000..9e78af38f
--- /dev/null
+++ b/Completion/Base/Utility/_shadow
@@ -0,0 +1,97 @@
+#autoload
+
+## Recommended usage:
+#  {
+#    _shadow fname
+#    function fname {
+#      # Do your new thing
+#    }
+#    # Invoke callers of fname
+#  } always {
+#    _unshadow
+#  }
+## Alternate usage:
+# {
+#   _shadow -s suffix fname
+#   function fname {
+#     # Do other stuff
+#     fname@suffix new args for fname
+#   }
+#   # Invoke callers of fname
+# } always {
+#   _unshadow
+# }
+##
+
+# BUGS:
+# * `functions -c` acts like `autoload +X`
+# * name collisions are possible in alternate usage
+# * functions that examine $0 probably misfire
+
+zmodload zsh/parameter # Or what?
+
+# This probably never comes up, but protect ourself from recursive call
+# chains that may duplicate the top elements of $funcstack by creating
+# a counter of _shadow calls and using it to make shadow names unique.
+builtin typeset -gHi .shadow.depth=0
+builtin typeset -gHa .shadow.stack
+
+# Create a copy of each fname so that a caller may redefine
+_shadow() {
+  emulate -L zsh
+  local -A fsfx=( -s ${funcstack[2]}:${functrace[2]}:$((.shadow.depth+1)) )
+  local fname shadowname
+  local -a fnames
+  zparseopts -K -A fsfx -D s:
+  for fname; do
+    shadowname=${fname}@${fsfx[-s]}
+    if (( ${+functions[$shadowname]} ))
+    then
+      # Called again with the same -s, just ignore it
+      continue
+    elif (( ${+functions[$fname]} ))
+    then
+      builtin functions -c -- $fname $shadowname
+      fnames+=(f@$fname)
+    elif (( ${+builtins[$fname]} ))
+    then
+      eval "function -- ${(q-)shadowname} { builtin ${(q-)fname} \"\$@\" }"
+      fnames+=(b@$fname)
+    else
+      eval "function -- ${(q-)shadowname} { command ${(q-)fname} \"\$@\" }"
+      fnames+=(c@$fname)
+    fi
+  done
+  [[ -z $REPLY ]] && REPLY=${fsfx[-s]}
+  builtin set -A .shadow.stack ${fsfx[-s]} $fnames -- ${.shadow.stack}
+  ((.shadow.depth++))
+}
+
+# Remove the redefined function and shadowing name
+_unshadow() {
+  emulate -L zsh
+  local fname shadowname fsfx=${.shadow.stack[1]}
+  local -a fnames
+  [[ -n $fsfx ]] || return 1
+  shift .shadow.stack
+  while [[ ${.shadow.stack[1]?no shadows} != -- ]]; do
+    fname=${.shadow.stack[1]#?@}
+    shadowname=${fname}@${fsfx}
+    if (( ${+functions[$fname]} )); then
+      builtin unfunction -- $fname
+    fi
+    case ${.shadow.stack[1]} in
+      (f@*) builtin functions -c -- $shadowname $fname ;&
+      ([bc]@*) builtin unfunction -- $shadowname ;;
+    esac
+    shift .shadow.stack
+  done
+  [[ -z $REPLY ]] && REPLY=$fsfx
+  shift .shadow.stack
+  ((.shadow.depth--))
+}
+
+# This is tricky.  When we call _shadow recursively from autoload,
+# there's an extra level of stack in $functrace that will confuse
+# the later call to _unshadow.  Fool ourself into working correctly.
+(( ARGC )) && _shadow -s ${funcstack[2]}:${functrace[2]}:1 "$@"
diff --git a/Completion/Base/Utility/_values b/Completion/Base/Utility/_values
index 688ada848..5ed79e890 100644
--- a/Completion/Base/Utility/_values
+++ b/Completion/Base/Utility/_values
@@ -60,7 +60,7 @@ if compvalues -i "$keep[@]" "$@"; then
       _describe "$descr" \
         noargs "$sep[@]" -M 'r:|[_-]=* r:|=*' -- \
         args -S "${argsep}" -M 'r:|[_-]=* r:|=*' -- \
-        opts -qS "${argsep}" -r "${argsep}${sep} \\t\\n\\-" -M 'r:|[_-]=* r:|=*'
+        opts -qS "${argsep}" -r "${argsep}${sep[2]} \\t\\n\\-" -M 'r:|[_-]=* r:|=*'
 
       curcontext="$oldcontext"
 
diff --git a/Completion/Base/Widget/_complete_debug b/Completion/Base/Widget/_complete_debug
index 94fd4accd..d8b1bd837 100644
--- a/Completion/Base/Widget/_complete_debug
+++ b/Completion/Base/Widget/_complete_debug
@@ -19,7 +19,7 @@ integer debug_fd=-1
     setopt localoptions no_ignorebraces
     debug_indent=( '%'{3..20}'(e. .)' )
   }
-  local PROMPT4 PS4="${(j::)debug_indent}+%N:%i> "
+  local PROMPT4="$PROMPT4" PS4="${(j::)debug_indent}+%N:%i> "
   setopt xtrace
   : $ZSH_NAME $ZSH_VERSION
   ${1:-_main_complete}
diff --git a/Completion/Base/Widget/_complete_help b/Completion/Base/Widget/_complete_help
index 69855de9d..da5947e7f 100644
--- a/Completion/Base/Widget/_complete_help
+++ b/Completion/Base/Widget/_complete_help
@@ -10,6 +10,7 @@ _complete_help() {
   local -H _help_filter_funcstack="alternative|call_function|describe|dispatch|wanted|requested|all_labels|next_label"
 
   {
+    _shadow compadd compcall zstyle
     compadd() { return 1 }
     compcall() { _help_sort_tags use-compctl }
     zstyle() {
@@ -43,7 +44,7 @@ _complete_help() {
 
     ${1:-_main_complete}
   } always {
-    unfunction compadd compcall zstyle
+    _unshadow compadd compcall zstyle
   }
 
   for i in "${(@ok)help_funcs}"; do
diff --git a/Completion/Darwin/Command/_open b/Completion/Darwin/Command/_open
index 2563e5eb5..1c693dfb8 100644
--- a/Completion/Darwin/Command/_open
+++ b/Completion/Darwin/Command/_open
@@ -25,14 +25,20 @@ _open() {
     '(: * -)--args[pass remaining arguments to application]:*:::argument' \
     '(-a -b -e -f -R -t)-b+[specify application bundle identifier]: :->bundle-ids' \
     '(-a -b -e -f -R -t)-e[open with TextEdit]' \
+    '*--env[add the environment variable of the launched application]:env_var=value:_parameters -g "*export*" -qS=' \
     '(-h)-f[open standard input with TextEdit or specified application]' \
     '(-R)-F[open application with fresh state]' \
-    '-g[do not bring application to foreground]' \
+    '(-j)-g[do not bring application to foreground]' \
     '(-f)-h[open library header file]' \
+    '(-g)-j[launch the app hidden]' \
     '(-R)-n[always open new instance of application]' \
     '(-a -b -e -f -F -n -s -t -W --args)-R[reveal in Finder]' \
     '(-R)-s+[specify SDK name/version]: :->sdks' \
+    '--stdin[launch the application with stdin connected to the given file]:file:_files' \
+    '--stdout[launch the application with stdout connected to the given file]:file:_files' \
+    '--stderr[launch the application with stderr connected to the given file]:file:_files' \
     '(-a -b -e -f -R -t)-t[open with default text editor]' \
+    '-u[open URL with whatever application claims the url scheme]:url:_urls' \
     '(-R)-W[wait for application to exit]' \
     '(-f)*: :->files' \
   && ret=0
diff --git a/Completion/Darwin/Command/_otool b/Completion/Darwin/Command/_otool
index c3fc70b91..b6a30a730 100644
--- a/Completion/Darwin/Command/_otool
+++ b/Completion/Darwin/Command/_otool
@@ -13,6 +13,7 @@ _arguments \
   '-D[display just the internal name of shared lib]' \
   '-s[display the contents of the specified section]:segment name: :section name: ' \
   '-t[display the contents of (__TEXT,__text) section]' \
+  '-x[display the content of every __text section found in the file]' \
   '-d[display the contents of (__DATA,__data) section]' \
   '-o[display the contents of __OBJC segment]' \
   '-r[display the relocation entries]' \
@@ -25,6 +26,9 @@ _arguments \
   '-G[display the data in code table]' \
   '-C[display the linker optimization hints]' \
   '-P[print the info_plist section as strings]' \
+  '-dyld_info[print bind and rebase information used by dyld]' \
+  '-dyld_opcodes[print raw dyld bind and rebase opcodes present in a final linked binary]' \
+  '-chained_fixups[print raw chained fixup data present in a final linked binary]' \
   '-p[with -t and -v/V: start disassembly from the specified symbol]:symbol name: ' \
   '-v[display verbosely (symbolically) when possible]' \
   '-V[display disassembled operands symbolically]' \
@@ -34,7 +38,8 @@ _arguments \
   '-function_offsets[with disassembly, print decimal offset from the last label]' \
   '-j[with disassembly, print opcode bytes]' \
   "-Q[use otool's disassembler]" \
-  '-arch[select the specified architecture from a universal file]:arch:(i386 x86_64)' \
+  '-addr_slide=[add an arbitrary slide to each pointer value when it is displayed]:slide size' \
+  '-arch[select the specified architecture from a universal file]:arch:(i386 x86_64 x86_64h arm64 arm64e all)' \
   '-m[object file names are not assumed to be in archive(member) syntax]' \
   '(- *)--version[print version of otool]' \
   '*:file:_object_files' && return 0
diff --git a/Completion/Darwin/Command/_qtplay b/Completion/Darwin/Command/_qtplay
index 39a7c6de2..839efee83 100644
--- a/Completion/Darwin/Command/_qtplay
+++ b/Completion/Darwin/Command/_qtplay
@@ -15,6 +15,6 @@ _arguments -S \
   '-t[specify update time]:update time (seconds)' \
   '-T[kill time]:ticks' \
   '-V[volume]:percentage of normal volume' \
-  '(-)'{-?,--help,-h}'[display help information]' \
+  '(-)'{-\?,--help,-h}'[display help information]' \
   '(-)*:quicktime file:_files'
 
diff --git a/Completion/Darwin/Command/_shortcuts b/Completion/Darwin/Command/_shortcuts
new file mode 100644
index 000000000..5e15f0a07
--- /dev/null
+++ b/Completion/Darwin/Command/_shortcuts
@@ -0,0 +1,88 @@
+#compdef shortcuts
+
+_shortcuts() {
+  local curcontext="$curcontext"
+  local -a line state
+
+  _arguments -C \
+    "1: :->subcommand" \
+    "*:: :->args"
+
+  case $state in
+  subcommand)
+    _values "subcommand" \
+      "run[run a shortcut]" \
+      "list[list your shortcuts]" \
+      "view[view a shortcut in shortcuts]" \
+      "sign[sign a shortcut file]" \
+      "help[show subcommand help information]"
+    ;;
+  args)
+    case ${line[1]} in
+    run)
+      _shortcuts-run
+      ;;
+    list)
+      _shortcuts-list
+      ;;
+    view)
+      _shortcuts-view
+      ;;
+    sign)
+      _shortcuts-sign
+      ;;
+    help)
+      _shortcuts-help
+      ;;
+    esac
+    ;;
+  esac
+}
+
+_shortcuts-run() {
+  _arguments \
+    ":shortcut name or identifier:$(_shortcut_options)" \
+    {-i,--input-path}'[specify input to provide to the shortcut]:input path:_files' \
+    {-o,--output-path}'[specify where to write the shortcut output, if applicable]:output path:_files' \
+    '--output-type[specify type to output data in]:output type (Universal Type Identifier format)' \
+    {-h,--help}'[show help information]'
+}
+
+_shortcuts-list() {
+  _arguments \
+    {-f,--folder-name}"[specify folder name or identifier to list shortcuts in, or \"none\" to list shortcuts not in a folder]:folder name:$(_shortcut_folder_options)" \
+    '--folders[list folders instead of shortcuts]' \
+    '--show-identifiers[show identifiers with each result]' \
+    {-h,--help}'[show help information]'
+}
+
+_shortcuts-view() {
+  _arguments \
+    ":shortcut name:$(_shortcut_options)" \
+    {-h,--help}'[show help information]'
+}
+
+_shortcuts-sign() {
+  _arguments \
+    {-m,--mode}'[specify signing mode]:mode [people-who-know-me]:(anyone people-who-know-me)' \
+    {-i,--input}'[specify shortcut file to sign]:input:_files -g "*.shortcut(-.)"' \
+    {-o,--output}'[specify output path for the signed shortcut file]:output:_files -g "*.shortcut(-.)"' \
+    {-h,--help}'[show help information]'
+}
+
+_shortcuts-help() {
+  _arguments \
+    ":subcommand:(run list view sign help)"
+}
+
+# utilities
+
+_shortcut_options() {
+  echo "($(shortcuts list | sed 's/ /\\ /g'))"
+}
+
+_shortcut_folder_options() {
+  echo "($(shortcuts list --folders | sed 's/ /\\ /g') none)"
+}
+
+_shortcuts "$@"
diff --git a/Completion/Darwin/Command/_softwareupdate b/Completion/Darwin/Command/_softwareupdate
index 6054fd768..9ac9b9cd2 100644
--- a/Completion/Darwin/Command/_softwareupdate
+++ b/Completion/Darwin/Command/_softwareupdate
@@ -1,75 +1,110 @@
 #compdef softwareupdate
 
-_softwareupdate_ignored_update_name() {
-  if [[ -z "$_softwareupdate_ignored_updates" ]]; then
-    local res="$(_call_program pkgs softwareupdate --ignored)"
-    _softwareupdate_ignored_updates=("${(Qs/, /)${${res#Current ignored updates: \(}%\)}}")
-  fi
-  if (( ${#_softwareupdate_ignored_updates} > 0 )); then
-    _wanted pkgs expl "ignored package" compadd -a _softwareupdate_ignored_updates && return 0
-  fi
-  return 1
+# rebuild cache for available updates everyday (ad hoc)
+_softwareupdate_caching_policy() {
+  local -a newer=( "$1"(Nmd-1) )
+  return $#newer
 }
 
-_softwareupdate_update_name() {
-  local name line
-  if [[ -z "$_softwareupdate_updates" ]]; then
+# completes available updates (with description)
+
+_softwareupdate_update_names () {
+  local name line update_policy ret=1
+  local cache_id=softwareupdate-updates
+  zstyle -s ":completion:${curcontext}:" cache-policy update_policy
+  if [[ -z "$update_policy" ]]; then
+    zstyle ":completion:${curcontext}:" cache-policy \
+                                      _softwareupdate_caching_policy
+ fi
+ if { [[ ! -v _softwareupdate_updates ]] || _cache_invalid $cache_id } &&
+    ! _retrieve_cache $cache_id; then
+    # Output format of 'softwareupdate --list' seems to be not stable,
+    # but at least on macOS 12 and 13 it contains the following two lines
+    # for each update:
+    #* Label: update name (may contain spaces)
+    #        Title: description of the update (single TAB before Title:)
+    # softwareupdate(1) manpage says the '*' before the Label: is replaced
+    # by '-' for non-recommended updates (but I've never seen it).
     _softwareupdate_updates=()
-    for line in ${(f)"$(_call_program pkgs softwareupdate --list)"}; do
-      if [[ $line == '   '* ]]; then
-        name="${line#   ? }"
-      elif [[ -n "$name" ]]; then
-        _softwareupdate_updates+=("$name:${line#	}")
-        name=""
+    for line in ${(f)"$(_call_program updates softwareupdate --list)"}; do
+      if [[ $line = [-\*]\ Label:\ (#b)(*) ]]; then
+        # add '*' or '-' in front of the name; this will be removed later
+        name=$line[1]$match[1]
+      elif [[ -n $name && $line = $'\t'Title:\ (#b)(*) ]]; then
+        _softwareupdate_updates+=( $name:$match[1] )
+        name=
       fi
     done
+    _store_cache $cache_id _softwareupdate_updates
   fi
-  if (( ${#_softwareupdate_updates} > 0 )); then
-    _describe -t pkgs "update name" _softwareupdate_updates && return 0
-  fi
-  return 1
+  # recommended and non-recommended updates
+  local rec=( ${${_softwareupdate_updates:#-*}#\*} )
+  local non=( ${${(M)_softwareupdate_updates:#-*}#-} )
+  _describe -t updates "update" rec && ret=0
+  _describe -t non-recommended-updates "non-recommended update" non && ret=0
+  return ret
+}
+
+# completes versions of available macOS full installer (with description)
+
+_softwareupdate_installer_versions () {
+  local versions=()
+  for line in ${(f)"$(_call_program installer-versions
+                        softwareupdate --list-full-installers 2>/dev/null)"}; do
+    if [[ $line = \*\ Title:\ *\ Version:\ (#b)([0-9.]##)* ]]; then
+      versions+=( ${match[1]}:${line#*Title: } )
+    fi
+  done
+  _describe -t insteller-versions "version" versions
 }
 
+# main completion script
+
 _softwareupdate() {
-  local context state line expl
-  typeset -A opt_args
+  local -a specs
 
-  _arguments -R \
-    '(-h --help -l --list)-q[quiet mode]' \
-    {-l,--list}'[list all available updates]:*:' \
-    {-d,--download}'[download to directory set in InternetConfig]:*:' \
-    {-i,--install}'[install (requires root)]:*: :->install' \
-    '--ignored[show or manage ignored updates list (per-user)]:*:: :->ignored' \
-    '--schedule[scheduler preferences (per-user)]:automatic checking:(on off)' \
-    {-h,--help}'[print command usage]:*:' && return 0
+  if (( ${words[(I)(-i|--install)]} == 0 )); then
+    specs=(
+      '--no-scan[do not scan when listing or installing updates]'
+      '--product-types[limit a scan to a particular product type only]:list of product types'
+      '--products[a comma separated list of product keys to operate on]:list of product keys'
+      '--force[force an operation to complete]'
+      '--agree-to-license[agree to the software license agreement without user interaction]'
+      '--verbose[enable verbose output]'
+      '(* -)'{-h,--help}'[print command usage]:*:'
 
-  case "$state" in
-    install)
-      _arguments \
-        '(* -a --all)'{-a,--all}'[all available active updates]' \
-        '(* -r --req)'{-r,--req}'[all required active updates]' \
-        '*:update name:_softwareupdate_update_name' && return 0
-      ;;
-    ignored)
-      local -a ignored_subcmd
-      ignored_subcmd=(add remove)
+      + '(operation)'
 
-      if (( CURRENT == 1 )); then
-        _describe -t commands "subcommand" ignored_subcmd && return 0
-      fi
-      case $words[1] in
-        add)
-          _softwareupdate_update_name && return 0
-          ;;
-        remove)
-          _arguments \
-            '(* -a --all)'{-a,--all}'[all available active updates]' \
-            '*:update name:_softwareupdate_ignored_update_name' && return 0
-          ;;
-      esac
-      ;;
-  esac
-  return 1
+      {-l,--list}'[list all available updates]'
+      {-d,--download}'[download but not install specified updates]:*: : _softwareupdate_update_names'
+      {-i,--install}'[download and install specified updates]'
+      '(* -)--list-full-installers[list the available macOS installers]'
+      '(* -)--fetch-full-installer[install the latest recommended macOS installer]: :(--full-installer-version): : _softwareupdate_installer_versions'
+      '--install-rosetta[install Rosetta 2 (Apple Silicon only)]'
+      '(* -)--schedule[returns the per-machine automatic check preference]'
+      '--background[trigger a background scan and update operation]'
+      '(* -)--dump-state[log the internal state of the SU daemon to /var/log/install.log]'
+      '--evaluate-products[evaluate a list of product keys specified by the --products option]'
+      '--history[show the install history]'
+    )
+  else    # if -i/--install is already on the command line
+    specs=(
+      !{-i,--install}
+      '(-R --restart)'{-R,--restart}'[automatically restart if required to complete installation]'
+      '--stdinpass[password to authenticate as an owner (Apple Silicon only)]'
+      '--user[local username to authenticate as an owner (Apple Silicon only)]'
+      '*: : _softwareupdate_update_names'
+
+      + '(select-updates)'
+
+      '(*)'{-a,--all}'[all updates that are applicable to your system]'
+      '(*)'{-r,--recommended}'[all updates recommended for your system]'
+      '(*)--os-only[only macOS updates]'
+      '(*)--safari-only[only Safari updates]'
+    )
+  fi
+
+  _arguments -s : $specs
 }
 
 _softwareupdate "$@"
diff --git a/Completion/Darwin/Command/_sw_vers b/Completion/Darwin/Command/_sw_vers
index 11814e0b0..415d3a05c 100644
--- a/Completion/Darwin/Command/_sw_vers
+++ b/Completion/Darwin/Command/_sw_vers
@@ -1,6 +1,11 @@
 #compdef sw_vers
 
+# Only options with a single dash '-' are accepted on Monterey or older,
+# but both a single and double dashes are accepted on Ventura (or newer).
+# We may replace '-' by '--' when Monterey fades out.
+
 _arguments : \
   '(-)-buildVersion[display build version only]' \
   '(-)-productName[display product name only]' \
-  '(-)-productVersion[display product version only]'
+  '(-)-productVersion[display product version only]' \
+  '(-)-productVersionExtra[display rapid security response version only]'
diff --git a/Completion/Darwin/Command/_system_profiler b/Completion/Darwin/Command/_system_profiler
index fe197579d..0fd8b473b 100644
--- a/Completion/Darwin/Command/_system_profiler
+++ b/Completion/Darwin/Command/_system_profiler
@@ -4,17 +4,13 @@ typeset -A opt_args
 local context state state_descr line
 local -a _data_types
 
-# TODO: Should this be static?  Calling `system_profiler -listDataTypes` takes
-# about 0.07-0.08 secs on my machine.  Does this list ever change (between
-# different versions of OS X)?
-_data_types=( SP{AirPort,Applications,Audio,Bluetooth,Camera,CardReader,Component,ConfigurationProfile,DeveloperTools,Diagnostics,DisabledSoftware,DiscBurning,Displays,Ethernet,Extensions,FibreChannel,FireWire,Firewall,Fonts,Frameworks,Hardware,HardwareRAID,InstallHistory,Logs,ManagedClient,Memory,Network,NetworkLocation,NetworkVolume,PCI,ParallelATA,ParallelSCSI,Power,PrefPane,Printers,PrintersSoftware,SAS,SPI,SerialATA,Software,StartupItem,Storage,SyncServices,Thunderbolt,USB,UniversalAccess,WWAN}DataType )
-# the dynamic alternative is:
-#_data_types=( ${${(f)"$(_call_program path system_profiler -listDataTypes 2>/dev/null)"}[2,-1]} )
+_data_types=( ${${(f)"$(_call_program data-types system_profiler -listDataTypes 2>/dev/null)"}[2,-1]} )
 
 _arguments \
   '(- *)-usage' \
   '(- *)-listDataTypes[lists the available datatypes]' \
-  '(-listDataTypes -usage)-xml[generate xml output]' \
+  '(-listDataTypes -usage -json)-xml[generate xml output]' \
+  '(-listDataTypes -usage -xml)-json[generate json output]' \
   '(-listDataTypes -usage)-detailLevel[level of detail for the report]:detail level:(mini basic full)' \
-  '(-listDataTypes -usage)-timeout+[maximum time to wait in seconds]' \
+  '(-listDataTypes -usage)-timeout+[maximum time to wait in seconds(0 means no timeout)]:timeout seconds' \
   '(-listDataTypes -usage)*:data type:'"($_data_types)"
diff --git a/Completion/Darwin/Command/_trash b/Completion/Darwin/Command/_trash
deleted file mode 100644
index 658716432..000000000
--- a/Completion/Darwin/Command/_trash
+++ /dev/null
@@ -1,22 +0,0 @@
-#compdef trash
-
-# We only provide completion for Ali Rantakari's trash utility. There are/were a
-# few others floating around with that name, but this is the one available as
-# `trash` in Homebrew and MacPorts
-_pick_variant ali='(Rantakari|hasseg)' other --version && {
-  # The hidden options here are options to rm that trash silently (and
-  # undocumentedly) ignores. Some options are not made mutually exclusive where
-  # they technically could be, for compatibility with aliases, etc.
-  _arguments -s -S -A '-*' : \
-    '!-'{d,f,i,r,P,R,W} \
-    '(: * -F -l -v)-e[empty trash]' \
-    '-F[use Finder instead of system API]' \
-    '(: * -e -F -s -y)-l[list items in trash]' \
-    '(: * -F -l -v)-s[securely empty trash]' \
-    '-v[increase output verbosity]' \
-    '-y[skip confirmation prompts (with -e or -s)]' \
-    '*: :_files'
-  return
-}
-
-_default
diff --git a/Completion/Debian/Command/_apt b/Completion/Debian/Command/_apt
index 494d3bf82..19f818c27 100644
--- a/Completion/Debian/Command/_apt
+++ b/Completion/Debian/Command/_apt
@@ -422,15 +422,14 @@ _apt-cmd () {
 	/$'[^\0/=]#='/ /'[]'/ ':apt-package-versions:package version:_apt_versions_of_binary_package' \| \
       \) \
     \) \| \
-    /$'(remove|reinstall|purge)\0'/ /$'[^\0]#\0'/ ':packages::_deb_packages "$expl_packages[@]" installed' \# \| \
+    /$'((|auto)(remove|purge)|reinstall)\0'/ /$'[^\0]#\0'/ ':packages::_deb_packages "$expl_packages[@]" installed' \# \| \
     /$'upgrade\0'/ \| \
     /$'autoclean\0'/ \| \
     /$'changelog\0'/ /$'[^\0]#\0'/ ':packages::_deb_packages "$expl_packages[@]" avail' \# \| \
-    /$'autoremove\0'/ \| \
     /$'full-upgrade\0'/ \| \
     /$'dist-upgrade\0'/ \| \
     /$'edit-sources\0'/ \| \
-    /"[]"/ ':argument-1::compadd "$expl_action[@]" list search showsrc show depends rdepends policy update install reinstall download source build-dep remove upgrade full-upgrade dist-upgrade edit-sources autoclean changelog autoremove purge'
+    /"[]"/ ':argument-1::compadd "$expl_action[@]" list search showsrc show depends rdepends policy update install reinstall download source build-dep remove upgrade full-upgrade dist-upgrade edit-sources autoclean changelog autopurge autoremove purge'
 
   _apt-cmd () {
     local expl_action expl_packages subcmd
@@ -487,19 +486,16 @@ _apt-get () {
 	/$'[^\0/=]#='/ /'[]'/ ':apt-package-versions:package version:_apt_versions_of_binary_package' \
       \) \
     \) \| \
-    /$'remove\0'/ /$'[^\0]#\0'/ ':packages::_deb_packages "$expl_packages[@]" installed' \# \| \
-    /$'purge\0'/ /$'[^\0]#\0'/ ':packages::_deb_packages "$expl_packages[@]" installed' \# \| \
+    /$'(|auto)(purge|remove)\0'/ /$'[^\0]#\0'/ ':packages::_deb_packages "$expl_packages[@]" installed' \# \| \
     /$'dist-upgrade\0'/ \| \
     /$'dselect-upgrade\0'/ \| \
     /$'clean\0'/ \| \
     /$'autoclean\0'/ \| \
     /$'changelog\0'/ /$'[^\0]#\0'/ ':packages::_deb_packages "$expl_packages[@]" avail' \# \| \
     /$'check\0'/ \| \
-    /$'autoremove\0'/ /$'[^\0]#\0'/ ':packages::_deb_packages "$expl_packages[@]" installed' \# \| \
     /$'help\0/' \| \
-    /$'markauto\0'/ /$'[^\0]#\0'/ ':packages::_deb_packages "$expl_packages[@]" installed' \# \| \
-    /$'unmarkauto\0'/ /$'[^\0]#\0'/ ':packages::_deb_packages "$expl_packages[@]" installed' \# \| \
-    /"[]"/	':argument-1::compadd "$expl_action[@]" update upgrade install remove purge dist-upgrade dselect-upgrade clean autoclean changelog check source build-dep autoremove help markauto unmarkauto download'
+    /$'(|un)markauto\0'/ /$'[^\0]#\0'/ ':packages::_deb_packages "$expl_packages[@]" installed' \# \| \
+    /"[]"/	':argument-1::compadd "$expl_action[@]" update upgrade install remove purge dist-upgrade dselect-upgrade clean autoclean changelog check source build-dep autopurge autoremove help markauto unmarkauto download'
 
   _apt-get () {
     local expl_action expl_packages
diff --git a/Completion/Debian/Command/_aptitude b/Completion/Debian/Command/_aptitude
index 91d233f11..5b10adb80 100644
--- a/Completion/Debian/Command/_aptitude
+++ b/Completion/Debian/Command/_aptitude
@@ -15,7 +15,7 @@ _arguments -C \
   '(-F --display-format)'{-F,--display-format}'[specify output format for search command]:format:->format-strings' \
   '--group-by=[control how the versions command groups its output]:grouping:(archive auto none package source-package source-version)' \
   '--log-file=[specify output log file]:file:_files' \
-  '*--log-level=[specify mimimum message level to log]:level:compadd -o nosort off fatal error warn info debug trace' \
+  '*--log-level=[specify minimum message level to log]:level:compadd -o nosort off fatal error warn info debug trace' \
   '--log-resolver[set some standard log levels related to the resolver]' \
   '(--allow-new-installs)--no-new-installs[prevent safe-upgrade from installing any new packages]' \
   '(--allow-new-upgrades)--no-new-upgrades[prevent safe-upgrade from upgrading packages regardless]' \
diff --git a/Completion/Debian/Command/_sbuild b/Completion/Debian/Command/_sbuild
index a32b5e8c5..459738d5d 100644
--- a/Completion/Debian/Command/_sbuild
+++ b/Completion/Debian/Command/_sbuild
@@ -124,7 +124,7 @@ _sbuild() {
     '--aspcud-criteria=[Optimization for aspcud]:criteria' \
     '(--resolve-alternatives --no-resolve-alternatives)--resolve-alternatives[allow alternatives in Build-Depends*]' \
     '(--resolve-alternatives --no-resolve-alternatives)--no-resolve-alternatives[disallow alternatives in Build-Depends*]' \
-    '--extra-package=[make a package or directory available to the resolver]:package:_files -g "*deb(-.)' \
+    '--extra-package=[make a package or directory available to the resolver]:package:_files -g "*deb(-.)"' \
     '--extra-repository=[add a repository to the resolver]:url' \
     '--extra-repository-key=[add key to the resolver]:key:_files -g "*.asc(-.)"' \
     '--build-path=[place to build the package inside chroot]:path:_files -/' \
diff --git a/Completion/Linux/Command/_basenc b/Completion/Linux/Command/_basenc
new file mode 100644
index 000000000..515621aaa
--- /dev/null
+++ b/Completion/Linux/Command/_basenc
@@ -0,0 +1,30 @@
+#compdef basenc
+# based on GNU coreutils 8.32
+
+local specs=(
+  + '(type)'
+  "(info)--base64[same as 'base64' program (RFC4648 section 4)]"
+  "(info)--base64url[file- and url-safe base64 (RFC4648 section 5)]"
+  "(info)--base32[same as 'base32' program (RFC4648 section 6)]"
+  "(info)--base32hex[extended hex alphabet base32 (RFC4648 section 7)]"
+  "(info)--base16[hex encoding (RFC4648 section 8)]"
+  "(info)--base2msbf[bit string with most significant bit (msb) first]"
+  "(info)--base2lsbf[bit string with least significant bit (lsb) first]"
+  "(info)--z85[ascii85-like encoding (ZeroMQ spec-32/Z85)]"
+
+  + enc
+  '(info dec -w --wrap)'{-w+,--wrap=}"[wrap encoded lines at specified column]:number of characters (0=disable wrapping) [76]: "
+
+  + dec
+  '(info enc -d --decode)'{-d,--decode}"[decode data]"
+  '(info enc -i --ignore-garbage)'{-i,--ignore-garbage}"[when decoding, ignore non-alphabet characters]"
+
+  + info
+  "(: -)--help[display help information and exit]"
+  "(: -)--version[output version information and exit]"
+
+  + input
+  '(info)1:input file:_files'
+)
+
+_arguments -s -S : $specs
diff --git a/Completion/Linux/Command/_btrfs b/Completion/Linux/Command/_btrfs
index bb0f724e6..d8b97a200 100644
--- a/Completion/Linux/Command/_btrfs
+++ b/Completion/Linux/Command/_btrfs
@@ -8,16 +8,16 @@ groups=( subvolume filesystem device scrub balance inspect-internal property
          quota qgroup replace rescue check restore send receive
          help version )
 cmds_1=( create delete list snapshot get-default set-default find-new show sync help )
-cmds_2=( df du show sync defragment resize label usage help )
+cmds_2=( df du show sync defragment resize label mkswapfile usage help )
 cmds_3=( add delete remove ready scan stats usage help )
 cmds_4=( start cancel resume status help )
 cmds_5=( start pause cancel resume status )
-cmds_6=( dump-{super,tree} {inode,logical,subvolid}-resolve min-dev-size rootid tree-stats help )
+cmds_6=( dump-{super,tree} {inode,logical,subvolid}-resolve map-swapfile min-dev-size rootid tree-stats help )
 cmds_7=( get set list )
 cmds_8=( enable disable rescan help )
-cmds_9=( assign remove create destroy show limit help )
+cmds_9=( assign remove create clear-stale destroy show limit help )
 cmds_10=( start status cancel help )
-cmds_11=( chunk-recover fix-device-size super-recover zero-log create-control-device )
+cmds_11=( chunk-recover clear-uuid-tree fix-device-size super-recover zero-log create-control-device )
 
 _arguments -C -A "-*" "$args[@]" \
   '(- *)--help[print help information]' \
@@ -25,6 +25,7 @@ _arguments -C -A "-*" "$args[@]" \
   '(-v --verbose -q --quiet --help --version)'{-v,--verbose}'[verbose output of operation]' \
   '(-v --verbose -q --quiet --help --version)'{-q,--quiet}'[suppress all messages except errors]' \
   '(--help --version)--format=[specify output format]:format:(text json)' \
+  '(--help --version)--log=[set log level]:level:(default info verbose debug quiet)' \
   '(--version)1: :->groups' \
   '2: :->cmds' \
   '*:: :->args' && ret=0
@@ -147,16 +148,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)'
+            '-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'
           )
         ;;
@@ -171,6 +172,13 @@ while (( $#state )); do
             '1: :_guard "^-*" uuid or label'
           )
         ;;
+        filesystem:mkswapfile)
+          args+=(
+            '-s[size]: :_numbers -d "2GiB" size K M G T P E'
+            '(-u --uuid)'{-u,--uuid}'[specify a uuid to use]:uuid:(clear random time)'
+            ':file:_files'
+          )
+        ;;
         filesystem:usage) args+=( '-T[show data in tabular format]' );;
         device:(add|delete|ready|remove))
           args+=(
@@ -194,6 +202,7 @@ while (( $#state )); do
           args+=(
             '(-c --check)'{-c,--check}'[return non-zero if any stat counter is not zero]'
             '(-z --reset)'{-z,--reset}'[reset stats when done]'
+            '-T[show current stats in tabular format]'
             "1:device or mountpoint:_files -g '*(-%,/)'"
           )
         ;;
@@ -233,7 +242,7 @@ while (( $#state )); do
         ;;
         balance:status) args+=( '!-v' '!--verbose' '1:path:_files -/' );;
         balance:(pause|cancel|resume)) args+=( '1:path:_files -/' );;
-        property:set) args+=( '3:value' );&
+        property:set) args+=( '-f[force the change]' '3:value' );&
         property:get) args+=( '2:property:(ro label compression)' );&
         property:list)
           args+=(
@@ -244,8 +253,9 @@ while (( $#state )); do
         quota:(enable|disable)) args+=( '1:path:_files -/' );;
         quota:rescan)
           args+=(
-            '-s[show status of currently running rescan]'
-            '-w[wait for rescan to finish]'
+            '(-s --status)'{-s,--status}'[show status of currently running rescan]'
+            '(-w --wait -W --wait-norescan)'{-w,--wait}'[wait for rescan to finish]'
+            '(-w --wait -W --wait-norescan)'{-w,--wait-norescan}'[wait for rescan to finish without starting it]'
             '1:path:_files -/'
           )
         ;;
@@ -268,11 +278,14 @@ while (( $#state )); do
             '-F[list impacted qgroups \(include ancestral qgroups\)]'
             '-f[list impacted qgroups \(exclude ancestral qgroups\)]'
             '--sort=-[sort qgroups]:sort:_values -s , sort \
-              qgroupid rfer excl max_rfer max_excl'
+              qgroupid rfer excl max_rfer max_excl path'
             '--sync[do filesystem sync before getting information]'
             '1:path:_files -/'
           )
         ;;
+        qgroup:clear-stale)
+          args+=( '(-q --quiet)'{-q,--quiet}'[print only errors]' '1:path:_files -/' )
+        ;;
         qgroup:limit)
           args+=(
             '-c[limit amount of data after compression]'
@@ -287,6 +300,7 @@ while (( $#state )); do
             '-r[read from specified source device only]:srcdev:_files'
             '-f[force overwriting of target]'
             "-B[don't background]"
+            '(-K --nodiscard)'{-K,--nodiscard}"[don't perform whole device TRIM]"
             ':srcdev or devid:_files'
             ':target:_files'
             ':path:->mounts'
@@ -332,6 +346,12 @@ while (( $#state )); do
             '2:filesystem path:_files -/'
           )
         ;;
+        inspect*:map-swapfile)
+          args+=(
+            '(-r --resume-offset)'{-r,--resume-offset}'[print only the value suitable as resume offset for file /sys/power/resume_offset]'
+            ':file:_files'
+          )
+        ;;
         inspect*:min*) args+=( '--id[specify the device id to query]:device id [1]' );;
         inspect*:rootid) args+=( '1:path:_files -/' );;
         inspect*:tree*) args+=( '-b[print raw numbers in bytes]' );;
@@ -395,6 +415,8 @@ while (( $#state )); do
             '*-c[use snapshot as clone source]:clone:_files -/'
             '-f[specify output file]:file:_files'
             '--no-data[send in NO_FILE_DATA mode]'
+            '--proto[specify protocol version]:version'
+            '--compressed-data[send data that is compressed on the filesystem directly without decompressing it]'
             '1:subvolume:_files -/'
           )
         ;;
@@ -405,6 +427,7 @@ while (( $#state )); do
             '(-C --chroot)'{-C,--chroot}'[confine the process to destination path using chroot(1)]'
             '(-E --max-errors)'{-E,--max-errors}'[terminate as soon as specified number of errors occur]:errors [1]'
             '(--dump)-m[specify root mount point of the destination filesystem]:mount point:_directories'
+            '--force-decompress[if the stream contains compressed data, always decompress it]'
             '(-m)--dump[dump stream metadata, one line per operation]'
             '1:mount:->mounts'
           )
@@ -424,7 +447,7 @@ while (( $#state )); do
     ;;
     mounts)
       _wanted mount-points expl 'mount point' compadd \
-          ${${${(M)${(f)"$(</etc/mtab)"}:#*btrfs*}#* }%% *} && ret=0
+          ${${${(M)${(f)"$(</proc/self/mounts)"}:#*btrfs*}#* }%% *} && ret=0
     ;;
     filters)
       state=()
diff --git a/Completion/Linux/Command/_chcon b/Completion/Linux/Command/_chcon
deleted file mode 100644
index 2d523f287..000000000
--- a/Completion/Linux/Command/_chcon
+++ /dev/null
@@ -1,24 +0,0 @@
-#compdef chcon
-
-local ign
-
-(( $#words > 2 )) && ign='!'
-_arguments -C -s -S \
-  '(-h --no-dereference)--dereference[dereference symlinks]' \
-  '(-h --no-dereference --dereference)'{-h,--no-dereference}'[operate on symlinks themselves]' \
-  '(1 -u --user -r --role  -l --range -t --type)--reference=[copy security context of specified file]:file:_files' \
-  '(1 --reference -u --user)'{-u+,--user=}'[set user in the target security context]: :_selinux_users' \
-  '(1 --reference -r --role)'{-r+,--role=}'[set role in the target security context]: :_selinux_roles' \
-  '(1 --reference -t --type)'{-t+,--type=}'[set type in the target security context]: :_selinux_types' \
-  '(1 --reference -l --range)'{-l+,--range=}'[set range in the target security context]:selinux range' \
-  '(--recursive -R)'{--recursive,-R}'[recurse subdirectories]' \
-  '(-v --verbose)'{-v,--verbose}'[output a diagnostic for every file processed]' \
-  '(-H -L -P)-H[follow symlinks on the command line]' \
-  '(-H -L -P)-L[follow all symlinks]' \
-  "(-H -L -P)-P[don't follow symlinks (default)]" \
-  '!(--preserve-root)--no-preserve-root' \
-  "--preserve-root[fail to operate recursively on '/']" \
-  '(--reference -u --user -r --role  -l --range -t --type)1:security context:_selinux_contexts' \
-  "${ign}--help[display help information]" \
-  "${ign}--version[display version information]" \
-  '*:file:_files'
diff --git a/Completion/Linux/Command/_chrt b/Completion/Linux/Command/_chrt
index 6789b66cf..5431b0799 100644
--- a/Completion/Linux/Command/_chrt
+++ b/Completion/Linux/Command/_chrt
@@ -62,7 +62,7 @@ elif (( CURRENT == 1 )); then
 else
   shift words
   (( CURRENT-- ))
-  _normal && ret=0
+  _normal -p $service && ret=0
 fi
 
 return ret
diff --git a/Completion/Linux/Command/_cpupower b/Completion/Linux/Command/_cpupower
index 6763bdd12..d342b69d9 100644
--- a/Completion/Linux/Command/_cpupower
+++ b/Completion/Linux/Command/_cpupower
@@ -95,7 +95,7 @@ case $state in
           '-i+[measurement interval]:interval (seconds)'
           '-c[schedule on every core]'
           '-v[increase verbosity]'
-          '*:::command: _normal'
+          '*:::command: _normal -p $service'
         )
       ;;
     esac
diff --git a/Completion/Linux/Command/_ethtool b/Completion/Linux/Command/_ethtool
index 95a8bbfb6..3e3fc0b1d 100644
--- a/Completion/Linux/Command/_ethtool
+++ b/Completion/Linux/Command/_ethtool
@@ -4,7 +4,7 @@ local curcontext="$curcontext"
 local -a state line expl cmds
 local -A opt_args
 
-_arguments -C \
+_arguments -C -A "-*" \
   '--debug[turn on debugging messages]:mask:((1\:parser\ information))' \
   '--json[output results in JSON]' \
   '(-I --include-statistics)'{-I,--include-statistics}'[include command-related statistics in the output]' \
@@ -59,12 +59,21 @@ _arguments -C \
   '--cable-test[perform cable test and report the results]' \
   '--cable-test-tdr[perform cable test and report Time Domain Reflectometer data]' \
   '--show-tunnels[show tunnel-related device capabilities and state]' \
+  '--show-module[show transceiver module settings]' \
+  '--set-module[set transceiver module settings]' \
+  '--get-plca-cfg[get PLCA configuration]' \
+  '--set-plca-cfg[set PLCA configuration]' \
+  '--get-plca-status[get PLCA status information]' \
+  '--show-mm[show MAC merge layer state]' \
+  '--set-mm[set MAC merge layer parameters]' \
+  '--show-pse[show settings for power sourcing equipment]' \
+  '--set-pse[set power sourcing equipment settings]' \
   '--monitor[listen to netlink notifications and displays them]::command:(
     --all -s --change -k --show-features --show-offload -K
     --features --offload  --show-priv-flags --set-priv-flags -g --show-ring
     -G --set-ring -l --show-channels -L --set-channels -c --show-coalesce
     -C --coalesce -a --show-pause -A --pause --show-eee --set-eee
-    --cable-test --cable-test-tdr
+    --cable-test --cable-test-tdr --show-module --set-module
   )' && return
 
 if [[ -n $state ]]; then
@@ -79,22 +88,30 @@ if [[ -n $state ]]; then
     fi
   ;;
   autoneg|adaptive-[rt]x|raw|hex|sg|tso|ufo|gso|lro|eee|tx-lpi|downshift) ;&
-  fast-link-down|energy-detect-power-down|mode)
+  cqe-mode-[rt]x|fast-link-down|energy-detect-power-down|mode) ;&
+  [tr]x-push|enable|*-enabled)
     _wanted onoff expl 'enabled' compadd off on
   ;;
   rx-usecs|rx-frames|rx-usecs-irq|rx-frames-irq|tx-usecs|tx-frames) ;&
   tx-usecs-irq|tx-frames-irq|stats-block-usecs|pkt-rate-low|rx-usecs-low) ;&
   rx-frames-low|tx-usecs-low|tx-frames-low|pkt-rate-high|rx-usecs-high) ;&
-  rx-frames-high|tx-usecs-high|tx-frames-high|sample-interval|dmac|rx-mini) ;&
-  rx-jumbo|offset|length|magic|value|phyad|proto|tos|tclass|l4proto|src-port) ;&
+  rx-frames-high|tx-usecs-high|tx-frames-high|sample-interval|dmac) ;&
+  tx-aggr-max-bytes|tx-aggr-max-frame|tx-aggr-time-usec) ;&
+  rx-mini|rx-jumbo|rx-buf-len|cqe-size|tx-push-buf-len) ;&
+  offset|length|magic|value|phyad|proto|tos|tclass|l4proto|src-port) ;&
   dst-port|spi|l4data|vlan-etype|vlan|user-def|action|vf|queue|loc) ;&
   page|bank|i2c|first|last|step|pair|lanes) ;&
-  rx-copybreak|tx-copybreak|pfc-prevention-tout) ;&
-  other|combined|tx-timer|count|msecs)
+  rx-copybreak|tx-copybreak|tx-buf-size|pfc-prevention-tout) ;&
+  other|combined|tx-timer|count|msecs) ;&
+  node-id|node-cnt|to-tmr|burst-cnt|burst-tmr) ;&
+  tx-min-frag-size)
     _message -e numbers 'number'
   ;;
+  podl-pse-admin-control)
+    _wanted values expl 'value' compadd enable disable
+  ;;
   speed)
-        _wanted -x speed expl 'speed' compadd 10 100 1000
+    _wanted -x speed expl 'speed' compadd 10 100 1000
   ;;
   duplex)
     _wanted duplex expl 'duplex mode' compadd half full
@@ -166,8 +183,14 @@ if [[ -n $state ]]; then
   context)
     _message -e contexts 'RSS context'
   ;;
+  power-mode-policy)
+    _wanted policies expl 'policy' compadd high auto
+  ;;
   *)
     case ${${(Mk)opt_args:#cmd?*}[1]#cmd?-} in
+    -a|--show-pause)
+      _arguments '--src=-:source:(aggregate emac pmac)'
+    ;;
     -A|--pause)
       _values -S ' ' -w 'pause parameter' \
         'autoneg[specify if pause autonegotiation is enabled]' \
@@ -177,14 +200,16 @@ if [[ -n $state ]]; then
     -C|--coalesce)
       _wanted settings expl 'coalescing setting' compadd -F line -M 'r:|-=* r:|=*' - \
         adaptive-{r,t}x {r,t}x-{usecs,frames}{,-irq,-high,-low} \
-        stats-block-usecs pkt-rate-{low,high} sample-interval
+        stats-block-usecs pkt-rate-{low,high} sample-interval cqe-mode-{r,t}x \
+        tx-aggr-{max-bytes,max-frames,time-usecs}
     ;;
     -G|--set-ring)
       _values -S ' ' -w 'ring parameter' \
         'rx[change number of ring entries for the RX ring]' \
         'rx-mini[change number of ring entries for the RX Mini ring]' \
         'rx-jumbo[change number of ring entries for the RX Jumbo ring]' \
-        'tx[change number of ring entries for the TX ring]'
+        'tx[change number of ring entries for the TX ring]' \
+        rx-buf-len cqe-size tx-push rx-push tx-push-buf-len
     ;;
     -d|--register-dump)
       _values -S ' ' -w 'option' \
@@ -216,7 +241,9 @@ if [[ -n $state ]]; then
       (( CURRENT = 4 )) && _message -e length 'duration (seconds)'
     ;;
     -S|--statistics)
-      _arguments '(-)--all-groups' '(-)--groups:eth-phy: :eth-mac: :eth-ctrl: :rmon'
+      _arguments '(-)--all-groups' \
+        '(-)--groups:eth-phy: :eth-mac: :eth-ctrl: :rmon' \
+        '--src=-:source:(aggregate emac pmac)' \
     ;;
     -t|--test)
       _values -S ' ' -w 'test mode' \
@@ -318,7 +345,7 @@ if [[ -n $state ]]; then
     ;;
     --[gs]et-tunable)
       _wanted options expl tunable compadd rx-copybreak tx-copybreak \
-          pfc-prevention-tout
+          tx-buf-size pfc-prevention-tout
     ;;
     --reset)
       _wanted components expl component compadd flags dedicated all \
@@ -341,6 +368,13 @@ if [[ -n $state ]]; then
     --cable-test-tdr)
       _wanted options expl 'distance options' compadd first last step pair
     ;;
+    --set-module)
+      _wanted options expl tunable compadd power-mode-policy
+    ;;
+    --set-plca-cfg)
+      _wanted options expl tunable compadd enable node-id node-cnt \
+          to-tmr burst-cnt burst-tmr
+    ;;
     esac
   ;;
   esac
diff --git a/Completion/Linux/Command/_findmnt b/Completion/Linux/Command/_findmnt
index 0c832364d..b29372c39 100644
--- a/Completion/Linux/Command/_findmnt
+++ b/Completion/Linux/Command/_findmnt
@@ -26,6 +26,7 @@ _arguments -s -C \
   '(H -o --output)--output-all[output all available columns]' \
   '(H -p --poll)'{-p+,--poll=}'[monitor changes in /proc/self/mountinfo]::action:(mount umount remount move)' \
   '(H --real)--pseudo[print only pseudo-filesystems]' \
+  '(H)--shadowed[print only filesystems over-mounted by another filesystem]' \
   '(H -R --submounts)'{-R,--submounts}'[print recursively all submounts]' \
   '(H --pseudo)--real[print only real filesystems]' \
   '(H -S --source :)'{-S+,--source=}'[specify the mount source]: :->sources' \
@@ -35,9 +36,11 @@ _arguments -s -C \
   '(H -U --uniq)'{-U,--uniq}'[ignore filesystems with duplicated mount targets]' \
   '(H -u --notruncate)'{-u,--notruncate}'[do not truncate text in columns]' \
   '(H -v --nofsroot)'{-v,--nofsroot}'[do not print \[/dir\] in the SOURCE column]' \
+  '(H -y --shell -n --noheadings)'{-y,--shell}'[use column names usable as shell variable identifiers]' \
   '(H -w --timeout)'{-w+,--timeout}'[specify timeout for --poll]:milliseconds: ' \
   '(H -x --verify)'{-x,--verify}'[check mount table content]' \
   '(H)--verbose[print more information]' \
+  '(H)--vfs-all[print all VFS options]' \
   '(H)1: :->sources_targets' \
   '(H)2:: :->targets' \
   + '(format)' \
diff --git a/Completion/Linux/Command/_free b/Completion/Linux/Command/_free
index 6d74e4a0d..a0da97446 100644
--- a/Completion/Linux/Command/_free
+++ b/Completion/Linux/Command/_free
@@ -3,6 +3,7 @@
 _arguments -s \
   '(-l --lohi)'{-l,--lohi}'[show detailed low and high memory statistics]' \
   '(-t --total)'{-t,--total}'[show total for RAM + swap]' \
+  '(-v --committed)'{-v,--committed}'[show committed memory and commit limit]' \
   '(-w --wide)'{-w,--wide}'[wide mode]' \
   '(-s --seconds)'{-s,--seconds}'[specify the delay between display]:seconds: ' \
   '(-c --count)'{-c+,--count=}'[specify the display count]:count: ' \
diff --git a/Completion/Linux/Command/_fusermount b/Completion/Linux/Command/_fusermount
index 41d3dec72..24f9a8018 100644
--- a/Completion/Linux/Command/_fusermount
+++ b/Completion/Linux/Command/_fusermount
@@ -1,4 +1,4 @@
-#compdef fusermount
+#compdef fusermount fusermount3
 
 local expl context state line
 typeset -A opt_args
@@ -19,7 +19,7 @@ case "$state" in
   if [[ $+opt_args[-u] -eq 0 ]]; then
     _files -/
   else
-    mtpts=(${${${"${(f)$(< /etc/mtab)}"}#* }%% *})
+    mtpts=(${${${"${(f)$(< /proc/self/mounts)}"}#* }%% *})
     _canonical_paths mounted 'mounted filesystem' "${(@g::)mtpts}"
   fi
   ;;
diff --git a/Completion/Linux/Command/_gpasswd b/Completion/Linux/Command/_gpasswd
index 24fe361b0..d5d16ebba 100644
--- a/Completion/Linux/Command/_gpasswd
+++ b/Completion/Linux/Command/_gpasswd
@@ -5,7 +5,7 @@ _arguments -s \
   '(-d --delete -a --add)'{-d,--delete}'[remove user from group]: : _users' \
   '(-)'{-h,--help}'[display help]' \
   '(-Q --root)'{-Q,--root}'[specify directory to chroot into]: : _files -/' \
-  '(-r --remove-password)'{-r,--remove-password}'[remove the group password]' \
+  '(-r --delete-password)'{-r,--delete-password}'[remove the group password]' \
   '(-R --restrict)'{-R,--restrict}'[restrict access to GROUP to its members]' \
   '(-M --members -A --administrators)'{-M,--members}'[set the list of members of GROUP]: :_sequence _users' \
   '(-A --administrators -M --members)'{-A,--administrators}'[set the list of admins for GROUP]: :_sequence _users' \
diff --git a/Completion/Linux/Command/_htop b/Completion/Linux/Command/_htop
index 28c7512bf..e8d2fffb1 100644
--- a/Completion/Linux/Command/_htop
+++ b/Completion/Linux/Command/_htop
@@ -1,11 +1,55 @@
-#compdef htop
-
-_arguments -S : \
-  '(-d --delay)'{-d+,--delay=}'[update frequency]:duration (tenths of seconds)' \
-  '(-C --no-color --no-colour)'{-C,--no-colo{,u}r}'[monochrome mode]' \
-  '(-)'{-h,--help}'[display usage information]' \
-  \*{-p+,--pid=}'[show given pids]: : _sequence -n ${$(</proc/sys/kernel/pid_max)\:-32768} _pids' \
-  '(-s --sort-key)'{-s+,--sort-key=}'[sort by key]:key:( ${(f)"$(_call_program sort-keys $words[1] --sort-key help)"} )' \
-  '(-t --tree)'{-t,--tree}'[show tree view of processes]' \
-  '(-u --user)'{-u+,--user=}'[show processes of user]: : _users' \
-  '(-)'{-v,--version}'[display version information]'
+#compdef htop pcp-htop
+
+# Notes:
+# - htop allows long options to be passed with a single dash; we don't account
+#   for this
+# - htop parses optional arguments to -H and -u 'cleverly' by allowing the next
+#   word to be the optarg if it doesn't begin with a '-'; this should work here
+# - There is a special version of htop designed to be used with PCP (Performance
+#   CoPilot); we don't fully account for this
+# - Some of the ranges and defaults listed here had to be found in the source
+
+local MATCH MBEGIN MEND ret=1
+local -a context line state state_descr args tmp
+
+args=(
+  '(-d --delay)'{-d+,--delay=}'[specify update frequency]:delay (tenths of seconds) (1-100) [15]'
+  '(-C --no-color --no-colour)'{-C,--no-colo{,u}r}'[use monochrome colour scheme]'
+  '(-F --filter)'{-F+,--filter=}'[show only commands matching specified filter]:case-insensitive command-line sub-string:_process_names -a'
+  '(-)'{-h,--help}'[display usage information]'
+  '(-H --highlight-changes)'{-H+,--highlight-changes=}'[highlight new and old processes (optionally specify delay)]::delay (seconds) (1-86400) [5]'
+  '(-M --no-mouse)'{-M,--no-mouse}'[disable mouse]'
+  \*{-p+,--pid=}'[show only specified PIDs]: : _sequence _pids'
+  '--readonly[disable all system and process changing features]'
+  '(-s --sort-key)'{-s+,--sort-key=}'[sort by specified column]: :->sort-keys'
+  '(-t --tree)'{-t,--tree}'[show tree view of processes]'
+  '(-u --user)'{-u+,--user=}'[show only processes of current or specified user]:: : _users'
+  '(-U --no-unicode)'{-U,--no-unicode}'[disable Unicode]'
+  '(-)'{-V,--version}'[display version information]'
+)
+
+[[ $OSTYPE == linux* ]] &&
+(( ! EUID || $+_comp_priv_prefix )) &&
+_pick_variant libcap=drop-capabilities $OSTYPE --help &&
+args+=(
+  '--drop-capabilities=-[drop specified capabilities]::mode [basic]:((
+    off\:"do not drop capabilities"
+    basic\:"drop capabilities not needed for standard functionality (retains kill, renice, etc.)"
+    strict\:"drop capabilities not needed for core functionality"
+  ))'
+)
+
+_arguments -s -S : $args && ret=0
+
+case $state in
+  sort-keys)
+    tmp=( ${(f)"$(_call_program sort-keys $words[1] --sort-key help)"} )
+    tmp=( ${tmp/#[[:space:]]##} )
+    tmp=( ${tmp//:/\\:} )
+    tmp=( ${tmp/[[:space:]]##/:} )
+    tmp=( ${tmp/(#m):[A-Z]/${(L)MATCH}} )
+    _describe -t sort-keys 'column (key)' tmp && ret=0
+    ;;
+esac
+
+return ret
diff --git a/Completion/Linux/Command/_ionice b/Completion/Linux/Command/_ionice
index ba403ca56..9989cd6a9 100644
--- a/Completion/Linux/Command/_ionice
+++ b/Completion/Linux/Command/_ionice
@@ -28,7 +28,7 @@ if [[ -n $state ]]; then
   elif (( $+opt_args[args--u] || $+opt_args[args---uid] )); then
     _message -e uids 'user id'
   else
-    _normal && ret=0
+    _normal -p $service && ret=0
   fi
 fi
 
diff --git a/Completion/Linux/Command/_iptables b/Completion/Linux/Command/_iptables
index 27c801da1..892c48710 100644
--- a/Completion/Linux/Command/_iptables
+++ b/Completion/Linux/Command/_iptables
@@ -1,7 +1,7 @@
-#compdef iptables iptables-save iptables-restore ip6tables ip6tables-save ip6tables-restore
+#compdef iptables iptables-save iptables-restore ip6tables ip6tables-save ip6tables-restore arptables ebtables
 
-local curcontext="$curcontext" state line expl i ret=1
-local -a cmds rcmds ropts rules states prev args
+local curcontext="$curcontext" i ret=1
+local -a state line expl cmds rcmds ropts rules states prev args
 
 case $service in
   iptables-save | ip6tables-save)
@@ -24,12 +24,12 @@ cmds=(
   -P --policy -E --rename-chain -h --help -V --version
 )
 ropts=(
-  -p --protocol -s --src --source -d --dst --destination -j --jump -i
+  -p --proto --protocol -s --src --source -d --dst --destination -j --jump -i
   --in-interface -o --out-interface -f --fragment -c --set-counters
 )
 
 prev=( ${words[1,CURRENT-1]} )
-case ${prev[${prev[(I)-p|--protocol]}+1]}; in
+case ${prev[${prev[(I)-p|--proto|--protocol]}+1]}; in
   tcp)
     args=(
       '--tcp-flags[match based on TCP flags in a packet]: :->tcp-flags: :->tcp-flags'
@@ -92,7 +92,42 @@ while
   (( i=words[(ib.i.)-m|--match]+1 ))
 (( i<CURRENT )); do
   case ${words[i]}; in
-    ah) args+=( '--ahspi[match SPIs in AH header]:*^!:spi' ) ;;
+    addrtype)
+      args+=(
+        '--src-type[match if the source address is of given type]:type:->address-types'
+        '--dst-type[match if the destination address is of given type]:type:->address-types'
+        '(--limit-iface-out)--limit-iface-in[limit to interface the packet is coming in]'
+        '(--limit-iface-in)--limit-iface-out[limit to interface the packet is going out]'
+      )
+    ;;
+    ah)
+      args+=( '--ahspi[match SPIs in AH header]:*^!:spi' )
+      [[ $service = ip6* ]] && args+=(
+        '--ahlen[total length of this header]:length (octets)'
+        '--ahres[match if the reserved field is filled with zero]'
+      )
+    ;;
+    bpf)
+      args+=(
+        '--object-pinned[pass a path to a pinned eBPF object]:path:_files'
+        '--bytecode[pass BPF byte code as generated by nfbpf_compile]:code'
+      )
+    ;;
+    cgroup)
+      args+=(
+        '--path[match cgroup2 membership]:path:_files -W /sys/fs/cgroup'
+        '--cgroup[match cgroup net_cls classid]:classid'
+      )
+    ;;
+    cluster)
+      args+=(
+        '--cluster-total-nodes[set number of total nodes in cluster]:number'
+        '--cluster-local-node[set the local node number ID]:number'
+        '--cluster-local-nodemask[set the local node number ID mask]:mask'
+        '--cluster-hash-seed[set seed value of the Jenkins hash]:value'
+      )
+    ;;
+    comment) args+=( '--comment[add comment to rule]:comment' ) ;;
     conntrack)
       args+=(
         '--ctstate[match packet state]:state:->cfstates'
@@ -160,30 +195,34 @@ _arguments -C -s \
   '(-)'{-V,--version}'[print version information]' \
   '(-h --help -V --version)'{-t,--table}'[specify table]:table:(filter nat mangle raw security)' \
   "($rcmds $cmds)"{-A,--append}'[append rules to end of specified chain]:chain:->chains' \
+  {-C,--check}'[check for the existence of a rule]' \
   "($rcmds $cmds -c --set-counters)"{-D,--delete}'[delete rules from specified chain]:chain:->chains::rule number:->rulenums' \
   "($rcmds $cmds)"{-I,--insert}'[insert rules before specified rule number]:chain:->chains::rule number:->rulenums' \
   "($rcmds $cmds)"{-R,--replace}'[replace a rule]:chain:->chains::rule number:->rulenums' \
-  "($rcmds "${(j. .)cmds:#(-Z|--zero)}" $ropts)"{-L,--list}'[list rules in selected chain]::chain:->chains' \
+  "($rcmds "${(j. .)cmds:#(-Z|--zero)}" $ropts)"{-L,--list}'[list rules in selected chain]::chain:->chains:rule number:->rulenums' \
+  '(-L --list -S --list-rules)'{-S,--list-rules}'[list rules in the form of options to iptables]::chain:->chains::rule number:->rulenums' \
   "($rcmds $cmds $ropts)"{-F,--flush}'[flush specified chain (delete all rules)]::chain:->chains' \
   "($rcmds "${(j. .)cmds:#(-L|--list)}" $ropts)"{-Z,--zero}'[zero the packet and byte counters]::chain:->chains' \
   "($rcmds $cmds)"{-N,--new,--new-chain}'[create a new user-defined chain]:chain name' \
   "($rcmds $cmds)"{-X,--delete-chain}'[delete a user-defined chain]:: :->user-chains' \
   "($rcmds $cmds)"{-P,--policy}'[set the policy for a chain to given target]:chain:->chains:target:->targets' \
   "($rcmds $cmds)"{-E,--rename-chain}'[rename a user-defined chain]:old chain:->user-chains:new chain name' \
-  "($cmds -p --protocol)"{-p,--protocol}'[specify protocol of rule]:*^!:protocol:(! tcp udp icmp all)' \
-  "($cmds -s --src --source)"{-s,--src,--source}'[specify source]:*^!:network:_hosts' \
-  "($cmds -d --dst --destination)"{-d,--dst,--destination}'[specify destination]:*^!:network:_hosts' \
+  "($cmds -p --proto --protocol)"{-p,--proto,--protocol}'[specify protocol of rule]:*^!:protocol:(! tcp udp icmp all)' \
+  "($cmds -s --src --source)"{-s,--src,--source}'[specify source]:*^!:network:_sequence _hosts' \
+  "($cmds -d --dst --destination)"{-d,--dst,--destination}'[specify destination]:*^!:network:_sequence _hosts' \
   "($cmds -j --jump)"{-j,--jump}'[specify rule target]:target:->targets' \
   "($cmds -i --in-interface)"{-i,--in-interface}'[specify interface via which packet is received]:*^!:interface:_net_interfaces' \
   "($cmds -o --out-interface)"{-o,--out-interface}'[specify interface via which packet is to be sent]:*^!:interface:_net_interfaces' \
   "($cmds -f --fragment)"{-f,--fragment}'[match second or further fragments only]' \
   "($cmds -D --delete -c --set-counters)"{-c,--set-counters}'[initialise packet and byte counters]:packets: :bytes' \
   '(-v --verbose)'{-v,--verbose}'[enable verbose output]' \
+  '(-w --wait)'{-w,--wait}'[specify maximum wait to acquire xtables lock before giving up]: :_numbers -u seconds -d 1 wait' \
+  '(-W --wait-interval)'{-W,--wait-interval}'[specify wait time to try to acquire xtables lock]: :_numbers -u usecs -d "1 second" wait' \
   '(-n --numeric)'{-n,--numeric}'[print IP addresses and port numbers in numeric format]' \
   '(-x --exact)'{-x,--exact}'[expand numbers (display exact values)]' \
   '--line-numbers[print line numbers when listing]' \
   '--modprobe=[specify command to load modules with]:command:_command_names -e' \
-  "($cmds)*"{-m,--match}'[extended match (may load extension)]:extension:(ah conntrack dscp esp helper icmp length limit mac mark multiport owner physdev pkttype state tcp tos ttl udp unclean)' \
+  "($cmds)*"{-m,--match}'[extended match (may load extension)]:extension:(addrtype ah bpf cgroup cluster comment connbytes connlabel connlimit connmark conntrack cpu dccp devgroup dscp dsr ecn esp eui64 frag hashlimit hbh helper hl icmp icmp6 iprange ipv6header ipvs length limit mac mark mh multiport nfacct osf owner physdev pkttype policy quota rateest realm recent rpfilter rt sctp set socket state statistic string tcp tcpmss time tos ttl u32 udp unclean)' \
   "$args[@]" && ret=0
 
 case "$state" in
@@ -230,6 +269,11 @@ case "$state" in
     [[ "$state" = cf* ]] && states+=( SNAT DNAT )
     _values -s , 'state' $states && return
   ;;
+  address-types)
+    _wanted address-types expl 'address type' compadd \
+        UNSPEC UNICAST LOCAL BROADCAST ANYCAST MULTICAST \
+        BLACKHOLE UNREACHABLE PROHIBIT THROW NAT XRESOLVE && ret=0
+  ;;
   port-list)
     compset -P '*,'
     if compset -S ',*'; then
diff --git a/Completion/Linux/Command/_lsblk b/Completion/Linux/Command/_lsblk
index 8a9bc18bf..63aac743c 100644
--- a/Completion/Linux/Command/_lsblk
+++ b/Completion/Linux/Command/_lsblk
@@ -6,16 +6,19 @@ local curcontext="$curcontext" state line expl
 typeset -A opt_args
 
 _arguments -C -s -S \
+  '(H -A --noempty)'{-A,--noempty}"[don't print empty devices]" \
   '(H -E --dedup)'{-E+,--dedup=}'[de-duplicate output by specified column]:column:->columns' \
   '(H -a --all)'{-a,--all}'[print all devices]' \
   '(H -b --bytes)'{-b,--bytes}'[print size in bytes rather than in human readable format]' \
   '(H -d --nodeps)'{-d,--nodeps}"[don't print slaves or holders]" \
   '(H -I --include)*'{-e,--exclude}'[exclude devices by major number]:major device number:->majorlist' \
   '(H -e --exclude)*'{-I+,--include=}'[show only devices with specified major numbers]:major device number:->majorlist' \
-  '(H -n --noheadings)'{-n,--noheadings}"[don't print headings]" \
+  '(H -n --noheadings -y --shell)'{-n,--noheadings}"[don't print headings]" \
   '(H -p --paths)'{-p,--paths}'[print complete device path]' \
   '(H -s --inverse)'{-s,--inverse}'[reverse dependency order]' \
+  '(H -w --width)'{-w+,--width=}'[specify output width]:width' \
   '(H -x --sort)'{-x+,--sort=}'[sort output by specified column]:column:->columns' \
+  '(H -y --shell -n --noheadings)'{-y,--shell}'[use column names usable as shell variable identifiers]' \
   '(H)--sysroot=[use specified directory as system root]:directory:_directories' \
   '*:device:_files -g "*(-%b)" -P / -W /' \
   + fields \
@@ -24,6 +27,8 @@ _arguments -C -s -S \
   '(H -f --fs -o --output -O --output-all)'{-f,--fs}'[output info about filesystems]' \
   '(H -m --perms -o --output -O --output-all)'{-m,--perms}'[output info about permissions]' \
   '(H -S --scsi -o --output -O --output-all)'{-S,--scsi}'[output info about SCSI devices]' \
+  '(H -N --nvme -o --output -O --output-all)'{-N,--nvme}'[output info about NVMe devices]' \
+  '(H -v --virtio -o --output -O --output-all)'{-v,--virtio}'[output info about virtio devices]' \
   '(H -t --topology -o --output -O --output-all)'{-t,--topology}'[output info about topology]' \
   '(H fields)'{-o+,--output=}'[specify output columns]:output column:->columnlist' \
   '(H fields)'{-O,--output-all}'[output all columns]' \
diff --git a/Completion/Linux/Command/_lsns b/Completion/Linux/Command/_lsns
new file mode 100644
index 000000000..994101d97
--- /dev/null
+++ b/Completion/Linux/Command/_lsns
@@ -0,0 +1,18 @@
+#compdef lsns
+
+local ign
+
+(( $#words > 2 )) && ign='!'
+_arguments -s -S \
+  '(-J --json)'{-J,--json}'[use JSON output format]' \
+  '(-l --list)'{-l,--list}'[use list format output]' \
+  '(-n --noheadings)'{-n,--noheadings}"[don't print headings]" \
+  '(-o --output)'{-o,--output}'[define which output columns to use]:column:_sequence compadd -M "m\:{a-z}={A-Z}" - NS TYPE PATH NPROCS PID PPID COMMAND UID USER NETNSID NSFS' \
+  '(-p --task)'{-p+,--task=}'[print process namespaces]:process id:_pids' \
+  '(-r --raw)'{-r,--raw}'[use the raw output format]' \
+  '(-u --notruncate)'{-u,--notruncate}"[don't truncate text in columns]" \
+  '(-W --nowrap)'{-W,--nowrap}"[don't use multi-line representation]" \
+  '(-t --type)'{-t+,--type=}'[filter by namespace type]:namespace type:(mnt net ipc user pid uts cgroup)' \
+  "$ign(- *)"{-h,--help}'[display usage information]' \
+  "$ign(- *)"{-V,--version}'[display version information]' \
+  '*: :_guard "^-*" namespace'
diff --git a/Completion/Linux/Command/_modutils b/Completion/Linux/Command/_modutils
index 1205f2506..f19784dff 100644
--- a/Completion/Linux/Command/_modutils
+++ b/Completion/Linux/Command/_modutils
@@ -105,7 +105,7 @@ _modutils() {
     loaded-modules|loadable-modules)
       if [[ -r /proc/modules ]]; then
 	loaded_modules=(${${(f)"$(</proc/modules)"}%% *})
-      # For compatibilty with old systems. Kernels nowadays provide
+      # For compatibility with old systems. Kernels nowadays provide
       # `/proc/modules` which is more reliable and faster for us.
       elif [[ -x /sbin/lsmod ]]; then
 	loaded_modules=(${${(f)"$(_call_program loaded-modules /sbin/lsmod)"}[2,-1]%% *})
@@ -127,7 +127,7 @@ _modutils() {
       fi
       if _cache_invalid modules-$kver || ! _retrieve_cache modules-$kver;
       then
-	modules=( $modules_dir/$kver/(*~(source|build))/**/*.(o|ko|ko.gz|ko.xz)(.:t:r:r) )
+	modules=( $modules_dir/$kver/(*~(source|build))/**/*.(o|ko|ko.gz|ko.xz|ko.zst)(.:t:r:r) )
 	modaliases=( ${${${(M)${(f)"$(<$modules_dir/$kver/modules.alias)"}:#alias*}#alias }%% *} )
 	_store_cache modules-$kver modules modaliases
       fi
diff --git a/Completion/Linux/Command/_networkmanager b/Completion/Linux/Command/_networkmanager
index 1e05252b2..d44c313db 100644
--- a/Completion/Linux/Command/_networkmanager
+++ b/Completion/Linux/Command/_networkmanager
@@ -42,8 +42,24 @@ _nm_fields() {
 }
 
 _nm_general() {
-  _arguments "1:command:(status hostname permissions logging help)"
-  # TODO: provide completions for logging
+  local curcontext="$curcontext" state line
+  _arguments "1:command:(status hostname permissions logging reload help)" \
+    "*::arguments:->args"
+
+  case $line[1] in
+    l*)
+      _values -w -S ' ' values \
+        'level:level' \
+        'domains:domain'
+    ;;
+    r*)
+      _describe -t flags 'flag' '(
+        "conf:NetworkManager.conf configuration"
+        "dns-rc:update DNS configuration"
+        "dns-full:restart the DNS plugin"
+      )'
+    ;;
+  esac
 }
 
 _nm_networking() {
diff --git a/Completion/Linux/Command/_perf b/Completion/Linux/Command/_perf
new file mode 100644
index 000000000..dd9621606
--- /dev/null
+++ b/Completion/Linux/Command/_perf
@@ -0,0 +1,809 @@
+#compdef perf
+
+local curcontext="$curcontext" curstate state line expl nm="$compstate[nmatches]"
+local -a args opts cmd fields sortkeys
+local -A exclude full short
+local -i i skip
+
+exclude=(
+  --add \* --cgroup \* --definition \* --del \*
+  --detailed \* --dlarg \* --dsos \* --event \* --events \*
+  --fields \* --funcs \* --node-info \* --symbols \* --vars \*
+  --gtk '(--stdio --stdio2 --tui)'
+  --tui '(--gtk --stdio --stdio2)'
+  --stdio '(--gtk --tui --stdio2)'
+  --stdio2 '(--gtk --tui --stdio)'
+  --log-fd '(--output)'
+  --output '(--log-fd)'
+  --tracer '(-G --graph-funcs -g --nograph-funcs -F --funcs)'
+  --graph-funcs '(-g --nograph-funcs -N --notrace-funcs -T --trace-funcs -t --tracer)*'
+  --nograph-funcs '(-G --graph-funcs -N --notrace-funcs -T --trace-funcs -t --tracer)*'
+  --trace-funcs '(-N --notrace-funcs -G --graph-funcs -g --nograph-funcs -t --tracer)*'
+  --notrace-funcs '(-T --trace-funcs -G --graph-funcs -g --nograph-funcs -t --tracer)*'
+  --source '!(--no-source)'
+)
+
+full=(
+  --addr-range '=[list traced records within address range]:range'
+  --affinity '=[set affinity mask of trace reading thread]:affinity:(node cpu)'
+  --aio '=[specify number of control blocks in asynchronous trace writing mode]:control blocks (1-4) [1]'
+  --all-cgroups '[record cgroup events]'
+  --all-cpus '[system-wide collection from all CPUs]'
+  --asm-raw '[show raw instruction encoding of assembly instructions]'
+  --aux-sample '=[sample AUX area]::options'
+  --baseline-only '[show only items with match in baseline]'
+  --branch-any '[sample any taken branches]'
+  --branch-filter '=[enable taken branch stack sampling]:mask'
+  --branch-stack '[use branch records for per branch histogram filling]'
+  --buffer-size '=[size of per-cpu buffer]: :_numbers size B K M G'
+  --build-ids '[inject build-ids into the output stream]'
+  --buildid-all '[handle build-id of all DSOs]'
+  --call-graph '=[enable call-graph (stacktrace) recording]:(fp dwarf)'
+  --cgroup '=[monitor event in named cgroup only]:cgroup'
+  --children '[accumulate callchains of children and show total overhead]'
+  --clang-opt '=:clang option'
+  --clang-path '=:clang binary:_command_names -e'
+  --clockid '=[specify clockid to use for events]:clock id'
+  --coalesce '=:coalesce field:_sequence compadd - pid tid iaddr dso'
+  --color-cpus '=[highlight given CPUs in map]:cpus'
+  --color-pids '=[highlight given pids in map]: :_sequence _pids'
+  --column-widths '=[use fixed column widths]:widths (comma-separated)'
+  --comms '=[restrict to specified comms]:comms'
+  --compression-level '=[produce compressed trace  using specified level]:level (1-22) [1]'
+  --compute '=[set comparison method]:comparison method [delta-abs]:(delta delta-abs ratio wdiff)'
+  --control '=[listen on ctl-fd descriptor for command to control measurement]:descriptor'
+  --count '=[specify event period]:period'
+  --count-filter '=[only display functions with more than given number of events]:minimum number of events'
+  --cpu '=[restrict to specified CPUs]:cpus'
+  --cpus '=[restrict to specified CPUs]:cpus'
+  --cycles-hist '[show cycles histogram and standard deviation]'
+  --data '[record the sample addresses]'
+  --data-page-size '[record the sampled data address data page size]'
+  --definition '=[show trace-event definition converted from given probe-event]:event'
+  --delay '=[specify delay before starting measurement after program start]:delay (ms)'
+  --demangle '[demangle symbols]'
+  --demangle-kernel '[demangle kernel symbols]'
+  --detailed '[detailed run - start a lot of events]'
+  --disassembler-style '=[specify disassembler style]:style'
+  --dlarg '=:dlfilter argument'
+  --dlfilter '=[filter sample events using the given shared object]:file:_files -g "*.so(-.)"'
+  --dry-run '[parse options then exit]'
+  --dsos '=[only consider symbols in these dsos]:dso'
+  --dump-raw-trace '[dump raw trace in ASCII]'
+  --dump-symtab '[dump the symbol table used for profiling]'
+  --duration '=[show only events with duration over threshold]:minimum duration (ms)'
+  --entries '=[specify how many functions to display]:number of functions'
+  --event '=[select the PMU event]:event:->events'
+  --exclude-other '[only display entries with parent-match]'
+  --exclude-perf "[don't record events from perf itself]"
+  --exec '=[specify path to executable or shared library]:file:_files'
+  --expr '=[specify syscalls/events to trace]:syscall or event'
+  --field-separator '=[specify field separator]:separator'
+  --fields '=[specify output field]:field:->fields'
+  --filter '=[event filter]:filter'
+  --filter-pids '=[specify pids to filter]: :_sequence _pids'
+  --for-each-cgroup '=[expand events for each cgroup]:cgroup'
+  --force "[don't complain, do it]"
+  --format '=[specify output formatting style]:style:(default simple)'
+  --formula '[show formula]'
+  --freq '=[specify profile frequency]:frequency (Hz)'
+  --func-opts '=[specify function tracer options]:option:_sequence compadd - call-graph irq-info'
+  --funcs '=[show available functions]::filter'
+  --graph-funcs '=[select function_graph tracer and trace given functions]:function'
+  --graph-function '=[only print symbols and callees with --call-trace/--call-ret-trace]:symbol list'
+  --graph-opts '=[specify graph tracer options]: : _values -s , option nosleep-time noirqs verbose thresh\:duration depth\:depth'
+  --group '=[show event group information together]'
+  --group-sort-idx '=[sort output by specified event in group]:event index'
+  --gtk '[use the graphical interface]'
+  --guestkallsyms '=[provide copy of guest os /proc/kallsyms]:file:_files'
+  --guestmodules '=[provide copy of guest os /proc/modules]:file:_files'
+  --guestmount '=[specify guest os root file system mount directory]:path:_directories'
+  --guestvmlinux '=[provide guest os kernel]:kernel file:_files'
+  --hide_kernel_symbols '[hide kernel symbols]'
+  --hide_user_symbols '[hide user symbols]'
+  --hide-unresolved '[only display entries resolved to a symbol]'
+  --hierarchy '[show entries in a hierarchy]'
+  --ignore-callees '=[ignore callees of specified functions in call graphs]:functions (regex)'
+  --ignore-vmlinux '[ignore vmlinux files]'
+  --inherit '[trace child processes]'
+  --input '=[specify input file]:file:_files'
+  --interval-count '=[print counts for fixed number of times]:times'
+  --interval-print '=[print counts at regular interval]:interval (ms)'
+  --intr-regs '=[sample selected machine registers on interrupt]:register'
+  --inverted '[alias for inverted call graph]'
+  --iostat '=::default'
+  --itrace '=[specify instruction tracing options]:option:->itrace-opts'
+  --jit '[merge jitdump files into perf.data file]'
+  --kallsyms '=[specify kallsyms pathname]:path:_files'
+  --kcore '=[add specified kcore file to the cache]:file:_files'
+  --kernel '[show running kernel build id]'
+  --Latency '[show latency attributes (irqs/preemption disabled, etc)]'
+  --list '[list all cached files]'
+  --list-opts '[list available options]'
+  --log-fd '=[log output to file descriptor instead of stderr]:file descriptor:_file_descriptors'
+  --map-dump '=[specify BPF map to periodically dump]:BPF map'
+  --max-blocks '=[set maximum number of code blocks to dump with brstackinsn]:blocks'
+  --max-events '=[set maximum number of events to print]:events'
+  --max-size '=[limit the maximum size of the output file]: :_numbers size B K M G'
+  --max-stack '=[set maximum stack depth when parsing the callchain]:depth [kernel.perf_event_max_stack or 127]'
+  --metrics '=[monitor specified metrics or metric groups]:metric'
+  --min-stack '=[set minimum stack depth when parsing the callchain]:depth'
+  --mmap-flush '=[specify minimum size that is extracted from mmap data pages]: :_numbers -d 1 -u bytes size B K M G'
+  --mmap-pages '=[specify number of mmap data pages]:number of pages'
+  --modules '[load module symbols]'
+  --namespaces '[record namespaces events]'
+  --no-bpf-event "[don't record bpf events]"
+  --no-buildid "[don't collect buildids in perf.data]"
+  --no-buildid-cache "[don't update the buildid cache]"
+  --no-inherit "[child tasks don't inherit counters]"
+  --no-samples "[don't sample]"
+  --node-info '[show extra node info in report]'
+  --nograph-funcs "=[select function_graph tracer and don't trace given functions]:function"
+  --notrace-funcs "=[select function tracer and don't trace given functions]:function filter"
+  --null "[null run - don't start any counters]"
+  --num-thread-synthesize '=[specify number of threads to run for event synthesis]:threads'
+  --objdump '=[specify objdump binary to use for disassembly and annotations]:path:_command_names -e'
+  --order '=[specify compute sorting]:ordering [1]:((
+    0\:baseline\ overhead
+    1\:computed\ value\ of\ column\ 1))'
+  --output '=[specify output file]:file:_files'
+  --parent '=[filter by parent caller]:parent (regex)'
+  --percent-limit "=[don't show entries under specified percentage]:percent"
+  --percent-type '=[set annotation percent type]:compadd {local,global}{period,hits}'
+  --percentage '=[set display of filtered entries percentages]:display:(relative absolute)'
+  --phys-data '[record/report sample physical addresses]'
+  --pid '=[restrict to specified process id]:process: _sequence _pids'
+  --post '=[specify command to run after to the measured command]: :_cmdstring'
+  --pre '=[specify command to run prior to the measured command]: :_cmdstring'
+  --prefix '=[add prefix to source file path names]:prefix:_directories'
+  --prefix-strip '=[strip elements from source file path names]:elements'
+  --pretty '=[specify pretty printing style]:key:(normal raw)'
+  --proc-map-timeout '=[specify per-thread proc mmap processing timeout]:timeout (ms)'
+  --quiet "[don't print any messages]"
+  --raw-samples '[collect raw sample records from all opened counters]'
+  --raw-trace '[show raw trace event output]'
+  --realtime '=[profile --addevents with specified priority]:RT SCHED_FIFO priority'
+  --repeat '=[specify amount of times to repeat the run]:repetitions'
+  --samples '=[specify number of samples to save per histogram entry for individual browsing]:samples'
+  --sched-stat '[get details of how long tasks slept]'
+  --show-cpu-utilization '[show sample percentage for different cpu modes]'
+  --show-info '[display extended perf.data information]'
+  --show-nr-samples '[show a column with the number of samples]'
+  --show-on-off-events '[show the --switch-on/off events too]'
+  --show-round-events '[display finished round events]'
+  --show-switch-events '[display context switch events]'
+  --show-total-period '[show a column with the sum of periods]'
+  --skip-missing '--skip-missing[skip symbols that cannot be annotated]'
+  --snapshot '=[select AUX area tracing snapshot mode]::snapshot capturing parameter'
+  --socket-filter '=[only show processor socket that match specified filter]:filter'
+  --sort '=[sort by specified keys]:key:->sort-keys'
+  --stat '[per-thread counts]'
+  --stdio '[use the stdio interface]'
+  --stdio-color '=[specify when to use colors in output]:mode [always]:(always never auto)'
+  --stdio2 '[use the stdio2 interface, non-interactive, TUI formatting]'
+  --stitch-lbr '[enable LBR callgraph stitching approach]'
+  --stop-bt '=[stop display of callgraph at these symbols]:symbol list'
+  --stream '[enable hot streams comparison]'
+  --strip '[strip non-synthesized events]'
+  --summary '[show only syscall summary with statistics]'
+  --switch-max-files '=[limit number of generated files to keep]:limit'
+  --switch-off '=[stop considering events after occurrence of specified event]:event'
+  --switch-on '=[consider events after occurrence of specified event]:event'
+  --switch-output '=[specify when to rotate output file]::signal or size [USR2]:_signals'
+  --switch-output-event '=[switch output event selector]:event:->events'
+  --sym-annotate '=[specify symbol to annotate]:symbol'
+  --symbol '=[specify symbol]:symbol'
+  --symbol-filter '=[only show symbols that match filter]:filter'
+  --symbols '=[only consider specified symbols]:symbol'
+  --symfs '=[look symbol files relative to specified directory]:directory:_directories'
+  --sync '[call sync() before starting a run]'
+  --system '[read and write system config file]'
+  --target-ns '=[obtain mount namespace information form the target pid]:pid:_processes'
+  --td-level '=[set the metrics level for the top-down statistics]:level'
+  --tid '=[restrict to specified threads]:tids'
+  --time '=[specify time span of interest]:time span (start,stop)'
+  --time-quantum '=[set time quantum for time sort key]: :_numbers -d 100ms "time quantum" ms us ns s'
+  --timeout '=[stop workload and print counts after a timeout period]:timeout (ms)'
+  --timestamp-filename '[append timestamp to output file name]'
+  --trace-fields '[show tracepoint fields]'
+  --trace-funcs '=[select function tracer and set function filter]:function filter'
+  --tracer '=[specify tracer to use]:tracer:(function_graph function)'
+  --tui '[use the curses interface]'
+  --uid '=[profile events in threads owned by uid]:uid:_users'
+  --user '[read and write user config file]'
+  --user-regs '=[sample selected machine registers on interrupt]:registers'
+  --vars '=[show available local variables at given probe point]:probe'
+  --vcpu '=[specify vcpu id to report]:vcpu'
+  --verbose '[be more verbose]'
+  --vm-time-correlation '=[correlate time between VM guests and the host]::options'
+  --vmlinux '=[specify vmlinux path]:vmlinux pathname:_files'
+  --weight '[sample by weight (on special events only)]'
+  --with-hits '[show only DSOs with hits]'
+  --with-summary '[show all syscalls and summary with statistics]'
+  --zero '[zero history across updates]'
+)
+short=(
+  --add                -a
+  --all-cpus           -a
+  --baseline-only      -b
+  --branch-any         -b
+  --build-ids          -b
+  --cpu                -C
+  --coalesce           -c
+  --compute            -c
+  --count              -c
+  --delay              -D
+  --dump-raw-trace     -D
+  --data               -d
+  --dsos               -d
+  --event              -e
+  --fields             -F
+  --formula            -F
+  --freq               -F
+  --funcs              -F
+  --force              -f
+  --cgroup             -G
+  --graph-funcs        -G
+  --with-hits          -H
+  --intr-regs          -I
+  --show-info          -I
+  --input              -i
+  --no-inherit         -i
+  --branch-filter      -j
+  --jit                -j
+  --clockid            -k
+  --key                -k
+  --vmlinux            -k
+  --list               -l
+  --disassembler-style -M
+  --buffer-size        -m
+  --mmap-pages         -m
+  --modules            -m
+  --node-info          -N
+  --no-buildid-cache   -N
+  --no-samples         -n
+  --show-nr-samples    -n
+  --order              -o
+  --output             -o
+  --pid                -p
+  --quiet              -q
+  --raw-samples        -R
+  --realtime           -r
+  --repeat             -r
+  --snapshot           -S
+  --symbols            -S
+  --with-summary       -S
+  --sched-stat         -s
+  --script             -s
+  --sort               -s
+  --summary            -s
+  --timestamp          -T
+  --tid                -t
+  --tracer             -t
+  --uid                -u
+  --verbose            -v
+  --weight             -W
+  --column-widths      -w
+  --field-separator    -x
+  --compression-level  -z
+  --zero               -z
+)
+
+cmd=( $words[1] )
+(( $#words > 2 )) && ign='!'
+
+_arguments -C -A "-*" \
+  "${ign}(- *)"{-v,--version}'[display version information]' \
+  "${ign}(- *)"{-h,--help}'[display usage information]' \
+  "${ign}(- *)-vv[print the compiled-in status of libraries]" \
+  '(- *)--exec-path[display or set exec path]' \
+  '(- *)--html-path[display html documentation path]' \
+  "${ign}(- *)--list-opts[list available options]" \
+  "${ign}(- *)--list-cmds[list available subcommands]" \
+  '!(-p --paginate --no-pager)'{-p,--paginate} \
+  --no-pager \
+  '--buildid-dir=[setup buildid cache directory]: :_directories' \
+  '--debugfs-dir=[set debugfs directory]: :_directories' \
+  '--debug=[setup debug variable]: : _values -s, "debug option"
+    verbose\:level ordered-events data-convert stderr perf-event-open' \
+  '1: :->subcmds' \
+  '*:: :->args'
+
+while (( $#state )); do
+  curstate=$state
+  shift state
+  case $curstate in
+    subcmds)
+      subcmds=(
+        ${${${(f)"$(_call_program subcmds $cmd)"}[3,-2]## ##}/ ##(#m)?/:$MATCH[-1]:l}
+        'help:display help information about perf'
+      )
+      _describe 'subcommand' subcmds
+    ;;
+    subsubcmds)
+      _description commands expl command
+      compadd "$expl[@]" -a subcmds
+    ;;
+    args)
+      (( $#words < 3 )) && ign=''
+      cmd+=( $words[1] )
+      curcontext="${curcontext%:*:*}:${(j.-.)cmd}:"
+      args=()
+      skip=0
+      case ${(j.-.)cmd[2,-1]} in
+        kvm-*|top|stat)
+          full[--group]='[put the counters into a counter group]'
+        ;|
+        bench-[^-]##(|-all)) skip=1 opts=() subcmds=() ;|
+
+        annotate)
+          full+=(
+            --full-paths "[don't shorten the displayed pathnames]"
+            --print-line "[print matching source lines (may be slow)]"
+          )
+          short+=(
+            --print-line -l
+            --full-paths -P
+            --symbol -s
+          )
+          args+=(
+            "--no-source[don't interleave source code with assembly code]"
+            '1:: :_guard "^-*" "symbol name"'
+          )
+        ;;
+
+        archive)
+          _arguments --help '1:file:_files'
+          break
+        ;;
+
+        bench)
+          short+=(
+            --edge -E
+            --format -f
+            --nfds -f
+            --group -g
+            --iterations -i
+            --loop -l
+            --nr_loops -l
+            --nr-mmaps -m
+            --multiq -m
+            --nested -N
+            --noaffinity -n
+            --nonblocking -B
+            --nr-samples -n
+            --pipe -p
+            --randomize -R
+             -fruntime -r
+            --size -s
+            --thread -t
+            --threaded -T
+          )
+          args=(
+            '1:subsystem:(sched syscall mem numa futex epoll internals all)'
+            '*:: :->args'
+          )
+          full+=(
+            --group '=[specify number of groups]:groups'
+            --nr_loops '=[specify number of loops to run]:loops [100]'
+            --pipe '[use pipe() instead of socketpair()]'
+            --runtime '=[specify runtime]:runtime (seconds)'
+            --thread '[be multi thread instead of multi process]'
+            --threads '=[specify number of threads]:threads'
+            --loop '=[specify number of loops]:loops'
+            --iterations '=[number of iterations used to compute average]:iterarions'
+            --threaded '[specify threads/process based task setup]'
+            --size '=[specify size of memory buffers]: :_numbers -d 1MB size B KB MB GB TB'
+          )
+        ;;
+        bench-sched) args=( '1:suite:(all messaging pipe)' '*:: :->args' ) ;;
+        bench-numa) args=( '1:suite:(all mem)' '*:: :->args' ) ;;
+        bench-mem) args=( '1:suite:(all memcpy memset find_bit)' '*:: :->args' ) ;;
+        bench-futex)
+          args=( '1:suite:(all hash wake wake-parallel requeue lock-pi)' '*:: :->args' )
+        ;;
+        bench-epoll) args=( '1:suite:(all wait ctl)' '*:: :->args' ) ;;
+        bench-internals) args=( '1:suite:(all synthesize kallsyms-parse inject-build-id)' '*:: :->args' ) ;;
+        bench-syscall) args=( '1:suite:(all basic)' '*:: :->args' ) ;;
+
+        buildid-cache)
+          full+=(
+            --add '=[add specified file to the cache]:file:_files'
+            --debuginfod '=[specify debuginfod URL to be used when retrieving perf.data binaries]:url:_urls'
+            --missing '=[list missing build ids in the cache for the specified]:file:_files'
+            --purge '=[purge all cached binaries including older caches which have specified path from the cache]:path:_files'
+            --purge-all '[purge all cached binaries - flush out entire cache]'
+            --remove '=[remove a cached binary which has same build-id of specified file from the cache]:file:_files'
+            --update '=[update specified file of the cache]:file:_files'
+          )
+          short+=(
+            --kcore -k
+            --missing -M
+            --purge -p
+            --purge-all -P
+            --remove -r
+            --update -u
+          )
+        ;;
+        c2c)
+          args+=( '1:commands:(record report)' '*:: :->args' )
+        ;;
+        daemon)
+          full+=(
+            --base '=[specify base directory]:base directory:_directories'
+            --config '=[specify config file path]:config file:_files'
+            --foreground "[don't put process in background]"
+            --session '=[apply to specific session]:session'
+          )
+          short[--foreground]=-f
+          args=( '1:action:(start stop signal ping)' '*:: :->args' )
+        ;;
+        (kvm-|)buildid-list)
+          short[--kernel]=-k
+        ;;
+        config)
+          full[--list]='[show current config variables]'
+        ;;
+        data)
+          full+=(
+            --all '[convert all events]'
+            --to-json '=[convert to JSON format]:output file:_files'
+            --to-ctf '=[convert to CTF format]:output file:_files'
+            --tod '[convert time to wall clock time]'
+          )
+          exclude+=(
+            --to-ctf '(--to-json)'
+            --to-json '(--to-ctf)'
+          )
+        ;;
+        (kvm-|)diff)
+          short+=(
+            --baseline-only -b
+            --compute -c
+            --comms -C
+            --field-separator -t
+            --formula -F
+            --order -o
+            --period -p
+          )
+          full+=(
+            --period '[show period values]'
+          )
+          unset 'short[--pid]'
+          unset 'short[--tid]'
+          sortkeys=( pid comm dso symbol cpu parent srcline )
+        ;;
+        evlist)
+          short+=( --group -g )
+        ;;
+        ftrace)
+          short+=(
+            --nograph-funcs -g
+            --graph-funcs -G
+            --buffer-size -m
+            --notrace-funcs -N
+            --trace-funcs -T
+            --tracer -t
+          )
+          unset 'short[--tid]'
+        ;;
+        help*)
+          short+=( -a --all -i --info -m --man -w --web )
+        ;;
+        inject)
+          short+=( --jit -j --build-ids -b --sched-stat -s )
+        ;;
+        kmem)
+          full+=(
+            --alloc '[show per-allocation statistics]'
+            --caller '[show per-callsite statistics]'
+            --raw-ip '[show raw ip instead of symbol]'
+            --line '=[show specified number of lines]:lines'
+            --live '[show live page stat]'
+            --slab '[analyze SLAB allocator events]'
+            --page '[analyze page allocator events]'
+          )
+          short[--line]=-l
+          sortkeys=(
+            ptr callsite bytes hit pingpong frag
+            page order migtype gfp
+          )
+        ;;
+        list)
+          short+=( --desc -d --long-desc -v )
+          full+=(
+            --desc '[print extra event descriptions]'
+            --details '[print information on the perf event names and expressions used internally by events]'
+            --long-desc '[print longer event descriptions]'
+          )
+          args=( '*::events:->event-types' )
+        ;;
+        lock-info)
+          short[--map]=-m
+          short[--threads]=-t
+          full+=(
+            --map '[dump map of lock instances (address:name table)]'
+            --threads '[dump thread list in perf.data]'
+          )
+        ;;
+        lock-report)
+          full[--key]='=[specify sort key]:key [acquired]:(acquired contended avg_wait wait_total wait_max wait_min)'
+        ;;
+        mem)
+          short[--phys-data]=-p
+          short[--type]=-t
+          short[--dump-raw-samples]=-D
+          full[--type]='=[select the memory operation type]:type:(load store)'
+          full[--dump-raw-samples]='[dump raw samples in ASCII]'
+        ;;
+        probe)
+          full+=(
+            --add '=[probe point definition]:probe'
+            --del '=[delete a probe event]:probe event'
+            --filter '=[set a filter]:filter'
+            --line '[show source code lines which can be probed]'
+            --max-probes '=[set how many probe points can be found for a probe]:probes'
+            --module '=[specify target module name or path]:module name or path:_directories'
+            --range '[show variables location range in scope]'
+            --source '=[specify path to kernel source]:path:_directories'
+          )
+          short+=(
+            --definition -D
+            --del -d
+            --exec -x
+            --line -L
+            --module -m
+            --dry-run -n
+            --source -s
+            --vars -V
+          )
+          unset 'exclude[--source]'
+          unset 'short[--list]'
+        ;;
+        timechart-record)
+          short+=( --io-only -I --callchain -g )
+          full+=(
+            --callchain '[record callchain]'
+            --io-only '[record only IO data]'
+          )
+        ;;
+        *record)
+          short+=(
+            --data -d
+            --clockid -k
+            --no-samples -n
+            --no-buildid -B
+            --no-buildid-cache -N
+            --period -P
+            --stat -s
+          )
+          full+=(
+            --overwrite '[use overwrite mode]'
+            --period '[record the sample period]'
+            --timestamp '[record the sample timestamps]'
+            --transaction '[sample transaction flags (special events only)]'
+          )
+        ;;
+        (c2c-|kvm-|)report)
+          short+=(
+            --branch-stack -b
+            --comms -c
+            --inverted -G
+            --call-graph -g
+            --parent -p
+            --threads -T
+            --field-separator -t
+            --exclude-other -x
+          )
+          full+=(
+            --threads '[show per-thread event counters]'
+          )
+          unset 'short[--pid]'
+          unset 'short[--tid]'
+          sortkeys=(
+            pid comm dso symbol parent cpu socket srcline weight local_weight cgroup_id
+          )
+          fields=(
+	    overhead period sample overhead overhead_sys overhead_us
+	    overhead_guest_sys overhead_guest_us overhead_children
+	    sample period pid comm dso symbol parent cpu socket
+	    srcline srcfile local_weight weight transaction trace
+	    symbol_size dso_size cgroup cgroup_id ipc_null time
+	    code_page_size local_ins_lat ins_lat p_stage_cyc dso_from
+	    dso_to symbol_from symbol_to mispredict abort in_tx
+	    cycles srcline_from srcline_to ipc_lbr symbol_daddr
+	    dso_daddr locked tlb mem snoop dcacheline symbol_iaddr
+	    phys_daddr data_page_size blocked
+          )
+        ;;
+        sched-latency)
+          short+=(
+            --CPU -C
+            --pids -p
+          )
+          full+=(
+            --pids '[latency stats per pid instead of per comm]'
+            --CPU '=[specify CPU to profile on]:cpu'
+          )
+        ;;
+        sched-timehist)
+          short+=(
+            --idle-hist -I
+            --migrations -M
+            --next -n
+            --cpu-visual -V
+            --wakeups -w
+          )
+          full+=(
+            --cpu-visual '[add CPU visual]'
+            --idle-hist '[show idle events only]'
+            --migrations '[show migration events]'
+            --next '[show next task]'
+            --state '[show task state when sched-out]'
+            --wakeups '[show wakeup events]'
+          )
+        ;;
+        (*-|)script)
+          short+=( --comms -c --gen-script -g --Latency -L --debug-mode -d )
+          full+=(
+            --debug-mode '[do various checks like samples ordering and lost events]'
+            --gen-script '=[generate perf-script.xx script in specified language]:language'
+            --script '=[specify script file name]:script file name:_files'
+          )
+          unset 'short[--pid]'
+          unset 'short[--dsos]'
+          unset 'short[--tid]'
+          fields=(
+	    comm tid pid time cpu event trace ip sym dso addr symoff
+	    srcline period iregs uregs brstack brstacksym flags
+	    bpf-output brstackinsn brstackoff callindent insn insnlen
+	    synth phys_addr metric misc ipc tod data_page_size
+	    code_page_size
+          )
+        ;;
+        *stat*)
+          full+=(
+            --big-num "[print large numbers with thousands' separators]"
+            --delay '=[wait after starting program]:delay (msecs)'
+            --key '=[specify key for sorting]:key:(sample time)'
+            --no-aggr '[disable CPU count aggregation]'
+            --transaction '[hardware transaction statistics]'
+          )
+          short+=(
+            --no-aggr -A
+            --big-num -B
+            --detailed -d
+            --group -g
+            --interval-print -I
+            --metrics -M
+            --null -n
+            --sync -S
+            --transaction -T
+          )
+          exclude+=(
+            --log-fd '(-o --output)'
+            --output '(--log-fd)'
+          )
+          unset 'short[--quiet]'
+        ;;
+        test*)
+          short+=( --dont-fork -F --skip -s )
+          full+=(
+            --dont-fork "[don't fork for testcase]"
+            --skip '=[specify tests to skip]:test'
+          )
+        ;;
+        timechart)
+          short+=( --width -w --topology -t --proc-num -n --process -p )
+          full+=(
+            --highlight '=[highlight tasks that outlast duration or with given name]:duration or name'
+            --io-skip-eagain "[don't draw EAGAIN IO events]"
+            --io-min-time '=[all IO faster than minimum time will visually appear longer]: :_numbers -u ns -d 1ms time ms us'
+            --io-merge-dist '=[merge events that are within specified time]: :_numbers -u ns -d 1us time ms us'
+            --process '=[select process]:process:_pids'
+            --proc-num '=[specify minimum number of tasks to print]:tasks'
+            --topology '[sort CPUs according to topology]'
+            --width '=[specify page width]:page width'
+          )
+        ;;
+        (kvm-|)top)
+          full+=(
+            --delay '=[specify delay between refreshes]:delay (seconds)'
+            --comms '=[only consider symbols in specified comms]:comm'
+            --dsos '=[only consider symbols in these dsos]:dso'
+            --overwrite '[use a backward ring buffer]'
+          )
+          short+=(
+            --count-filter -f
+            --delay -d
+            --dump-symtab -D
+            --entries -E
+          )
+          unset 'short[--dsos]'
+          unset 'short[--fields]'
+          unset 'short[--force]'
+          unset 'short[--symbols]'
+          sortkeys=(
+            pid comm dso symbol parent srcline weight local_weight
+            abort in_tx transaction overhead sample period
+          )
+          fields=( overhead period sample $sortkeys )
+        ;;
+        trace)
+          short+=(
+            --pf -F
+            --summary -s
+            --time -T
+          )
+          full+=(
+            --pf '=[trace pagefaults]::type [maj]:(all min maj)'
+            --time '[show full timestamp, not relative]'
+          )
+          unset 'short[--no-inherit]'
+        ;;
+      esac
+      if (( !skip )); then
+        subcmds=( $(_call_program commands "$cmd --list-cmds|grep -v -e '^#' -e Unknown") )
+        opts=( $(_call_program options "$cmd --list-opts|grep -v -e '^#' -e Unknown") )
+      fi
+
+      for (( i = $#opts; i; i-- )); do
+        opts[i]=(
+          ${exclude[$opts[i]]}${opts[i]}${full[$opts[i]]}
+          ${short[$opts[i]]:+${exclude[$opts[i]]}${short[$opts[i]]}${full[$opts[i]]/(#s)=/+}}
+        )
+      done
+      (( $#subcmds)) && opts+=(
+        "${ign}(- *)--list-cmds[list available subcommands]" \
+        '1: :->subsubcmds'
+        '*:: :->args'
+      )
+      (( $#opts )) && opts+=(
+        "${ign}(- *)--help[display help information]"
+        "${ign}(- *)--list-opts[list available options]"
+      )
+      _arguments -C $opts $args \
+        "${ign}(- *)-h[display brief usage summary]"
+    ;;
+    event-types)
+      _wanted event-types expl 'event type' compadd - hw sw cache pmu tracepoint event_glob
+    ;&
+    events)
+      _wanted events expl event compadd - \
+        ${${=${${(f)"$(_call_program events perf list hw sw cache pmu tracepoint event_glob)"}[2,-5]#  }%% [ \[]*}:#OR}
+    ;;
+    itrace-opts)
+      _values -s '' "itrace option [ibxwpe]" \
+        'i[synthesize instructions events]' \
+        'b[synthesize branches events (branch misses for Arm SPE)]' \
+        'c[synthesize branches events (calls only)]' \
+        'r[synthesize branches events (returns only)]' \
+        'x[synthesize transactions events]' \
+        'w[synthesize ptwrite events]' \
+        'p[synthesize power events (incl. PSB events for Intel PT)]' \
+        'o[synthesize other events recorded due to the use of aux-output]' \
+        'e[synthesize error events]' \
+        'd[create a debug log]' \
+        'f[synthesize first level cache events]' \
+        'm[synthesize last level cache events]' \
+        'M[synthesize memory events]' \
+        't[synthesize TLB events]' \
+        'a[synthesize remote access events]' \
+        'g[synthesize a call chain (use with i or x)]' \
+        'G[synthesize a call chain on existing event records]' \
+        'l[synthesize last branch entries (use with i or x)]' \
+        'L[synthesize last branch entries on existing event records]' \
+        's[skip initial number of events]' \
+        'q[quicker (less detailed) decoding]' \
+        'Z[prefer to ignore timestamps (so-called "timeless" decoding)]'
+    ;;
+    fields)
+      _sequence _wanted fields expl 'field' compadd - -a fields
+    ;;
+    sort-keys)
+      _sequence _wanted sort-keys expl 'sort key' compadd - -a sortkeys
+    ;;
+  esac
+done
+
+[[ nm -ne compstate[nmatches] ]]
diff --git a/Completion/Linux/Command/_pidof b/Completion/Linux/Command/_pidof
index dd0649ce9..151a0e0f6 100644
--- a/Completion/Linux/Command/_pidof
+++ b/Completion/Linux/Command/_pidof
@@ -3,19 +3,51 @@
 local curcontext="$curcontext" state line expl ret=1
 typeset -A opt_args
 
-local exargs="-h --help -V --version"
-_arguments -C -s -w \
-  '(- *)'{-h,--help}'[display help information]' \
-  '(- *)'{-V,--version}'[print program version]' \
-  "(-s --single-shot $exargs)"{-s,--single-shot}'[return one PID only]' \
-  "(-c --check-root $exargs)"{-c,--check-root}'[omit processes with different root]' \
-  '-q[quiet mode, only set the exit code]' \
-  '(-w --with-workers)'{-w,--with-workers}'[show kernel workers too]' \
-  "(-x $exargs)"-x'[include shells running named scripts]' \
-  "($exargs)"\*{-o+,--omit-pid=}'[omit processes with PIDs]:pids:_sequence -s , _pids' \
-  '(-S --separator)'{-S+,--separator=}'[specify separator put between PIDs]:separator' \
-  '*:process:->procnames' \
-  && return 0
+_pick_variant -r variant procps='--separator' $OSTYPE -h
+
+case $variant in
+  (procps)
+    local exargs="-h --help -V --version"
+    _arguments -C -s -w \
+      '(- *)'{-h,--help}'[display help information]' \
+      '(- *)'{-V,--version}'[print program version]' \
+      "(-s --single-shot $exargs)"{-s,--single-shot}'[return one PID only]' \
+      "(-c --check-root $exargs)"{-c,--check-root}'[omit processes with different root]' \
+      '-q[quiet mode, only set the exit code]' \
+      '(-w --with-workers)'{-w,--with-workers}'[show kernel workers too]' \
+      "(-x $exargs)"-x'[include shells running named scripts]' \
+      "($exargs)"\*{-o+,--omit-pid=}'[omit processes with PIDs]:pids:_sequence -s , _pids' \
+      '(-S --separator)'{-S+,--separator=}'[specify separator put between PIDs]:separator' \
+      '*:process:->procnames' \
+      && return 0
+    ;;
+  (darwin*)
+    # Night Production pidof
+    _arguments -s -w \
+      '(- *)'{-h,-\?}'[display help information]' \
+      '(- *)-v[print out version info on pidof]' \
+      '-l[print output in long format]' \
+      '-k[kill processes by name]' \
+      '*:process:_process_names -a' \
+      && return 0
+    ;;
+  (*)
+    # sysvinit-utils
+    _arguments -C -s -w \
+      '(- *)-h[display help information]' \
+      '-c[return PIDs with the same root directory]' \
+      '-d[use the provided character as output separator]:separator' \
+      '-n[avoid using stat system function on network shares]' \
+      '-o[omit results with a given PID]:pid:_sequence -s , _pids' \
+      '-s[return one PID only]' \
+      '-q[quiet mode. Do not display output]' \
+      '-s[only return one PID]' \
+      '-x[return PIDs of shells running scripts with a matching name]' \
+      '-z[list zombie and I/O waiting processes. May cause pidof to hang]' \
+      '*:process:->procnames' \
+      && return 0
+    ;;
+esac
 
 case $state in
   procnames)
diff --git a/Completion/Linux/Command/_selinux b/Completion/Linux/Command/_selinux
new file mode 100644
index 000000000..a7ba68952
--- /dev/null
+++ b/Completion/Linux/Command/_selinux
@@ -0,0 +1,796 @@
+#compdef audit2allow audit2why avcstat chcon checkmodule checkpolicy fixfiles getpidprevcon getsebool matchpathcon newrole restorecon runcon sealert secon sedta seinfo selinuxconlist selinuxdefcon selinuxexeccon semanage semodule semodule_unpackage sepolgen sepolicy sesearch sestatus setenforce setsebool validatetrans
+
+# encompasses checkpolicy libselinux-utils policycoreutils
+# policycoreutils-devel policycoreutils-python-utils setools-console
+# setools-console-analyses setroubleshoot-server and a few utilities from
+# coreutils
+
+_selinux_attributes() {
+  local -a seattrs expl
+
+  seattrs=( ${(f)"$(_call_program selinux-attributes seinfo --flat -a)"} )
+  _description selinux-attrs expl "selinux attribute"
+  compadd "$@" "$expl[@]" -a seattrs
+}
+
+_selinux_bools() {
+  local -a sebools expl
+
+  sebools=( ${(f)"$(_call_program selinux-bools seinfo --flat -b)"} )
+  _description selinux-bools expl "selinux boolean"
+  compadd "$@" "$expl[@]" -a sebools
+}
+
+_selinux_categories() {
+  local -a secats expl
+
+  secats=( ${(f)"$(_call_program selinux-categories seinfo --flat --category)"} )
+  _description selinux-categories expl "selinux category"
+  compadd "$@" "$expl[@]" -a secats
+}
+
+_selinux_classes() {
+  local -a seclasses expl
+
+  seclasses=( ${(f)"$(_call_program selinux-classes seinfo --flat -c)"} )
+  _description selinux-classes expl "selinux object class"
+  compadd "$@" "$expl[@]" -a seclasses
+}
+
+_selinux_commons() {
+  local -a secommons expl
+
+  secommons=( ${(f)"$(_call_program selinux-commons seinfo --flat --common)"} )
+  _description selinux-commons expl "selinux common permission set"
+  compadd "$@" "$expl[@]" -a secommons
+}
+
+_selinux_interfaces() {
+  local -a seints expl
+
+  seints=( ${(f)"$(_call_program selinux-interfaces sepolicy interface -l)"} )
+  _description selinux-interfaces expl "selinux interface"
+  compadd "$@" "$expl[@]" -a seints
+}
+
+_selinux_permissions() {
+  local -a seperms expl
+
+  seperms=( ${${${${(f)"$(_call_program selinux-permissions seinfo -c --flat -x)"}:#[^[:blank:]]*}#[[:blank:]]}:1} )
+  _description selinux-permissions expl "selinux permission"
+  compadd "$@" "$expl[@]" -a seperms
+}
+
+_selinux_sids() {
+  local -a sesids expl
+
+  sesids=( ${(f)"$(_call_program selinux-sids seinfo --flat --initialsid)"} )
+  _description selinux-sids expl "selinux SID"
+  compadd "$@" "$expl[@]" -a sesids
+}
+
+_selinux_sens() {
+  local -a sens expl
+
+  sesids=( ${(f)"$(_call_program selinux-sens seinfo --flat --initialsid)"} )
+  _description selinux-sensitivities expl "selinux sensitivity"
+  compadd "$@" "$expl[@]" -a sesids
+}
+
+_selinux_modules() {
+  local -a modules expl
+
+  modules=( ${(f)"$(_call_program selinux-modules semodule -l)"} )
+  _description selinux-modules expl "selinux module"
+  compadd "$@" "$expl[@]" -a modules
+}
+
+local curcontext="$curcontext" ret=1
+local -A opt_args
+local -a args sepolgen state state_descr line
+local ign
+(( $#words > 2 )) && ign='!'
+
+sepolgen=(
+  "${ign}(-h --help)"{-h,--help}'[display help information]'
+  '(--application --cgi --dbus --inetd --init --admin_user --confined_admin --desktop_user --newtype --sandbox --x_user)'*{-d+,--domain=}'[specify domain to expand]:domain:_selinux_types -a domain'
+  \*{-r+,--role=}'[specify role(s) to which the administrator domain will transition]: :_selinux_roles'
+  \*{-u+,--user=}'[specify SELinux user(s) which will transition to this domain]: :_selinux_users'
+  \*{-a+,--admin=}'[specify domain(s) which this confined admin will administrate]:admin domain:_selinux_types'
+  '(-n --name)'{-n+,--name=}'[specify name of policy to generate]:name'
+  '(--admin_user --confined_admin --desktop_user --newtype --sandbox --x_user)*'{-t+,--type=}'[specify type(s) for which you will generate new definition and rule(s)]:type:_selinux_types'
+  '(-p --path)'{-p+,--path=}'[specify path in which the generated policy files will be stored]:path:_directories'
+  '(--newtype)*'{-w+,--writepath=}'[specify path to which the confined processes will need to write]:path:_directories'
+  '1:command:_files'
+  + '(application)'
+  "(-d)--application[generate 'User Application' policy]"
+  "(-d)--cgi[generate 'Web Application/Script (CGI)' policy]"
+  "(-d)--dbus[generate 'DBUS System Daemon' policy]"
+  "(-d)--inetd[generate 'Internet Services Daemon' policy]"
+  "(-d)--init[generate 'Standard Init Daemon' policy]"
+  "(-d -t 1)--admin_user[generate 'Administrator Login User Role' policy]"
+  "(-d -t 1)--confined_admin[generate 'Confined Root Administrator Role' policy]"
+  "(1)--customize[generate 'Existing Domain Type' policy]"
+  "(-d -t 1)--desktop_user[generate 'Desktop Login User Role' policy]"
+  "(-d -w 1)--newtype[generate 'Module information for a new type' policy]"
+  "(-d -t 1)--sandbox[generate 'Sandbox' policy]"
+  "(-d -t 1)--term_user[generate 'Minimal Terminal Login User Role' policy]"
+  "(-d -t 1)--x_user[generate 'Minimal X Windows Login User Role' policy]"
+)
+
+case $service in
+  check(module|policy))
+    args=(
+      '(-b --binary)'{-b,--binary}'[read an existing binary policy file rather than a source policy.conf file]'
+      '(-C --cil)'{-C,--cil}'[write CIL policy file rather than binary policy file]'
+      '(-E --werror)'{-E,--werror}'[treat warnings as errors]'
+      "${ign}(-h --help)"{-h,--help}'[display help information]'
+      '(-U --handle-unknown)'{-U+,--handle-unknown=}'[specify how the kernel should handle unknown classes or permissions]:action:(deny allow reject)'
+      '(-M --mls)'{-M,--mls}'[enable the MLS policy when checking and compiling the policy]'
+      '(-o --output)'{-o+,--output=}'[write a policy file]:file:_files'
+      '-c+[specify the policy version]:policy version [latest]'
+      ':input file:_files'
+    )
+  ;|
+
+  audit2(allow|why))
+    args=(
+      '(-b --boot -i --input)'{-b,--boot}'[audit messages since last boot]'
+      '(-a --all -i --input -d --dmesg)'{-a,--all}'[read input from audit log]'
+      '(-p --policy)'{-p+,--policy=}'[specify policy file to use for analysis]:file:_files'
+      '(-d --dmesg -a --all -i --input)'{-d,--dmesg}'[read input from dmesg]'
+      '(-i --input -a --all -b --boot)'{-i+,--input=}'[read input from file]:file:_files'
+      '(-l --lastreload)'{-l,--lastreload}'[read input only after the last reload]'
+      '(-r --requires)'{-r,--requires}'[generate require statements for rules]'
+      '(-m --module -M --module-package -r --requires)'{-m+,--module=}'[set the module name]:module name:_selinux_modules'
+      '(-M --module-package -o --output -m --module)'{-M+,--module-package=}'[generate a module package]:module package:_files'
+      '(-o --output -M --module-package)'{-o+,--output=}'[append output to file]:file:_files'
+      '(-D --dontaudit)'{-D,--dontaudit}'[generate policy with dontaudit rules]'
+      '(-R --reference)'{-R,--reference}'[use installed macros in generated policy]'
+      '!(-R --reference -N --noreference)'{-N,--noreference}
+      '(-v --verbose)'{-v,--verbose}'[explain generated output]'
+      '(-e --explain)'{-e,--explain}'[fully explain generated output]'
+      '(-t --type)'{-t+,--type=}'[only process messages with type matching regex]:type'
+      '--perm-map=[specify file name of perm map]:file:_files'
+      '--interface-info=[specify file name of interface information]:file:_files'
+      '(-x --xperms)'{-x,--xperms}'[generate extended permission rules]'
+      '--debug[leave generated modules for -M]'
+      '(-w --why)'{-w,--why}'[translate SELinux audit messages into a description of why the access was denied]'
+      "${ign}(-h --help)"{-h,--help}'[display help information]'
+      "${ign}--version[display version information]"
+    )
+  ;;
+
+  avcstat)
+    args=(
+      '-c[cumulative]'
+      '-f+[specify AVC statistics file]:file [/sys/fs/selinux/avc/cache_stats]:_files'
+      ': :_guard "^-*" "interval (seconds)"'
+    )
+  ;;
+
+  chcon)
+    args=( -S
+      '(-h --no-dereference)--dereference[dereference symlinks]' \
+      '(-h --no-dereference --dereference)'{-h,--no-dereference}'[operate on symlinks themselves]' \
+      '(1 -u --user -r --role  -l --range -t --type)--reference=[copy security context of specified file]:file:_files' \
+      '(1 --reference -u --user)'{-u+,--user=}'[set user in the target security context]: :_selinux_users' \
+      '(1 --reference -r --role)'{-r+,--role=}'[set role in the target security context]: :_selinux_roles' \
+      '(1 --reference -t --type)'{-t+,--type=}'[set type in the target security context]: :_selinux_types' \
+      '(1 --reference -l --range)'{-l+,--range=}'[set range in the target security context]:selinux range' \
+      '(--recursive -R)'{--recursive,-R}'[recurse subdirectories]' \
+      '(-v --verbose)'{-v,--verbose}'[output a diagnostic for every file processed]' \
+      '(-H -L -P)-H[follow symlinks on the command line]' \
+      '(-H -L -P)-L[follow all symlinks]' \
+      "(-H -L -P)-P[don't follow symlinks (default)]" \
+      '!(--preserve-root)--no-preserve-root' \
+      "--preserve-root[fail to operate recursively on '/']" \
+      '(--reference -u --user -r --role  -l --range -t --type)1:security context:_selinux_contexts' \
+      "${ign}--help[display help information]" \
+      "${ign}--version[display version information]" \
+      '*:file:_files'
+    )
+  ;;
+
+  checkmodule)
+    args=(
+      "${ign}(-)"{-V,--version}'[show policy versions created by this program]'
+      '-m[build a policy module instead of a base module]'
+      '-c+[build a policy module targeting a modular policy version]:version (4-21)'
+    )
+  ;;
+
+  checkpolicy)
+    args=(
+      '(-F --conf)'{-F,--conf}'[write policy.conf file rather than binary policy file]'
+      '(-d --debug)'{-d,--debug}'[enter debug mode after loading the policy]'
+      '(-S --sort)'{-S,--sort}'[sort ocontexts before writing out the binary policy]'
+      '(-t --target)'{-t+,--target=}'[specify the target platform]:platform:(selinux xen)'
+      '(-O --optimize)'{-O,--optimize}'[optimize the final kernel policy (remove redundant rules)]'
+      "${ign}(-)"{-V,--version}'[display version information]'
+    )
+  ;;
+
+  fixfiles)
+    args=(
+      '-B[record current date in /.autorelabel to speed later labeling]'
+      '-F[force reset of context to match file_context for customizable files]'
+      '-f[clear /tmp directory without prompt for removal]'
+      '-R+[discover files from specified rpm packages]:package'
+      '-C+[run a diff on the specified file]:file:_files'
+      '-N+[only act on files created after the specified date]:date (YYYY-MM-DD HH\:MM):_dates'
+      '-v[show changes in file labels]'
+      '-T+[specify number of threads to use]:threads'
+      '1::action:(check verify restore relabel onboot)'
+      '*:file:_files'
+    )
+  ;;
+
+  getpidprevcon)
+    _pids
+    return
+  ;;
+
+  getsebool)
+    args=(
+      '(:)-a[show all booleans]'
+      '(-a):boolean:_selinux_bools'
+    )
+  ;;
+
+  matchpathcon)
+    args=(
+      '-m+[force file type for the lookup]:type:(file dir pipe chr_file blk_file lnk_file sock_file)'
+      "-n[don't display path]"
+      "-N[don't use translations]"
+      '-f+[use alternate file_context file]:file:_files'
+      '-p+[use prefix to speed translations]:prefix'
+      '-P+[use alternate policy root path]:path:_directories'
+      '-V[verify file context on disk matches defaults]'
+      '*:file path:_files'
+    )
+  ;;
+
+  newrole)
+    local cmd cpp
+    cmd="$words[1]"
+    cpp='_comp_priv_prefix=( $cmd ${(kv)opt_args[(I)-([rtl]|-role|-type|-level)]} )'
+    args=(
+      '(-r --role)'{-r+,--role=}'[specify role]: :_selinux_roles'
+      '(-t --type)'{-t+,--type=}'[specify type]: :_selinux_types'
+      '(-l --level)'{-l+,--range=}'[specify level]:level'
+      '(-p --preserve-environment)'{-p,--preserve-environment}"[don't create new minimal environment]"
+      "${ign}(-)"{-V,--version}'[display version information]'
+      "(-)1: :{ $cpp; _command_names -e }" \
+      "*:: :{ $cpp; _normal }"
+    )
+  ;;
+
+  restorecon)
+    args=(
+      '*-e+[exclude a directory]:directory:_directories'
+      '-f+[provide list of files to be processed]:file:_files'
+      '-F[force reset of context to match file_context for customizable files]'
+      "-i[ignore files that don't exist]"
+      '-I[ignore digest to force checking of labels even if SHA256 digest matches]'
+      '-D[set or update any directory SHA256 digests]'
+      '-m[include non-seclabel mounts in relabeling checks]'
+      "-n[don't change any file labels (passive check)]"
+      '(-v)-p[show progress]'
+      '(-R -r)'{-R,-r}'[change file labels recursively]'
+      '(-p)-v[show changes in file labels]'
+      '-W[display warnings about entries that had no matching files]'
+      '-0[expect NUL characters as input filename separators]'
+      "-x[don't cross file system boundaries]"
+      '-T+[specify number of threads to use]:threads'
+      "${ign}(-)"{-h,-\?}'[display help information]'
+      '*:file path:_files'
+    )
+  ;;
+
+  runcon)
+    args=(
+      '(1 -c --compute)'{-c,--compute}'[compute process transition context before modifying]'
+      '(1 -t --type)'{-t+,--type=}'[specify type]: :_selinux_types'
+      '(1 -u --user)'{-u+,--user=}'[specify user identity]: :_selinux_users'
+      '(1 -r --role)'{-r+,--role=}'[specify role]: :_selinux_roles'
+      '(1 -l --range)'{-l+,--range=}'[specify level range]:range'
+      '(-)1:security context:_selinux_contexts'
+      '*:::args:_normal'
+    )
+  ;;
+
+  sealert)
+    args=(
+      '(-b --browser)'{-b,--browser}'[launch the browser]'
+      '(-s --service -S --noservice)'{-s,--service}'[start sealert as a dbus service]'
+      '(-S --noservice -s --service)'{-S,--noservice}'[start sealert without dbus service as standalone app]'
+      '(-l --lookupid)'{-l+,--lookupid=}'[lookup alert by id, id may be wildcard * to lookup all alerts]:id'
+      '(-a --analyze)'{-a+,--analyze=}'[scan a log file, analyze its AVCs]:log file:_files'
+      '(-u --user)'{-u+,--user=}'[logon user name]:username'
+      '(-p --password)'{-p+,--password=}'[logon user password]:password'
+      '(-P --plugin)'{-P+,--plugin=}'[specify plugin name, required for -f]:plugin name'
+      '(-f --fix)'{-f+,--fix=}'[fix avc with the given uuid, requires plugin]:uuid'
+      "${ign}(-)"{-h,--help}'[display help information]'
+    )
+  ;;
+
+  secon)
+    args=(
+      "${ign}(-)"{-h,--help}'[display help information]'
+      "${ign}(-)--version[display version information]"
+      '(-P --prompt)'{-P,--prompt}'[output in a format good for a prompt]'
+      '(-u --user)'{-u,--user}'[show user of the context]'
+      '(-r --role)'{-r,--role}'[show role of the context]'
+      '(-t --type)'{-t,--type}'[show type of the context]'
+      '(-s --sensitivity)'{-s,--sensitivity}'[show sensitivity level of the context]'
+      '(-c --clearance)'{-c,--clearance}'[show clearance level of the context]'
+      '(-m --mls-range)'{-m,--mls-range}'[show sensitivity to clearance range of]'
+      '(-R --raw)'{-R,--raw}'[output context in "raw" format]'
+      '(-C --color)'{-C,--color}'[output using ANSI color codes (requires -P)]'
+      + '(context)'
+      {--self,--current}'[get context for the current process]'
+      {--self-exec,--current-exec}'[get exec context for the current process]'
+      {--self-fs,--current-fs}'[get fs context for the current process]'
+      {--self-key,--current-key}'[get key context for the current process]'
+      '--parent[get context for the parent process]'
+      '--parent-exec[get exec context for the parent process]'
+      '--parent-fs[get fs context for the parent process]'
+      '--parent-key[get key context for the parent process]'
+      {-p+,--pid=}'[context from the specified pid]:pid:_pids'
+      '--pid-exec[use exec context from the specified pid]:pid:_pids'
+      '--pid-fs[use fs context from the specified pid]:pid:_pids'
+      '--pid-key[use key context from the specified pid]:pid:_pids'
+      {-f+,--file=}'[use context from the specified file]:file:_files'
+      {-L+,--link=}"[use context from the specified file, doesn't follow symlinks]:file:_files"
+      ':context:_selinux_contexts'
+    )
+  ;;
+
+  sedta)
+    args=(
+      '(-p --policy)'{-p+,--policy=}'[specify path to SELinux policy to analyze]:policy:_files'
+      '(-s --source)'{-s+,--source=}'[specify source type of the analysis]:source:_selinux_types -a domain'
+      '(-t --target)'{-t+,--target=}'[specify target type of the analysis]:target:_selinux_types -a domain'
+      '--full[print rule lists for transitions]'
+      '--stats[display statistics at the end of the analysis]'
+      '(-v --verbose)'{-v,--verbose}'[extra informational messages]'
+      '--debug[enable debugging]'
+      '(-S --shortest_path)'{-S,--shortest_path}'[calculate all shortest paths]'
+      '(-A --all_paths)'{-A+,--all_paths=}'[calculate all paths]:max steps'
+      '(-r --reverse)'{-r,--reverse}'[perform a reverse DTA]'
+      '(-l --limit_trans)'{-l+,--limit_trans=}'[limit to the specified number of transitions]:limit'
+      '*:excluded domain:_selinux_types -a domain'
+      "${ign}(- *)"{-h,--help}'[display help information]'
+      "${ign}(-)--version[display version information]"
+    )
+  ;;
+
+  seinfo)
+    args=(
+      '(-a --attribute)'{-a,--attribute}'[list attributes or print named attribute]:: :_selinux_attributes'
+      '(-b --bool)'{-b,--bool}'[list booleans or print named boolean]:: :_selinux_bools'
+      '(-c --class)'{-c,--class}'[list object classes or print named object class]:: :_selinux_classes'
+      '(-r --role)'{-r,--role}'[list roles or print named role]:: :_selinux_roles'
+      '(-t --type)'{-t,--type}'[list types or print named type]:: :_selinux_types'
+      '(-u --user)'{-u,--user}'[list users or print named user]:: :_selinux_users'
+      '--category[list categories or print named category]:: :_selinux_categories'
+      '--common[list common permission sets or print named common]:: :_selinux_commons'
+      '--constrain[list constraints or print constraints for named object class]:: :_selinux_classes'
+      '--default[list default_* statements or print statements for named object class]:: :_selinux_classes'
+      '--fs_use[list fs_use_* statements or print statements for named filesystem type]:: :_file_systems'
+      '--genfscon[list genfscon statements or print statements for named filesystem type]:: :_file_systems'
+      '--initialsid[list initial SIDs or print named SID]:: : _selinux_sids'
+      '--netifcon[list netif contexts or print for named interface]:: : _net_interfaces'
+      '--nodecon[list node contexts or print statement for node with specified address]::address'
+      '--permissive[list permissive types or print named statement]::type'
+      '--polcap[list policy capabilities or print named statement]::type'
+      '--portcon[list port contexts or print statements for port range]::port range'
+      '--sensitivity[list sensitivities or print named sensitivity]:: :_selinux_sens'
+      '--typebounds[list type bounds or print named bound type]:: :_selinux_typebounds'
+      '--validatetrans[list validatetrans rules or print constraints for named object class]:: :_selinux_classes'
+      '--all[list all components]'
+      '(-x --expand)'{-x,--expand}'[print additional details]'
+      '--flat[exclude headers and indentation in output]'
+      '(-v --verbose)'{-v,--verbose}'[print additional informational messages]'
+      '--debug[enable debugging output]'
+      "${ign}--help[display help information]"
+      "${ign}--version[display version information]"
+      ':policy:_files'
+    )
+  ;;
+
+  selinuxconlist)
+    args=(
+      '-l+[specify mcs/mls level]:level'
+      ':user:_selinux_users'
+      ':context:_selinux_contexts'
+    )
+  ;;
+
+  selinuxdefcon)
+    args=(
+      '-l+[specify mcs/mls level]:level'
+      ':user:_users'
+      ':context:_selinux_contexts'
+    )
+  ;;
+
+  selinuxexeccon)
+    args=(
+      '1:command:_files -g "*(-*)"'
+      '2:from context:_selinux_contexts'
+    )
+  ;;
+
+  semanage)
+    _arguments -C \
+      {-h,--help}'[display help information]' \
+      ': :->command' \
+      '*::: := ->option-or-argument' && ret=0
+
+    case $state in
+      command)
+        local -a subcmds
+
+        subcmds=(
+          import:'import local customizations'
+          export:'output local customizations'
+          login:'manage login mappings between linux users and SELinux confined users'
+          user:'manage SELinux confined users (Roles and levels for an SELinux user)'
+          port:'manage network port type definitions'
+          interface:'manage network interface type definitions'
+          module:'manage SELinux policy modules'
+          node:'manage network node type definitions'
+          fcontext:'manage file context mapping definitions'
+          boolean:'manage booleans to selectively enable functionality'
+          permissive:'manage process type enforcement mode'
+          dontaudit:'disable/enable dontaudit rules in policy'
+          ibpkey:'manage infiniband pkey type definitions'
+          ibendport:'manage infiniband end port type definitions'
+        )
+
+        _describe -t commands command subcmds
+        return
+      ;;
+      option-or-argument)
+        (( $#words > 2 )) && ign='!' || ign=''
+        curcontext=${curcontext%:*}-$line[1]:
+        args=(
+          "${ign}(-)"{-h,--help}'[display help information]'
+          '(-S --store)'{-S+,--store=}'[select an alternate SELinux Policy Store to manage]:store:_files'
+        )
+
+        case $line[1] in
+          ^export)
+            args+=( '(-N --noreload)'{-N,--noreload}"[don't reload policy after commit]" )
+          ;|
+          boolean|fcontext|ibendport|ibpkey|interface|login|module|node|port|user)
+            args+=( '(-C --locallist)'{-C,--locallist}'[list local customizations]' )
+          ;|
+          boolean|fcontext|ibendport|ibpkey|interface|login|module|node|permissive|port|user)
+            args+=(
+              '(-n --noheading)'{-n,--noheading}"[don't print list heading]"
+              '(-l --list)'{-l,--list}'[list records]'
+              '(-E --extract)'{-E,--extract}'[extract customizable commands, for use within a transaction]'
+            )
+          ;|
+          fcontext|ibendport|ibpkey|interface|login|module|node|permissive|port|user)
+            args+=( '(-a --add)'{-a,--add}'[add a record]' )
+          ;|
+          boolean|fcontext|ibendport|ibpkey|interface|login|node|permissive|port|user)
+            args+=(
+              '(-d --delete)'{-d,--delete}'[delete a record]'
+              '(-D --deleteall)'{-D,--deleteall}'[remove all local customizations]'
+            )
+          ;|
+          boolean|fcontext|ibendport|ibpkey|interface|login|node|port|user)
+            args+=( '(-m --modify)'{-m,--modify}'[modify a record]' )
+          ;|
+          fcontext|login)
+            args+=( '(-s --seuser)'{-s+,--seuser=}'[SELinux user name]:seuser:_selinux_users' )
+          ;|
+          fcontext|ibendport|ibpkey|interface|node|port)
+            args+=( '(-t --type)'{-t+,--type=}'[SELinux Type for the object]:type:_selinux_contexts -a file_type' )
+          ;|
+          fcontext|ibendport|ibpkey|interface|login|node|port|user)
+            args+=( '(-r --range)'{-r+,--range=}'[specify MLS/MCS Security Range]:range' )
+          ;|
+
+          import)
+            args+=( '(-f --input_file)'{-f+,--input_file=}'[specify input file]:input file:_files' )
+          ;;
+          export)
+            args+=( '(-f --output_file)'{-f+,--output_file=}'[specify output file]:output_file' )
+          ;;
+          login)
+            args+=( '(-l --list)1: :{ compset -P % && _groups || _users }' )
+          ;;
+          user)
+            args+=(
+              '(-L --level)'{-L,--level}'[default SELinux Level for SELinux user, s0 Default. (MLS/MCS Systems only)]:level'
+              \*{-R,--roles}'[specify SELinux Roles]:roles:_selinux_roles'
+              ': :_selinux_users'
+            )
+          ;;
+          port)
+            args+=(
+              '(-p --proto)'{-p+,--proto=}'[specify protocol for the specified port]:protocol:(tcp udp dccp sctp)'
+              ': :_ports'
+            )
+          ;|
+          interface)
+            args+=( ': :_selinux_interfaces' )
+          ;;
+          module)
+            args+=(
+              '(-P --priority)'{-P+,--priority=}'[select a priority for module operations]:priority [400]'
+              '(-E --extract)'{-E,--extract}'[extract customizable commands, for use within a transaction]'
+              '(-a --add)'{-a,--add}'[add a module]:module name:_selinux_modules'
+              '(-r --remove)'{-r,--remove}'[remove a module]:module name:_selinux_modules'
+              '(-d --disable)'{-d,--disable}'[disable a module]:module name:_selinux_modules'
+              '(-e --enable)'{-e,--enable}'[enable a module]:module name:_selinux_modules'
+            )
+          ;;
+          node)
+            args+=(
+              '(-p --proto)'{-p+,--proto=}'[specify protocol for the specified node]:protocol:(ipv4 ipv6)'
+              '(-M --netmask)'{-M+,--netmask=}'[specify network mask]:netmask'
+              ':node:'
+            )
+          ;;
+          fcontext)
+            args+=(
+              '(-e --equal)'{-e+,--equal=}'[substitute target path with sourcepath when generating default label]:equal'
+              '(-f --ftype)'{-f+,--ftype=}'[specify file type]:file type:((
+                f\:regular\ file
+                d\:directory
+                c\:character\ device
+                b\:block device
+                s\:socket
+                l\:symbolic\ link
+                p\:named\ pipe))'
+              ':file spec (regex):_files'
+            )
+          ;;
+          boolean)
+            args+=(
+              '(-)'{-1,--on}'[enable]'
+              '(-)'{-0,--off}'[disable]'
+              ':boolean:_selinux_bools'
+            )
+          ;;
+          permissive)
+            args+=( '1:type:_selinux_types' )
+          ;;
+          dontaudit)
+            args+=( '1:value:(on off)' )
+          ;;
+          ibpkey)
+            args+=(
+              '(-x --subnet_prefix)'{-x,--subnet_prefix}'[specify subnet prefix for the specified infiniband ibpkey]:subnet prefix'
+              ':pkey:'
+            )
+          ;;
+          ibendport)
+            args+=(
+              '(-z --ibdev_name)'{-z+,--ibdev_name=}'[specify name for the specified infiniband end port]:ibdev name'
+            )
+          ;;
+        esac
+      ;;
+    esac
+  ;;
+
+  semodule)
+    args=(
+      \*{-R,--reload}'[force a reload of policy]'
+      \*{-B,--build}'[build and reload policy]'
+      \*'--refresh[like --build but reuse existing linked policy if module files unchanged]'
+      \*{-D,--disable_dontaudit}'[remove dontaudits from policy]'
+      \*{-i+,--install=}'[install a new module]:module package:_files -g "*.(pp|cil)(-.)"'
+      \!{-b,--base,-u,--upgrade}':module package:_files -g "*.(pp|cil)(-.)"'
+      \*{-r+,--remove=}'[remove existing module at desired priority]:module name:_selinux_modules'
+      \*{-l+,--list-modules=-}'[display list of installed modules]::kind:((
+        standard\:highest\ priority,\ enabled\ modules
+        full\:list\ all\ modules
+      ))'
+      \*{-X+,--priority=}'[set priority for following operations]:priority (1-999)'
+      \*{-e,--enable=}'[enable module]:module name:_selinux_modules'
+      \*{-d,--disable=}'[disable module]:module name:_selinux_modules'
+      \*{-E,--extract=}'[extract module]:module name:_selinux_modules'
+      '(-s --store)'{-s+,--store=}'[name of the store to operate on]:store'
+      '(-N -n --noreload)'{-N,-n,--noreload}"[don't reload policy after commit]"
+      '(-v --verbose)'{-v,--verbose}'[be verbose]'
+      '(-P --preserve_tunables)'{-P,--preserve_tunables}'[preserve tunables in policy]'
+      '(-C --ignore-module-cache)'{-C,--ignore-module-cache}'[rebuild CIL modules compiled from HLL files]'
+      '(-p --path)'{-p,--path}'[use an alternate path for the policy root]'
+      '(-S --store-path)'{-S+,--store-path=}'[use an alternate path for the policy store root]:path:_directories'
+      '(-c --cil)'{-c,--cil}'[extract module as cil; only affects module extraction]'
+      '(-H --hll)'{-H,--hll}'[extract module as hll; only affects module extraction]'
+      '(-m --checksum)'{-m,--checksum}'[add SHA256 checksum of modules to the list output]'
+      '!(--refresh)--rebuild-if-modules-changed'
+      "${ign}(-)"{-h,--help}'[display help information]'
+    )
+  ;;
+
+  semodule_unpackage)
+    args=(
+      ':pp file:_files -g "*.pp(-.)"'
+      ':mod file:_files -g "*.mod(-.)"'
+      ':fc file:_files -g "*.fc(-.)"'
+    )
+  ;;
+
+  sepolgen)
+    args=( $sepolgen )
+  ;;
+  sepolicy)
+    _arguments -C \
+      '-P+[specify policy to examine]' \
+      "${ign}(- 1)-h[display help information]" \
+      '1:command:((
+          booleans\:"get description of booleans"
+          communicate\:"query if domains can communicate with each other"
+          generate\:"generate policy module template"
+          gui\:"graphical user interface for policies"
+          interface\:"list policy interfaces"
+          manpage\:"generate man pages for policies"
+          network\:"query policy network information"
+          transition\:"query policy to see how a source process domain can transition to the target process domain"))' \
+      '*::: := ->option-or-argument' && ret=0
+    case $state in
+      option-or-argument)
+        curcontext=${curcontext%:*}-$line[1]:
+        args=( '(-)'{-h,--help}'[display help information]' )
+        case $line[1] in
+          transition|communicate)
+            args+=(
+              '(-s --source)'{-s+,--source=}'[specify source domain]:source:_selinux_types -a domain'
+              '(-t --target)'{-t+,--target=}'[specify target domain]:target:_selinux_types -a domain'
+            )
+          ;|
+          manpage|network)
+            args+=(
+              {-d,--domain}'[specify domain]:*: :_selinux_types -a domain'
+              '!*'{-d-,--domain=-}': :_selinux_types -a domain'
+            )
+          ;|
+          booleans)
+            args+=(
+              '(-)'{-a,--all}'[get all booleans descriptions]'
+              \*{-b,--boolean}'[specify boolean to show description]:*:boolean:_selinux_bools'
+              '!(-a --all -h --help)*'{-b-,--boolean=}': :_selinux_bools'
+            )
+          ;;
+          communicate)
+            args+=(
+              '(-c --class)'{-c+,--class=}'[specify class to use for communications]:tclass [file]:_selinux_classes'
+              '(-S --sourceaccess)'{-S+,--sourceaccess=}'[specify permissions for the source type to use]:source access [open,write]'
+              '(-T --targetaccess)'{-T+,--targetaccess=}'[specify permissions for the target type to use]:target access [open,read]'
+            )
+          ;;
+          generate)
+            args=( $sepolgen )
+          ;;
+          interface)
+            args+=(
+              '(-c --compile)'{-c,--compile}'[run compile test for selected interface]'
+              '(-v --verbose)'{-v,--verbose}'[show verbose information]'
+              '(-f --file)'{-f+,--file=}'[specify interface file]:interface file:_files'
+              '(-a --list_admin)'{-a,--list_admin}'[list all domains with admin interface - DOMAIN_admin()]'
+              '(-u --list_user)'{-u,--list_user}'[list all domains with SELinux user role interface - DOMAIN_role()]'
+              '(-l --list)'{-l,--list}'[list all interfaces]'
+              {-i,--interfaces}'[specify interface names]:*:interface:_selinux_interfaces'
+              '!*'{-i-,--interfaces=-}':interface:_selinux_interfaces'
+            )
+          ;;
+          manpage)
+            args+=(
+              '(-p --path)'{-p+,--path=}'[specify path in which the generated selinux man pages will be stored]:path:_directories'
+              '(-o --os)'{-o+,--os=}'[specify name of the OS for man pages]:OS'
+              '(-w --web)'(-w,--web)'[generate HTML man pages structure]'
+              '(-r --root)'{-r+,--root=}'[specify alternate root directory]:root [/]:_directories'
+              '--source_files[alternative root path needs to include file context files and policy.xml file]'
+              '(-a --all -d --domain)'{-a,--all}'[all domains]'
+            )
+          ;;
+          network)
+            args+=(
+              '(-l --list)'{-l,--list}'[list all SELinux port types]'
+              {-p,--port}'[specify type related to the port]:*:port number'
+              '!*'{-p-,--port=-}':port number'
+              {-t,--type}'[show ports defined for this SELinux type]:*:port type:_selinux_types -a port_type'
+              '!*'{-t-,--type=-}':port type:_selinux_types -a port_type'
+              {-d,--domain}'[specify domain]:*:domain:_selinux_types -a domain'
+              '!*'{-d-,--domain=-}':domain:_selinux_types -a domain'
+              {-a,--application}'[show ports to which this application can bind and/or connect]:*:application:_selinux_types -a application_domain_type'
+              '!*'{-a-,--application=-}':domain:_selinux_types -a application_domain_type' # am not sure this is what is meant by applications
+            )
+          ;;
+        esac
+      ;;
+    esac
+  ;;
+
+  sesearch)
+    args=(
+      "${ign}(-h --help)"{-h,--help}'[display help information]'
+      "${ign}--version[display version information]"
+      '(-v --verbose)'{-v,--verbose}'[print extra informational messages]'
+      '--debug[enable debugging]'
+      '-A[search allow and allowxperm rules]'
+      '--allow[search allow rules]'
+      '--allowxperm[search allowxperm rules]'
+      '--auditallow[search auditallow rules]'
+      '--auditallowxperm[search auditallowxperm rules]'
+      '--dontaudit[search dontaudit rules]'
+      '--dontauditxperm[search dontauditxperm rules]'
+      '--neverallow[search neverallow rules]'
+      '--neverallowxperm[search neverallowxperm rules]'
+      '(-T --type_trans)'{-T,--type_trans}'[search type_transition rules]'
+      '--type_change[search type_change rules]'
+      '--type_member[search type_member rules]'
+      '--role_allow[find role allow rules]'
+      '--role_trans[find range_transition rules]'
+      '--range_trans[search range_transition rules]'
+      '(-s --source)'{-s+,--source=}'[source type/role of the TE/RBAC rule]: : _alternative
+        "types\:type\:_selinux_types"
+        "roles\:role\:_selinux_attributes"'
+      '(-t --target)'{-t+,--target=}'[target type/role of the TE/RBAC rule]: : _alternative
+        "types\:type\:_selinux_types"
+        "roles\:role\:_selinux_attributes"'
+      '(-c --class)'{-c+,--class=}'[comma separated list of object classes]:class:_sequence _selinux_classes'
+      '(-p --perms)'{-p+,--perms=}'[comma separated list of permissions]: :_sequence _selinux_permissions'
+      '(-x --xperms)'{-x+,--xperms=}'[comma separated list of extended permissions]:xperms'
+      '(-D --default)'{-D+,--default=}'[default of the rule. (type/role/range transition rules]:default'
+      '(-b --bool)'{-b+,--bool=}'[comma separated list of Booleans in the conditional expression]:bool '
+      '-eb[match Boolean list exactly instead of matching any listed boolean]'
+      '-ep[match permission set exactly instead of matching any listed permission]'
+      '-ex[match extended permission set exactly instead of matching any listed permission]'
+      '-Sp[match rules where the listed permissions are a subset of the rule permissions]'
+      '-ds[match source attributes directly instead of matching member types/roles]'
+      '-dt[match target attributes directly instead of matching member types/roles]'
+      '-rs[use regular expression matching for the source type/role]'
+      '-rt[use regular expression matching for the target type/role]'
+      '-rc[use regular expression matching for the object class]'
+      '-rd[use regular expression matching for the default type/role]'
+      '-rb[use regular expression matching for booleans]'
+      ':policy:_files'
+    )
+  ;;
+
+  sestatus)
+    args=( '-b[booleans]' '-v[contexts of files and processes listed in the /etc/sestatus.conf]' )
+  ;;
+
+  setenforce)
+    _alternative \
+      'enable-args:enable:(Enforcing 1)' \
+      'disable-args:disable:(Permissive 0)'
+    return
+  ;;
+
+  setsebool)
+    args=(
+      '-P[make changes persistent by writing pending values to disk]'
+      "-N[don't reload policy from disk]"
+      '-V[print verbose error messages]'
+      ':boolean:_selinux_bools'
+      ': : _values value
+              {1,on}"[enable]"
+              {0,off}"[disable]"'
+    )
+  ;;
+
+  validatetrans)
+    args=(
+      ':source context:_selinux_contexts'
+      ':target context:_selinux_contexts'
+      ':class:_selinux_classes'
+      ':new context:_selinux_contexts'
+    )
+  ;;
+esac
+
+_arguments -s $args
diff --git a/Completion/Linux/Command/_setpriv b/Completion/Linux/Command/_setpriv
index 196f2f627..8b8d99785 100644
--- a/Completion/Linux/Command/_setpriv
+++ b/Completion/Linux/Command/_setpriv
@@ -93,10 +93,10 @@ _arguments -C -S -s \
   '--reuid[set real and effective UNIX user id]:UNIX user:_users' \
   '--securebits[set "process securebits"]: : _sequence __setpriv_prctl_securebits_set_elements' \
   '--pdeathsig[keep, clear, or set parent death signal]: : __setpriv_death_signals' \
-  '--selinux-label[request a selinux label]:SELinux labels: ' \
+  '--selinux-label[request a selinux label]:SELinux label:_selinux_contexts' \
   '--apparmor-profile[request an apparmor profile]:AppArmor profiles: ' \
   '--reset-env[set environment as for a classic login shell]' \
-  '*:::command:_normal' \
+  '*:::command: _normal -p $service' \
   && return 0
 
 case $state in
diff --git a/Completion/Linux/Command/_strace b/Completion/Linux/Command/_strace
index b3b6f5096..37e14b6d6 100644
--- a/Completion/Linux/Command/_strace
+++ b/Completion/Linux/Command/_strace
@@ -11,11 +11,13 @@ _arguments -C -s \
   \*{-E+,--env=}'[set or remove exported environment variable]:variable:->envars' \
   '(:)*'{-p+,--attach=}'[attach to the process with specified process ID and begin tracing]:process ID:_pids' \
   "${root}(-u --user)"{-u+,--user=}'[run as specified user]:user:_users' \
+  '--argv0=[set argv0 for program]:name' \
   '(-b --detach-on)'{-b+,--detach-on=}'[detach from process on specified syscall]:syscall:(execve)' \
   '(--daemonize)-D[run tracer as detached grandchild, keeping traced process as direct child of calling process]' \
   '(-D)--daemonize=-[specify how to run tracer process]::method:(grandchild pgroup session)' \
   '(-f --follow-forks)'{-f,--follow-forks}'[trace child processes as they are created by currently traced processes]' \
   '(-I --interruptible)'{-I+,--interruptible=}'[specify when strace can be interrupted by signals]:interruptible:((1\:"no signals are blocked" 2\:"fatal signals are blocked while decoding syscall (default)" 3\:"fatal signals are always blocked (default with -o)" 4\:"fatal signals and SIGTSTP are always blocked"))' \
+  '--kill-on-exit[kill all tracees if strace is killed]' \
   \*{-e+,--trace=}'[select events to trace or how to trace]:system call:->expressions' \
   \*{-P+,--path=}'[trace only system calls accessing given path]:path:_files' \
   '(-z -Z --successful-only --failed-only)'{-z,--successful-only}'[trace only system calls that return success]' \
@@ -45,11 +47,14 @@ _arguments -C -s \
   '(-v --no-abbrev)'{-v,--no-abbrev}'[print unabbreviated versions of environment, stat, termios, etc. calls]' \
   '(-xx --strings-in-hex)-x[print all non-ASCII strings in hexadecimal string format]' \
   '(-x --strings-in-hex)-xx[print all strings in hexadecimal string format]' \
-  '(-x -xx)--strings-in-hex=[specify strings to print in hexadecimal format]:string type:(all non-ascii)' \
+  '(-x -xx)--strings-in-hex=[specify strings to print in hexadecimal format]:string type:(all non-ascii non-ascii-chars)' \
   '(-X --const-print-style)'{-X+,--const-print-style=}'[set the format for printing of named constants and flags]:format:(raw abbrev verbose)' \
   '(-c --summary-only -yy --decode-fds)-y[print paths associated with file descriptor arguments]' \
   '(-c --summary-only -y --decode-fds)-yy[print protocol specific information associated with socket file descriptors]' \
-  '(-c --summary-only -y -yy)--decode-fds=-[print information associated with file descriptors]::information [none]:_sequence compadd - none all path socket dev pidfd' \
+  '(-c --summary-only -y -yy)--decode-fds=-[print information associated with file descriptors]::information [none]:_sequence compadd - none all path socket dev pidfd signalfd' \
+  '(-c --summary-only -Y)--decode-pids=[print information associated with process IDs]:information [none]:_sequence compadd - none comm pidns' \
+  '!(-c --summary-only -Y --decode-pids)--pidns-translation' \
+  '(-c --summary-only --decode-pids)-Y[print command names for PIDs]' \
   '(-c --summary-only -C --summary -i --instruction-pointer -k --stack-traces -r --relative-timestamps -ff -t -tt -ttt --absolute-timestamps -T --syscall-times -y -yy --decode-fds)'{-c,--summary-only}'[count time, calls, and errors for each system call and report a summary]' \
   '(-c --summary-only -C --summary)'{-C,--summary}'[count time, calls, and errors for each system call and report a summary in addition to regular output]' \
   '(-O --summary-syscall-overhead)'{-O+,--summary-syscall-overhead=}'[specify overhead for tracing system calls]:overhead (microseconds)' \
@@ -57,9 +62,11 @@ _arguments -C -s \
   '(-U --summary-columns)'{-U+,--summary-columns=}'[show specific columns in the summary report]:column:_sequence compadd - time-percent total-time min-time max-time avg-time calls errors name' \
   '(-w --summary-wall-clock)'{-w,--summary-wall-clock}'[summarise syscall latency]' \
   '(-c --summary-only -C)-ff[write each process trace to <filename>.<pid> (when using -o <filename>]' \
+  '--syscall-limit=[detach all tracees after tracing given number of syscalls]:limit' \
   '(-d --debug)'{-d,--debug}'[show debug output of strace itself on standard error]' \
   '(- 1 *)'{-h,--help}'[display help information]' \
   '--seccomp-bpf[enable seccomp-bpf filtering]' \
+  '--tips=-[show strace tips, tricks, and tweaks before exit]:tip [id\:random,format\:compact]' \
   '(- 1 *)'{-V,--version}'[display version information]' \
   '(-):command name: _command_names -e' \
   '*::arguments:_normal' && ret=0
@@ -72,6 +79,7 @@ case $state in
       'verbose[dereference structures for the specified set of system calls]:system call:_sequence _sys_calls -a -n' \
       'raw[print raw, undecoded arguments for the specified set of system calls]:system call:_sequence _sys_calls -a -n' \
       'signal[trace only the specified subset of signals]:signal:_sequence _signals -s -M "B\:!="' \
+      'trace-fds[trace operations on listed file descriptors]:file descriptor:_sequence _file_descriptors' \
       'read[perform a full hex and ASCII dump of all the data read from listed file descriptors]:file descriptor:_sequence _file_descriptors' \
       'write[perform a full hex and ASCII dump of all the data written to listed file descriptors]:file descriptor:_sequence _file_descriptors' \
       'fault[perform syscall fault injection]:system call:_sys_calls -a -n' \
@@ -79,7 +87,8 @@ case $state in
       'status[trace system calls with given return status]:status:->status' \
       'quiet[suppress various information messages]:message [none]:_sequence compadd - none attach exit path-resolution personality thread-execve superseded' \
       'kvm[print the exit reason of kvm vcpu]: :(vcpu)' \
-      'decode-fds[print information associated with file descriptors]:information [none]:_sequence compadd - none all path socket dev pidfd' && ret=0
+      'decode-fds[print information associated with file descriptors]:information [none]:_sequence compadd - none all path socket dev pidfd signalfd' \
+      'decode-pids[print information associated with process IDs]:information [none]:_sequence compadd - none comm pidns' && ret=0
     if [[ $state = status ]]; then
       _values -s , 'return status [all]' \
         all successful failed \
diff --git a/Completion/Linux/Command/_sysstat b/Completion/Linux/Command/_sysstat
index eba99fc5a..59a2f5da9 100644
--- a/Completion/Linux/Command/_sysstat
+++ b/Completion/Linux/Command/_sysstat
@@ -52,10 +52,11 @@ _sadf() {
       '(-g -j -p -r -x)-h[print on a single line when used with -d]' \
       '-O[specify output options]: : _values -s , option
         autoscale bwcol customcol height\:value oneday packed showidle showinfo showtoc skipempty hz\:value pcparchive\:name\:_files debug' \
-      '-P[restrict processor dependant statistics]:processor number(zero indexed) or ALL:(ALL)' \
+      '-P[restrict processor dependent statistics]:processor number(zero indexed) or ALL:(ALL)' \
       '--dev=-[specify block devices for which statistics are to be displayed]:block device:_files -g "*(-%)"' \
       '--fs=-[specify filesystems for which statistics are to be displayed]:file system:_dir_list -s ,' \
       '--iface=-[specify network interfaces for which statistics are to be displayed]:network interface:_sequence _net_interfaces' \
+      '--int=-[specify interrupts for which statistics are to be displayed]: : _values -s "," interrupt 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15' \
       '-s[set starting time of report]:starting time (HH\:MM\:SS)"' \
       '(-t -U)-T[display timestamp in local time]' \
       '(-T -U)-t[display timestamp in file\''s original localtime]' \
@@ -99,9 +100,10 @@ _sar() {
     '(--human -p)-h[make output easier to read: implies --human and -p]' \
     '(- 1 2)--help[display usage information]' \
     '--human[print sizes in human readable format]' \
-    '*-I[report statistics for interrupts]: : _values -s "," interrupt 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 SUM ALL XALL' \
+    '-I[report statistics for interrupts]:interrupt:(SUM ALL)' \
     '-i[select records as close as possible to interval]:interval' \
     '--iface=-[specify network interfaces for which statistics are to be displayed]:network interface:_sequence _net_interfaces' \
+    '--int=-[specify interrupts for which statistics are to be displayed]: : _values -s "," interrupt 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15' \
     '-j[display persistent device names]:type:(ID LABEL PATH UUID)' \
     '-m[report power management statistics]:keyword:_sequence compadd - CPU FAN FREQ IN TEMP USB ALL' \
     '-n[report network statistics]:keyword:_sequence compadd - DEV EDEV NFS NFSD SOCK IP EIP ICMP EICMP TCP ETCP UDP SOCK6 IP6 EIP6 ICMP6 EICMP6 UDP6 FC SOFT ALL' \
@@ -130,7 +132,7 @@ _pidstat() {
   _arguments -s : \
     '-C[filter tasks by string]:task filter' \
     '-d[report I/O statistics]' \
-    '-e[execute specified program and monitor it with pidstat]:*::command: _normal' \
+    '-e[execute specified program and monitor it with pidstat]:*::command: _normal -p $service' \
     '-H[display timestamp in seconds since the epoch]' \
     '-h[display horizontally]' \
     '-I[divide CPU usage by number of processors]' \
diff --git a/Completion/Linux/Command/_valgrind b/Completion/Linux/Command/_valgrind
index b4bb3248e..5eaaea338 100644
--- a/Completion/Linux/Command/_valgrind
+++ b/Completion/Linux/Command/_valgrind
@@ -165,7 +165,7 @@ args_massif=(
   "--time-unit=-[specify time unit]:unit [i]:((
     i\:instructions\ executed
     ms\:milliseconds
-    b\:heap\ bytes\ alloc\'d/dealloc\'d
+    B\:heap\ bytes\ alloc\'d/dealloc\'d
   ))"
   '--detailed-freq=-[every Nth snapshot should be detailed]:snapshot interval [10]'
   '--max-snapshots=-[specofy maximum number of snapshots recorded]:maximum [100]'
@@ -216,7 +216,7 @@ _arguments -C ${(P)args} $cmd \
   '--vgdb=-[activate gdbserver]:enable [yes]:(yes no full)' \
   '--vgdb-error=-[invoke gdbserver after specified number of errors]:errors [999999999]:errors' \
   '--vgdb-stop-at=-[invoke gdbserver for given events]:event:_sequence compadd - startup exit valgrindabexit all none' \
-  '--track-fds=-[track open file descriptors]:enable:(yes no)' \
+  '--track-fds=-[track open file descriptors]:enable [no]:(yes no all)' \
   '--time-stamp=-[add timestamps to log messages]:enable:(yes no)' \
   '--log-fd=-[log messages to specified file descriptor]:file descriptor:_file_descriptors' \
   '--log-file=-[log messages to specified file with pid appended]:file:_files' \
diff --git a/Completion/Linux/Type/_selinux_contexts b/Completion/Linux/Type/_selinux_contexts
index 4c2cf4288..bdad8e72b 100644
--- a/Completion/Linux/Type/_selinux_contexts
+++ b/Completion/Linux/Type/_selinux_contexts
@@ -1,14 +1,21 @@
 #autoload
 
-local -a parts suf
+local -a parts users roles types
+
+zparseopts -E -D a:=types P:=users
+
+if ! compset -S ':*'; then
+  users+=( -qS : )
+  roles+=( -qS : )
+  [[ $(</sys/fs/selinux/mls) = 0 ]] 2>/dev/null || types+=( -qS : )
+fi
 
 parts=( users roles types )
 while compset -P 1 '*:' && (( $+parts[1] )) ; do
   shift parts
 done
 if (( $+parts[1] )); then
-  compset -S ':*' || suf=( -S : )
-  _selinux_$parts[1] $suf
+  _selinux_$parts[1] ${(P)parts[1]}
 else
   _message -e selinux-ranges 'selinux range'
 fi
diff --git a/Completion/Linux/Type/_selinux_types b/Completion/Linux/Type/_selinux_types
index ef31f45d2..69047c690 100644
--- a/Completion/Linux/Type/_selinux_types
+++ b/Completion/Linux/Type/_selinux_types
@@ -1,7 +1,19 @@
 #autoload
 
-local -a setypes expl
+# Pass -a attribute to filter types, e.g.:
+#   -a domain    - for process types
+#   -a file_type - for file types
+#   -a port_type - for network ports
+
+local -a setypes expl extra
+
+zparseopts -E -D -a extra a:
+
+if (( $#extra )); then
+  setypes=( ${${${(f)"$(_call_program selinux-types seinfo $extra --flat -x)"}#[[:blank:]]}:1} )
+else
+  setypes=( ${(f)"$(_call_program selinux-types seinfo --flat -t)"} )
+fi
 
-setypes=( ${(f)"$(_call_program selinux-types seinfo --flat -t)"} )
 _description selinux-types expl "selinux type"
 compadd "$@" "$expl[@]" -a setypes
diff --git a/Completion/Mandriva/Command/_urpmi b/Completion/Mandriva/Command/_urpmi
index be6350129..21c44ffaa 100644
--- a/Completion/Mandriva/Command/_urpmi
+++ b/Completion/Mandriva/Command/_urpmi
@@ -131,7 +131,7 @@ _urpmi() {
 	"($help --no-probe --probe-hdlist)--probe-synthesis[try to find and use synthesis file]" \
 	"($help)--update[mark as update media]" \
 	"($help)--version[use specified distribution version]:Mandrake version: " \
-	"($help)--virtual[create virtual media wich are always up-to-date]" \
+	"($help)--virtual[create virtual media which are always up-to-date]" \
 	"($help)-c[clean headers cache directory]" \
 	"($help)-f[force generation of hdlist files]" \
 	"($help --distrib):name of media: " \
diff --git a/Completion/Redhat/Command/_dnf b/Completion/Redhat/Command/_dnf
index 174788ec6..a5edf8564 100644
--- a/Completion/Redhat/Command/_dnf
+++ b/Completion/Redhat/Command/_dnf
@@ -245,7 +245,7 @@ _dnf() {
     '--security[include security relevant packages]'
     '*--setopt=[override config option]:repoid.option=value: '
     '--skip-broken[resolve depsolve problems by skipping packages]'
-    '--show-duplicates[show duplicate packages in repos]'
+    '--showduplicates[show duplicate packages in repos]'
     '(-v --verbose)'{-v,--verbose}'[set verbose, show debug messages]'
     '(- *)--version[show dnf version]'
     '(-y --assumeyes --assumeno)'{-y,--assumeyes}'[answer yes for all questions]'
@@ -345,7 +345,7 @@ _dnf_command() {
         ;;
       clean)
         tmp=(
-          'dbcache:remove chache files generated from the repository metadata'
+          'dbcache:remove cache files generated from the repository metadata'
           'expire-cache:mark the repository metadata expired'
           'metadata:remove the repository metadata'
           'packages:remove any cached packages'
diff --git a/Completion/Redhat/Command/_rpm b/Completion/Redhat/Command/_rpm
index d00f88429..97f65cd6c 100644
--- a/Completion/Redhat/Command/_rpm
+++ b/Completion/Redhat/Command/_rpm
@@ -74,6 +74,7 @@ _rpm () {
   selectopts=(
     {-a,--all}'[query all packages]'
     {-f,--file}'[query packages that own specified files]'
+    '--path[query packages that own specified files, installed or not]'
     {-p,--package}'[query uninstalled packages]'
     {-g,--group}'[query packages in one of specified groups]'
     --pkgid --hdrid --tid --querybynumber
@@ -165,9 +166,7 @@ _rpm () {
         {-F+,--freshen}'[freshen mode]:*:upgrade:->upgrade'
         {-e+,--erase}'[uninstall mode]:*:uninstall:->uninstall'
         '--reinstall[reinstall mode]:*:install:->install'
-        '--setperms[set file permissions]:*:package:->setattrs'
-        '--setugids[set file owner/group]:*:package:->setattrs'
-        '--setcaps[set capabilities of files in the given package]:*:package:->setattrs'
+        '!--set'{perms,ugids,caps}':*:package:->setattrs'
         '--restore[restore owner, group, permissions and capabilities of files in the given package]:*:package:->setattrs'
       )
     ;;
@@ -261,13 +260,15 @@ _rpm () {
     install)
       _arguments -s -C \!{-i,--install,-U,--upgrade,-F,--freshen} $tmp \
         $commonopts $pathopts \
+        '(--nodb)--justdb[update the database but not the filesystem]' \
+        '(--justdb)--nodb[update the filesystem but not the database]' \
         '--excludepath=:file to exclude:_files -/' \
 	'--relocate:relocate:->relocate' \
         '--prefix=[relocate the package]:package prefix directory:_files -/' \
         '(-h --hash)'{-h,--hash}'[print hash marks as package installs]' \
 	'(--replacepkgs --replacefiles --oldpackage)--force' \
 	'(--force)--'{replacefiles,replacepkgs} \
-        --{aid,allfiles,badreloc,excludedocs,ignorearch,ignoreos,ignoresize,includedocs,justdb,percent,test} \
+        --{aid,allfiles,badreloc,excludedocs,ignorearch,ignoreos,ignoresize,includedocs,percent,test} \
         --no{deps,filedigest,contexts,caps,order,suggest,pre,post,preun,postun,trigger{s,in,un,postun}} \
 	'(--nopre --nopost --nopreun --nopostun)--noscripts' \
         '*:pkg file:->package_file'
@@ -275,7 +276,9 @@ _rpm () {
     uninstall)
       _arguments -s -C \!{-e,--erase} \
 	"${commonopts[@]}" "${pathopts[@]}" \
-	--{allmatches,justdb,repackage,test} \
+        '(--nodb)--justdb[update the database but not the filesystem]' \
+        '(--justdb)--nodb[update the filesystem but not the database]' \
+	--{allmatches,repackage,test} \
 	--no{deps,scripts,preun,postun,trigger{s,un,postun}} \
         '*:package:->package'
       ;;
diff --git a/Completion/Solaris/Command/_dumpadm b/Completion/Solaris/Command/_dumpadm
index 44d681ae0..aa1c058bb 100644
--- a/Completion/Solaris/Command/_dumpadm
+++ b/Completion/Solaris/Command/_dumpadm
@@ -16,7 +16,7 @@ _arguments -s \
   '-y[run savecore on reboot]' \
   '-c[set dump content]:dump content:(($content))' \
   '-d[set dump device]: : _alternative "tokens\:token\:(swap none)" "files\:block device\:_files -g \*\(-%b\)"' \
-  '-m[set minfree size]:size' \
+  '-m[set minfree size]: :_numbers size k m %' \
   '-s[set the savecore directory]:directory:_files -/' \
   '-r[alternate root directory]:directory:_files -/' \
   '-z[enable saving core files in a compressed format]:compression:(on off)'
diff --git a/Completion/Solaris/Command/_ipadm b/Completion/Solaris/Command/_ipadm
index 34d1eacba..c59fc8108 100644
--- a/Completion/Solaris/Command/_ipadm
+++ b/Completion/Solaris/Command/_ipadm
@@ -136,7 +136,7 @@ _ipadm() {
 	proto_icmp_properties=( "max_buf" "recv_buf" "send_buf" )
 	proto_all_properties=( $proto_ipv4_properties $proto_ipv6_properties $proto_tcp_properties
 		$proto_udp_properties $proto_sctp_properties $proto_icmp_properties )
-	proto_all_properties=( $^proto_all_properties:value:_ipadm_get_possible_values )
+	proto_all_properties=( ${^proto_all_properties}:value:_ipadm_get_possible_values )
 
 	proto_propproperties=( "proto" "property" "perm" "current" "persistent" "default" "possible" )
 
diff --git a/Completion/Solaris/Command/_pkg5 b/Completion/Solaris/Command/_pkg5
index bcd4e3daf..5524e4eda 100644
--- a/Completion/Solaris/Command/_pkg5
+++ b/Completion/Solaris/Command/_pkg5
@@ -378,6 +378,7 @@ _pkg5() {
 			'--non-sticky[Make this publisher non-sticky]' \
 			'--search-after[Set publisher search-order]:publisher:_pkg5_pubs' \
 			'--search-before[Set publisher search-order]:publisher:_pkg5_pubs' \
+			'--search-first[set the specified publisher first in the search order]' \
 			'--approve-ca-cert[Add trusted CA certificate]:CA cert path:_path_files' \
 			'--revoke-ca-cert[Revoke CA certificate]:CA cert hash:(${${certs#/etc/openssl/certs/}%.0})' \
 			'--unset-ca-cert[Remove trusted CA certificate]:CA cert hash:' \
diff --git a/Completion/Unix/Command/_adb b/Completion/Unix/Command/_adb
index 1375813bb..8a071fa8e 100644
--- a/Completion/Unix/Command/_adb
+++ b/Completion/Unix/Command/_adb
@@ -43,6 +43,7 @@ _adb() {
           "disconnect"
           "emu"
           "enable-verity"
+          "exec-out"
           "forward"
           "get-devpath"
           "get-serialno"
@@ -81,6 +82,7 @@ _adb() {
   if ! adb ${ADB_DEVICE_SPECIFICATION} shell exit 2>/dev/null; then
       # early bail-out until a single valid device/emulator is specified and up-and-running
       [[ $words[CURRENT-1] = -s ]] || _message -r "No (started) device specified, completions do not yet work"
+      #TODO handle -t transport-id
       _arguments \
 	'-s[serial]: :_adb_device_serial' \
 	'(   -e)-d[device]' \
@@ -109,7 +111,7 @@ _adb_dispatch_command () {
   fi
 
   case ${curcontext} in
-    (*:adb-shell:)
+    (*:adb-shell:|*:adb-exec-out:)
       (( $+functions[_adb_dispatch_shell] )) && _adb_dispatch_shell
       ;;
     (*:adb-backup:)
@@ -164,18 +166,16 @@ _adb_sanitize_context () {
 
 (( $+functions[_adb_device_specification] )) ||
 _adb_device_specification () {
-  local -a word
-  word=($words[(R)-[des]])
-  if [[ $words[(R)-s] == -s ]]; then
-    local i=$words[(I)-s]
-    word=($words[i,i+1])
+  if [[ $words[2] == -[de] ]]; then
+    ADB_DEVICE_SPECIFICATION=($words[2])
+  elif [[ $words[2] == -[st] ]]; then
+    ADB_DEVICE_SPECIFICATION=($words[2,3])
   fi
-  ADB_DEVICE_SPECIFICATION=($word)
 }
 
 (( $+functions[_adb_dispatch_shell] )) ||
 _adb_dispatch_shell () {
-  if [[ ${#words} -le 2 ]]
+  if [[ $CURRENT -le 2 ]]
   then
     (( $+functions[_adb_shell_commands_handler] )) && _adb_shell_commands_handler
     return
@@ -188,6 +188,15 @@ _adb_dispatch_shell () {
     (pm)
       (( $+functions[_adb_package_manager_handler] )) && _adb_package_manager_handler
       ;;
+    (cmd)
+      (( $+functions[_adb_cmd_handler] )) && _adb_cmd_handler
+      ;;
+    (dumpsys)
+      (( $+functions[_adb_dumpsys_handler] )) && _adb_dumpsys_handler
+      ;;
+    (start|stop)
+      (( $+functions[_adb_startstop] )) && _adb_startstop ${words[2]}
+      ;;
     (*)
       _arguments '*: :_adb_remote_folder'
       ;;
@@ -262,7 +271,7 @@ _adb_intent_handler () {
 
 (( $+functions[_adb_activity_manager_handler] )) ||
 _adb_activity_manager_handler () {
-  if [[ ${#words} -le 3 ]]
+  if [[ $CURRENT -le 3 ]]
   then
     _wanted am_argument expl 'am argument' compadd start startservice broadcast instrument profile
     return
@@ -318,6 +327,79 @@ _adb_package_manager_handler () {
   esac
 }
 
+(( $+functions[_adb_cmd_handler] )) ||
+_adb_cmd_handler () {
+  local -a cmds
+  cmds=(${${${(f)"$(adb ${ADB_DEVICE_SPECIFICATION} exec-out cmd -l)"}[2,-1]}##[[:space:]]##})
+  _wanted dumpsys expl 'cmd command' compadd ${cmds%$'\r'}
+}
+
+(( $+functions[_adb_dumpsys_handler] )) ||
+_adb_dumpsys_handler () {
+  if [[ $CURRENT -eq 3 ]]; then
+    local -a services
+    services=(${${${(f)"$(adb ${ADB_DEVICE_SPECIFICATION} exec-out dumpsys -l)"}[2,-1]}##[[:space:]]##})
+    _wanted dumpsys expl 'dumpsys service' compadd - ${services%$'\r'}
+  elif [[ $CURRENT -ge 4 && $words[3] == SurfaceFlinger ]]; then
+    (( CURRENT -= 2 ))
+    shift 2 words
+    typeset -A opt_args
+    local context state state_descr line
+    _arguments -R \
+      '--file[start/stop continuous dumpsys to file]' \
+      '--no-limit[disable wrapping around continuous dumpsys at ~20MB]' \
+      '--full-dump[set fullDump = true]' \
+      '--allocated_buffers[show allocated buffers dump]' \
+      '--display-id[show display id dump]' \
+      '--dispsync[show dispsync dump]' \
+      '--edid[raw edid dump for specified hwc display (binary output)]:*:hwc display:->hwcdisplay' \
+      '--latency[show latency stats]:*:layer:->layer' \
+      '--latency-clear[clear latency stats]:*:layer:->layer' \
+      '--list[list all layers]' \
+      '--planner[pass planner dump arguments]:*:planner arguments:->planner' \
+      '--static-screen[show static screen stats]' \
+      '--timestats[pass time stats arguments]:*:timestats arguments:->timestats' \
+      '--vsync[show vsync dump]' \
+      '--wide-color[show wide color info]' \
+      '--frametimeline[pass frametimeline arguments]:*:frametimeline arguments:->frametimeline' \
+      '--mini[show mini dump]'
+    if [[ $? == 300 ]]; then
+      case $state in
+        layer)
+          typeset -a layers
+          layers=(${${(f)"$(adb ${ADB_DEVICE_SPECIFICATION} exec-out dumpsys SurfaceFlinger --list)"}[2,-1]})
+          _wanted dumpsys expl 'layers' compadd - ${layers%$'\r'}
+          ;;
+        planner)
+          _arguments \
+            {--compare,-c}'[compare predictions of two hashes]:left: :right: :' \
+            {--describe,-d}'[describe hash]:hash: :' \
+            {--help,-h}'[help]' \
+            {--similar,-s}'[show similar stacks matching given plan]:plan: :' \
+            {--layers,-l}'[show current layers]'
+          ;;
+        timestats)
+          _arguments -disable -enable -clear -dump -maxlayers'[only with -dump]:int:'
+          ;;
+        frametimeline)
+          _arguments -jank -all
+          ;;
+      esac
+    fi
+  fi
+}
+
+(( $+functions[_adb_startstop] )) ||
+_adb_startstop () {
+  local -a services
+  local -A service_status
+  services=(${(f)"$(adb ${ADB_DEVICE_SPECIFICATION} exec-out getprop)"})
+  service_status=( ${(s,: ,)${(j,: ,)${(M)services:#\[init.svc.*}}} )
+  local -A map=(start stopped stop running)
+  services=( ${(k)service_status[(R)*$map[$1]*]} )
+  _wanted services expl "$map[$1] services" compadd - ${${${services#\[}%\]}#init.svc.}
+}
+
 (( $+functions[_adb_dispatch_uninstall] )) ||
 _adb_dispatch_uninstall () {
   _arguments \
@@ -344,12 +426,12 @@ _adb_dispatch_install () {
 
 (( $+functions[_adb_dispatch_push] )) ||
 _adb_dispatch_push () {
-  if [[ ${#words} -gt 3 ]] 
+  if [[ $CURRENT -gt 3 ]] 
   then
     _message -r "Notice: you can only push a single item at a time"
     return
   fi 
-  if [[ ${#words} -gt 2 ]]
+  if [[ $CURRENT -gt 2 ]]
   then
     _arguments '*: :_adb_remote_folder'
   else
@@ -359,12 +441,12 @@ _adb_dispatch_push () {
 
 (( $+functions[_adb_dispatch_pull] )) ||
 _adb_dispatch_pull () {
-  if [[ ${#words} -gt 3 ]] 
+  if [[ $CURRENT -gt 3 ]] 
   then
     _message -r "Notice: you can only pull a single item at a time"
     return
   fi 
-  if [[ ${#words} -gt 2 ]]
+  if [[ $CURRENT -gt 2 ]]
   then
     _arguments '*:local file/folder:_files'
   else
@@ -411,11 +493,13 @@ _adb_device_serial() {
   local expl
   local -a devices device_desc
   local device
-  devices=( $(adb devices -l | sed -n 's/^\([^[:space:]]*\)[[:space:]]*.*product:\([^[:space:]]*\).*$/\1:\2/p') )
+  devices=( $(adb devices -l | sed -n -e 's/:/\\:/' -e 's/^\([^[:space:]]*\)[[:space:]]*.*product:\([^[:space:]]*\).*$/\1:\2/p') )
   zstyle -a :completion:${curcontext} device-names device_desc
   for device in $device_desc; do
     if [[ -n $devices[(r)${device%:*}:*] ]]; then
       devices[(i)${device%:*}:*]=$device
+    elif [[ -n $devices[(r)*:${device%:*}] ]]; then
+      devices[(i)*:${device%:*}]=${${devices[(r)*:${device%:*}]}%:*}:${device#*:}
     fi
   done
   _describe -t dev_serial 'available device' devices
@@ -465,7 +549,7 @@ _adb_options_handler() {
 (( $+functions[_adb_shell_commands_handler] )) ||
 _adb_shell_commands_handler() {
   local expl
-  _wanted adb_shell_commands expl 'adb shell command' compadd ls pm am mkdir rmdir rm cat
+  _wanted adb_shell_commands expl 'adb shell command' compadd ls pm am mkdir rmdir rm cat cmd dumpsys start stop
 }
 
 (( $+functions[_adb_device_available] )) ||
diff --git a/Completion/Unix/Command/_ansible b/Completion/Unix/Command/_ansible
index 6ec7d0c2e..e0d9fb9b6 100644
--- a/Completion/Unix/Command/_ansible
+++ b/Completion/Unix/Command/_ansible
@@ -20,10 +20,11 @@ case $service in
   ;|
   ansible|ansible-console|ansible-playbook|ansible-pull)
     args+=(
-      '(-K --ask-become-pass)'{-K,--ask-become-pass}'[ask for privilege escalation password]'
-      '(-k --ask-pass)'{-k,--ask-pass}'[ask for connection password]'
+      '(-K --ask-become-pass --become-password-file)'{-K,--ask-become-pass}'[ask for privilege escalation password]'
+      '(-K --ask-become-pass)--become-password-file=[specify file containing become password]:file:_files'
+      '(-k --ask-pass --connection-password-file)'{-k,--ask-pass}'[ask for connection password]'
+      '(-k --ask-pass)--connection-password-file=[specify file containing connection password]:file:_files'
       '--list-hosts[output list of matching hosts]'
-      '(-l --limit)'{-l+,--limit=}'[further limit hosts to an additional pattern]:host subset:->hosts'
       '(-T --timeout)'{-T+,--timeout=}'[override the connection timeout]:timeout (seconds) [10]'
       '(-c --connection)'{-c+,--connection=}'[specify connection type]:connection type [smart]:->connect-types'
       '(-u --user)'{-u+,--user=}'[specify remote user for connection]:remote user:_users'
@@ -42,19 +43,19 @@ case $service in
       '(-f --forks)'{-f+,--forks=}'[specify number of parallel processes to use]:processes [5]'
       '--become-method=[specify privilege escalation method to use]:method [sudo]:(sesu sudo su pbrun pfexec doas dzdo ksu runas pmrun enable machinectl)'
       '--become-user=[specify remote user for running operations]:user:_users'
-      "--syntax-check[perform a syntax check on the playbook, but don't execute it]"
       '!(-R --su-user -U --sudo-user)'{-R,-U,--su-user,--sudo-user}':user [root]:_users'
     )
   ;|
   ansible|ansible-console|ansible-inventory|ansible-playbook|ansible-pull)
     args+=(
       --ask-vault-pass{,word}'[ask for vault password]'
-      '(-e --extra-vars)'{-e+,--extra-vars=}'[set additional variables]:key=value or YAML/JSON'
-      '--vault-id=[specify vault identity to use]:vault identity'
+      \*{-e+,--extra-vars=}'[set additional variables]:key=value, YAML/JSON or @file:->extra-vars'
+      '*--vault-id=[specify vault identity to use]:vault identity'
       --vault-pass{,word}-file='[specify vault password file]:vault password file:_files'
       \*{-i+,--inventory=}'[specify inventory host file or host list]: : _alternative "files\:inventory file\:_files"
 	"hosts\:host\: _sequence _hosts"'
       '!(-i --inventory)--inventory-file=:inventory file:_files'
+      '(-l --limit)'{-l+,--limit=}'[further limit hosts to an additional pattern]:host subset:->hosts'
     )
   ;|
   ansible|ansible-console|ansible-inventory)
@@ -68,6 +69,11 @@ case $service in
       "--skip-tags[only run plays and tasks whose tags don't match]"
     )
   ;|
+  ansible-playbook|ansible-console)
+    args+=(
+      '--step[one-step-at-a-time: confirm each task before running]'
+    )
+  ;|
   ansible|ansible-console)
     args+=(
       '--task-timeout[set the task timeout limit]:timeout (seconds)'
@@ -86,31 +92,26 @@ case $service in
     )
   ;;
   ansible-config)
-    args+=(
-      '(-c --config)'{-c+,--config=}'[specify configuration file]:config file:_files'
+    args=( -A "-*" $args
       '1:action:((
         list\:list\ all\ configuration
 	dump\:show\ the\ current\ settings,\ merge\ specified\ configuration
 	view\:display\ the\ current\ config\ file
+        init\:create\ initial\ configuration
       ))'
-    )
-    [[ -n $words[(r)dump] ]] && args+=( '--only-changed[only show configuration that is changed from the default]' )
-  ;;
-  ansible-console)
-    args+=(
-      '--step[one-step-at-a-time: confirm each task before running]'
+      '*::args:->config'
     )
   ;;
   ansible-doc)
     args+=(
-      '!--metadata-dump' # "internal testing only"
+      '!--metadata-dump' '!--no-fail-on-errors' # "internal use only"
       '(-l --list -F --list_files -s --snippet --metadata-dump -e --entry-point)'{-j,--json}'[change output to json format]'
       '(-l --list -F --list_files -s --snippet --metadata-dump -e --entry-point)'{-l,--list}'[list available plugins]'
       '(-l --list -F --list_files -s --snippet --metadata-dump -e --entry-point)'{-F,--list_files}'[show plugin names and their source files without summaries]'
-      '(-l --list -F --list_files -s --snippet --metadata-dump -e --entry-point)'{-s,--snippet}'[show playbook snippet for specified plugins]'
+      '(-l --list -F --list_files -s --snippet --metadata-dump -e --entry-point)'{-s,--snippet}'[show playbook snippet for inventory, lookup and module plugins]'
       '(-l --list -F --list_files -s --snippet -e --entry-point)--metadata-dump[dump json metadata for all plugins]'
       '(-l --list -F --list_files -s --snippet --metadata-dump -e --entry-point)'{-e+,--entry-point=}'[select the entry point for roles]:entry point'
-      '(-t --type)'{-t+,--type=}'[choose plugin type]:plugin type [module]:(become cache callback cliconf connection httpapi inventory lookup netconf shell vars module strategy role keyword)'
+      '(-t --type)'{-t+,--type=}'[choose plugin type]:plugin type [module]:(become cache callback cliconf connection httpapi inventory lookup netconf shell vars module strategy test filter role keyword)'
       '(-r --roles-path)'{-r+,--roles-path=}'[specify directory containing roles]:directory:_directories'
       '*:plugin:->plugins'
     )
@@ -145,6 +146,7 @@ case $service in
       '--list-tags[list all available tags]'
       '--list-tasks[list all tasks that would be executed]'
       '--start-at-task=[start the playbook at specified task]:task'
+      "--syntax-check[perform a syntax check on the playbook, but don't execute it]"
       '--key-file=[specify file to use to authenticate the connection]:private key file:_files'
       '*:playbook:_files -g "(#i)*.y(|a)ml"'
     )
@@ -218,18 +220,13 @@ case $state in
   ;;
   connect-types)
     plug=connection
-  ;&
-  plugins)
-    plugvar=_ansible_${plug}_plugins
-    typeset -ga ${plug}
-    if zstyle -T ":completion:${curcontext}:plugins" verbose; then
-      (( ${(P)#plugvar} )) || set -A ${plugvar} \
-	  ${${(f)"$(_call_program plugins ansible-doc -t $plug -l)"}/ ##/:}
-      _describe -t plugins "${plug} plugin" $plugvar -M 'r:|.=* r:|=*' && ret=0
+    state=plugins
+  ;;
+  extra-vars)
+    if compset -P '@'; then
+      _files -g "*.(json|yml|yaml|ini)(-.)" && ret=0
     else
-      (( ${(P)#plugvar} )) || set -A ${plugvar} \
-	  ${${(f)"$(_call_program plugins ansible-doc -t $plug -F)"}%% *}
-      _wanted plugins expl "${plug} plugin" compadd -M 'r:|.=* r:|=*' -a $plugvar && ret=0
+      _message 'key=value, YAML/JSON or @file'
     fi
   ;;
   tags)
@@ -237,9 +234,45 @@ case $state in
     _sequence _wanted tags expl tag compadd - \
         ${(s.,.)${(j.,.)${(M)${(f)"$(cat **/*.yml)"}:# #tags:*}#*: }} && ret=0
   ;;
+  config)
+    ign=''
+    curcontext="${curcontext%:*}-${words[1]}:"
+    (( $#words > 3 )) && ign='!'
+    args=(
+      "${ign}(-)"{-h,--help}'[display usage information]'
+      \*{-v,--verbose}'[verbose mode]'
+      '(-c --config)'{-c+,--config=}'[specify configuration file]:config file:_files'
+      '(-t --type)'{-t+,--type=}'[filter down to a specific plugin type]:plugin type [base]:(all base become cache callback cliconf connection httpapi inventory lookup netconf shell vars)'
+      '*:plugin:->plugins'
+    )
+    case $words[1] in
+      dump)
+        args+=(
+          '(--only-changed --changed-only)'{--only-changed,--changed-only}'[only show configuration that is changed from the default]'
+          '(-f --format)'{-f+,--format=}'[specify output format]:format:(json yaml display)'
+        )
+      ;;
+      init)
+        args+=(
+          '--format=[specify output format for init]:format:(init env vars)'
+          '--disabled[prefix all entries with a comment character]'
+        )
+      ;;
+      list)
+        args+=(
+          '(-f --format)'{-f+,--format=}'[specify output format]:format:(json yaml)'
+        )
+      ;;
+    esac
+    _arguments -s -S : $args && ret=0
+    plug=${(v)opt_args[(i)-(t|-type)]}
+    [[ $plug = base ]] && state=
+  ;;
   galaxy)
     ign=''
     gactions=( delete import info init install list remove search setup )
+    args=( "${ign}(-)"{-h,--help}'[display usage information]' )
+    (( $#words > 3 )) && ign='!'
     case ${(j.:.)line[1,3]} in
       (role|collection):*:*)
         subcmd="${line[1]}-${line[2]}"
@@ -253,18 +286,16 @@ case $state in
       [^:]#)
         words=( role "$words[@]" )
         (( CURRENT++ ))
+        args=()
       ;;
     esac
     curcontext="${curcontext%:*}-${subcmd}:"
-    (( $#words > 3 )) && ign='!'
-    args=(
-      "${ign}(-)"{-h,--help}'[display usage information]'
-      '1: :{ _wanted actions expl action compadd -a gactions }'
-    )
+    args+=( '1: :{ _wanted actions expl action compadd -a gactions }' )
     case $subcmd in
       *-*)
         args+=(
           '(-c --ignore-certs)'{-c,--ignore-certs}'[ignore SSL certificate validation errors]'
+          '--timeout=[specify time to wait for operations against the galaxy]:timeout (seconds) [60]'
           '(-s --server)'{-s+,--server=}'[specify API server destination]:server:_hosts'
           --{token,api-key}='[specify ansible galaxy API key]:api key'
           \*{-v,--verbose}'[verbose mode]'
@@ -278,7 +309,7 @@ case $state in
       ;|
       role-(info|init|install|list|remove))
         args+=( '*: :_guard "^-*" "role name"' )
-      ;;
+      ;|
       role-(info|search|list|remove|install))
 	args+=( '(-p --roles-path)'{-p,--roles-path}'[specify location of roles]:path:_directories' )
       ;|
@@ -358,7 +389,7 @@ case $state in
           '(-p --collections-path)'{-p+,--collections-path=}'[specify directory containing collections]:_directories'
           '(-r --requirements-file *)'{-r+,--requirements-file=}'[specify file containing a list of collections to install]:file:_files'
           '--pre[include pre-release versions]'
-          '*:collecion name:_files'
+          '*:collection name:_files'
         )
       ;;
     esac
@@ -403,4 +434,19 @@ case $state in
   ;;
 esac
 
+if [[ $state = plugins ]]; then
+  [[ -z $plug ]] && return ret
+  plugvar=_ansible_${plug}_plugins
+  typeset -ga ${plug}
+  if zstyle -T ":completion:${curcontext}:plugins" verbose; then
+    (( ${(P)#plugvar} )) || set -A ${plugvar} \
+        ${${${(f)"$(_call_program plugins ansible-doc -t $plug -l)"}:# *}/(:|) ##/:}
+    _describe -t plugins "${plug} plugin" $plugvar -M 'r:|.=* r:|=*' && ret=0
+  else
+    (( ${(P)#plugvar} )) || set -A ${plugvar} \
+        ${${(f)"$(_call_program plugins ansible-doc -t $plug -F)"}%%(|:) *}
+    _wanted plugins expl "${plug} plugin" compadd -M 'r:|.=* r:|=*' -a $plugvar && ret=0
+  fi
+fi
+
 return ret
diff --git a/Completion/Unix/Command/_ant b/Completion/Unix/Command/_ant
index 7401c7449..fd6112add 100644
--- a/Completion/Unix/Command/_ant
+++ b/Completion/Unix/Command/_ant
@@ -6,7 +6,8 @@ local curcontext="$curcontext" state line expl ret=1
 typeset -A opt_args
 local buildfile classpath cp userjars importedfiles target='*:target:->target' targets tmp
 
-find_targets() {
+(( $+functions[_ant_targets] )) ||
+_ant_targets() {
     importedfiles=( $(sed -n "s/ *<import[^>]* file=[\"']\([^\"']*\)[\"'].*/\1/p" < $1) )
     # Tweaked to omit targets beginning with "-" that can't
     # be invoked from the command line; see zsh-workers/24129.
@@ -14,12 +15,12 @@ find_targets() {
     if (( $#importedfiles )) ; then
         ( cd $1:h
             for file in $importedfiles ; do
-                expanded=( $(echo $file | sed -n "s|\${ant.home}|$ANT_HOME|p") )
-                if [[ ! "bla$expanded" = "bla" ]]; then
+                expanded=${file//\${ant.home}/$ANT_HOME}
+                if [[ "$expanded" != "$file" ]]; then
                     file=$expanded
                 fi
                 if [[ -f $file ]]; then
-                    find_targets $file
+                    _ant_targets $file
                 fi
         done )
     fi
@@ -79,8 +80,8 @@ case $state in
     compset -P '*:'
     compset -S ':*'
     _alternative \
-      "classpath:$state:_path_files -qS: -g '*.(jar|zip)(-.)'" \
-      "classpath:$state:_path_files -r': ' -/" && ret=0
+      "classpath:${state}:_path_files -qS: -g '*.(jar|zip)(-.)'" \
+      "classpath:${state}:_path_files -r': ' -/" && ret=0
   ;;
   property)
     if compset -P 1 '*='; then
@@ -122,20 +123,20 @@ case $state in
                         read default_target junk
                     fi
                     # Output target again indicating its the default one.
-                    print -n "'${default_target}:(Default target) ' "
+                    print -rn -- "${(qq):-${default_target}:(Default target)} "
                 ;;
                 (Searching:*|Main:targets:|Subtargets:|BUILD:SUCCESSFUL|Total:time:*)
                 ;;
                 (*)
                     # Return target and description
-                    print -n "'$ln' "
+                    print -rn -- "${(qq)ln} "
                 ;;
             esac
           done
         )//$'\015'}"
         _describe 'target' tmp && ret=0
       else
-        targets=( $(find_targets $buildfile) )
+        targets=( $(_ant_targets $buildfile) )
         _wanted targets expl target compadd -a targets && ret=0
       fi
     else
diff --git a/Completion/Unix/Command/_arp b/Completion/Unix/Command/_arp
index 389f1099b..7727de28c 100644
--- a/Completion/Unix/Command/_arp
+++ b/Completion/Unix/Command/_arp
@@ -61,7 +61,7 @@ case $OSTYPE in
   openbsd*)
     args+=(
       '(-a -d -W)-F[overwrite existing entries]'
-      '(-W)-V+[select the routing domain]:routing domain'
+      '(-W)-V+[select the routing domain]:routing domain:_routing_domains'
     )
     cmds+=(
       '(- 1)-W[send the wake on LAN frame]'
diff --git a/Completion/Unix/Command/_awk b/Completion/Unix/Command/_awk
index e8f4a2530..b69cc5cf8 100644
--- a/Completion/Unix/Command/_awk
+++ b/Completion/Unix/Command/_awk
@@ -50,6 +50,7 @@ case $variant in
       {-D-,--debug=-}'[enable debugging]::debugger command file:_files'
       {-g,--gen-pot}'[scan awk program and generate .po file on stdout]'
       '*'{-i+,--include}'[load source library]:library file:->script'
+      {-I,--trace}'[print internal byte code names as they are executed]'
       '*'{-l+,--load}'[load dynamic extension]:extension:->extension'
       {-M,--bignum}'[select arbitrary-precision arithmetic on numbers]'
       {-o-,--pretty-print=-}'[pretty-print awk program]::output file:_files'
diff --git a/Completion/Unix/Command/_cal b/Completion/Unix/Command/_cal
index 82bb98b5f..b92e8153f 100644
--- a/Completion/Unix/Command/_cal
+++ b/Completion/Unix/Command/_cal
@@ -1,28 +1,131 @@
 #compdef cal ncal
 
-local args
+local -a args
+args=()
 
 case $service in
   cal)
-    args=(
-      '-3[three in a row]'
-      '-m[Monday as first day of the week]'
-    )
+    # check util-linux's cal or bsdmainutils's cal
+    if $service --version 1>/dev/null 2>/dev/null ; then
+      args+=(
+        '(-1 --one)'{-1,--one}'[show only a single month]'
+        '(-3 --three)'{-3,--three}'[show three months spanning the date]'
+        '(-n --months)'{-n,--months=}"[show num months starting with date's month]:month"
+        '(-S --span)'{-S,--span}'[span the date when displaying multiple month]'
+        '(-s --sunday)'{-s,--sunday}'[Sunday as first day of week]'
+        '(-m --monday)'{-m,--monday}'[Monday as first day of week]'
+        '(-j --julian)'{-j,--julian}'[use day-of-year for all calendars]'
+        '--reform=[Gregorian reform date]:val:(1752 gregorian iso julian)'
+        '--iso[alias for --reform=iso]'
+        '(-y --year)'{-y,--year}'[show the whole year]'
+        '(-Y --twelve)'{-Y,--twelve}'[show the next twelve months]'
+        '(-w --week)'{-w,--week=-}'[show US or ISO-8601 week numbers]::num'
+        '(-v --vertical)'{-v,--vertical}'[show day vertically instead of line]'
+        '(-c --columns)'{-c,--columns=}'[amount of columns to use]:width'
+        '--color=-[colorize messages]:when:(auto always never)'
+        '(- *)'{-h,--help}'[display help]'
+        '(- *)'{-V,--version}'[display version]'
+      )
+    else
+      case $OSTYPE in
+        (linux*|openbsd*|freebsd*|netbsd*|darwin*|dragonfly*)
+          args+=(
+            '-j[display Julian days]'
+          )
+        ;|
+        (linux*|freebsd*|netbsd*|darwin*|dragonfly*)
+          args+=(
+            '-3[display the previous, current and next month surrounding today]'
+            '-A[months to add after]:months'
+            '-B[months to add before]:months'
+          )
+        ;|
+        (freebsd*|netbsd*|darwin*|dragonfly*)
+          args+=(
+            '-h[turns off highlighting of today]'
+          )
+        ;|
+        (netbsd*|openbsd*)
+          args+=(
+            '-y[display a calendar for the current year]'
+          )
+        ;|
+        (linux*|freebsd*|darwin*|dragonfly*)
+          args+=(
+            '-m[display the specified month]:month'
+            '-y[display a calendar for the specified year]:year'
+            '-C[switch to cal mode]'
+            '-d[use yyyy-mm as the current date]:yyyy-mm'
+          )
+        ;|
+        (freebsd*|darwin*|dragonfly*)
+          args+=(
+            '-N[switch to ncal mode]'
+          )
+        ;|
+        (linux*)
+          args+=(
+            '-1[display only the current month]'
+          )
+        ;|
+        (openbsd*)
+          args+=(
+            '-m[display weeks starting on Monday instead of Sunday]'
+            '-w[display week numbers in the month display]'
+          )
+        ;|
+        (netbsd*)
+          args+=(
+            '-C[display context months before and after the specified month]:months'
+            '-d[specifies the day of the week on which the calendar should start]:day_of_week'
+            '-h[highlight the current day]'
+            '-R[selects an alternate Gregorian reform point from the default of September 3rd, 1752]:reform-sp'
+            '-r[display the month in which the Gregorian Reform adjustment was applied]'
+          )
+        ;;
+      esac
+    fi
   ;;
   ncal)
     args=(
-      '-J[display Julian calendar]'
-      '-e[display date of western Easter]'
-      '-o[display date of orthodox Easter]'
-      '-p[assume as by ncal]'
-      '-s[country code]'
-      '-w[print number of the week below each column]'
+      '-h[turns off highlighting of today]'
+      '-J[display Julian Calendar]'
+      '-e[display date of Easter]'
+      '-j[display Julian days]'
+      '-o[display date of Orthodox Easter]'
+      '-m[display the specified month]:month'
+      '-p[print the country codes and switching days from Julian to Gregorian Calendar]'
+      '-s[assume the switch from Julian to Gregorian Calendar at the date associated with the country_code]:country_code'
+      '-w[print the number of the week below each week column]'
+      '-y[display a calendar for the specified year]:year'
+      '-3[display the previous, current and next month surrounding today]'
+      '-A[months to add after]:months'
+      '-B[months to add before]:months'
+      '-C[switch to cal mode]'
+      '-d[use yyyy-mm as the current date]:yyyy-mm'
+      '-H[use yyyy-mm-dd as the current date]:yyyy-mm-dd'
+      '-M[weeks start on Monday]'
+      '-S[weeks start on Sunday]'
+      '-W[first week of the year has at least number days]:number'
+      '-b[use oldstyle format for ncal output]'
     )
+
+    case $OSTYPE in
+      (linux*)
+        args+=(
+          '-b[use oldstyle format for ncal output]'
+          '-1[display only the current month]'
+        )
+        ;;
+      (*)
+        args+=(
+          '-N[switch to ncal mode]'
+        )
+        ;;
+    esac
   ;;
 esac
 
 _arguments "${args[@]}" \
-  '-j[display Julian days]' \
-  '-y[display a calendar for the current year]' \
   '::month' \
   ':year'
diff --git a/Completion/Unix/Command/_cat b/Completion/Unix/Command/_cat
index 74d7278b8..526c49e31 100644
--- a/Completion/Unix/Command/_cat
+++ b/Completion/Unix/Command/_cat
@@ -38,6 +38,9 @@ elif [[ "$OSTYPE" == (*bsd|dragonfly|darwin)* ]]; then
     '-B+[read with buffer of specified size]:size (bytes)'
     '-f[only attempt to display regular files]'
   )
+  [[ $OSTYPE = darwin* ]] && args+=(
+    '-l[set an exclusive advisory lock on standard output]'
+  )
 elif [[ $OSTYPE = solaris* ]]; then
   args=(
     -A "-*"
diff --git a/Completion/Unix/Command/_chmod b/Completion/Unix/Command/_chmod
index 3f6db7e91..42e3fa63b 100644
--- a/Completion/Unix/Command/_chmod
+++ b/Completion/Unix/Command/_chmod
@@ -1,7 +1,10 @@
 #compdef chmod gchmod zf_chmod
 
 local curcontext="$curcontext" state line expl ret=1 variant
-local -a args privs aopts=( -A '-*' )
+local -a args privs aopts
+
+# usual -* pattern picks up valid non-options, e.g. -x which is like a-x
+aopts=( -A '-[^gorstuwxX]*' )
 
 args=( '*: :->files' '1: :_file_modes' )
 
diff --git a/Completion/Unix/Command/_chown b/Completion/Unix/Command/_chown
index 9ebbf7bab..4362d6e75 100644
--- a/Completion/Unix/Command/_chown
+++ b/Completion/Unix/Command/_chown
@@ -43,7 +43,7 @@ case "$variant" in
       '(-H -L -P)-P[do not follow symlinks (default)]'
     )
     ;|
-  dragonfly*|freebsd*)
+  dragonfly*|freebsd*|darwin*)
     args+=(
       "-x[don't traverse file systems]"
     )
@@ -63,6 +63,11 @@ case "$variant" in
       '-s[owner and/or group are Windows SID strings]'
     )
     ;;
+  darwin*)
+    args+=(
+      '-n[interpret user and group as numeric, avoiding name lookups]'
+    )
+    ;;
 esac
 
 (( $+words[(r)--reference*] )) || args+=( '(--reference)1: :->owner' )
diff --git a/Completion/Unix/Command/_chroot b/Completion/Unix/Command/_chroot
index 516992694..a9c577bd7 100644
--- a/Completion/Unix/Command/_chroot
+++ b/Completion/Unix/Command/_chroot
@@ -33,7 +33,7 @@ case $variant in
     ;;
 esac
 
-args+=( '1:new root directory:_directories' '*:::command:_normal' )
+args+=( '1:new root directory:_directories' '*::: : _normal -p $service' )
 
 _arguments -s -S : $args && ret=0
 
diff --git a/Completion/Unix/Command/_cmp b/Completion/Unix/Command/_cmp
index 6d7bfb1b7..20d309e32 100644
--- a/Completion/Unix/Command/_cmp
+++ b/Completion/Unix/Command/_cmp
@@ -1,23 +1,29 @@
 #compdef cmp gcmp
 
-local args variant
+local args variant units
 _pick_variant -r variant gnu=GNU $OSTYPE --version
 
 case $variant in
-  gnu)
+  freebsd*|gnu)
     args=(
       '(-b --print-bytes)'{-b,--print-bytes}'[print differing bytes]'
       '(-i --ignore-initial)'{-i+,--ignore-initial}'[skip specified number of bytes]:bytes'
       '(-l --verbose -s --silent --quiet)'{-l,--verbose}'[output all differences]'
       '(-n --bytes)'{-n+,--bytes=}'[specify maximum bytes to compare]:bytes'
       '(-s --quiet --silent -l --verbose)'{-s,--quiet,--silent}'[return status alone signifies differences]'
+    )
+    units=":_numbers -u bytes offset K M G T P E Z Y"
+  ;|
+  gnu)
+    args=(
       '(- *)'{-v,--version}'[display version information]'
       '(- *)--help[display help information]'
     )
+    units+=" kB MB GB TB PB EB ZB YB"
   ;;
   netbsd*) args+=( "-c[don't use mmap]" ) ;|
   freebsd*|openbsd*)
-    args=(
+    args+=(
       "-h[don't follow symbolic links]"
       '-x[hexadecimal output and zero based offset index]'
       '-z[compare file sizes first]'
@@ -31,4 +37,4 @@ case $variant in
   ;;
 esac
 
-_arguments -s $args '1:file 1:_files' '2:file 2:_files' '::byte offset' '::byte offset'
+_arguments -s $args '1:file 1:_files' '2:file 2:_files' "::byte offset$units" "::byte offset$units"
diff --git a/Completion/Unix/Command/_column b/Completion/Unix/Command/_column
index 94bdccf0a..687d7620f 100644
--- a/Completion/Unix/Command/_column
+++ b/Completion/Unix/Command/_column
@@ -22,7 +22,7 @@ case $variant in
     aopts=()
     args=(
       '(info json -c --output-width)'{-c+,--output-width=}'[format output to fit display of specified width]:width'
-      '(info)'{-L,--table-empty-lines}"[don't ignore empty lines]"
+      '(info)'{-L,--keep-empty-lines}"[don't ignore empty lines]"
       + fill
       '(info table text json -x --fillrows)'{-x,--fillrows}'[print across before down]'
       + table
@@ -30,8 +30,20 @@ case $variant in
       '(info fill -o --output-separator)'{-o+,--output-separator=}'[specify column separator for table output]:separator [two spaces]'
       '(info fill -s --separator)'{-s+,--separator=}'[specify column delimiters in input data]:delimiters'
       '(info fill -O --table-order)'{-O+,--table-order=}'[specify order of output columns]: :->columns'
-      '(info fill -N --table-columns)'{-N+,--table-columns=}'[specify column names]:names'
+      '(info fill -N --table-columns)*'{-C+,--table-column=}'[specify column properties]: :_values -s, -S= property
+        "name[column name]\:name"
+        "trunc[truncate text in the columns when necessary]"
+        "right[right align text]"
+        "width[specify column width]\:width"
+        "strictwidth[strictly follow column width setting]"
+        "noextreme[allow length to be ignored]"
+        "wrap[wrap text when necessary]"
+        "hide[don'\''t print column]"
+        "json[define type for JSON output]\:type\:(string number boolean)"'
+      '(info fill -N --table-columns -C --table-column)'{-N+,--table-columns=}'[specify column names]:names'
+      '(info fill -l --table-columns-limit)'{-l+,--table-columns-limit=}'[specify maximum number of input columns]:columns'
       '(info fill -H --table-hide)'{-H+,--table-hide=}"[don't print specified columns]: :->columns"
+      '(info fill -m --table-maxout)'{-m,--table-maxout}'[fill all available space]'
       + text
       '(info fill json -d --table-noheadings)'{-d,--table-noheadings}"[don't print header]"
       '(info fill json -E --table-noextreme)'{-E+,--table-noextreme}"[specify columns where length can be ignored]: :->columns"
diff --git a/Completion/Unix/Command/_cp b/Completion/Unix/Command/_cp
index f7411055b..cb899cc28 100644
--- a/Completion/Unix/Command/_cp
+++ b/Completion/Unix/Command/_cp
@@ -32,7 +32,7 @@ if _pick_variant gnu=GNU unix --version; then
     '(-v --verbose)'{-v,--verbose}'[explain what is being done]' \
     '(-x --one-file-system)'{-x,--one-file-system}'[stay on this file system]' \
     '(--context)-Z[set destination SELinux security context]' \
-    '(-Z)--context=-[set destination SELinux security context]:: :_selinux_contexts' \
+    '(-Z)--context=-[set destination SELinux security context]:: :_selinux_contexts -a file_type' \
     '(- *)--help' '(- *)--version' \
     '*:file or directory:_files'
 else
@@ -51,14 +51,16 @@ else
     '(aix|hpux|irix|solaris)*' '-r[copy directories recursively]' \
     'solaris2.<9->*' '-@[preserve extended attributes]' \
     'solaris2.<11->*' '-/[preserve extended attributes and extended system attributes]' \
+    'solaris2.<11->*' '-z[fast relink(3C) based copy]' \
     '(darwin|dragonfly|freebsd)*' "(-f -i)-n[don't overwrite existing file]" \
     'netbsd*' "-N[don't copy file flags]" \
     '(darwin|dragonfly|freebsd|netbsd|openbsd)*' '-a[archive mode, same as -RpP]' \
-    '(dragonfly|freebsd)*' '-l[link files instead of copying]' \
+    '(dragonfly|freebsd|darwin)*' '-l[link files instead of copying]' \
     '(darwin|dragonfly|*bsd)*' '-v[show file names as they are copied]' \
     'darwin*' "-X[don't copy extended attributes or resource forks]" \
-    '(dragonfly|freebsd)*' "-x[don't traverse file systems]" \
-    'freebsd<10->.*' '-s[make symbolic links instead of copies of non-directories]'
+    '(dragonfly|freebsd|darwin)*' "-x[don't traverse file systems]" \
+    '(freebsd<10->.|darwin)*' '-s[make symbolic links instead of copies of non-directories]' \
+    'darwin*' '-c[copy files using clonefile(2)]'
   do
     [[ $OSTYPE = $~pattern ]] && args+=( $arg )
   done
diff --git a/Completion/Unix/Command/_csplit b/Completion/Unix/Command/_csplit
new file mode 100644
index 000000000..5f72232bb
--- /dev/null
+++ b/Completion/Unix/Command/_csplit
@@ -0,0 +1,51 @@
+#compdef csplit
+
+local curcontext=$curcontext cnt_info ret=1
+local -a state state_descr line specs optA
+typeset -A opt_args
+
+# common specs
+specs=(
+  '(hv -f --prefix)'{-f+,--prefix=}'[specify prefix for output file names]:prefix [xx]: '
+  '(hv -n --digits -b --suffix-format)'{-n+,--digits=}'[specify number of digits in output file names]:number [2]: '
+  '(hv -k --keep-files)'{-k,--keep-files}'[do not remove output files on errors]'
+  '(hv -s --quiet --silent)'{-s,--quiet,--silent}'[do not print counts of output file sizes]'
+  '(hv)1: :_files'
+  '(hv)*: :->patterns'
+)
+
+if _pick_variant gnu=GNU unix --version; then
+  # GNU coreutils 8.32
+  specs+=(
+    '(hv -b --suffix-format -n --digits)'{-b+,--suffix-format=}'[specify format for numbers in output file names]:format [%%02d]: '
+    '(hv)--suppress-matched[suppress the lines matching the pattern]'
+    '(hv -z --elide-empty)'{-z,--elide-empty-files}'[remove empty output files]'
+    + hv
+    '(: * -)--help[display help and exit]'
+    '(: * -)--version[output version information and exit]'
+  )
+  cnt_info="(integer or '*')"
+else
+  # POSIX ({Free,Open}BSD, DragonFly, macOS)
+  specs=( ${specs:#(|*\))--*} )  # remove long options
+  optA=( -A '-?*' )  # a single '-' is a valid file name (stdin)
+fi
+
+_arguments -C -s -S $optA : $specs && ret=0
+
+case $state in
+  patterns)
+    if compset -P '(/?*/|%?*%)'; then
+      _message '[+|-]offset' && ret=0
+    elif compset -P '[/%]'; then
+      _message 'regex' && ret=0
+    elif compset -P '(|\\){'; then
+      _message "count $cnt_info" && ret=0
+    elif compset -P '[0-9]*'; then
+      _message 'line number' && ret=0
+    elif [[ ${words[CURRENT]} != -* ]] then
+      _message "line_number, '/regex/[offset]', '%%regex%%[offset]', or '{count}'" && ret=0
+    fi
+esac
+
+return ret
diff --git a/Completion/Unix/Command/_cut b/Completion/Unix/Command/_cut
index d3b1e2b10..778439cf1 100644
--- a/Completion/Unix/Command/_cut
+++ b/Completion/Unix/Command/_cut
@@ -1,6 +1,7 @@
 #compdef cut gcut
 
 typeset -A _cut_args
+local -a args
 
 case $LANG in
   (de_DE.UTF-8)
@@ -45,7 +46,7 @@ if _pick_variant gnu="Free Soft" unix --version; then
     '*:file:_files'
 else
   case $OSTYPE in
-    freebsd*|dragonfly*) args+=( '(-d)-w[use whitespace as the delimiter]' ) ;;
+    freebsd*|dragonfly*|darwin*) args=( '(-d)-w[use whitespace as the delimiter]' ) ;;
   esac
   _arguments $args \
     "-b[${_cut_args[bytes]}]:list" \
diff --git a/Completion/Unix/Command/_date b/Completion/Unix/Command/_date
index 97c272830..f0053ec02 100644
--- a/Completion/Unix/Command/_date
+++ b/Completion/Unix/Command/_date
@@ -7,8 +7,8 @@ local -a opts args
 opts=( -s -w -C )
 
 if _pick_variant gnu="Free Software Foundation" unix --version; then
-  local d='(-d --date -f --file -r --reference -s --set)'
-  local f='(-I --iso-8601 -R --rfc-email --rfc-3339)'
+  local d='(-d --date -f --file -r --reference -s --set --resolution)'
+  local f='(-I --iso-8601 -R --rfc-email --rfc-3339 --resolution)'
   args=(
     $d{-d+,--date=}'[output date specified by string]:time string'
     '--debug[annotate parsed date and warn about questionable usage]'
@@ -16,9 +16,10 @@ if _pick_variant gnu="Free Software Foundation" unix --version; then
     $d{-r+,--reference=}'[output last modification time of specified file]:file:_files'
     $d{-s+,--set=}'[set time]:time string'
     $f{-I-,--iso-8601=-}'[display in ISO 8601 format]::precision:(date hours minutes seconds ns)'
+    '(-)--resolution[output the available resolution of timestamps]'
     $f{-R,--rfc-email}'[display in RFC5322 format]'
     $f'--rfc-3339=-[display in RFC 3339 format]:precision:(date seconds ns)'
-    '(-u --utc --universal)'{-u,--utc,--universal}'[display or set time in UTC]'
+    '(-u --utc --universal --resolution)'{-u,--utc,--universal}'[display or set time in UTC]'
     '(- :)--help[output help and exit]'
     '(- :)--version[output version info and exit]'
   )
@@ -43,12 +44,12 @@ else
 	'-f+[use specified format for input]:parsing format:_date_formats:new date'
       )
     ;|
-    dragonfly*|darwin*|netbsd*|openbsd*)
+    dragonfly*|netbsd*|openbsd*)
       args+=(
 	'-r+[output date specified by reference time]:seconds since epoch'
       )
     ;|
-    freebsd*)
+    freebsd*|darwin*)
       local -a alts
       alts=(
 	'seconds:sec:_guard "(0x[0-9a-fA-F]#|[0-9]#)" "seconds since epoch"'
@@ -56,27 +57,25 @@ else
       )
       args+=(
 	'-r+[reference time: file modification or literal time]:reference: _alternative $alts'
-	'(-R)-I-[display in ISO 8601 format]::precision:(date hours minutes seconds)'
       )
     ;|
     freebsd*|dragonfly*|darwin*)
       args+=(
+        '-R[display in RFC2822 format]'
+	'(-R)-I-[display in ISO 8601 format]::precision [date]:(date hours minutes seconds)'
 	"*-v+[adjust and print (but don't set) date]:[+-]value[ymwdHMS]"
       )
     ;|
-    freebsd<-12>.*|darwin*)
+    freebsd<-12>.*)
       args+=(
 	'-d+:daylight saving time value'
 	'-t+:minutes west of GMT'
       )
     ;|
-    freebsd*|dragonfly*)
-      args+=( '-R[display in RFC2822 format]' )
-    ;|
     openbsd*|netbsd*) args+=( '-a[gradually skew]' )
     ;|
-    openbsd*)
-      args+=( '-z[specify timezone for output]:time zone:_time_zone')
+    freebsd<14->.*|openbsd*)
+      args+=( '-z+[specify timezone for output]:time zone:_time_zone')
     ;|
     netbsd*)
       args+=( '-d[output date specified by string]:time string:' )
diff --git a/Completion/Unix/Command/_dbus b/Completion/Unix/Command/_dbus
index 37b5458d7..d2a93152c 100644
--- a/Completion/Unix/Command/_dbus
+++ b/Completion/Unix/Command/_dbus
@@ -8,11 +8,13 @@ case $service in
   dbus-send)
     _arguments -A "--*" -C \
       '(--session)--system' '(--system)--session' \
-      '--address=-:bus address:->addresses' \
+      '--bus=-:bus address:->addresses' \
+      '--peer=-:bus address:->addresses' \
       '--dest=-:connection:->connections' \
       '--print-reply=-::format:(literal)' \
       '--reply-timeout=-:timeout (ms)' \
-      '--type=-:type:(method_call signal)' \
+      '--sender=-:name' \
+      '--type=-:type [signal]:(method_call signal)' \
       '(* -)--help' \
       ':object path:->objectpaths' \
       ':message name:->methods' \
diff --git a/Completion/Unix/Command/_dd b/Completion/Unix/Command/_dd
index e5c5e63ce..c55efb68c 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}
@@ -73,8 +74,9 @@ case $variant in
     vals+=(
       'status[specify level of information to print to stderr]:level:(none noxfer progress)'
     )
-    flags+=( fullblock noatime nocache count_bytes skip_bytes seek_bytes )
+    flags+=( fullblock noatime nocache )
     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/_dig b/Completion/Unix/Command/_dig
index 3081e2cfd..c09bebbe5 100644
--- a/Completion/Unix/Command/_dig
+++ b/Completion/Unix/Command/_dig
@@ -6,8 +6,9 @@ local -a alts args
   '*+'{no,}'tcp[use TCP instead of UDP for queries]'
   '*+'{no,}'ignore[ignore truncation in UDP responses]'
   '*+domain=[set search list to single domain]:domain:_hosts'
-  '*+dscp=[set DSCP code point for query]:code point (0..63)'
+  '!*+dscp=:code point (0..63)'
   '*+'{no,}'search[use search list defined in resolv.conf]'
+  '!*+'{no,}defname
   '*+'{no,}'showsearch[show intermediate results in domain search]'
   '*+split[split hex/base64 fields into chunks]:width (characters) [56]'
   '*+'{no,}'aaonly[set aa flag in the query]'
@@ -18,6 +19,7 @@ local -a alts args
   '*+'{no,}'class[display the CLASS whening printing the record]'
   '*+'{no,}'cookie[add a COOKIE option to the request]'
   '*+'{no,}'crypto[display cryptographic fields in DNSSEC records]'
+  '*+'{no,}'dns64prefix[get the DNS64 prefixes from ipv4only.arpa]'
   '*+edns=[specify EDNS version for query]:version (0-255)'
   '*+noedns[clear EDNS version to be sent]'
   '*+ednsflags=[set EDNS flags bits]:flags'
@@ -27,11 +29,15 @@ local -a alts args
   '*+'{no,}'expandaaaa[expand AAAA records]'
   '*+'{no,}'expire[send an EDNS Expire option]'
   '*+'{no,}'header-only[send query without a question section]'
+  '*+'{no,}'https=[DNS-over-HTTPS POST mode]::endpoint [/dns-query]'
+  '!*+'{no,}'https-post=::endpoint [/dns-query]'
+  '*+'{no,}'https-get=[DNS-over-HTTPS GET mode]::endpoint [/dns-query]'
+  '*+'{no,}'http-plain=[DNS-over-HTTP POST mode]::endpoint [/dns-query]'
+  '*+'{no,}'http-plain-get=[DNS-over-HTTP GET mode]::endpoint [/dns-query]'
   '*+'{no,}'idnin[set processing of IDN domain names on input]'
   '*+'{no,}'idnout[set conversion of IDN puny code on output]'
   '*+'{no,}'keepalive[request EDNS TCP keepalive]'
   '*+'{no,}'keepopen[keep TCP socket open between queries]'
-  '*+'{no,}'mapped[allow mapped IPv4 over IPv6 to be used]'
   '*+'{no,}'recurse[set the RD (recursion desired) bit in the query]'
   '*+'{no,}'nssearch[search all authoritative nameservers]'
   '*+opcode[set DNS message opcode of the request]:opcode [QUERY]:(QUERY IQUERY STATUS NOTIFY UPDATE)'
@@ -39,10 +45,12 @@ local -a alts args
   '*+'{no,}'trace[trace delegation down from root]'
   '*+'{no,}'cmd[print initial comment in output]'
   '*+'{no,}'short[print terse output]'
+  '*+'{no,}'showbadcookie[show BADCOOKIE message]'
   '*+'{no,}'identify[print IP and port of responder]'
   '*+'{no,}'comments[print comment lines in output]'
   '*+'{no,}'stats[print statistics]'
   '*+padding[set padding block size]:size [0]'
+  '*+qid=[specify query ID]:query ID'
   '*+'{no,}'qr[print query as it was sent]'
   '*+'{no,}'question[print question section of a query]'
   '*+'{no,}'raflag[set RA flag in the query]'
@@ -52,6 +60,11 @@ local -a alts args
   '*+'{no,}'subnet[send EDNS client subnet option]:addr/prefix-length'
   '*+'{no,}'tcflag[set TC flag in the query]'
   '*+timeout=[set query timeout]:timeout (seconds) [5]'
+  '*+'{no,}'tls[DNS-over-TLS mode]'
+  '*+'{no,}"tls-ca=[enable remote server's TLS certificate validation]:file:_files"
+  '*+'{no,}"tls-hostname=[explicitly set the expected TLS hostname]:hostname"
+  '*+'{no,}'tls-certfile=[load client TLS certificate chain from file]:file:_files'
+  '*+'{no,}'tls-keyfile=[load client TLS private key from file]:file:_files'
   '*+tries=[specify number of UDP query attempts]:tries'
   '*+retry=[specify number of UDP query retries]:retries'
   '*+'{no,}'rrcomments[set display of per-record comments]'
@@ -65,7 +78,6 @@ local -a alts args
   '*+'{no,}'nsid[include EDNS name server ID request in query]'
   '*+'{no,}'ttlid[display the TTL whening printing the record]'
   '*+'{no,}'ttlunits[display the TTL in human-readable units]'
-  '*+'{no,}'unexpected[print replies from unexpected sources]'
   '*+'{no,}'unknownformat[print RDATA in RFC 3597 "unknown" format]'
   '*+'{no,}'yaml[present the results as YAML]'
   '*+'{no,}'zflag[set Z flag in query]'
diff --git a/Completion/Unix/Command/_dmidecode b/Completion/Unix/Command/_dmidecode
index 047b74f6d..e2c511313 100644
--- a/Completion/Unix/Command/_dmidecode
+++ b/Completion/Unix/Command/_dmidecode
@@ -4,6 +4,7 @@ _arguments -s \
   '(-d --dev-mem --from-dump)'{-d+,--dev-mem=}'[read memory from specified file]:memory device [/dev/mem]:_files' \
   '(-)'{-h,--help}'[display usage information]' \
   '(-q --quiet -u --dump)'{-q,--quiet}'[be less verbose]' \
+  '--no-quirks[decode everything without quirks]' \
   '(-t --type -H --handle -u --dump --dump-bin -s --string)'{-s+,--string=}'[only display value of specified DMI string]:DMI string:(bios-vendor bios-version bios-release-date system-manufacturer system-product-name system-version system-serial-number system-uuid baseboard-manufacturer baseboard-product-name baseboard-version baseboard-serial-number baseboard-asset-tag chassis-manufacturer chassis-type chassis-version chassis-serial-number chassis-asset-tag processor-family processor-manufacturer processor-version processor-frequency)' \
   '(-s --string -H --handle --dump-bin)*'{-t+,--type=}'[only display entries of specified type]:entry type:(bios system baseboard chassis processor memory cache connector slot)' \
   '(-s --string -t --type -H --handle --dump-bin)'{-H,--handle=}'[only display the entry of specified handle]:handle' \
diff --git a/Completion/Unix/Command/_du b/Completion/Unix/Command/_du
index 711f43471..ccb5bdd94 100644
--- a/Completion/Unix/Command/_du
+++ b/Completion/Unix/Command/_du
@@ -55,7 +55,7 @@ else
   )
   local xdev='[skip directories on different filesystems]'
   for pattern arg in \
-    'freebsd*' '-A[apparent size instead of usage]' \
+    '(freebsd|darwin)*' '-A[apparent size instead of usage]' \
     '(darwin*|*bsd*|dragonfly*|solaris2.<10->)' '(-H -L -P)-H[follow symlinks on the command line]' \
     '(darwin|*bsd|dragonfly)*' '(-H -L -P)-P[do not follow symlinks (default)]' \
     '(darwin|dragonfly|freebsd)*' '*-I+[ignore files/directories matching specified mask]:mask' \
@@ -64,12 +64,12 @@ else
     'netbsd*' '-i[output inode usage instead of blocks]' \
     '(darwin*|freebsd*|netbsd*|solaris2.<11->)' '(-h -k -g -B)-m[use block size of 1M-byte]' \
     '(darwin|freebsd<8->.|netbsd)*' '(-h -k -m -B)-g[use block size of 1G-byte]' \
-    'freebsd*' '(-h -k -m -g)-B+[block size]:block size (bytes)' \
+    '(freebsd|darwin)*' '(-h -k -m -g)-B+[block size]:block size (bytes)' \
     '(darwin|*bsd|dragonfly)*' '-c[display grand total]' \
-    'freebsd*' '-l[count sizes many times if hard linked]' \
+    '(freebsd|darwin)*' '-l[count sizes many times if hard linked]' \
     '(freebsd|netbsd)*' '-n[ignore files and directories with nodump flag set]' \
     'solaris*' "(-a)-o[don't add child directories' usage to parent's total]" \
-    'freebsd<8->.*' '-t+[report only entries for which size exceeds threshold]:threshold' \
+    '(freebsd|darwin)*' '-t+[report only entries for which size exceeds threshold]:threshold' \
     'solaris*' "-d$xdev" \
     '(darwin|*bsd|dragonfly|solaris)*' "-x$xdev"
   do
diff --git a/Completion/Unix/Command/_elfdump b/Completion/Unix/Command/_elfdump
index 065f4b97f..b3cc77695 100644
--- a/Completion/Unix/Command/_elfdump
+++ b/Completion/Unix/Command/_elfdump
@@ -34,10 +34,15 @@ case $OSTYPE in
       '-l[show long section names without truncation]'
       '-O[specify osabi to apply]:osabi'
       '-P[use alternative section header]'
-      "*:elf file:_object_files"
     )
   ;;
-  freebsd*) args+=( '-a[dump all information]' ) ;;
+  freebsd*)
+    args+=(
+      '-a[dump all information]'
+      '(-)-E[return success if file is an ELF file and failure if not]'
+    )
+  ;;
 esac
 
-_arguments -s $args
+_arguments -s $args \
+  "*:elf file:_object_files"
diff --git a/Completion/Unix/Command/_enscript b/Completion/Unix/Command/_enscript
index 3e09da5a4..4658ae4bc 100644
--- a/Completion/Unix/Command/_enscript
+++ b/Completion/Unix/Command/_enscript
@@ -128,7 +128,7 @@ case "$state" in
     local suf='{'
     compquote suf
     if [[ ${PREFIX} = *[%$]D${suf}[^}]# ]]; then
-      _strftime
+      _date_formats
     elif [[ ${(Q)PREFIX} = *\$\([^\)]# ]]; then
       compset -P '*\('
       _parameters -g '*export*' -S '\)'
diff --git a/Completion/Unix/Command/_env b/Completion/Unix/Command/_env
index a5dd49d37..8cf0ad467 100644
--- a/Completion/Unix/Command/_env
+++ b/Completion/Unix/Command/_env
@@ -9,6 +9,7 @@ case $variant in
     (( $#words > 2 )) && ign='!'
     args=(
       '(-)'{-i,--ignore-environment}'[start with empty environment]'
+      '(* -0 --null)'{-0,--null}'[end each output line with NUL, not newline]'
       '(--ignore-environment -i --help --version)*'{-u+,--unset=}'[remove variable from the environment]:env var to remove:_parameters -g "*export*"'
       '(-C --chdir)'{-C+,--chdir=}'[change working directory]:directory:_directories'
       '(-S --split-string)'{-S+,--split-string=}'[perform word splitting]:string to split'
@@ -23,11 +24,13 @@ case $variant in
   ;;
   freebsd*)
     args=(
-      '-0[use NUL, not newline after each variable in output]'
       '-L[add variables from system login.conf(5)]: :->user-class'
       '-U[add variables from user and system login.conf(5)]: :->user-class'
     )
   ;|
+  freebsd*|darwin*)
+    args=( '-0[use NUL, not newline after each variable in output]' )
+  ;|
   freebsd*|darwin*|dragonfly*)
     args+=(
       '(-i)*-u+[remove variable from the environment]:env var to remove:_parameters -g "*export*"'
@@ -58,7 +61,7 @@ if [[ -n $state ]]; then
         shift words
         (( CURRENT-- ))
       done
-      _normal && ret=0
+      _normal -p env && ret=0
     ;;
     user-class)
       if compset -P 1 '*/'; then
diff --git a/Completion/Unix/Command/_ffmpeg b/Completion/Unix/Command/_ffmpeg
index 1329939cd..e5afdac4f 100644
--- a/Completion/Unix/Command/_ffmpeg
+++ b/Completion/Unix/Command/_ffmpeg
@@ -125,7 +125,7 @@ local -a _ffmpeg_argspecs
                 lastopt_description=${lastopt_description//:/\\:}
                 if [[ $example == filename ]]; then
                     lastopt_takesargs=0
-                    lastopt+=":$lastopt_description:_files"
+                    lastopt+=":${lastopt_description}:_files"
                 elif [[ $lastopt == -[asv]pre ]]; then
                     lastopt_takesargs=0
                     lastopt="*$lastopt"
diff --git a/Completion/Unix/Command/_find b/Completion/Unix/Command/_find
index 8ff60baf2..4f1c338ee 100644
--- a/Completion/Unix/Command/_find
+++ b/Completion/Unix/Command/_find
@@ -37,6 +37,11 @@ case $variant in
     args+=(
       '*-Bmin:birth time (minutes)'
       '*-Bnewer:file to compare (birth time):_files'
+      '*-newer'{a,B,c,m}{a,B,c,m}'[if [aBcm\]time is newer than [aBcm\]time of given file]:reference file:_files'
+      '*-newerat[if access time is newer than given timestamp]:timestamp: '
+      '*-newerBt[if birth time is newer than given timestamp]:timestamp: '
+      '*-newerct[if creation time is newer than given timestamp]:timestamp: '
+      '*-newermt[if modification time is newer than given timestamp]:timestamp: '
       '*-Btime:birth time (hours)'
     )
   ;|
@@ -46,7 +51,7 @@ case $variant in
       '*-anewer:file to compare (access time):_files'
       '*-cnewer:file to compare (inode change time):_files'
       '*-empty'
-      '*-execdir:program: _command_names -e:*\;::program arguments: _normal'
+      '*-execdir:program: _command_names -e:*(\;|+)::program arguments: _normal'
       '*-maxdepth:maximum search depth'
       '*-mindepth:minimum search depth'
       '*-path:path pattern to search:'
@@ -110,13 +115,14 @@ case $variant in
       '*-readable'
       '*-writable'
       '*-xtype:file type:((b\:block\ special\ file c\:character\ special\ file d\:directory p\:named\ pipe f\:normal\ file l\:symbolic\ link s\:socket))'
+      '(*)-files0-from[start recursing from targets in given file]:NUL-separated targets file:_files'
       '*-fls:output file:_files'
       '*-fprint:output file:_files'
       '*-fprint0:output file:_files'
       '*-fprintf:output file:_files:output format'
       '*-printf:output format'
     )
-    [[ $OSTYPE = linux-gnu ]] && args+=( '*-context:SELinux context (glob pattern):_selinux_contexts' )
+    [[ $OSTYPE = linux-gnu ]] && args+=( '*-context:SELinux context (glob pattern):_selinux_contexts -a file_type' )
   ;;
 esac
 
@@ -126,7 +132,7 @@ _arguments -C $args \
   '*-atime:access time (days):->times' \
   '*-ctime:inode change time (days):->times' \
   '*-depth' \
-  '*-exec:program: _command_names -e:*\;::program arguments: _normal' \
+  '*-exec:program: _command_names -e:*(\;|+)::program arguments: _normal' \
   '*-follow' \
   '*-fstype:file system type:_file_systems' \
   '*-group:group:_groups' \
@@ -147,7 +153,7 @@ _arguments -C $args \
   '*-user:user:_users' \
   '*-xdev' \
   '*-a' '*-o' \
-  '(-D -E -H -L -O -P -f -s -x --help --version)*:directory:_files -/' \
+  '(-D -E -H -L -O -P -f -s -x --files0-from --help --version)*:directory:_files -/' \
 && ret=0
 
 if [[ $state = times ]]; then
@@ -156,11 +162,11 @@ if [[ $state = times ]]; then
     if zstyle -t ":completion:${curcontext}:senses" verbose; then
       zstyle -s ":completion:${curcontext}:senses" list-separator sep || sep=--
       default=" [default exactly]"
-      disp=( "- $sep before" "+ $sep since" )
+      disp=( "+ $sep before (older files)" "- $sep since (newer files)" )
       smatch=( - + )
     else
       disp=( before exactly since )
-      smatch=( - '' + )
+      smatch=( + '' - )
     fi
     alts=( "senses:sense${default}:compadd -V times -S '' -d disp -a smatch" )
   fi
diff --git a/Completion/Unix/Command/_flac b/Completion/Unix/Command/_flac
index 82b6f0160..1773061ee 100644
--- a/Completion/Unix/Command/_flac
+++ b/Completion/Unix/Command/_flac
@@ -85,6 +85,7 @@ case $service in
       '(-p --qlp-coeff-precision-search -q --qlp-coeff-precision)'{-p,--qlp-coeff-precision-search}'[exhaustively search LP coeff quantization]' \
       '(-p --qlp-coeff-precision-search -q --qlp-coeff-precision)'{-q,--qlp-coeff-precision=}'[specify precision]:precision (bits)' \
       '(-r --rice-partition-order)'{-r,--rice-partition-order=}'[set min/max residual partition order]:order' \
+      "--limit-min-bitrate[don't allow frames consisting of only constant subframes]" \
       '--endian=:byte order:(big little)' \
       '--channels=:channels' \
       '--bps=:bits per sample' \
diff --git a/Completion/Unix/Command/_gcc b/Completion/Unix/Command/_gcc
index b6f1da2c6..8690c5599 100644
--- a/Completion/Unix/Command/_gcc
+++ b/Completion/Unix/Command/_gcc
@@ -957,10 +957,10 @@ if [[ "$service" = clang* ]]; then
     '-fveclib=[use the given vector functions library]:arg'
     '-fvectorize[enable the loop vectorization passes]'
     '-fvirtual-function-elimination[enables dead virtual function elimination optimization]'
-    '-fvisibility-dllexport=[the visibility for dllexport defintions]:arg'
+    '-fvisibility-dllexport=[the visibility for dllexport definitions]:arg'
     '-fvisibility-externs-dllimport=[the visibility for dllimport external declarations]:arg'
     '-fvisibility-externs-nodllstorageclass=[the visibility for external declarations without an explicit DLL dllstorageclass]:arg'
-    '-fvisibility-from-dllstorageclass[set the visiblity of symbols in the generated code from their DLL storage class]'
+    '-fvisibility-from-dllstorageclass[set the visibility of symbols in the generated code from their DLL storage class]'
     '-fvisibility-global-new-delete-hidden[give global C++ operator new and delete declarations hidden visibility]'
     '-fvisibility-inlines-hidden[give inline C++ member functions hidden visibility by default]'
     '-fvisibility-inlines-hidden-static-local-var[visibility inlines hidden static local var]'
@@ -1318,11 +1318,13 @@ fi
 
 local -a sanitizers
 sanitizers=(
-  address alignment bool bounds enum float-cast-overflow float-divide-by-zero
-  integer-divide-by-zero memory nonnull-attribute null nullability-arg
-  nullability-assign nullability-return object-size pointer-overflow return
-  unsigned-integer-overflow returns-nonnull-attribute shift signed-integer-overflow
-  unreachable vla-bound vptr
+  address alignment bool bounds bounds-strict enum builtin float-cast-overflow
+  float-divide-by-zero hwaddress integer-divide-by-zero kernel-address
+  kernel-hwaddress leak memory nonnull-attribute null nullability-arg nullability-assign
+  nullability-return object-size pointer-compare pointer-overflow pointer-subtract return
+  returns-nonnull-attribute shadow-call-stack shift shift-base shift-exponent
+  signed-integer-overflow thread undefined unsigned-integer-overflow unreachable
+  vla-bound vptr
 )
 
 local -a languages
@@ -1892,7 +1894,7 @@ args+=(
   '-freschedule-modulo-scheduled-loops[enable/disable the traditional scheduling in loops that already passed modulo scheduling]'
   '-frounding-math[disable optimizations that assume default FP rounding behavior]'
   '-frtti[generate run time type descriptor information]'
-  "-fsanitize=-[enable AddressSanitizer, a memory error detector]:style:($sanitizers)"
+  "*-fsanitize=-[enable AddressSanitizer, a memory error detector]:style:->sanitize"
   '-fsched2-use-superblocks[if scheduling post reload, do superblock scheduling]'
   '-fsched-critical-path-heuristic[enable the critical path heuristic in the scheduler]'
   '-fsched-dep-count-heuristic[enable the dependent count heuristic in the scheduler]'
@@ -2282,6 +2284,9 @@ archgeneric)
   arch+=(generic)
   _wanted cputypes expl "CPU type" compadd -a arch && ret=0
   ;;
+sanitize)
+  _values -s , 'sanitizer' $sanitizers
+  ;;
 esac
 
 return ret
diff --git a/Completion/Unix/Command/_gcore b/Completion/Unix/Command/_gcore
index a31a81267..ef3afd919 100644
--- a/Completion/Unix/Command/_gcore
+++ b/Completion/Unix/Command/_gcore
@@ -46,6 +46,7 @@ case $OSTYPE in
     _arguments -s \
       '-c+[write core file to specified file]:file:_files' \
       '-f[dump all available segments]' \
+      '-k[use the ptrace(2) PT_COREDUMP kernel facility to write the core dump]' \
       '::executable:' \
       ':pid:_pids'
   ;;
diff --git a/Completion/Unix/Command/_gem b/Completion/Unix/Command/_gem
index 7e244ccad..c5a64cdf1 100644
--- a/Completion/Unix/Command/_gem
+++ b/Completion/Unix/Command/_gem
@@ -20,6 +20,7 @@ lropts=( $proxy
 _arguments -C -s \
   '(* -)'{-h,--help}'[display usage information]' \
   '(* -)'{-v,--version}'[display version information]' \
+  '-C[change directory first]:directory:_directories' \
   '*::command:->command' && ret=0
 
 if [[ $state = command ]]; then
@@ -27,7 +28,7 @@ if [[ $state = command ]]; then
     cmd=subcommands
   else
     cmds=(
-      build cert check cleanup contents dependency environment fetch
+      build cert check cleanup contents dependency environment exec fetch
       generate_index help install info list lock mirror open outdated owner
       pristine push query rdoc search server signin signout sources
       specification stale uninstall unpack update which yank
@@ -56,6 +57,11 @@ if [[ $state = command ]]; then
     check|cleanup|contents|dependency|list|open|pristine|rdoc|uninstall|unpack|update)
       args+=( '(--all --skip)*:installed gem:->gems-local' )
     ;|
+    install)
+      (( ${(M)#line:#[^-]*} > 1 )) && args+=(
+        '(*)--[specify build options]:*:build option:_default'
+      )
+    ;|
     fetch|install|lock|owner|search|yank)
       args+=( '*:gem:->gems-remote' )
     ;|
@@ -82,13 +88,13 @@ if [[ $state = command ]]; then
         '!(-d --details)--no-details'
       )
     ;|
-    check|contents|dependency|fetch|install|list|open|pristine|query|rdoc|search|specification|uninstall|unpack|yank)
+    check|contents|dependency|exec|fetch|install|list|open|pristine|query|rdoc|search|specification|uninstall|unpack|yank)
       args+=( '(-v --version)'{-v,--version=}'[specify version of gem]:version' )
     ;|
-    dependency|fetch|install|outdated|specification|uninstall|update|yank)
+    build|dependency|fetch|install|outdated|specification|uninstall|update|yank)
       args+=( '--platform=[specify the platform of gem]:platform' )
     ;|
-    dependency|fetch|install|list|query|search|specification|update)
+    dependency|exec|fetch|install|list|query|search|specification|update)
       args+=( '--prerelease[include prerelease versions of a gem]' '!(--prerelease)--no-prerelease' )
     ;|
     install|unpack|update)
@@ -120,13 +126,13 @@ if [[ $state = command ]]; then
     ;|
     (un|)install|pristine|update)
       args+=(
+        '(-i --install-dir)'{-i,--install-dir=}'[specify gem repository directory to get installed gems]:directory:_directories'
         '(-n --bindir)'{-n,--bindir=}'[specify directory where binary files are located]:directory:_directories'
       )
     ;|
     (un|)install|update)
       args+=(
         '--ignore-dependencies[ignore dependency requirements]'
-        '(-i --install-dir)'{-i,--install-dir=}'[specify gem repository directory to get installed gems]:directory:_directories'
       )
     ;|
     owner|push)
@@ -161,6 +167,7 @@ if [[ $state = command ]]; then
         '(-b --build)'{-b,--build=}'[build private key and self-signed certificate for specified email address]:email address:_email_addresses -c'
         '(-C --certificate)'{-C,--certificate=}'[specify signing certificate for --sign]:certificate'
         '(-K --private-key)'{-K,--private-key=}'[specify key for --sign or --build]:key'
+        '(-A --key-algorithm)'{-A,--key-algorithm=}'[select which key algorithm to use for --build]:algorithm'
         '(-s --sign)'{-s,--sign=}'[sign specified certificate with the key from -K and the certificate from -C]:certificate'
         '(-d --days)'{-d,--days=}'[specify days before certificate expires]:days'
         '(-R --re-sign)'{-R,--re-sign}'[re-sign the certificate]'
@@ -176,7 +183,7 @@ if [[ $state = command ]]; then
     ;;
     cleanup)
       args+=(
-        '(-n -d --dryrun)'{-n,-d,--dryrun}"[don't uninstall gems]"
+        '(-n -d --dry-run)'{-n,-d,--dry-run}"[don't uninstall gems]"
         "--user-install[cleanup in user's home directory instead of GEM_HOME]"
       )
     ;;
@@ -196,11 +203,20 @@ if [[ $state = command ]]; then
       )
     ;;
     environment)
-      args+=( '1:information:(gemdir gempath version remotesources platform)' )
+      args+=( '1:information:(gemdir gempath home path user_gemhome version remotesources platform)' )
+    ;;
+    exec)
+      args+=(
+        '--conservative[prefer most recent installed version to the overall latest]'
+        '1:gem:->gems-remote'
+        '*: :_default'
+      )
     ;;
     fetch)
       def=( both \! local \! remote \! )
-      args+=( ${(e)lropts} )
+      args+=( ${(e)lropts}
+        "--no-suggestions[don't suggest alternates when gems are not found]"
+      )
     ;;
     generate_index)
       args+=(
@@ -227,13 +243,15 @@ if [[ $state = command ]]; then
       args+=(
         '(*)*--skip=[with --all, skip specified gem]:installed gem:->gems-local'
         "--no-extensions[don't restore gems with extensions in addition to regular gems]"
+        '--only-missing-extensions[only restore gems with missing extensions]'
         '--only-executables[only restore executables]'
+        '--only-plugins[only restore plugins]'
       )
     ;;
     push)
       args+=( '1:gem file:_files -g "*.gem(-.)"' )
     ;;
-    query)
+    query) # deprecated
       args+=(
         '(-n --name-matches)'{-n,--name-matches=}'[specify regex to match against gem names]:gem name (regex):->gems-local'
       )
@@ -261,6 +279,7 @@ if [[ $state = command ]]; then
         '(-r --remove)'{-r,--remove=}'[remove source]:source URI:_urls'
         '(-c --clear-all)'{-c,--clear-all}'[remove all sources (clear the cache)]'
         '(-u --update)'{-u,--update}'[update source cache]'
+        '(-f --force)'{-f,--force}"[don't show any confirmation prompts]"
       )
     ;;
     specification)
@@ -314,7 +333,7 @@ if [[ $state = command ]]; then
     '--norc[avoid loading any .gemrc file]' && ret=0
 
   if [[ $state == gems* ]]; then
-    filter=( ${${opt_args[(I)-([lbr]|-local|-remote|-both)]}:-${${(M)state:#*-*}/gems-/--}} )
+    filter=( ${${opt_args[(I)-([lbr]|-conservative|-local|-remote|-both)]/conservative/local}:-${${(M)state:#*-*}/gems-/--}} )
     _description gems expl gem
     compadd "$expl[@]" ${${(f)"$(_call_program gems gem list $filter -q --no-versions)"}%% *} && ret=0
   fi
diff --git a/Completion/Unix/Command/_getent b/Completion/Unix/Command/_getent
index b96852db3..5604e526e 100644
--- a/Completion/Unix/Command/_getent
+++ b/Completion/Unix/Command/_getent
@@ -8,6 +8,7 @@ typeset -A opt_args
 if _pick_variant -r is_gnu gnu='(Free Soft|GNU|GLIBC|Gentoo)' unix --version; then
   args+=(
     '(- 1 *)'{-\?,--help}'[display help information]'
+    '(-A --no-addrconfig)'{-A,--no-addrconfig}"[don't filter out unsupported IPv4/IPv6 addresses (with ahosts*)]"
     '(- 1 *)--usage[display a short usage message]'
     '(- 1 *)'{-V,--version}'[display version information]'
     '*'{-s+,--service=}'[specify service configuration to use]: :->services'
@@ -23,7 +24,7 @@ case $state in
   services)
     # @todo GNU getent supports both `-s svc` and `-s db:svc`; we only complete
     # the former here
-    services=( {,/usr}/lib/{,*-linux-gnu/}libnss_*(N-.:fr:t:s/libnss_//) )
+    services=( {,/usr}/lib{,64}/{,*-linux-gnu/}libnss_*(N-.:fr:t:s/libnss_//) )
     _wanted services expl 'service or database:service' \
       compadd ${(u)services%-*} \
     && ret=0
diff --git a/Completion/Unix/Command/_getopt b/Completion/Unix/Command/_getopt
index 3359818b5..a8b0f6fc9 100644
--- a/Completion/Unix/Command/_getopt
+++ b/Completion/Unix/Command/_getopt
@@ -2,9 +2,10 @@
 
 local -a args aopts
 
-# Note: BusyBox getopt is borrowed straight from util-linux, so they're
-# basically identical
-if _pick_variant busybox=BusyBox util-linux='getopt*enhanced' unix --version; then
+# @todo BusyBox getopt is borrowed straight from util-linux, so they're nearly
+# identical, but not quite: BusyBox doesn't have -h and -V and often doesn't
+# support long options. So possibly this could be more accurate
+if _pick_variant busybox=BusyBox util-linux='(enhanced|util-linux)' unix --version; then
   args=(
     '(-a --alternative)'{-a,--alternative}'[allow long options with single -]'
     '(: -)'{-h,--help}'[display help information]'
diff --git a/Completion/Unix/Command/_git b/Completion/Unix/Command/_git
index 7c7fb22bc..7370aaead 100644
--- a/Completion/Unix/Command/_git
+++ b/Completion/Unix/Command/_git
@@ -68,22 +68,29 @@ _git-add () {
     '--refresh[do not add files, but refresh their stat() info in index]' \
     '--ignore-errors[continue adding if an error occurs]' \
     $ignore_missing \
-    '--chmod[override the executable bit of the listed files]:override:(-x +x)' \
+    '--sparse[allow updating entries outside of sparse-checkout cone]' \
+    '--chmod=[override the executable bit of the listed files]:override:(-x +x)' \
+    '(*)--pathspec-from-file=[read pathspec from file]:file:_files' \
+    '(*)--pathspec-file-nul[pathspec elements are separated with NUL character]' \
     '*:: :->file' && return
 
   case $state in
     (file)
-      declare -a ignored_files_alternatives
+      declare -a file_alternatives
+      if [[ -z ${opt_args[(I)-u|--update]} ]]; then
+        file_alternatives=(
+          'other-files::__git_ignore_line_inside_arguments __git_other_files'
+        )
+      fi
       if [[ -n ${opt_args[(I)-f|--force]} ]]; then
-        ignored_files_alternatives=(
+        file_alternatives+=(
           'ignored-modified-files:ignored modified file:__git_ignore_line_inside_arguments __git_modified_files --ignored'
           'ignored-other-files:ignored other file:__git_ignore_line_inside_arguments __git_other_files --ignored')
       fi
 
       _alternative \
         'modified-files::__git_ignore_line_inside_arguments __git_modified_files' \
-        'other-files::__git_ignore_line_inside_arguments __git_other_files' \
-        $ignored_files_alternatives && ret=0
+        $file_alternatives && ret=0
       ;;
   esac
 
@@ -97,11 +104,8 @@ _git-am () {
 
   # NOTE: --rebasing and --resolvemsg are only for internal use between git
   # rebase and git am.
-  # TODO: --patch-format is undocumented.
-  # TODO: --rerere-autoupdate and --no-rerere-autoupdate are
-  # undocumented (and not implemented here).
   _arguments -s -S $endopt \
-    '(-s --signoff)'{-s,--signoff}'[add Signed-off-by: line to the commit message]' \
+    '(-s --signoff)'{-s,--signoff}'[add Signed-off-by: trailer to the commit message]' \
     '(-S --gpg-sign --no-gpg-sign)'{-S-,--gpg-sign=-}'[GPG-sign the commit]::key id' \
     "(-S --gpg-sign --no-gpg-sign)--no-gpg-sign[don't GPG-sign the commit]" \
     '(-k --keep)'{-k,--keep}'[pass -k to git mailinfo]' \
@@ -111,14 +115,18 @@ _git-am () {
     '(--keep-cr             )--no-keep-cr[do not pass --keep-cr to git mailsplit]' \
     '(-c --scissors --no-scissors)'{-c,--scissors}'[strip everything before a scissors line]' \
     '(-c --scissors --no-scissors)--no-scissors[ignore scissors lines]' \
+    '--quoted-cr=[specify action when quoted CR is found]:action [warn]:(nowarn warn strip)' \
     '(-q --quiet)'{-q,--quiet}'[only print error messages]' \
     '(-u --utf8 --no-utf8)'{-u,--utf8}'[pass -u to git mailinfo]' \
     '(-u --utf8 --no-utf8)--no-utf8[pass -n to git mailinfo]' \
     '(-3 --3way)'{-3,--3way}'[use 3-way merge if patch does not apply cleanly]' \
     $apply_options \
     '--quit[abort the patching operation but keep HEAD where it is]' \
-    '--show-current-patch[show the patch being applied]' \
+    '--show-current-patch=-[show the message being applied]::show [raw]:(diff raw)' \
+    '(--empty)--allow-empty[record the empty patch as an empty commit]' \
+    '(--allow-empty)--empty=[select hanndling of empty patches]:handling:(stop drop keep)' \
     '(-i --interactive)'{-i,--interactive}'[apply patches interactively]' \
+    '(-n --no-verify)'{-n,--no-verify}'[bypass pre-applypatch and applypatch-msg hooks]' \
     '--committer-date-is-author-date[use author date as committer date]' \
     '--ignore-date[use committer date as author date]' \
     '--skip[skip the current patch]' \
@@ -159,7 +167,10 @@ _git-archive () {
     '--format=-[format of the resulting archive]:archive format:__git_archive_formats' \
     '(- :)'{-l,--list}'[list available archive formats]' \
     '(-v --verbose)'{-v,--verbose}'[report progress to stderr]' \
+    '--mtime=[set modification time of archive entries]:mtime' \
     '--prefix=-[prepend the given path prefix to each filename]:path prefix:_directories -r ""' \
+    '--add-file=[add untracked file to archive]:file:_files' \
+    '--add-virtual-file=[add untracked file to archive]:path:_files' \
     '(-o --output)'{-o+,--output=}'[write archive to specified file]:archive:_files' \
     '--worktree-attributes[look for attributes in .gitattributes in working directory too]' \
     $backend_args \
@@ -179,8 +190,6 @@ _git-archive () {
 
 (( $+functions[_git-bisect] )) ||
 _git-bisect () {
-  # TODO: next subcommand is undocumented.  Git-bisect.sh mentions that the
-  # subcommand might be removed from the UI level.
   local curcontext=$curcontext state line ret=1
   declare -A opt_args
   local good bad
@@ -226,6 +235,7 @@ _git-bisect () {
 	    --term-{good,old}'=[specify alternate term for good revisions]:term' \
 	    --term-{bad,new}'=[specify alternate term for bad revisions]:term' \
 	    '--no-checkout[set BISECT_HEAD reference instead of doing checkout at each iteration]' \
+            '--first-parent[follow only the first parent commit upon seeing a merge commit]' \
             ':bad revision:__git_commits' \
             '*: :->revision-or-path' && ret=0
           case $state in
@@ -323,12 +333,13 @@ _git-branch () {
     "($c $m     -a)"{-r,--remotes}'[list or delete only remote-tracking branches]' \
     "($c $m $d : -r --remotes)-a[list both remote-tracking branches and local branches]" \
     "($c $m $d : -v -vv --verbose)"{-v,-vv,--verbose}'[show SHA1 and commit subject line for each head]' \
-    "($c $m $d :)--abbrev=[set minimum SHA1 display-length]: :__git_guard_number length" \
+    "($c $m $d :)--abbrev=[use specified digits to display object names]:digits" \
     "($c $m $d :)--no-abbrev[don't abbreviate sha1s]" \
     "(- :)--show-current[show current branch name]" \
     "($l $m $d)--create-reflog[create the branch's reflog]" \
     "($l $m $d -f --force)"{-f,--force}'[force the creation of a new branch]' \
-    "($l $m $d -t --track)"{-t,--track}'[setup configuration so that pull merges from the start point]' \
+    "($l $m $d --track)-t[setup configuration so that pull merges from the start point]" \
+    "($l $m $d -t)--track=-[setup configuration so that pull merges from the start point]::upstream tracking:(direct inherit)" \
     "($l $m $d)--no-track[override the branch.autosetupmerge configuration variable]" \
     "($l $m $d -u --set-upstream --set-upstream-to --unset-upstream)"{-u+,--set-upstream-to=}'[set up configuration so that pull merges]:remote branch:__git_remote_branch_names' \
     "($l $m $d -u --set-upstream --set-upstream-to --unset-upstream)--unset-upstream[remove upstream configuration]" \
@@ -340,6 +351,7 @@ _git-branch () {
     $dependent_creation_args \
     "($l $c $d $m)"{-m,--move}"[rename a branch and the corresponding reflog]" \
     "($l $c $d $m)-M[rename a branch even if the new branch-name already exists]" \
+    "--omit-empty[don't output a newline after empty formatted refs]" \
     "($l $c $d $m)"{-c,--copy}"[copy a branch and the corresponding reflog]" \
     "($l $c $d $m)-C[copy a branch even if the new branch-name already exists]" \
     $dependent_modification_args \
@@ -349,6 +361,7 @@ _git-branch () {
     '*--sort=[specify field to sort on]: :__git_ref_sort_keys' \
     '--points-at=[only list tags of the given object]: :__git_commits' \
     "($c $m $d -i --ignore-case)"{-i,--ignore-case}'[sorting and filtering are case-insensitive]' \
+    "($l $m $d)--recurse-submodules[recurse through submodules]" \
     $dependent_deletion_args
 }
 
@@ -380,10 +393,14 @@ _git-bundle () {
         (create)
           if (( CURRENT == 2 )); then
             _arguments \
+              '(-q --quiet)'{-q,--quiet}"[don't show progress]" \
+              '--progress[show progress meter]' \
+              \!--all-progress{,-implied} \
+              '--version=[specify bundle format version]:version:(2 3)' \
               ':bundle:_files' && ret=0
           else
             local revision_options
-            __git_setup_revision_options
+            __git_setup_revision_options -d
 
             _arguments -S -s \
               $revision_options \
@@ -393,13 +410,20 @@ _git-bundle () {
           ;;
         (verify)
           _arguments \
+            '(-q --quiet)'{-q,--quiet}"[don't show bundle details]" \
             ':bundle:_files' && ret=0
           ;;
-        (list-heads|unbundle)
+        (list-heads)
           _arguments \
             ':bundle:_files' \
             '*: :__git_references' && ret=0
-          ;;
+        ;;
+        (unbundle)
+          _arguments \
+            '--progress[show progress meter]' \
+            ':bundle:_files' \
+            '*: :__git_references' && ret=0
+        ;;
       esac
       ;;
   esac
@@ -451,13 +475,14 @@ _git-checkout () {
     '(-q --quiet -2 --ours -3 --theirs --patch)'{-3,--theirs}'[check out stage #3 for unmerged paths]' \
     '(   -B --orphan -2 --ours -3 --theirs --conflict --patch -d --detach)-b+[create a new branch based at given commit]: :__git_branch_names' \
     '(-b    --orphan -2 --ours -3 --theirs --conflict --patch -d --detach)-B+[create or update branch based at given commit]: :__git_branch_names' \
-    '(-t --track --orphan --patch -d --detach)'{-t,--track}'[set up configuration so pull merges from the base commit]' \
+    '(--track --no-track --orphan --patch -d --detach)-t[set upstream info for new branch]' \
+    '(-t --no-track --orphan --patch -d --detach)--track=-[set upstream info for new branch]::configuration:(direct inherit)' \
     '(--patch)--no-track[override the branch.autosetupmerge configuration variable]' \
     $new_branch_reflog_opt \
     '(-b -B -t --track --patch --orphan -d --detach)'{-d,--detach}'[detach the HEAD at named commit]' \
     '(-b -B -t --track --patch -d --detach)--orphan=[create a new orphan branch based at given commit]: :__git_branch_names' \
     '(-q --quiet -f --force -m --merge --conflict --patch)'{-m,--merge}'[3way merge current branch, working tree and new branch]' \
-    '(-q --quiet -f --force -m --merge --patch)--conflict=[same as --merge, using given merge style]:style:(merge diff3)' \
+    '(-q --quiet -f --force -m --merge --patch)--conflict=[same as --merge, using given merge style]:style:(merge diff3 zdiff3)' \
     '(-)'{-p,--patch}'[interactively select hunks in diff between given tree-ish and working tree]' \
     "--ignore-skip-worktree-bits[don't limit pathspecs to sparse entries only]" \
     "--no-guess[don't second guess 'git checkout <no-such-branch>']" '!(--no-guess)--guess' \
@@ -466,6 +491,8 @@ _git-checkout () {
     '--no-overlay[remove files from index or working tree that are not in the tree-ish]' \
     '(-q --quiet --progress)--no-progress[suppress progress reporting]' \
     '--progress[force progress reporting]' \
+    '(*)--pathspec-from-file=[read pathspec from file]:file:_files' \
+    '(*)--pathspec-file-nul[pathspec elements are separated with NUL character]' \
     '(-)--[start file arguments]' \
     '*:: :->branch-or-tree-ish-or-file' && ret=0
 
@@ -514,10 +541,7 @@ _git-cherry-pick () {
   local -a git_commit_opts
   git_commit_opts=(--all --not HEAD --not)
   _arguments \
-    '(- :)--quit[end revert or cherry-pick sequence]' \
-    '(- :)--continue[resume revert or cherry-pick sequence]' \
-    '(- :)--skip[skip current commit and continue]' \
-    '(- :)--abort[cancel revert or cherry-pick sequence]' \
+    - init \
     '--cleanup=[specify how to strip spaces and #comments from message]:mode:_git_cleanup_modes' \
     '--allow-empty[preserve initially empty commits]' \
     '--allow-empty-message[allow replaying a commit with an empty message]' \
@@ -525,15 +549,21 @@ _git-cherry-pick () {
     '(-e --edit --ff)'{-e,--edit}'[edit commit before committing the cherry-pick]' \
     '(--ff)-x[append information about what commit was cherry-picked]' \
     '(-m --mainline)'{-m+,--mainline=}'[specify mainline when cherry-picking a merge commit]:parent number' \
-    '--rerere-autoupdate[update index with reused conflict resolution if possible]' \
+    '(--no-rerere-autoupdate)--rerere-autoupdate[update index with reused conflict resolution if possible]' \
+    '(--rerere-autoupdate)--no-rerere-autoupdate' \
     '(-n --no-commit --ff)'{-n,--no-commit}'[do not make the actual commit]' \
-    '(-s --signoff --ff)'{-s,--signoff}'[add Signed-off-by line at the end of the commit message]' \
+    '(-s --signoff --ff)'{-s,--signoff}'[add Signed-off-by trailer at the end of the commit message]' \
     '(-S --gpg-sign --no-gpg-sign)'{-S-,--gpg-sign=-}'[GPG-sign the commit]::key id' \
     "(-S --gpg-sign --no-gpg-sign)--no-gpg-sign[don't GPG-sign the commit]" \
-    '*'{-s+,--strategy=}'[use given merge strategy]:merge strategy:__git_merge_strategies' \
-    '*'{-X+,--strategy-option=}'[pass merge-strategy-specific option to merge strategy]:option' \
+    '*--strategy=[use given merge strategy]:merge strategy:__git_merge_strategies' \
+    '*'{-X+,--strategy-option=}'[pass merge-strategy-specific option to merge strategy]: :_git_strategy_options' \
     '(-e --edit -x -n --no-commit -s --signoff)--ff[fast forward, if possible]' \
-    '*: : __git_commit_ranges -O expl:git_commit_opts'
+    '*: : __git_commit_ranges -O expl:git_commit_opts' \
+    - '(sequencer)' \
+    '--quit[end revert or cherry-pick sequence]' \
+    '--continue[resume revert or cherry-pick sequence]' \
+    '--skip[skip current commit and continue]' \
+    '--abort[cancel revert or cherry-pick sequence]' \
 }
 
 (( $+functions[_git-citool] )) ||
@@ -548,7 +578,7 @@ _git-clean () {
 
   _arguments -C -S -s $endopt \
     '-d[also remove untracked directories]' \
-    '(-f --force)'{-f,--force}'[required when clean.requireForce is true (default)]' \
+    \*{-f,--force}'[required by default; twice, removes untracked nested repositories]' \
     '(-i --interactive)'{-i,--interactive}'[show what would be done and clean files interactively]' \
     '(-n --dry-run)'{-n,--dry-run}'[only show what would and what would not be removed]' \
     '(-q --quiet)'{-q,--quiet}"[don't print names of files removed]" \
@@ -618,6 +648,7 @@ _git-clone () {
     '(-q --quiet)'{-q,--quiet}'[operate quietly]' \
     '(-v --verbose)'{-v,--verbose}'[always display the progressbar]' \
     '--progress[output progress even if stderr is not a terminal]' \
+    "--reject-shallow[don't clone shallow repository]" \
     '(-n --no-checkout)'{-n,--no-checkout}'[do not checkout HEAD after clone is complete]' \
     '(-o --origin)--bare[make a bare GIT repository]' \
     '(--bare)--mirror[clone refs into refs/* instead of refs/remotes/origin/*]' \
@@ -626,22 +657,24 @@ _git-clone () {
     '(-u --upload-pack)'{-u+,--upload-pack=}'[specify path to git-upload-pack on remote side]:remote path' \
     '--template=[directory to use as a template for the object database]: :_directories' \
     '*'{-c,--config}'[<key>=<value> set a configuration variable in the newly created repository]' \
-    '--depth[create a shallow clone, given number of revisions deep]: :__git_guard_number depth' \
-    '--shallow-since=[shallow clone since a specific time]:time' \
-    '*--shallow-exclude=[shallow clone excluding commits reachable from specified remote revision]:revision' \
+    '(--bundle-uri)--depth[create a shallow clone, given number of revisions deep]: :__git_guard_number depth' \
+    '(--bundle-uri)--shallow-since=[shallow clone since a specific time]:time' \
+    '(--bundle-uri)*--shallow-exclude=[shallow clone excluding commits reachable from specified remote revision]:revision' \
     '(--no-single-branch)--single-branch[clone only history leading up to the main branch or the one specified by -b]' \
     '(--single-branch)--no-single-branch[clone history leading up to each branch]' \
     "--no-tags[don't clone any tags and make later fetches not follow them]" \
     '--shallow-submodules[any cloned submodules will be shallow]' \
     '--recursive[initialize all contained submodules]' \
-    '--recurse-submodules=-[initialize submodules in the clone]::file:__git_files' \
+    '(--recursive --recurse-submodules)'{--recursive,--recurse-submodules}'=-[initialize submodules in the clone]::file:__git_files' \
     '--separate-git-dir[place .git dir outside worktree]:path to .git dir:_path_files -/' \
     \*--server-option='[send specified string to the server when using protocol version 2]:option' \
     '(-4 --ipv4 -6 --ipv6)'{-4,--ipv4}'[use IPv4 addresses only]' \
     '(-4 --ipv4 -6 --ipv6)'{-6,--ipv6}'[use IPv6 addresses only]' \
     '--filter=[object filtering]:filter:_git_rev-list_filters' \
+    '--also-filter-submodules[apply partial clone filters to submodules]' \
     '--remote-submodules[any cloned submodules will use their remote-tracking branch]' \
     '--sparse[initialize the sparse-checkout file to start with only the top-level files]' \
+    '(--depth --shallow-since --shallow-exclude)--bundle-uri=[before fetching, get a bundle from specified location]:uri:_urls' \
     ': :->repository' \
     ': :_directories' && ret=0
 
@@ -685,7 +718,7 @@ _git-commit () {
   # TODO: --interactive isn't explicitly listed in the documentation.
   _arguments -S -s $endopt \
     '(-a --all --interactive -o --only -i --include *)'{-a,--all}'[stage all modified and deleted paths]' \
-    '--fixup=[construct a commit message for use with rebase --autosquash]:commit to be amended:__git_recent_commits' \
+    '--fixup=[construct a commit message for use with rebase --autosquash]:commit to be amended:_git_fixup' \
     '--squash=[construct a commit message for use with rebase --autosquash]:commit to be amended:__git_recent_commits' \
     $reset_author_opt \
     '(        --porcelain --dry-run)--short[dry run with short output format]' \
@@ -694,10 +727,11 @@ _git-commit () {
     "--no-ahead-behind[don't display detailed ahead/behind counts relative to upstream branch]" \
     '(--short             --dry-run)--porcelain[dry run with machine-readable output format]' \
     '(--short --porcelain --dry-run -z --null)'{-z,--null}'[dry run with NULL-separated output format]' \
-    {-p,--patch}'[use the interactive patch selection interface to chose which changes to commit]' \
+    {-p,--patch}'[use the interactive patch selection interface to choose which changes to commit]' \
     '(--reset-author)--author[override the author name used in the commit]:author name' \
     '--date=[override the author date used in the commit]:date' \
-    '(-s --signoff)'{-s,--signoff}'[add Signed-off-by line at the end of the commit message]' \
+    '*--trailer=[add custom trailer(s)]:trailer:__git_trailers_tokens' \
+    '(-s --signoff)'{-s,--signoff}'[add Signed-off-by trailer at the end of the commit message]' \
     '(-n --no-verify)'{-n,--no-verify}'[bypass pre-commit and commit-msg hooks]' \
     '--allow-empty[allow recording an empty commit]' \
     '--allow-empty-message[allow recording a commit with an empty message]' \
@@ -705,11 +739,13 @@ _git-commit () {
     '(-e --edit --no-edit)'{-e,--edit}'[edit the commit message before committing]' \
     '(-e --edit --no-edit)--no-edit[do not edit the commit message before committing]' \
     '--no-post-rewrite[bypass the post-rewrite hook]' \
-    '(-a --all --interactive -o --only -i --include)'{-i,--include}'[update the given files and commit the whole index]' \
-    '(-a --all --interactive -o --only -i --include)'{-o,--only}'[commit only the given files]' \
+    '(-a --all --interactive -o --only)*'{-i,--include}'[update the given files and commit the whole index]' \
+    '(-a --all --interactive -i --include)*'{-o,--only}'[commit only the given files]' \
     '(-u --untracked-files)'{-u-,--untracked-files=-}'[show files in untracked directories]::mode:((no\:"show no untracked files"
                                                                                                   normal\:"show untracked files and directories"
                                                                                                   all\:"show individual files in untracked directories"))' \
+    '(*)--pathspec-from-file=[read pathspec from file]:file:_files' \
+    '(*)--pathspec-file-nul[pathspec elements are separated with NUL character]' \
     '(-q --quiet -v --verbose)'{-v,--verbose}'[show unified diff of all file changes]' \
     '(-q --quiet -v --verbose)'{-q,--quiet}'[suppress commit summary message]' \
     '--dry-run[only show list of paths that are to be committed or not, and any untracked]' \
@@ -724,7 +760,7 @@ _git-commit () {
       {-C+,--reuse-message=}'[use existing commit object with same log message]: :__git_commits' \
       {-c+,--reedit-message=}'[use existing commit object and edit log message]: :__git_commits' \
       {-F+,--file=}'[read commit message from given file]: :_files' \
-      {-m+,--message=}'[use the given message as the commit message]:message' \
+      \*{-m+,--message=}'[use the given message as the commit message]:message' \
       {-t+,--template=}'[use file as a template commit message]:template:_files'
 }
 
@@ -736,7 +772,7 @@ _git-describe () {
     '--all[use any ref found in "$GIT_DIR/refs/"]' \
     '--tags[use any ref found in "$GIT_DIR/refs/tags"]' \
     '(--tags)--contains[find the tag after the commit instead of before]' \
-    '--abbrev=[set minimum SHA1 display-length]: :__git_guard_number length' \
+    '--abbrev=[use specified digits to display object names]:digits' \
     '(             --exact-match)--candidates=[consider up to given number of candidates]: :__git_guard_number "number of candidates"' \
     '(--candidates              )--exact-match[only output exact matches, same as --candidates=0]' \
     '--debug[display information about the searching strategy]' \
@@ -760,6 +796,7 @@ _git-diff () {
   _arguments -C -s $endopt \
     $* \
     $diff_options \
+    '--exit-code[report exit code 1 if differences, 0 otherwise]' \
     '(--exit-code)--quiet[disable all output]' \
     $diff_stage_options \
     '(--cached --staged)--no-index[show diff between two paths on the filesystem]' \
@@ -789,18 +826,6 @@ _git-diff () {
 
       # Otherwise, more complex conditions need to be checked.
       case $CURRENT in
-        (1)
-          local files_alt='files::__git_changed-in-working-tree_files'
-          if [[ -n ${opt_args[(I)--cached|--staged]} ]]; then
-            files_alt='files::__git_changed-in-index_files'
-          fi
-
-          _alternative \
-            'commit-ranges::__git_commit_ranges' \
-            'blobs-and-trees-in-treeish::__git_blobs_and_trees_in_treeish' \
-            $files_alt \
-            'blobs::__git_blobs ' && ret=0
-          ;;
         (2)
           # Check if first argument is something special. In case of committish ranges and committishs offer a full list compatible completions.
           if __git_is_committish_range $line[1]; then
@@ -822,10 +847,19 @@ _git-diff () {
           elif [[ -n ${opt_args[(I)--cached|--staged]} ]]; then
             # Example: git diff --cached file1 <tab>
             __git_changed-in-index_files && ret=0
-          else
-            # Example: git diff file1 <tab>
-            __git_changed-in-working-tree_files && ret=0
           fi
+          ;&
+        (1)
+          local files_alt='files::__git_changed-in-working-tree_files'
+          if [[ -n ${opt_args[(I)--cached|--staged]} ]]; then
+            files_alt='files::__git_changed-in-index_files'
+          fi
+
+          _alternative \
+            'commit-ranges::__git_commit_ranges' \
+            'blobs-and-trees-in-treeish::__git_blobs_and_trees_in_treeish' \
+            $files_alt \
+            'blobs::__git_blobs ' && ret=0
           ;;
         (*)
           if __git_is_committish_range $line[1]; then
@@ -870,16 +904,18 @@ _git-fetch () {
 
   _arguments -C -S -s $endopt \
     $fetch_options \
-    '--shallow-since=[deepen history of shallow repository based on time]:time' \
-    '*--shallow-exclude=[deepen history of shallow clone by excluding revision]:revision' \
-    '--deepen[deepen history of shallow clone]:number of commits' \
-    '(-n --no-tags -t --tags)'{-n,--no-tags}'[disable automatic tag following]' \
+    '--atomic[use atomic transaction to update references]' \
     '(--all -m --multiple)'{-m,--multiple}'[fetch from multiple remotes]' \
+    '(-n --no-tags -t --tags)'{-n,--no-tags}'[disable automatic tag following]' \
+    '--prefetch[modify the refspec to place all refs within refs/prefetch/]' \
+    '--refetch[fetch all objects as a fresh clone would]' \
     '(-P --prune-tags)'{-P,--prune-tags}'[prune local tags no longer on remote and clobber changed tags]' \
-    \*{-o+,--server-option=}'[send specified string to the server when using protocol version 2]:option' \
-    '--negotiation-tip=[only report refs reachable from specified object to the server]:commit:__git_commits' \
+    '--write-fetch-head[write fetched references to the FETCH_HEAD file]' \
+    "--negotiate-only[don't fetch a packfile; instead, print ancestors of negotiation tips]" \
     '--filter=[object filtering]:filter:_git_rev-list_filters' \
-    "--auto-gc[run 'gc --auto' after fetching]" \
+    '(--auto-maintenance --auto-gc)'--auto-{maintenance,gc}"[run 'maintenance --auto' after fetching]" \
+    '--write-commit-graph[write the commit-graph after fetching]' \
+    '--stdin[accept refspecs from stdin]' \
     '*:: :->repository-or-group-or-refspec' && ret=0
 
   case $state in
@@ -919,7 +955,7 @@ _git-format-patch () {
     '--start-number=[start numbering patches at given number]: :__git_guard_number "patch number"' \
     '--numbered-files[use only number for file name]' \
     '(-n --numbered -N --no-numbered -k --keep-subject --rfc --subject-prefix)'{-k,--keep-subject}"[don't strip/add \[PATCH\] from the first line of the commit message]" \
-    '(-s --signoff)'{-s,--signoff}'[add Signed-off-by: line to the commit message]' \
+    '(-s --signoff)'{-s,--signoff}'[add Signed-off-by: trailer to the commit message]' \
     '(-o --output-directory)--stdout[output the generated mbox on standard output (implies --mbox)]' \
     '(         --no-attach --inline)--attach=-[create attachments instead of inlining patches]::boundary' \
     '(--attach             --inline)--no-attach[disable creation of attachments]' \
@@ -930,7 +966,9 @@ _git-format-patch () {
     '--in-reply-to=[make the first mail a reply to the given message]:message id' \
     '--ignore-if-in-upstream[do not include a patch that matches a commit in the given range]' \
     '(-v --reroll-count)'{-v+,--reroll-count=}'[mark the series as the <n>-th iteration of the topic]: :__git_guard_number iteration' \
+    '--filename-max-length=[specify max length of output filename]:length' \
     '(-k --keep-subject --subject-prefix)--rfc[use \[RFC PATCH\] instead of \[PATCH\]]' \
+    "--cover-from-description=[generate parts of a cover letter based on a branch's description]:mode:(message default subject auto none)" \
     '(-k --keep-subject --rfc)--subject-prefix=[use the given prefix instead of \[PATCH\]]:prefix' \
     '*--to=[add To: header to email headers]: :_email_addresses' \
     '*--cc=[add Cc: header to email headers]: :_email_addresses' \
@@ -950,6 +988,7 @@ _git-format-patch () {
     '--interdiff=[insert interdiff against previous patch series in cover letter or single patch]:reference to tip of previous series:__git_revisions' \
     '--range-diff=[insert range-diff against previous patch series in cover letter or single patch]:reference to tip ot previous series:__git_revisions' \
     '--creation-factor=[for range-diff, specify weighting for creation]:weighting (percent)' \
+    '--force-in-body-from[show in-body From: even if identical to the e-mail header]' \
     ': :->commit-or-commit-range' && ret=0
 
   case $state in
@@ -970,8 +1009,9 @@ _git-gc () {
   _arguments -S -s $endopt \
     '--aggressive[more aggressively optimize]' \
     '--auto[check whether housekeeping is required]' \
-    '(        --no-prune)--prune=-[prune loose objects older than given date]::date [2 weeks ago]:__git_datetimes' \
+    '(        --no-prune)--prune=-[prune loose objects older than given date]::date [2 weeks ago]:_git_approxidates' \
     '(--prune           )--no-prune[do not prune any loose objects]' \
+    '--cruft[pack unreferenced objects separately]' \
     '(-q --quiet)'{-q,--quiet}'[suppress progress reporting]' \
     '--keep-largest-pack[repack all other packs except the largest pack]' \
 }
@@ -1034,6 +1074,7 @@ _git-grep () {
     '--threads=[use specified number of threads]:number of threads' \
     '(-c --count -p --show-function)'{-p,--show-function}'[show preceding line containing function name of match]' \
     '(-c --count -W --function-context)'{-W,--function-context}'[show whole function where a match was found]' \
+    '(-m --max-count)'{-m+,--max-count=}'[specify maximum number of results per file]:results' \
     '(1)*-f+[read patterns from given file]:pattern file:_files' \
     '(1)*-e+[use the given pattern for matching]:pattern' \
     $pattern_operators \
@@ -1148,6 +1189,8 @@ _git-init () {
     '--template=[directory to use as a template for the object database]: :_directories' \
     '--shared=[share repository amongst several users]:: :__git_repository_permissions' \
     '--separate-git-dir=[create git dir elsewhere and link it using the gitdir mechanism]:: :_directories' \
+    '(-b --initial-branch)'{-b+,--initial-branch=}'[override the name of the initial branch]:branch name' \
+    '--object-format=[specify the hash algorithm to use]:algortithm:(sha1 sha256)' \
     ':: :_directories'
 }
 
@@ -1249,6 +1292,9 @@ _git-maintenance() {
             "--quiet[don't report progress or other information to stderr]" \
             '*--task=[run a specific task]:task:(gc commit-graph prefetch loose-objects incremental-repack pack-refs)' && ret=0
         ;;
+        (start)
+          _arguments \
+            '--scheduler=:scheduler:(auto crontab systemd-timer launchctl schtasks)'
       esac
     ;;
   esac
@@ -1266,6 +1312,7 @@ _git-merge () {
     $merge_options \
     \*{-m+,--message=}'[set the commit message to be used for the merge commit]:merge message' \
     \*{-F+,--file=}'[read commit message from a file]:file' \
+    '--into-name=[use specified name instead of the real target]:branch name:__git_branch_names' \
     '(--edit --no-edit)-e[open an editor to change the commit message]' \
     '(                    --no-rerere-autoupdate)--rerere-autoupdate[allow the rerere mechanism to update the index]' \
     '(--rerere-autoupdate                       )--no-rerere-autoupdate[do not allow the rerere mechanism to update the index]' \
@@ -1287,6 +1334,7 @@ _git-mv () {
     '(-f --force)'{-f,--force}'[rename/move even if targets exist]' \
     '-k[skip rename/move that would lead to errors]' \
     '(-n --dry-run)'{-n,--dry-run}'[only show what would happen]' \
+    '--sparse[allow updating entries outside of sparse-checkout cone]' \
     ':source:__git_cached_files' \
     '*:: :->source-or-destination' && ret=0
 
@@ -1304,6 +1352,7 @@ _git-mv () {
 (( $+functions[_git-notes] )) ||
 _git-notes () {
   local curcontext=$curcontext state line ret=1
+  local -a args
   declare -A opt_args
 
   _arguments -C $endopt \
@@ -1341,16 +1390,21 @@ _git-notes () {
         (add)
           # TODO: Only complete commits that don't have notes already, unless
           # -f or --force has been given.
-          _arguments -S -s $endopt \
+          args=( '(-f --force)'{-f,--force}'[overwrite existing note]' )
+        ;&
+        (append)
+          _arguments -S -s $endopt $args \
             '*'{-m+,--message=}'[use given note message]:message' \
             '*'{-F+,--file=}'[take note message from given file]:note message file:_files' \
             '(-C --reuse-message)'{-C+,--reuse-message=}'[take note message from given blob object]: :__git_blobs' \
             '(-c --reedit-message)'{-c+,--reedit-message=}'[take note message from given blob object and edit it]: :__git_blobs' \
-            '(-f --force)'{-f,--force}'[overwrite existing note]' \
+            '--allow-empty[allow storing empty note]' \
+            '(--no-separator)--separator=-[insert text between paragraphs]::paragraph break' \
+            '(--separator)--no-separator' \
+            '--stripspace[remove unnecessary whitespace]' \
             ': :__git_commits' && ret=0
           ;;
         (copy)
-          # TODO: --for-rewrite is undocumented.
           _arguments -S -s $endopt \
             '(-f --force)'{-f,--force}'[replace existing note]' \
             '(:)--stdin[read objects from stdin]' \
@@ -1378,14 +1432,6 @@ _git-notes () {
 	(remove)
 	  _arguments -S $endopt --ignore-missing --stdin ':object:__git_commits' && ret=0
 	  ;;
-        (append)
-          _arguments -S -s $endopt \
-            '*'{-m+,--message=}'[use given note message]:message' \
-            '*'{-F+,--file=}'[take note message from given file]:note message file:_files' \
-            '(-C --reuse-message)'{-C+,--reuse-message=}'[take note message from given blob object]: :__git_blobs' \
-            '(-c --reedit-message)'{-c+,--reedit-message=}'[take note message from given blob object and edit it]: :__git_blobs' \
-            ': :__git_commits' && ret=0
-          ;;
         (get-ref)
           _nothing
           ;;
@@ -1415,7 +1461,6 @@ _git-pull () {
       interactive\:"allow list of commits to be edited"
     ))' \
     '(-r --rebase            )--no-rebase[do not perform a rebase after fetching]' \
-    '--autostash[automatically stash/stash pop before and after rebase]' \
     $fetch_options \
     '(--no-tags -t --tags)--no-tags[disable automatic tag following]' \
     ': :__git_any_repositories' \
@@ -1435,18 +1480,27 @@ _git-push () {
   # only complete files on the local end, not the remote end.  Still, it may be
   # helpful to get some sort of completion going, perhaps modifying the path
   # later on to match the remote end.
+
+  local ref_arg
+  if (( words[(I)-d|--delete] )); then
+      ref_arg='*: :__git_remote_branch_names_noprefix'
+  else
+      ref_arg='*: :__git_ref_specs_pushy'
+  fi
+
   _arguments -S -s $endopt \
-    '--all[push all refs under refs/heads/]' \
+    '(* --all --branches --mirror --tags)'{--all,--branches}'[push all branches]' \
     '--prune[remove remote branches that do not have a local counterpart]' \
-    '--mirror[push all refs under refs/heads/ and refs/tags/ and delete non-existing refs]' \
+    '(* --all --branches --tags)--mirror[push all refs under refs/heads/ and refs/tags/ and delete non-existing refs]' \
     '(-n --dry-run)'{-n,--dry-run}'[do everything except actually send the updates]' \
     '--porcelain[produce machine-readable output]' \
     '(-d --delete)'{-d,--delete}'[delete all listed refs from the remote repository]' \
-    '--tags[all tags under refs/tags are pushed]' \
+    '(* --all --branches --mirror)--tags[all tags under refs/tags are pushed]' \
     '--follow-tags[also push missing annotated tags reachable from the pushed refs]' \
     '(--receive-pack --exec)'{--receive-pack=-,--exec=-}'[path to git-receive-pack on remote]:remote git-receive-pack:_files' \
     '(--force-with-lease --no-force-with-lease)*--force-with-lease=-[allow refs that are not ancestors to be updated if current ref matches expected value]::ref and expectation:->lease' \
     '(--force-with-lease --no-force-with-lease)--no-force-with-lease[cancel all previous force-with-lease specifications]' \
+    '--force-if-includes[require remote updates to be integrated locally]' \
     '(-f --force)'{-f,--force}'[allow refs that are not ancestors to be updated]' \
     '(:)--repo=[default repository to use]:repository:__git_any_repositories' \
     '(-u --set-upstream)'{-u,--set-upstream}'[add upstream reference for each branch that is up to date or pushed]' \
@@ -1465,11 +1519,11 @@ _git-push () {
     '(--no-signed --sign)--signed[GPG sign the push]' \
     "(--sign --signed)--no-signed[don't GPG sign the push]" \
     '--atomic[request atomic transaction on remote side]' \
-    '(-o --push-option)'{-o+,--push-option=}'[transmit string to server to pass to pre/post-receive hooks]:string' \
+    '*'{-o+,--push-option=}'[transmit string to server to pass to pre/post-receive hooks]:string' \
     '(-4 --ipv4 -6 --ipv6)'{-4,--ipv4}'[use IPv4 addresses only]' \
     '(-4 --ipv4 -6 --ipv6)'{-6,--ipv6}'[use IPv6 addresses only]' \
     ': :__git_any_repositories' \
-    '*: :__git_ref_specs_pushy' && ret=0
+    $ref_arg && ret=0
 
   case $state in
     (lease)
@@ -1493,6 +1547,9 @@ _git-range-diff () {
   _arguments -s -S $endopt \
     '--creation-factor=[specify weighting for creation]:weighting (percent)' \
     '--no-dual-color[use simple diff colors]' \
+    '(--no-notes)*--notes=[show notes that annotate commit, with optional ref argument show this notes ref instead of the default notes ref(s)]:: :__git_notes_refs' \
+    '(--right-only)--left-only[only emit output related to the first range]' \
+    '(--left-only)--right-only[only emit output related to the second range]' \
     $diff_options \
     '1:range 1:__git_commit_ranges' \
     '2:range 2:__git_commit_ranges' \
@@ -1518,38 +1575,40 @@ _git-rebase () {
     '(-)--quit[abort but keep HEAD where it is]' \
     '(-)--show-current-patch[show the patch file being applied or merged]' \
     - options \
-    '(-m --merge)'{-m,--merge}'[use merging strategies to rebase]' \
+    '(--onto --root)--keep-base[use the merge-base of upstream and branch as the current base]' \
     '(-S --gpg-sign --no-gpg-sign)'{-S-,--gpg-sign=-}'[GPG-sign the commit]::key id' \
     "(-S --gpg-sign --no-gpg-sign)--no-gpg-sign[don't GPG-sign the commit]" \
-    '*'{-s+,--strategy=}'[use given merge strategy]:merge strategy:__git_merge_strategies' \
-    '*'{-X+,--strategy-option=}'[pass merge-strategy-specific option to merge strategy]:option' \
     '(-q --quiet -v --verbose --stat -n --no-stat)'{-q,--quiet}'[suppress all output]' \
     '(-q --quiet -v --verbose --stat -n --no-stat)'{-v,--verbose}'[output additional information]' \
     '(-n --no-stat)'{-n,--no-stat}"[don't show diffstat of what changed upstream]" \
     '--rerere-autoupdate[update the index with reused conflict resolution if possible]' \
     '--no-verify[bypass the pre-rebase hook]' \
-    '-C-[ensure that given lines of surrounding context match]: :__git_guard_number "lines of context"' \
+    '(--apply -m --merge -s --strategy -X --strategy-option --auto-squash --no-auto-squash -r --rebase-merges -i --interactive -x --exec --empty --reapply-cherry-picks --edit-todo --reschedule-failed-exec)-C-[ensure that given lines of surrounding context match]: :__git_guard_number "lines of context"' \
     '(-f --force-rebase)'{-f,--force-rebase}'[force rebase even if current branch descends from commit rebasing onto]' \
-    '(-i --interactive)--ignore-whitespace[ignore whitespace in context]' \
-    '(-i --interactive)--whitespace=-[detect a new or modified line that has whitespace errors]: :__git_apply_whitespace_strategies' \
+    '(-i --interactive)--ignore-whitespace[ignore changes in whitespace]' \
+    '(--apply -m --merge -s --strategy -X --strategy-option --auto-squash --no-auto-squash -r --rebase-merges -i --interactive -x --exec --empty --reapply-cherry-picks --edit-todo --reschedule-failed-exec)--whitespace=-[detect a new or modified line that has whitespace errors]: :__git_apply_whitespace_strategies' \
     '(-i --interactive)--committer-date-is-author-date[use author date as committer date]' \
-    '(-i --interactive --ignore-whitespace --whitespace --committer-date-is-author-date)'{-i,--interactive}'[make a list of commits to be rebased and open in $EDITOR]' \
-    '(-r --rebase-merges)'{-r-,--rebase-merges=-}'[try to rebase merges instead of skipping them]::option:(rebase-cousins no-rebase-cousins)' \
-    '!(-p --preserve-merges --interactive)'{-p,--preserve-merges} \
-    {-x+,--exec=}'[with -i\: append "exec <cmd>" after each line]:command:_command_names -e' \
-    '(-k --keep-empty)'{-k,--keep-empty}'[keep empty commits in the result]' \
-    '--allow-empty-message[allow rebasing commits with empty messages]' \
-    '(1)--root[rebase all reachable commits]' \
+    '(-f --force-rebase)'{--ignore-date,--reset-author-date}'[ignore author date and use current date]' \
+    '(-m --merge -s --strategy -X --strategy-option --auto-squash --no-auto-squash -r --rebase-merges -i --interactive -x --exec --empty --reapply-cherry-picks --edit-todo --reschedule-failed-exec)--apply[use apply strategies to rebase]' \
+    '(-m --merge --apply --whitespace -C)'{-m,--merge}'[use merging strategies to rebase]' \
+    '(-i --interactive --ignore-whitespace --apply --whitespace -C --committer-date-is-author-date)'{-i,--interactive}'[make a list of commits to be rebased and open in $EDITOR]' \
+    '(--apply --whitespace -C)--empty=[specify how to handle commits that become empty]:handling:(drop keep ask)' \
+    '(--apply --whitespace -C)'{-x+,--exec=}'[with -i\: append "exec <cmd>" after each line]:command:_command_names -e' \
+    '(-r --rebase-merges --apply --whitespace -C)'{-r-,--rebase-merges=-}'[try to rebase merges instead of skipping them]::option:(rebase-cousins no-rebase-cousins)' \
+    '(--apply --whitespace -C)*'{-s+,--strategy=}'[use given merge strategy]:merge strategy:__git_merge_strategies' \
+    '(--apply --whitespace -C)*'{-X+,--strategy-option=}'[pass merge-strategy-specific option to merge strategy]: :_git_strategy_options' \
+    '(1 --keep-base --fork-point)--root[rebase all reachable commits]' \
     $autosquash_opts \
     '(--autostash --no-autostash)--autostash[stash uncommitted changes before rebasing and apply them afterwards]' \
     "(--autostash --no-autostash)--no-autostash[don't stash uncommitted changes before rebasing and apply them afterwards]" \
-    '--fork-point[use merge-base --fork-point to refine upstream]' \
-    '--ignore-date[use current timestamp for author date]' \
-    '--signoff[add Signed-off-by: line to the commit message]' \
+    '(--root)--fork-point[use merge-base --fork-point to refine upstream]' \
+    '--signoff[add Signed-off-by: trailer to the commit message]' \
     '--no-ff[cherry-pick all rebased commits with --interactive, otherwise synonymous to --force-rebase]' \
     '(--keep-base)--onto=[start new branch with HEAD equal to given revision]:newbase:__git_revisions' \
-    '(--onto)--keep-base[use the merge-base of upstream and branch as the current base]' \
-    "--reschedule-failed-exec[automatically re-schedule any 'exec' that fails]" \
+    "(--apply --whitespace -C)--reschedule-failed-exec[automatically re-schedule any 'exec' that fails]" \
+    '(--apply --whitespace -C)--reapply-cherry-picks[apply all changes, even those already present upstream]' \
+    '--update-refs[update branches that point to commits that are being rebased]' \
+    '!(--update-refs)--no-update-refs' \
     ':upstream branch:__git_revisions' \
     '::working branch:__git_revisions'
 }
@@ -1569,6 +1628,9 @@ _git-reset () {
       '--recurse-submodules=-[control recursive updating of submodules]::reset:__git_commits' \
       '(-p --patch)'{-p,--patch}'[select diff hunks to remove from the index]' \
       '(-q --quiet)'{-q,--quiet}'[suppress all output]' \
+      '--no-refresh[skip refreshing the index after reset]' \
+      '(*)--pathspec-from-file=[read pathspec from file]:file:_files' \
+      '(*)--pathspec-file-nul[pathspec elements are separated with NUL character]' \
       '(--soft --mixed --hard --merge --keep):: :__git_commits' \
       '(--soft --mixed --hard --merge --keep)*:: :->file' && ret=0
 
@@ -1606,11 +1668,13 @@ _git-restore() {
     '(-q --quiet --progress)--no-progress[suppress progress reporting]' \
     '(--no-progress)--progress[force progress reporting]' \
     '(-m --merge)'{-m,--merge}'[perform a 3-way merge with the new branch]' \
-    '--conflict=[change how conflicting hunks are presented]:conflict style [merge]:(merge diff3)' \
+    '--conflict=[change how conflicting hunks are presented]:conflict style [merge]:(merge diff3 zdiff3)' \
     '(-2 --ours -3 --theirs -m --merge)'{-2,--ours}'[checkout our version for unmerged files]' \
     '(-2 --ours -3 --theirs -m --merge)'{-3,--theirs}'[checkout their version for unmerged files]' \
     '(-p --patch)'{-p,--patch}'[select hunks interactively]' \
     "--ignore-skip-worktree-bits[don't limit pathspecs to sparse entries only]" \
+    '(*)--pathspec-from-file=[read pathspec from file]:file:_files' \
+    '(*)--pathspec-file-nul[pathspec elements are separated with NUL character]' \
     '*:path spec:->pathspecs' && ret=0
 
   case $state in
@@ -1653,9 +1717,10 @@ _git-revert () {
     '(-n --no-commit)'{-n,--no-commit}'[do not commit the reversion]' \
     '(-s --signoff)'{-s,--signoff}'[add Signed-off-by line at the end of the commit message]' \
     '--strategy=[use given merge strategy]:merge strategy:__git_merge_strategies' \
-    '*'{-X,--strategy-option=}'[pass merge-strategy-specific option to merge strategy]:option' \
+    '*'{-X+,--strategy-option=}'[pass merge-strategy-specific option to merge strategy]: :_git_strategy_options' \
     '(-S --gpg-sign --no-gpg-sign)'{-S-,--gpg-sign=-}'[GPG-sign the commit]::key id' \
     "(-S --gpg-sign --no-gpg-sign)--no-gpg-sign[don't GPG-sign the commit]" \
+    "--reference[use the 'reference' format to refer to commits in log message]" \
     ': :__git_recent_commits'
 }
 
@@ -1670,6 +1735,9 @@ _git-rm () {
     '-r[allow recursive removal when a leading directory-name is given]' \
     '--cached[only remove files from the index]' \
     '--ignore-unmatch[exit with 0 status even if no files matched]' \
+    '--sparse[allow updating entries outside of sparse-checkout cone]' \
+    '(*)--pathspec-from-file=[read pathspec from file]:file:_files' \
+    '(*)--pathspec-file-nul[pathspec elements are separated with NUL character]' \
     '(-q --quiet)'{-q,--quiet}"[don't list removed files]" \
     '*:: :->file' && ret=0
 
@@ -1698,6 +1766,8 @@ _git-shortlog () {
     '(-s --summary)'{-s,--summary}'[suppress commit description]' \
     '(-e --email)'{-e,--email}'[show email address of each author]' \
     '-w-[linewrap the output]:: :->wrap' \
+    '*--group=[group commits by field]: : _values -S\: field author committer trailer\:trailer' \
+    '(-c --committer)'{-c,--committer}'[alias for --group=committer]' \
     $revision_options \
     '(-)--[start file arguments]' \
     '*:: :->commit-range-or-file' && ret=0
@@ -1793,6 +1863,7 @@ _git-sparse-checkout() {
         add:'update the sparse-checkout file to include additional patterns'
         reapply:'reapply the sparsity pattern rules to paths in the working tree'
         disable:'disable the config setting, and restore all files in the working directory'
+        check-rules:'check whether sparsity rules match one or more paths'
       )
 
       _describe -t commands command commands && ret=0
@@ -1803,13 +1874,22 @@ _git-sparse-checkout() {
         init)
           _arguments \
             '--cone[allow for better performance with a limited set of patterns]' \
-            '--no-sparse-index[rewrite index to not be sparse]'
+            '--no-sparse-index[rewrite index to not be sparse]' && ret=0
         ;;
         set|add)
           _arguments -S \
-            '--stdin[read patterns from input]' \
+            '--cone[initialize the sparse-checkout in cone mode]' \
+            '--sparse-index[toggle the use of a sparse index]' \
+            '--skip-checks[skip some sanity checks on the given paths that might give false positives]' \
+            '(*)--stdin[read patterns from input]' \
             '*:pattern:_files' && ret=0
         ;;
+        check-rules)
+          _arguments \
+           '-z[terminate input and output files by a NUL character]' \
+           '--cone[interpret rules file patterns as cone mode patterns]' \
+           '--rules-file=[use patterns in specified file]:file:_files' && ret=0
+        ;;
       esac
     ;;
   esac
@@ -1828,13 +1908,16 @@ _git-stash () {
     '(-k --keep-index --no-keep-index)'{-k,--keep-index}'[all changes already added to the index are left intact]'
     '(-k --keep-index)--no-keep-index[all changes already added to the index are undone]'
     '(-q --quiet)'{-q,--quiet}'[suppress all output]'
-    '(-p --patch -a --all -u --include-untracked)'{-u,--include-untracked}'[include untracked files]'
-    '(-p --patch -a --all -u --include-untracked)'{-a,--all}'[include ignored files]'
+    '(-p --patch -a --all -u --include-untracked -S --staged)'{-u,--include-untracked}'[include untracked files]'
+    '(-p --patch -a --all -u --include-untracked -S --staged)'{-a,--all}'[include ignored files]'
+    '(* -p --patch)--pathspec-from-file=[read pathspec from file]:file:_files'
+    '(* -p --patch)--pathspec-file-nul[pathspec elements are separated with NUL character]'
+    '(-S --staged -a --all -u --include-untracked)'{-S,--staged}'[only stash changes that are currently staged]'
   )
 
   _arguments -C \
     '*::: :->args' \
-    '(-m --message)'{-m,--message}'[specify stash description]' \
+    '(-m --message)'{-m+,--message=}'[specify stash description]:description' \
     ${save_arguments//#\(/(* } && ret=0
 
   if [[ -n $state ]]; then
@@ -1851,6 +1934,7 @@ _git-stash () {
         clear:'remove all the stashed states'
         drop:'remove a single stashed state from the stash list'
         create:'create a stash without storing it in the ref namespace'
+        store:'store a stash created with git stash create in the stash ref'
       )
 
       _describe -t commands command commands && ret=0
@@ -1867,8 +1951,8 @@ _git-stash () {
         (push)
           _arguments -S $endopt \
             $save_arguments \
-	    '(-m --message)'{-m,--message}'[specify stash description]' \
-            ':: :__git_modified_files' && ret=0
+            '(-m --message)'{-m+,--message=}'[specify stash description]:description' \
+            '*: : __git_ignore_line __git_modified_files' && ret=0
           ;;
         (--)
             __git_modified_files
@@ -1887,7 +1971,9 @@ _git-stash () {
           __git_setup_diff_options
 
           _arguments -S -s $endopt \
-            $diff_options \
+            ${diff_options:#*\)-u*} \
+            '(-u --include-untracked --only-untracked)'{-u,--include-untracked}'[show the untracked files in the stash entry as part of the diff]' \
+            '(-u --include-untracked)--only-untracked[show only the untracked files in the stash entry as part of the diff]' \
             ':: :__git_stashes' && ret=0
           ;;
         (pop|apply)
@@ -1909,9 +1995,14 @@ _git-stash () {
             '(-q --quiet)'{-q,--quiet}'[suppress all output]' \
             ':: :__git_stashes' && ret=0
           ;;
+        (store)
+          _arguments -S -s $endopt \
+            '(-m --message)'{-m+,--message=}'[specify stash description]:description' \
+            '(-q --quiet)'{-q,--quiet}'[suppress all output]' && ret=0
+        ;;
         (create)
-          _nothing
-          ;;
+          _message -e messages message
+        ;;
         (*)
           _nothing
           ;;
@@ -1971,7 +2062,8 @@ _git-submodule () {
         init:'initialize a submodule'
         deinit:'unregister a submodule'
         update:'update a submodule'
-	set-branch:'set the default remote tracking branch for the submodule'
+        set-branch:'set default remote tracking branch for the submodule'
+        set-url:'set URL of the specified submodule'
         summary:'show commit summary between given commit and working tree/index'
         foreach:'evaluate shell command in each checked-out submodule'
 	absorbgitdirs:'move the git directory of a submodule into its superprojects'
@@ -2014,7 +2106,6 @@ _git-submodule () {
             '*: :__git_ignore_line_inside_arguments __git_submodules' && ret=0
           ;;
         (update)
-          # TODO: --init not properly documented.
           _arguments -S \
             '(-q --quiet)'{-q,--quiet}'[suppress all output]' \
             '(-N --no-fetch)'{-N,--no-fetch}'[do not fetch new objects from repository]' \
@@ -2027,6 +2118,8 @@ _git-submodule () {
             '--remote[use the status of the submodule''s remote-tracking branch]' \
             '--force[discard local changes by checking out the current up-to-date version]' \
             '--init[initialize uninitialized submodules]' \
+            '--single-branch[clone only one branch]' \
+            '--filter=[apply partial clone filter to the submodule]:filter' \
             '*: :__git_ignore_line_inside_arguments __git_submodules' && ret=0
 	;;
 	(set-branch)
@@ -2035,6 +2128,11 @@ _git-submodule () {
 	    '(-b --branch)'{-b,--branch=}'[specify the remote branch]:remote branch' \
 	    '1:path:_directories'
         ;;
+	(set-url)
+          _arguments -C -A '-*' \
+            '1:path:_directories' \
+            '2:url:_urls' && ret=0
+        ;;
         (summary)
           _arguments -C -A '-*' \
             '(-q --quiet)'{-q,--quiet}'[suppress all output]' \
@@ -2093,7 +2191,7 @@ _git-subtree () {
   _arguments -C \
     '(-q --quiet)'{-q,--quiet}'[suppress progress output]' \
     '(-P --prefix)'{-P+,--prefix=}'[the path to the subtree in the repository to manipulate]: :_directories' \
-    '-d[show debug messages]' \
+    '(-d --debug)'{-d,--debug}'[show debug messages]' \
     ': :->command' \
     '*::: := ->option-or-argument' && ret=0
 
@@ -2190,9 +2288,10 @@ _git-switch() {
     '(-q --quiet --progress)--no-progress[suppress progress reporting]' \
     '--progress[force progress reporting]' \
     '(-m --merge --discard-changes --orphan)'{-m,--merge}'[perform a 3-way merge with the new branch]' \
-    '(--discard-changes --orphan)--conflict=[change how conflicting hunks are presented]:conflict style [merge]:(merge diff3)' \
+    '(--discard-changes --orphan)--conflict=[change how conflicting hunks are presented]:conflict style [merge]:(merge diff3 zdiff3)' \
     '(-d --detach -c --create -C --force-create --ignore-other-worktrees --orphan --guess --no-guess 1)'{-d,--detach}'[detach HEAD at named commit]' \
-    '(-t --track --no-track --guess --orphan 1)'{-t,--track}'[set upstream info for new branch]' \
+    '(--track --no-track --guess --orphan 1)-t[set upstream info for new branch]' \
+    '(-t --no-track --guess --orphan 1)--track=-[set upstream info for new branch]::configuration:(direct inherit)' \
     "(-t --track --guess --orphan 1)--no-track[don't set upstream info for a new branch]" \
     '(-c --create -C --force-create -d --detach --ignore-other-worktrees -m --merge --conflict -t --track --guess --no-track -t --track)--orphan[create new unparented branch]: :__git_branch_names' \
     '!--overwrite-ignore' \
@@ -2253,6 +2352,7 @@ _git-tag () {
       "*--no-contains=[only list tags that don't contain the specified commit]: :__git_commits" \
       '--merged=-[print only tags that are merged]:: :__git_commits' \
       '--no-merged=-[print only tags that are not merged]:: :__git_commits' \
+      "--omit-empty[don't output a newline after empty formatted refs]" \
       '--sort=[specify how the tags should be sorted]:field:__git_ref_sort_keys' \
       '--points-at=[only list tags of the given object]: :__git_commits' \
       '--format=[specify format to use for the output]:format:__git_format_ref' \
@@ -2284,6 +2384,7 @@ _git-worktree() {
 	lock:'prevent a working tree from being pruned'
 	move:'move a working tree to a new location'
 	remove:'remove a working tree'
+        repair:'repair worktree administrative files'
 	unlock:'allow working tree to be pruned, moved or deleted'
       )
 
@@ -2298,23 +2399,34 @@ _git-worktree() {
 	  else
 	    args=( ':commit:__git_commits' )
 	  fi
-          _arguments -S $endopt \
+          _arguments -s -S $endopt \
 	    '(-f --force)'{-f,--force}'[checkout branch even if already checked out in another worktree]' \
-	    '(-B --detach)-b+[create a new branch]: :__git_branch_names' \
-	    '(-b --detach)-B+[create or reset a branch]: :__git_branch_names' \
-	    '(-b -B)--detach[detach HEAD at named commit]' \
+            '(-B -d --detach --guess-remote)-b+[create a new branch]: :__git_branch_names' \
+            '(-b -d --detach --guess-remote)-B+[create or reset a branch]: :__git_branch_names' \
+            '(-b -d --detach)--orphan[create unborn/orphaned branch]' \
+            '(-d --detach -b -B --orphan --guess-remote --track --no-track)'{-d,--detach}'[detach HEAD at named commit]' \
 	    '--no-checkout[suppress file checkout in new worktree]' \
 	    '--lock[keep working tree locked after creation]' \
+            '--reason=[specify reason for locking]:reason' \
+            '(2 --no-guess-remote -b -B -d --detach)--guess-remote[guess remote tracking branch from path basename]' \
+            "(--guess-remote)--no-guess-remote[don't guess remote tracking branch from path basename]" \
+            '(--no-track -d --detach)--track[set upstream info for new branch]' \
+            "(--track -d --detach)--no-track[don't set upstream info for new branch]" \
+            '(-q --quiet)'{-q,--quiet}'[suppress feedback messages]' \
 	    ':path:_directories' $args && ret=0
 	;;
         (prune)
-          _arguments -S $endopt \
+          _arguments -s -S $endopt \
 	    '(-n --dry-run)'{-n,--dry-run}"[don't remove, show only]" \
 	    '(-v --verbose)'{-v,--verbose}'[report pruned objects]' \
-	    '--expire[expire objects older than specified time]:time' && ret=0
+            '--expire=[expire objects older than specified time]: :_git_approxidates' && ret=0
 	;;
         (list)
-	  _arguments -S $endopt '--porcelain[machine-readable output]' && ret=0
+          _arguments -S $endopt \
+            '(-v --verbose --porcelain -z)'{-v,--verbose}'[output additional information about worktrees]' \
+            "--expire=[add 'prunable' annotation to worktrees older than specified time]: :_git_approxidates" \
+            '(-v)--porcelain[machine-readable output]' \
+            '(-v)-z[terminate each line with a NUL rather than a newline]' && ret=0
 	;;
 	(lock)
 	  _arguments -C -S $endopt '--reason=[specify reason for locking]:reason' ': :->worktrees' && ret=0
@@ -2325,9 +2437,13 @@ _git-worktree() {
             ':location:_directories' && ret=0
 	;;
 	(remove)
-	  _arguments -C -S $endopt '--force[remove working trees that are not clean or that have submodules]' \
+          _arguments -C -S $endopt \
+            '(-f --force)'{-f,--force}'[remove working trees that are not clean or that have submodules]' \
             ': :->worktrees' && ret=0
 	;;
+        (repair)
+          _directories && ret=0
+        ;;
 	(unlock)
 	  state=worktrees
 	;;
@@ -2385,17 +2501,20 @@ _git-config () {
     '(--global --system --local            -f --file --blob)--worktree[use per-worktree config file]' \
     '(--global --system --local --worktree           --blob)'{-f+,--file=}'[use given config file]:config file:_files' \
     '(--global --system --local --worktree -f --file)--blob=[read config from given blob object]:blob:__git_blobs' \
-    '(-t --type --bool --int --bool-or-int --path --expiry-date)'{-t+,--type=}'[ensure that incoming and outgoing values are canonicalize-able as the given type]:type:(bool int bool-or-int path expiry-date color)' \
-    '(-t --type --int --bool-or-int --path --expiry-date)--bool[setting is a boolean]' \
-    '(-t --type --bool --bool-or-int --path --expiry-date)--int[setting is an integer]' \
-    '(-t --type --bool --int --path --expiry-date)--bool-or-int[setting is an integer]' \
-    '(-t --type --bool --int --bool-or-int --expiry-date)--path[setting is a path]' \
-    '(-t --type --bool --int --bool-or-int --path)--expiry-date[setting is an expiry date]' \
+    '(-t --type --bool --int --bool-or-int --bool-or-str --path --expiry-date)'{-t+,--type=}'[ensure that incoming and outgoing values are canonicalize-able as the given type]:type:(bool int bool-or-int bool-or-str path expiry-date color)' \
+    '(-t --type --int --bool-or-int --bool-or-str --path --expiry-date)--bool[setting is a boolean]' \
+    '(-t --type --bool --bool-or-int --bool-or-str --path --expiry-date)--int[setting is an integer]' \
+    '(-t --type --bool --int --bool-or-str --path --expiry-date)--bool-or-int[setting is a boolean or integer]' \
+    '(-t --type --bool --int --bool-or-int --path --expiry-date)--bool-or-str[setting is a boolean or string]' \
+    '(-t --type --bool --int --bool-or-int --bool-or-str --expiry-date)--path[setting is a path]' \
+    '(-t --type --bool --int --bool-or-int --bool-or-str --path)--expiry-date[setting is an expiry date]' \
     '(-z --null)'{-z,--null}'[end values with NUL and newline between key and value]' \
+    '--fixed-value[use string equality when comparing values]' \
     '(--get --get-all --get-urlmatch --replace-all --add --unset --unset-all --rename-section --remove-section -e --edit --get-color --get-colorbool)--name-only[show variable names only]' \
     '(--includes)'--no-includes"[don't respect \"include.*\" directives]" \
     '(--no-includes)'--includes'[respect "include.*" directives in config files when looking up values]' \
-    '(--global --system --local -f --file --blob --get-urlmatch --replace-all --add --unset --unset-all --rename-section --remove-section -e --edit --get-color --get-colorbool)--show-origin[show origin of config]' \
+    '(--global --system --local -f --file --blob --get-urlmatch --replace-all --add --unset --unset-all --rename-section --remove-section -e --edit --get-color --get-colorbool --show-scope)--show-origin[show origin of config]' \
+    '(--global --system --local -f --file --blob --get-urlmatch --replace-all --add --unset --unset-all --rename-section --remove-section -e --edit --get-color --get-colorbool --show-origin)--show-scope[show scope of config (worktree, local, global, system, command)]' \
     '(2 --add -e --edit -l --list --name-only --rename-section --remove-section --replace-all --unset --unset-all)--default=[with --get, use specified default value when entry is missing]:default' \
     $name_arg \
     $value_arg \
@@ -2407,14 +2526,14 @@ _git-config () {
       '(--name-only --show-origin)--get-urlmatch[get value specific for the URL]' \
       '(-z --null --name-only --show-origin)--replace-all[replace all values of the given key]' \
       '(3 -z --null --name-only --show-origin)--add[add new value without altering any existing ones]' \
-      '(2 --bool --int --bool-or-int --path -z --null --name-only --show-origin)--unset[remove the first matching value of the key]' \
-      '(2 --bool --int --bool-or-int --path -z --null --name-only --show-origin)--unset-all[remove all matching values of the key]' \
-      '(3 --bool --int --bool-or-int --path -z --null --name-only --show-origin)--rename-section[rename the given section]'  \
-      '(3 --bool --int --bool-or-int --path -z --null --name-only --show-origin)--remove-section[remove the given section]' \
-      '(: --bool --int --bool-or-int --path)'{-l,--list}'[list all variables set in config file]' \
-      '(-e --edit --bool --int --bool-or-int --path -z --null --name-only --show-origin)'{-e,--edit}'[open config file for editing]' \
-      '(2 3 --bool --int --bool-or-int --path -z --null --name-only --show-origin)--get-color[find color setting]: :->gettable-color-option' \
-      '(2 3 --bool --int --bool-or-int --path -z --null --name-only --show-origin)--get-colorbool[check if color should be used]: :->gettable-colorbool-option' && ret=0
+      '(2 --bool --int --bool-or-int --bool-or-str --path -z --null --name-only --show-origin)--unset[remove the first matching value of the key]' \
+      '(2 --bool --int --bool-or-int --bool-or-str --path -z --null --name-only --show-origin)--unset-all[remove all matching values of the key]' \
+      '(3 --bool --int --bool-or-int --bool-or-str --path -z --null --name-only --show-origin)--rename-section[rename the given section]'  \
+      '(3 --bool --int --bool-or-int --bool-or-str --path -z --null --name-only --show-origin)--remove-section[remove the given section]' \
+      '(: --bool --int --bool-or-int --bool-or-str --path)'{-l,--list}'[list all variables set in config file]' \
+      '(-e --edit --bool --int --bool-or-int --bool-or-str --path -z --null --name-only --show-origin)'{-e,--edit}'[open config file for editing]' \
+      '(2 3 --bool --int --bool-or-int --bool-or-str --path -z --null --name-only --show-origin)--get-color[find color setting]: :->gettable-color-option' \
+      '(2 3 --bool --int --bool-or-int --bool-or-str --path -z --null --name-only --show-origin)--get-colorbool[check if color should be used]: :->gettable-colorbool-option' && ret=0
   __git_config_option-or-value "$@" && ret=0
   return ret
 }
@@ -3700,11 +3819,12 @@ _git-fast-export () {
     '--import-marks-if-exists=[load marks from file if it exists]: :_files' \
     '--fake-missing-tagger=[fake a tagger when tags lack them]' \
     '--use-done-feature[start with a "feature done" stanza, and terminate with a "done" command]' \
-    '--no-data[do not output blocb objects, instead referring to them via their SHA-1 hash]' \
+    "--no-data[skip output of blob objects, instead referring to them via their SHA-1 hash]" \
     '--full-tree[output full tree for each commit]' \
     '(--get --get-all)--name-only[show variable names only]' \
     '*--refspec=[apply refspec to exported refs]:refspec' \
     '--anonymize[anonymize output]' \
+    '*--anonymize-map[apply conversion in anonymized output]:from\:to' \
     '--reference-excluded-parents[reference parents not in fast-export stream by object id]' \
     '--show-original-ids[show original object ids of blobs/commits]' \
     '--mark-tags[label tags with mark ids]' \
@@ -3720,8 +3840,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' \
@@ -3777,7 +3897,11 @@ _git-pack-refs () {
     '(      --no-all)--all[pack all refs]' \
     '(--all         )--no-all[do not pack all refs]' \
     '(        --no-prune)--prune[remove loose refs after packing them]' \
-    '(--prune           )--no-prune[do not remove loose refs after packing them]'
+    '(--prune           )--no-prune[do not remove loose refs after packing them]' \
+    '*--include=[references to include]:reference pattern:_git_full_references' \
+    '*--exclude=[references to exclude]:reference pattern:_git_full_references' \
+    '--no-include[clear and reset the list of include patterns]' \
+    '--no-exclude[clear and reset the list of exclude patterns]'
 }
 
 (( $+functions[_git-prune] )) ||
@@ -3786,7 +3910,7 @@ _git-prune () {
     '(-n --dry-run)'{-n,--dry-run}'[do not remove anything; just report what would be removed]' \
     '(-v --verbose)'{-v,--verbose}'[report all removed objects]' \
     '--progress[show progress]' \
-    '--expire=[only expire loose objects older than specified date]: :__git_datetimes' \
+    '--expire=[only expire loose objects older than specified date]: :_git_approxidates' \
     '--exclude-promisor-objects[limit traversal to objects outside promisor packfiles]' \
     '*:: :__git_heads'
 }
@@ -3831,21 +3955,19 @@ _git-reflog () {
 
         case $line[1] in
           (expire)
-            # TODO: -n, --dry-run is undocumented.
             _arguments -S \
-              '(-n --dry-run)'{-n,--dry-run}'[undocumented]' \
-              '--stale-fix[TODO\: provide a decent description for this option]' \
-              '--expire=-[prune entries older than given time]: :__git_datetimes' \
-              '--expire-unreachable=-[prune entries older than given time and unreachable]: :__git_datetimes' \
+              '(-n --dry-run)'{-n,--dry-run}"[don't actually prune any entries; show what would be pruned]" \
+              '--stale-fix[prune any reflog entries that point to "broken commits"]' \
+              '--expire=-[prune entries older than given time]:age [90 days]:_git_approxidates' \
+              '--expire-unreachable=-[prune entries older than given time and unreachable]:age [30 days]:_git_approxidates' \
               '--all[prune all refs]' \
               '--updateref[update ref with SHA-1 of top reflog entry after expiring or deleting]' \
               '--rewrite[adjust reflog entries to ensure old SHA-1 points to new SHA-1 of previous entry after expiring or deleting]' \
               '--verbose[output additional information]' && ret=0
             ;;
           (delete)
-            # TODO: -n, --dry-run is undocumented.
             _arguments -C -S \
-              '(-n --dry-run)'{-n,--dry-run}'[undocumented]' \
+              '(-n --dry-run)'{-n,--dry-run}"[don't update entries; show what would be done]" \
               '--updateref[update ref with SHA-1 of top reflog entry after expiring or deleting]' \
               '--rewrite[adjust reflog entries to ensure old SHA-1 points to new SHA-1 of previous entry after expiring or deleting]' \
               '--verbose[output additional information]' \
@@ -3925,7 +4047,9 @@ _git-remote () {
             ': :__git_remotes' && ret=0
           ;;
         (rename)
-          _arguments \
+          _arguments -S $endopt \
+            '(--no-progress)--progress' \
+            '(--progress)--no-progress' \
             ':old name:__git_remotes' \
             ':new name:__git_remotes' && ret=0
           ;;
@@ -3980,12 +4104,13 @@ _git-remote () {
 
 (( $+functions[_git-repack] )) ||
 _git-repack () {
-  # TODO: --quiet is undocumented.
   _arguments -s \
     '(-A --unpack-unreachable)-a[pack all objects into a single pack]' \
     '(-a -k --keep-unreachable)-A[pack all objects into a single pack, but unreachable objects become loose]' \
+    '--cruft[pack unreachable cruft objects separately]' \
+    '--cruft-expiration=[expire cruft objects older than specified time]: :_git_approxidates' \
     '-d[remove redundant packs after packing]' \
-    "--unpack-unreachable=[with -A, don't loosen objects older than specified date]:date" \
+    "--unpack-unreachable=[with -A, don't loosen objects older than specified date]: :_git_approxidates" \
     '-f[pass --no-reuse-delta option to git pack-objects]' \
     '-F[pass --no-reuse-object option to git pack-objects]' \
     "-n[don't update server information]" \
@@ -3993,7 +4118,7 @@ _git-repack () {
     '(-l --local)'{-l,--local}'[pass --local option to git pack-objects]' \
     '(-b --write-bitmap-index)'{-b,--write-bitmap-index}'[write a bitmap index]' \
     '(-i --delta-islands)'{-i,--delta-islands}'[pass --delta-islands to git-pack-objects]' \
-    "--unpack-unreachable=[with -A, don't loosen objects older than specified time]:time" \
+    "--unpack-unreachable=[with -A, don't loosen objects older than specified time]: :_git_approxidates" \
     '(-k --keep-unreachable)'{-k,--keep-unreachable}'[with -a, repack unreachable objects]' \
     '--window=[number of objects to consider when doing delta compression]:number of objects' \
     '--window-memory=[scale window size dynamically to not use more than specified amount of memory]: : __git_guard_bytes' \
@@ -4001,7 +4126,10 @@ _git-repack () {
     '--threads=[limit maximum number of threads]:threads' \
     '--max-pack-size=-[maximum size of each output packfile]: : __git_guard_bytes "maximum pack size"' \
     '--pack-kept-objects[repack objects in packs marked with .keep]' \
-    '--keep-pack=[ignore named pack]:pack'
+    '--keep-pack=[ignore named pack]:pack' \
+    '(-g --geometric)'{-g+,--geometric=}'[find a geometric progression with specified factor]:factor' \
+    '(-m --write-midx)'{-m,--write-midx}'[write a multi-pack index of the resulting packs]' \
+    '--expire-to=[pack prefix to store a pack containing pruned objects]:directory:_directories'
 }
 
 (( $+functions[_git-replace] )) ||
@@ -4034,7 +4162,7 @@ _git-blame () {
   declare -A opt_args
 
   declare -a revision_options
-  __git_setup_revision_options
+  __git_setup_revision_options -d
 
   # TODO: Not sure about __git_cached_files.
   _arguments -C -S -s $endopt \
@@ -4063,7 +4191,6 @@ _git-blame () {
     '--ignore-revs-file=[ignore revisions from file]:file:_files' \
     '(--color-by-age)--color-lines[color redundant metadata from previous line differently]' \
     '(--color-lines)--color-by-age[color lines by age]' \
-    '--indent-heuristic[use indent-based heuristic to improve diffs]' \
     $revision_options \
     ':: :__git_revisions' \
     ': :__git_cached_files' && ret=0
@@ -4078,7 +4205,8 @@ _git-blame () {
       else
         _alternative \
           'line-numbers: :__git_guard_number "line number"' \
-          'regexes::_guard "(/[^/]#(\\?[^/]#)#(/|)|)" regex' && ret=0
+          'regexes::_guard "(/[^/]#(\\?[^/]#)#(/|)|)" regex' \
+          'functions::_guard "(|:*)" "function name"' && ret=0
       fi
       ;;
   esac
@@ -4089,16 +4217,16 @@ _git-blame () {
 (( $+functions[_git-bugreport] )) ||
 _git-bugreport() {
   _arguments \
-    '(-o --output-directory)'{-o+,--output-directory=}'[specify a destination for the bugreport file]:directory:_directories' \
-    '(-s --suffix)'{-s+,--suffix=}'[specify a strftime format suffix for the filename]:format:_date_formats'
+    '--diagnose=-[create an additional zip archive of detailed diagnostics]::mode [stats]:(stats all)' \
+    '(-o --output-directory)'{-o+,--output-directory=}'[specify a destination for the bugreport]:directory:_directories' \
+    '(-s --suffix)'{-s+,--suffix=}'[specify a strftime format filename suffix]:format:_date_formats'
 }
 
 (( $+functions[_git-cherry] )) ||
 _git-cherry () {
-  # TODO: --abbrev is undocumented.
   _arguments -S $endopt \
     '(-v --verbose)'{-v,--verbose}'[output additional information]' \
-    '--abbrev=[set minimum SHA1 display-length]: :__git_guard_number length' \
+    '--abbrev=[use specified digits to display object names]:digits' \
     ':upstream commit:__git_commits' \
     '::head commit:__git_commits' \
     '::limit commit:__git_commits'
@@ -4111,6 +4239,14 @@ _git-count-objects () {
     {-H,--human-readable}'[print sizes in human readable format]'
 }
 
+(( $+functions[_git-diagnose] )) ||
+_git-diagnose() {
+  _arguments -S $endopt \
+    '(-o --output-directory)'{-o+,--output-directory=}'[specify a destination for the diagnostics archive]:destination:_directories' \
+    '(-s --suffix)'{-s+,--suffix=}'[specify a strftime format suffix for the filename]:format:_date_formats' \
+    '--mode=[specify the content of the diagnostic archive]:content [stats]:(stats all)'
+}
+
 (( $+functions[_git-difftool] )) ||
 _git-difftool () {
   # TODO: Is this fine, or do we need to modify the context or similar?
@@ -4140,9 +4276,10 @@ _git-fsck () {
     '--full[check all object directories]' \
     '--connectivity-only[check only connectivity]' \
     '--strict[do strict checking]' \
-    '(-v --verbose)'{-v,--verbose}'[output additional information]' \
+    '(-v --verbose --no-progress)'{-v,--verbose}'[output additional information]' \
     '--lost-found[write dangling objects into .git/lost-found]' \
-    '--progress[show progress]' \
+    "(-v --verbose)--no-progress[don't show progress]" \
+    '!(-v --verbose --no-progress)--progress' \
     '--name-objects[show verbose names for reachable objects]' \
     '*: :__git_objects'
 }
@@ -4155,14 +4292,19 @@ _git-get-tar-commit-id () {
 (( $+functions[_git-help] )) ||
 _git-help () {
   _arguments -S -s \
-    '(-c --config -i --info -m --man -w --web)'{-a,--all}'[show all available commands]' \
+    '(-a --all -g --guides --user-interfaces --developer-interfaces -c --config -i --info -m --man -w --web)'{-a,--all}'[show all available commands]' \
+    '(-g --guides --user-interfaces --developer-interfaces -c --config -i --info -m --man -w --web)--no-external-commands[exclude external commands, with --all]' \
+    '(-g --guides --user-interfaces --developer-interfaces -c --config -i --info -m --man -w --web)--no-aliases[exclude aliases, with --all]' \
+    '(-a --all -g --guides --user-interfaces --developer-interfaces -c --config -i --info -w --web)'{-m,--man}'[display manual for the command in man format]' \
+    '(-a --all -g --guides --user-interfaces --developer-interfaces -c --config -i --info -m --man)'{-w,--web}'[display manual for the command in HTML format]' \
+    '(-a --all -g --guides --user-interfaces --developer-interfaces -c --config -m --man -w --web)'{-i,--info}'[display manual for the command in info format]' \
+    '!(--no-verbose)'{-v,--verbose} \
+    "--no-verbose[don't print command descriptions]" \
+    '(-)'{-g,--guides}'[print list of useful guides]' \
+    '(-)--user-interfaces[print list of user-facing repository, command and file interfaces]' \
+    '(-)--developer-interfaces[print list of file formats, protocols and other developer interfaces]' \
     '(-)'{-c,--config}'[print all configuration variable names]' \
-    '(-a --all -g --guides -c --config -m --man -w --web)'{-i,--info}'[display manual for the command in info format]' \
-    '(-a --all -g --guides -c --config -i --info -w --web)'{-m,--man}'[display manual for the command in man format]' \
-    '(-a --all -g --guides -c --config -i --info -m --man)'{-w,--web}'[display manual for the command in HTML format]' \
-    '(-g --guides -c --config -i --info -m --man -w --web)'{-g,--guides}'[prints a list of useful guides on the standard output]' \
-    '(-v --verbose)'{-v,--verbose}'[print command descriptions]' \
-    ': : _alternative commands:command:_git_commands "guides:git guide:(attributes cli core-tutorial cvs-migration diffcore everyday glossary hooks ignore modules namespaces repository-layout revisions tutorial tutorial-2 workflows)"'
+    ': : _alternative commands:command:_git_commands "guides:git guide:_git_help_guides"'
 }
 
 (( $+functions[_git-instaweb] )) ||
@@ -4199,7 +4341,16 @@ _git-instaweb () {
 
 (( $+functions[_git-merge-tree] )) ||
 _git-merge-tree () {
-  _arguments \
+  _arguments -S $endopt \
+    '(1)--write-tree[do a real merge instead of a trivial merge]' \
+    '(-)--trivial-merge[do a trivial merge only]' \
+    '(--no-messages)--messages[also show informational/conflict messages]' \
+    "(--messages)--no-messages[don't show informational/conflict messages]" \
+    '-z[separate paths with the NUL character]' \
+    '--name-only[list filenames without modes/oids/stages]' \
+    '--allow-unrelated-histories[allow merging unrelated histories]' \
+    '--stdin[perform multiple merges, one per line of input]' \
+    '--merge-base=[specify a merge-base for the merge]:commit:__git_commits' \
     ':base-tree:__git_tree_ishs' \
     ':branch 1:__git_tree_ishs' \
     ':branch 2:__git_tree_ishs'
@@ -4210,17 +4361,16 @@ _git-rerere () {
   local curcontext=$curcontext state line ret=1
   declare -A opt_args
 
-  # TODO: --rerere-autoupdate is undocumented.
   _arguments -C -S -s $endopt \
     '--rerere-autoupdate[register clean resolutions in index]' \
-    ': :->command' && ret=0
+    ': :->command' \
+    '*: :{ [[ $words[CURRENT-1] = forget ]] && __git_cached_files }' && ret=0
 
   case $state in
     (command)
-      # TODO: This isn't optimal, as forget get confused.
       _values command \
         'clear[reset metadata used by rerere]' \
-        'forget[resets metadata used by rerere for specific conflict]: :__git_cached_files' \
+        'forget[resets metadata used by rerere for specific conflict]' \
         'diff[output diffs for the current state of the resolution]' \
         'status[print paths with conflicts whose merge resolution rerere will record]' \
         'remaining[print paths with conflicts that have not been autoresolved by rerere]' \
@@ -4296,8 +4446,8 @@ _git-rev-parse () {
       '--is-inside-work-tree[show whether or not current working directory is inside work tree]' \
       '--is-bare-repository[show whether or not repository is bare]' \
       '(--revs-only --no-revs --flags --no-flags --verify)--short=-[show only shorter unique name]:: :__git_guard_number length' \
-      '(--since --after)'{--since=-,--after=-}'[show --max-age= parameter corresponding given date string]:datestring' \
-      '(--until --before)'{--until=-,--before=-}'[show --min-age= parameter corresponding given date string]:datestring' \
+      '(--since --after)'{--since=-,--after=-}'[show --max-age= parameter corresponding given date string]: :_git_approxidates' \
+      '(--until --before)'{--until=-,--before=-}'[show --min-age= parameter corresponding given date string]: :_git_approxidates' \
       '--resolve-git-dir[check if <path> is a valid repository or gitfile and print location]:git dir:_files -/' \
       '*: :__git_objects' && ret=0
   fi
@@ -4337,7 +4487,7 @@ _git-show-branch () {
       if compset -P '[[:digit:]]##,'; then
         _alternative \
           'counts: :__git_guard_number count' \
-          'dates::__git_datetimes' && ret=0
+          'dates::_git_approxidates' && ret=0
       else
         __git_guard_number limit
       fi
@@ -4499,7 +4649,8 @@ _git-send-email () {
     '--8bit-encoding=[encoding to use for non-ASCII messages]: :__git_encodings' \
     '--compose-encoding=[encoding to use for compose messages]: :__git_encodings' \
     '--transfer-encoding=[specify transfer encoding to use]:transfer encoding:(quoted-printable 8bit base64)' \
-    '--envelope-sender[specify the envelope sender used to send the emails]: :_email_addresses' \
+    '--envelope-sender=[specify the envelope sender used to send the emails]: :_email_addresses' \
+    '--sendmail-cmd=[specify command to run to send email]:command:_cmdstring' \
     '--smtp-encryption=[specify encryption method to use]: :__git_sendemail_smtpencryption_values' \
     '--smtp-domain=[specify FQDN used in HELO/EHLO]: :_domains' \
     '--smtp-pass=[specify password to use for SMTP-AUTH]::password' \
@@ -4515,6 +4666,8 @@ _git-send-email () {
     '--relogin-delay=[specify delay between successive logins]:delay (seconds)' \
     '--cc-cmd=[specify command to generate Cc\: header with]:Cc\: command:_cmdstring' \
     '--to-cmd=[specify command to generate To\: header with]:To\: command:_cmdstring' \
+    '--header-cmd=[specify command to generate headers with]:header command:_cmdstring' \
+    '--no-header-cmd[disable any header command in use]' \
     '(                 --no-chain-reply-to)--chain-reply-to[send each email as a reply to previous one]' \
     '(--chain-reply-to                    )--no-chain-reply-to[send all emails after first as replies to first one]' \
     '--identity=[specify configuration identity]: :__git_sendemail_identities' \
@@ -4588,7 +4741,6 @@ _git-svn () {
 
       case $line[1] in
         (clone|dcommit|fetch|init|migrate|rebase|set-tree)
-	  # TODO: --ignore-refs is undocumented.
 	  # TODO: --no-auth-cache is undocumented.
 	  # TODO: --config-dir is undocumented.
 	  opts+=(
@@ -4791,8 +4943,9 @@ _git-svn () {
 	;;
         (rebase)
           opts+=(
-	  '(-l --local)'{-l,--local}"[don't fetch remotely, rebase against the last fetched commit from SVN]"
-	    '(--preserve-merges -p)'{--preserve-merges,-p}'[try to recreate merges instead of ignoring them]'
+            '(-l --local)'{-l,--local}"[don't fetch remotely, rebase against the last fetched commit from SVN]"
+            '!--preserve-merges'
+            '(--rebase-merges -p)'{--rebase-merges,-p}'[try to recreate merges instead of ignoring them]'
 	  )
 	;;
         (reset)
@@ -4842,7 +4995,7 @@ _git-apply () {
 
   _arguments -S -s $endopt \
     $apply_options \
-    '(--index --cached --reject)'{-3,--3way}'[fall back on 3-way merge if patch fails]' \
+    '(--index --cached --reject)'{-3,--3way}'[attempt three-way merge, fall back on normal patch if that fails]' \
     '--stat[output diffstat for input (turns off "apply")]' \
     '--numstat[same as --stat but in decimal notation and complete pathnames (turns off "apply")]' \
     '--summary[output summary of git-diff extended headers (turns off "apply")]' \
@@ -4857,8 +5010,10 @@ _git-apply () {
     '--no-add[ignore additions made by the patch]' \
     '--allow-overlap[allow overlapping hunks]' \
     '--inaccurate-eof[work around missing-new-line-at-EOF bugs]' \
-    '(-v --verbose)'{-v,--verbose}'[display progress on stderr]' \
+    '(-v --verbose -q --quiet)'{-v,--verbose}'[display progress on stderr]' \
+    '(-q --quiet -v --verbose)'{-q,--quiet}'[be more quiet]' \
     '--recount[do not trust line counts in hunk headers]' \
+    "--allow-empty[don't return error for empty patches]" \
     '*:patch:_files'
 }
 
@@ -4875,8 +5030,9 @@ _git-checkout-index () {
     '(-q --quiet)'{-q,--quiet}'[no warning for existing files and files not in index]' \
     '(-f --force)'{-f,--force}'[force overwrite of existing files]' \
     '(-a --all --stdin *)'{-a,--all}'[check out all files in index]' \
-    '(-n --no-create)'{-n,--no-create}'[do not checkout new files]' \
+    '(-n --no-create)'{-n,--no-create}"[don't checkout new files]" \
     '--temp[write content to temporary files]' \
+    "--ignore-skip-worktree-bits[don't skip files with skip-worktree set]" \
     '(-a --all *)--stdin[read list of paths from the standard input]' \
     '--prefix=[prefix to use when creating files]:directory:_directories' \
     '--stage=[check out files from named stage]:stage:(1 2 3 all)' \
@@ -4891,13 +5047,15 @@ _git-commit-graph() {
   if [[ $words[2] = write ]]; then
     args=( $progress
       '(--split --size-multiple --max-commits --expire-time)--append[include all commits present in existing commit-graph file]'
-      '(--append)--split[write the commit-graph as a chain of multiple commit-graph files]'
+      '--changed-paths[enable computation for changed paths]'
+      '(--append)--split=-[write the commit-graph as a chain of multiple commit-graph files]::strategy:(no-merge replace)'
       '(--stdin-packs --stdin-commits)--reachable[walk commits starting at all refs]'
       '(--reachable --stdin-commits)--stdin-packs[only walk objects in pack-indexes read from input]'
       '(--reachable --stdin-packs)--stdin-commits[walk commits starting at commits read from input]'
       '(--append)--size-multiple=:commits [2]'
       '(--append)--max-commits=:commits'
-      '(--append)--expire-time=:date/time:__git_datetimes'
+      '(--append)--expire-time=: :_git_approxidates'
+      '--max-new-filters=[specify maximum number of changed-path bloom filters to compute]:'
     )
   elif [[ $words[2] = verify ]]; then
     args=( $progress
@@ -4907,7 +5065,7 @@ _git-commit-graph() {
 
   _arguments -S $endopt $args \
     '--object-dir=[specify location of packfiles and commit-graph file]:directory:_directories' \
-    '(-h)1:verb:(read verify write)'
+    '(-h)1:verb:(verify write)'
 }
 
 (( $+functions[_git-commit-tree] )) ||
@@ -4953,6 +5111,8 @@ _git-index-pack () {
   _arguments \
     '-v[display progress on stderr]' \
     '-o[write generated pack index into specified file]: :_files' \
+    '(--no-rev-index)--rev-index[generate a reverse index corresponding to the given pack]' \
+    "(--rev-index)--no-rev-index[don't generate a reverse index corresponding to the given pack]" \
     '--stdin[read pack from stdin and instead write to specified file]' \
     $stdin_opts \
     '--strict[die if the pack contains broken objects or links]' \
@@ -4973,8 +5133,6 @@ _git-merge-file () {
     label_opt="*-L[label to use for the $ordinals[n_labels+1] file]:label"
   fi
 
-  # TODO: --marker-size in undocumented.
-  # TODO: --diff3 is undocumented.
   _arguments \
     $label_opt \
     '(-p --stdout)'{-p,--stdout}'[send merged file to standard output instead of overwriting first file]' \
@@ -4983,7 +5141,8 @@ _git-merge-file () {
     '(--ours          --union)--theirs[resolve conflicts favoring their side of the lines]' \
     '(--ours --theirs        )--union[resolve conflicts favoring both sides of the lines]' \
     '--marker-size[specify length of conflict markers]: :__git_guard_number "marker length"' \
-    '--diff3[use a diff3 based merge]' \
+    '(--zdiff3)--diff3[show conflicts in "diff3" style]' \
+    '(--diff3)--zdiff3[show conflicts in "zdiff3" style]' \
     ':current file:_files' \
     ':base file:_files' \
     ':other file:_files'
@@ -5023,6 +5182,9 @@ _git-mktree () {
 _git-multi-pack-index() {
   _arguments \
     '--object-dir=[specify location of git objects]:directory:_directories' \
+    '(--progress)--no-progress[turn progress off]' '!(--no-progress)--progress' \
+    '--stdin-packs[write a multi-pack index containing only pack index basenames provided on stdin]' \
+    '--refs-snapshot=[specify a file which contains a "refs snapshot" taken prior to repacking]:file:_files' \
     '--batch-size=[during repack, select packs so as to have pack files of at least the specified size]:size' \
     '1:verb:(write verify expire repack)'
 }
@@ -5052,16 +5214,19 @@ _git-pack-objects () {
     '--delta-base-offset[use delta-base-offset packing]' \
     '--threads=-[specify number of threads for searching for best delta matches]: :__git_guard_number "number of threads"' \
     '--non-empty[only create a package if it contains at least one object]' \
-    '--revs[read revision arguments from standard input]' \
+    '(--stdin-packs)--revs[read revision arguments from standard input]' \
     '(--revs)--unpacked[limit objects to pack to those not already packed]' \
-    '(--revs)--all[include all refs as well as revisions already specified]' \
+    '(--revs --stdin-packs)--all[include all refs as well as revisions already specified]' \
     '--reflog[include objects referred by reflog entries]' \
     '--indexed-objects[include objects referred to by the index]' \
+    '(--revs --all --keep-unreachable --pack-loose-unreachable --unpack-unreachable)--stdin-packs[read packs from stdin]' \
     '(: --max-pack-size)--stdout[output pack to stdout]' \
     '--include-tag[include unasked-for annotated tags if object they reference is included]' \
-    '(--unpack-unreachable)--keep-unreachable[keep unreachable ]' \
-    '--pack-loose-unreachable[pack loose unreachable objects]' \
-    '(--keep-unreachable)--unpack-unreachable=-[unpack unreachable objects newer than specified time]::time' \
+    '(--revs --stdin-packs --unpack-unreachable)--keep-unreachable[add objects unreachable from refs in packs named with --unpacked to resulting pack]' \
+    '(--revs --stdin-packs)--pack-loose-unreachable[pack unreachable loose objects]' \
+    '(--revs --stdin-packs --keep-unreachable)--unpack-unreachable=-[keep unreachable objects in loose form]:: :_git_approxidates' \
+    '--cruft[create a cruft pack]' \
+    '--cruft-expiration=[expire cruft objects older than specified time]: :_git_approxidates' \
     '--sparse[use sparse reachability algorithm]' \
     '--include-tag[include tag objects that refer to objects to be packed]' \
     $thin_opt \
@@ -5076,6 +5241,7 @@ _git-pack-objects () {
     '--missing=[specify how missing objects are handled]:action:(error allow-any allow-promisor print)' \
     "--exclude-promisor-objects[don't pack objects in promisor packfiles]" \
     '--delta-islands[respect islands during delta compression]' \
+    '--uri-protocol=[exclude any configured uploadpack.blobpackfileuri with given protocol]:protocol' \
     ':base-name:_files'
 }
 
@@ -5138,6 +5304,7 @@ _git-symbolic-ref () {
     '(-q --quiet)'{-q,--quiet}'[do not issue error if specified name is not a symbolic ref]' \
     '--short[shorten the ref name (eg. refs/heads/master -> master)]' \
     '-m[update reflog for specified name with specified reason]:reason for update' \
+    '--no-recurse[stop after dereferencing a single level of symbolic ref]' \
     ':symbolic reference:__git_heads' \
     ':: :__git_references'
 }
@@ -5176,6 +5343,7 @@ _git-update-index () {
     '(-q --unmerged --ignore-missing --refresh)--really-refresh[refresh index, unconditionally checking stat information]' \
     '(                --no-skip-worktree)--skip-worktree[set "skip-worktree" bit for given paths]' \
     '(--skip-worktree                   )--no-skip-worktree[unset "skip-worktree" bit for given paths]' \
+    "--ignore-skip-worktree-entries[don't touch index-only entries]" \
     '(-)'{-g,--again}'[run git-update-index on differing index entries]' \
     '(-)--unresolve[restore "unmerged" or "needs updating" state of files]' \
     '--info-only[only insert files object-IDs into index]' \
@@ -5232,8 +5400,8 @@ _git-cat-file () {
   _arguments -S -s \
     '(-t -s -e -p --allow-unknown-type 1)--textconv[show content as transformed by a textconv filter]' \
     '(-t -s -e -p --allow-unknown-type 1)--filters[show content as transformed by filters]' \
-    '(-t -s -e -p --allow-unknown-type 1)--path=[use a specific path for --textconv/--filters]:path:_directories' \
     - query \
+    '(-t -s -e -p --allow-unknown-type 1)--path=[use a specific path for --textconv/--filters]:path:_directories' \
     '(-s -e -p --textconv --filters 1)-t[show type of given object]' \
     '(-t -e -p --textconv --filters 1)-s[show size of given object]' \
     '(-e -p --textconv --filters 1)--allow-unknown-type[allow query of broken/corrupt objects of unknown type]' \
@@ -5242,12 +5410,14 @@ _git-cat-file () {
     '(-):object type:(blob commit tag tree)' \
     ': :__git_objects' \
     - batch \
-    '(--batch-check)--batch=-[print SHA1, type, size and contents (or in specified format)]::format' \
-    '(--batch)--batch-check=-[print SHA1, type and size (or in specified format)]::format' \
+    '(--batch-check --batch-command)--batch=-[print SHA1, type, size and contents (or in specified format)]::format' \
+    '(--batch --batch-command)--batch-check=-[print SHA1, type and size (or in specified format)]::format' \
+    '(--batch-check --batch)--batch-command=-[enter a command mode that reads commands and arguments from stdin]::format' \
     '--follow-symlinks[follow in-tree symlinks (used with --batch or --batch-check)]' \
     '--batch-all-objects[show all objects with --batch or --batch-check]' \
     "--unordered[don't order --batch-all-objects output]" \
-    '--buffer[disable flushing of output after each object]'
+    '--buffer[disable flushing of output after each object]' \
+    '-Z[input and output is NUL-delimited instead of newline-delimited]'
 }
 
 (( $+functions[_git-diff-files] )) ||
@@ -5275,8 +5445,11 @@ _git-diff-index () {
   # to given tree-ish?  This should be done for git-diff as well, in that case.
   _arguments -S \
     $revision_options \
+    '--exit-code[report exit code 1 if differences, 0 otherwise]' \
+    '(--exit-code)--quiet[disable all output]' \
     "--cached[don't consider the work tree at all]" \
     '-m[flag non-checked-out files as up-to-date]' \
+    '--merge-base[use merge base instead of comparing directly]' \
     ': :__git_tree_ishs' \
     '*: :__git_cached_files'
 }
@@ -5293,16 +5466,18 @@ _git-diff-tree () {
   # __git_setup_revision_options, but only used by this command, so only have
   # them here.
   _arguments -C -S -s \
-    $revision_options \
+    ${revision_options:#*--cc\[*} \
+    '--exit-code[report exit code 1 if differences, 0 otherwise]' \
+    '(--exit-code)--quiet[disable all output]' \
     '-r[recurse into subdirectories]' \
     '(-r   )-t[display tree objects in diff output]' \
     '--root[display root diff]' \
+    '--merge-base[use merge base instead of comparing directly]' \
     '-m[do not ignore merges]' \
     '-s[do not show differences]' \
     '(--pretty --header)-v[display commit message before differences]' \
     '--no-commit-id[do not display commit IDs]' \
-    '(-c --cc)-c[show differences from each of parents to merge result]' \
-    '(-c --cc)--cc[how differences from each of parents and omit differences from only one parent]' \
+    '(-c)--cc[combined diff format for merge commits, further omitting uninteresting hunks]' \
     '--combined-all-paths[show name of file in all parents for combined diffs]' \
     '--always[always show commit itself and commit log message]' \
     ': :__git_tree_ishs' \
@@ -5339,21 +5514,24 @@ _git-for-each-ref () {
   # is, %(refname), %(objecttype), %(objectsize), %(objectname) with optional '*'
   # in front.
   _arguments -S -s \
+    "--omit-empty[don't output a newline after empty formatted refs]" \
     '--count=[maximum number of refs to iterate over]: :__git_guard_number "maximum number of refs"' \
     '*--sort=[key to sort refs by]: :__git_ref_sort_keys' \
     '--format=-[output format of ref information]:format:__git_format_ref' \
     '--color=-[respect any colors specified in the format]::when:(always never auto)' \
+    '--exclude=[exclude refs which match pattern]:pattern:_git_full_references' \
     '*--points-at=[print only refs which point at the given object]:object:__git_commits' \
     '*--merged=[print only refs that are merged]:object:__git_commits' \
     '*--no-merged=[print only refs that are not merged]:object:__git_commits' \
     '*--contains=[print only refs that contain specified commit]:object:__git_commits' \
     "*--no-contains=[print only refs that don't contain specified commit]:object:__git_commits" \
     '--ignore-case[sorting and filtering are case-insensitive]' \
+    '(1)--stdin[read reference patterns from stdin]' \
     '(-s --shell -p --perl --python --tcl)'{-s,--shell}'[use string literals suitable for sh]' \
     '(-s --shell -p --perl --python --tcl)'{-p,--perl}'[use string literals suitable for Perl]' \
     '(-s --shell -p --perl          --tcl)'--python'[use string literals suitable for Python]' \
     '(-s --shell -p --perl --python      )'--tcl'[use string literals suitable for Tcl]' \
-    ':: :_guard "([^-]?#|)" pattern'
+    ':: :_git_full_references'
 }
 
 (( $+functions[_git-for-each-repo] )) ||
@@ -5372,22 +5550,22 @@ _git-ls-files () {
     no_empty_directory_opt="--no-empty-directory[don't list empty directories]"
   fi
 
-  # TODO: --resolve-undo is undocumented.
   # TODO: Replace _files with something more intelligent based on seen options.
   # TODO: Apply excludes like we do for git-clean.
   _arguments -S -s $endopt \
     '(-c --cached)'{-c,--cached}'[show cached files in output]' \
     '(-d --deleted)'{-d,--deleted}'[show deleted files in output]' \
     '(-m --modified)'{-m,--modified}'[show modified files in output]' \
-    '(-o --others)'{-o,--others}'[show other files in output]' \
+    '(-o --others --format)'{-o,--others}'[show other files in output]' \
     '(-i --ignored)'{-i,--ignored}'[show ignored files in output]' \
-    '(-s --stage --with-tree)'{-s,--stage}'[show stage files in output]' \
+    '(-s --stage --with-tree --format)'{-s,--stage}'[show stage files in output]' \
     '--directory[if a whole directory is classified as "other", show just its name]' \
-    '--eol[show line endings of files]' \
+    '(--format)--eol[show line endings of files]' \
     $no_empty_directory_opt \
     '(-s --stage -u --unmerged --with-tree)'{-u,--unmerged}'[show unmerged files in output]' \
-    '(-k --killed)'{-k,--killed}'[show killed files in output]' \
-    '-z[use NUL termination on output]' \
+    '(--format)--resolve-undo[show resolve-undo information]' \
+    '(-k --killed --format)'{-k,--killed}'[show killed files in output]' \
+    '-z[separate paths with the NUL character]' \
     '*'{-x,--exclude=-}'[skip files matching given pattern]:file pattern' \
     '*'{-X,--exclude-from=-}'[skip files matching patterns in given file]: :_files' \
     '*--exclude-per-directory=-[skip directories matching patterns in given file]: :_files' \
@@ -5398,8 +5576,11 @@ _git-ls-files () {
     '(-v)-f[indicate status of each file using lowercase for fsmonitor clean files]' \
     '--full-name[force paths to be output relative to the project top directory]' \
     '--recurse-submodules[recurse through submodules]' \
-    '--abbrev=[set minimum SHA1 display-length]: :__git_guard_number length' \
+    '--abbrev=[use specified digits to display object names]:digits' \
     '--debug[show debugging data]' \
+    '--deduplicate[suppress duplicate entries]' \
+    '--sparse[show sparse directories in the presence of a sparse index]' \
+    '(-s --stage -o --others -k --killed --resolve-undo --eol)--format=[specify format to use for the output]:format' \
     '*:: :_files'
 }
 
@@ -5430,10 +5611,12 @@ _git-ls-tree () {
     '(-t)-d[do not show children of given tree (implies -t)]' \
     '-r[recurse into subdirectories]' \
     '-t[show tree entries even when going to recurse them]' \
-    '(-l --long)'{-l,--long}'[show object size of blob entries]' \
+    '(-l --long --name-only --name-status --format)'{-l,--long}'[show object size of blob entries]' \
     '-z[use NUL termination on output]' \
-    '(--name-only --name-status)'{--name-only,--name-status}'[list only filenames, one per line]' \
-    '--abbrev=[set minimum SHA1 display-length]: :__git_guard_number length' \
+    '(--name-only --name-status -l --long --object-only --format --abbrev)'{--name-only,--name-status}'[list only filenames, one per line]' \
+    '(--name-only --name-status --format)--object-only[list only objects]' \
+    '(--name-only --name-status -l --long --object-only)--format=[specify format to use for the output]:format' \
+    '(--name-only --name-status)--abbrev=[use specified digits to display object names]:digits' \
     '--full-name[output full path-names]' \
     '(--full-name)--full-tree[do not limit listing to current working-directory]' \
     ': :__git_tree_ishs' \
@@ -5467,12 +5650,13 @@ _git-name-rev () {
     '*--refs=[only use refs matching given pattern]: :_guard "?#" "shell pattern"' \
     '--no-refs[clear any previous ref patterns given]' \
     '*--exclude=[ignore refs matching specified pattern]:pattern' \
-    '(--stdin :)--all[list all commits reachable from all refs]' \
-    '(--all :)--stdin[read from stdin and append revision-name]' \
+    '(--annotate-stdin :)--all[list all commits reachable from all refs]' \
+    '(--all :)--annotate-stdin[annotate text from stdin]' \
+    '!(--all : --annotate-stdin)--stdin' \
     '--name-only[display only name of commits]' \
     '--no-undefined[die with non-zero return when a reference is undefined]' \
     '--always[show uniquely abbreviated commit object as fallback]' \
-    '(--stdin --all)*: :__git_commits'
+    '(--annotate-stdin --all)*: :__git_commits'
 }
 
 (( $+functions[_git-pack-redundant] )) ||
@@ -5490,7 +5674,7 @@ _git-rev-list () {
   declare -A opt_args
 
   declare -a revision_options
-  __git_setup_revision_options
+  __git_setup_revision_options -d
 
   _arguments -C -S $endopt \
     $revision_options \
@@ -5505,6 +5689,8 @@ _git-rev-list () {
     "--no-object-names[don't print the names of the object IDs that are found]" \
     '!(--no-object-names)--object-names)' \
     '--timestamp[print raw commit timestamp]' \
+    "*--exclude-hidden=[don't include refs that would be hidden by git-receive-pack or git-upload-pack]:value:(fetch receive uploadpack)" \
+    '--disk-usage=-[print space used for storage by the selected commits or objects]::value:(human)' \
     '(         --bisect-vars --bisect-all)--bisect[show only middlemost commit object]' \
     '(--bisect)--bisect-vars[same as --bisect, displaying shell-evalable code]' \
     '(--bisect)--bisect-all[display all commit objects between included and excluded commits]' \
@@ -5536,8 +5722,9 @@ _git_rev-list_filters() {
 }
 
 (( $+functions[_git-show-index] )) ||
-_git-show-index () {
-  _message 'no arguments allowed; accepts index file on standard input'
+_git-show-index() {
+  _arguments \
+    '--object-format=[specify the hash algorithm to use]:algortithm:(sha1 sha256)'
 }
 
 (( $+functions[_git-show-ref] )) ||
@@ -5550,7 +5737,7 @@ _git-show-ref () {
       '(-d --dereference)'{-d,--dereference}'[dereference tags into object IDs as well]' \
       '(-s --hash)'{-s+,--hash=-}'[only show the SHA-1 hash, not the reference name]:: :__git_guard_number length' \
       '--verify[enable stricter reference checking]' \
-      '--abbrev=[set minimum SHA1 display-length]: :__git_guard_number length' \
+      '--abbrev=[use specified digits to display object names]:digits' \
       '(-q --quiet)'{-q,--quiet}'[do not print any results]' \
       '*: :_guard "([^-]?#|)" pattern' \
     - exclude \
@@ -5579,6 +5766,7 @@ _git-verify-pack () {
   _arguments -S -s $endopt \
     '(-v --verbose)'{-v,--verbose}'[show objects contained in pack]' \
     '(-s --stat-only)'{-s,--stat-only}'[do not verify pack contents; only display histogram of delta chain length]' \
+    '--object-format=[specify the hash algorithm to use]:algortithm:(sha1 sha256)' \
     '*:index file:_files -g "*.idx(-.)"'
 }
 
@@ -5657,14 +5845,14 @@ _git-send-pack () {
     '(-q --quiet)'{-q,--quiet}'[be more quiet]' \
     '(--receive-pack --exec)'{--receive-pack=-,--exec=-}'[specify path to git-receive-pack on remote side]:remote path' \
     '--remote[specify remote name]:remote' \
-    '--all[update all refs that exist locally]' \
+    '(*)--all[update all refs that exist locally]' \
     '(-n --dry-run)'{-n,--dry-run}'[do everything except actually sending the updates]' \
     '--mirror[mirror all refs]' \
     '(-f --force)'{-f,--force}'[update remote orphaned refs]' \
     "(--no-signed --signed)--sign=-[GPG sign the push]::signing enabled:(($^^sign))" \
     '(--no-signed --sign)--signed[GPG sign the push]' \
     "(--sign --signed)--no-signed[don't GPG sign the push]" \
-    '--push-option=[specify option to transmit]:option' \
+    '*--push-option=[specify option to transmit]:option' \
     '--progress[force progress reporting]' \
     '--thin[send a thin pack]' \
     '--atomic[request atomic transaction on remote side]' \
@@ -5672,6 +5860,7 @@ _git-send-pack () {
     '--stdin[read refs from stdin]' \
     '--helper-status[print status from remote helper]' \
     '--force-with-lease=[require old value of ref to be at specified value]:refname\:expect' \
+    '--force-if-includes[require remote updates to be integrated locally]' \
     ': :__git_any_repositories' \
     '*: :__git_remote_references'
 }
@@ -5691,8 +5880,10 @@ _git-http-fetch () {
     '-v[report what is downloaded]' \
     '-w[write commit-id into the filename under "$GIT_DIR/refs/<filename>"]:filename' \
     '--recover[recover from a failed fetch]' \
-    '(1)--stdin[read commit ids and refs from standard input]' \
-    ': :__git_commits' \
+    '(1 --packfile)--stdin[read commit ids and refs from standard input]' \
+    '!(1 --stdin)--packfile=:hash' \
+    '!--index-pack-args=:args' \
+    '1: :__git_commits' \
     ': :_urls'
 }
 
@@ -5713,12 +5904,9 @@ _git-http-push () {
 
 (( $+functions[_git-receive-pack] )) ||
 _git-receive-pack () {
-  # TODO: --advertise-refs is undocumented.
-  # TODO: --stateless-rpc is undocumented.
   _arguments -S -A '-*' $endopt \
     '(-q --quiet)'{-q,--quiet}'[be quiet]' \
-    '--advertise-refs[undocumented]' \
-    '--stateless-rpc[undocumented]' \
+    '--stateless-rpc[quit after a single request/response exchange]' \
     ':directory to sync into:_directories'
 }
 
@@ -5787,46 +5975,51 @@ _git-upload-pack () {
 
 (( $+functions[_git-check-attr] )) ||
 _git-check-attr () {
-  local z_opt=
-
-  local curcontext=$curcontext state line ret=1
+  local curcontext="$curcontext" z_opt ret=1
+  local -a state line
   declare -A opt_args
 
   if (( words[(I)--stdin] )); then
-    z_opt='-z[paths are separated with NUL character when reading from stdin]'
+    z_opt='-z[terminate input file list and output records by a NUL character]'
+  else
+    z_opt='-z[separate output records with NUL character]'
   fi
 
-  _arguments -C \
-    {-a,--all}'[list all attributes that are associated with the specified paths]' \
+  _arguments -C $z_opt \
     '--stdin[read file names from stdin instead of from command line]' \
-    '--cached[consider .gitattributes in the index only, ignoring the working tree.]' \
-    '-z[terminate input and output records by a NUL character]' \
-    $z_opt \
+    '(--source)--cached[consider .gitattributes in the index only, ignoring the working tree]' \
+    '(--cached)--source=[specify tree to scan for .gitattributes (useful in bare repo)]:tree object:__git_tree_ishs' \
+    - files \
+    '(-a --all --)'{-a,--all}'[list all attributes that are associated with the specified paths]' \
     '(-)--[interpret preceding arguments as attributes and following arguments as path names]' \
-    '*:: :->attribute-or-file' && ret=0
+    '*: :__git_cached_files' \
+    - attrs \
+    '*:::attribute:->attributes' && ret=0
 
   case $state in
-    (attribute-or-file)
-      local -a attributes
-
-      attributes=(crlf ident filter diff merge)
-
-      local only_attributes=1
-      for (( i = 2; i < $#words; i++ )); do
-        if (( attributes[(I)$words[i]] == 0 )); then
-          only_attributes=0
-          break
-        fi
-      done
-
-      if (( !only_attributes )) || [[ -n ${opt_args[(I)--]} ]]; then
-        __git_cached_files && ret=0
-      else
-        _alternative \
-          'attributes::__git_attributes' \
-          'files::__git_cached_files' && ret=0
-      fi
-      ;;
+    attributes)
+      local -a attributes plain dedup
+      attributes=(
+        crlf:"line-ending convention (deprecated)"
+        text:"line-ending normalization"
+        eol:"line-ending style"
+        working-tree-encoding:"text encoding in working directory"
+        ident:'$Id$ substitution'
+        filter:"filters"
+        diff:"textual diff"
+        merge:"merging strategy"
+        conflict-marker-size:"length of markers left in the work tree"
+        whitespace:"control over what diff and apply should consider whitespace errors"
+        export-ignore:"exclude from archive files"
+        export-subst:"expand placeholders when adding to an archive"
+        delta:"don't attempt compression of blobs"
+        encoding:"character encoding that should be used by GUI tools"
+      )
+      plain=( ${attributes%%:*} )
+      dedup=( "${(@)words[1,CURRENT-1]}" )
+      (( ! ${#dedup:|plain} )) && _describe -t git-attributes \
+          attribute attributes -F dedup && ret=0
+    ;;
   esac
 
   return ret
@@ -5850,9 +6043,28 @@ _git-fmt-merge-msg () {
     '(      --no-log)--log=-[display one-line descriptions from actual commits being merged]::number of commits [20]' \
     '(--log         )--no-log[do not display one-line descriptions from actual commits being merged]' \
     '(-m --message)'{-m+,--message=}'[use given message instead of branch names for first line in log message]:message' \
-    '(-F --file)'{-F,--file}'[specify list of merged objects from file]: :_files'
+    '--into-name=[specify substitute name for the real target branch to use]:name' \
+    '(-F --file)'{-F+,--file=}'[specify list of merged objects from file]: :_files'
+}
+
+(( $+functions[_git-hook] )) ||
+_git-hook() {
+  local -a args
+  local gitdir=$(_call_program gitdir git rev-parse --git-dir)
+  [[ -f $gitdir/gitdir ]] && gitdir=$(<$gitdir/gitdir) # needed in worktrees
+
+  (( ${(M)#words[1,CURRENT-1]:#[^-]*} >= 3 )) && args=(
+    {--,--end-of-options}'[end options to git hook, allowing options to the hook itself]'
+  )
+  [[ -n ${(M)words[1,CURRENT-1]:#--(|end-of-options)} ]] && args=( '*:: :_default' )
+  _arguments $args \
+    '--ignore-missing[ignore any missing hook by quietly returning zero]' \
+    "--to-stdin=[specify file which will be redirected to hook's stdin]:file:_files" \
+    '1:subcommand:(run)' \
+    '2:hook name:compadd $gitdir/hooks/*(x\:t)'
 }
 
+
 (( $+functions[_git-mailinfo] )) ||
 _git-mailinfo () {
   # TODO: --no-inbody-headers is undocumented.
@@ -5863,8 +6075,10 @@ _git-mailinfo () {
     '(-u --encoding)--encoding=-[encode commit information in given encoding]: :__git_encodings' \
     '-n[disable all charset re-coding of metadata]' \
     '(-m --message-id)'{-m,--message-id}'[copy the Message-ID header at the end of the commit message]' \
+    '-n[disable charset re-coding of metadata]' \
     '(           --no-scissors)--scissors[remove everything in body before a scissors line]' \
     '(--scissors              )--no-scissors[do not remove everything in body before a scissors line]' \
+    '--quoted-cr=[specify action when quoted CR is found]:action [warn]:(nowarn warn strip)' \
     '--no-inbody-headers[undocumented]' \
     ':message file:_files' \
     ':patch file:_files'
@@ -5890,7 +6104,8 @@ _git-merge-one-file () {
 _git-patch-id () {
    _arguments \
      '--stable[use a sum of hashes unaffected by diff ordering]' \
-     '--unstable[use patch-id compatible with git 1.9 and older]'
+     '--unstable[use patch-id compatible with git 1.9 and older]' \
+     "--verbatim[don't strip whitespace from the patch]"
 }
 
 # NOTE: git-sh-setup isn't a user command.
@@ -6105,6 +6320,7 @@ _git_commands () {
     blame:'show what revision and author last modified each line of a file'
     bugreport:'collect information for user to file a bug report'
     count-objects:'count unpacked objects and display their disk consumption'
+    diagnose:'generate an archive of diagnostic information'
     difftool:'show changes using common diff tools'
     fsck:'verify connectivity and validity of objects in database'
     help:'display help information about git'
@@ -6134,7 +6350,7 @@ _git_commands () {
     checkout-index:'copy files from index to working directory'
     commit-graph:'write and verify Git commit-graph files'
     commit-tree:'create new commit object'
-    hash-object:'compute object ID and optionally create a blob from a file'
+    hash-object:'compute object ID and optionally create an object from a file'
     index-pack:'build pack index file for an existing packed archive'
     merge-file:'run a three-way file merge'
     merge-index:'run merge for files needing merging'
@@ -6196,6 +6412,7 @@ _git_commands () {
     check-ref-format:'ensure that a reference name is well formed'
     column:'display data in columns'
     fmt-merge-msg:'produce merge commit message'
+    hook:'run git hooks'
     mailinfo:'extract patch and authorship from a single email message'
     mailsplit:'split mbox file into a list of files'
     merge-one-file:'standard helper-program to use with git merge-index'
@@ -6205,8 +6422,8 @@ _git_commands () {
   zstyle -a :completion:$curcontext: user-commands user_commands
 
   local command
-  for command in $_git_third_party_commands; do
-    (( $+commands[git-${command%%:*}] )) && third_party_commands+=$command
+  for command in ${(k)_git_third_party_commands}; do
+    (( $+commands[git-${command}] )) && third_party_commands+=$command$_git_third_party_commands[$command]
   done
 
   local -a aliases
@@ -6239,6 +6456,18 @@ _git_commands () {
   _alternative $alts
 }
 
+(( $+functions[_git_help_guides] )) ||
+_git_help_guides() {
+  local -a guides userint devint
+  guides=( ${${${(M)${(f)"$(_call_program git-guides git help -g)"}:# *}## #}/ ##/:} )
+  userint=( ${${${(M)${(f)"$(_call_program git-guides git help --user-interfaces)"}:# *}## #}/ ##/:} )
+  devint=( ${${${(M)${(f)"$(_call_program git-guides git help --developer-interfaces)"}:# *}## #}/ ##/:} )
+  _alternative \
+    'git-guides: : _describe -t git-guides guide guides' \
+    'user-interfaces: : _describe -t user-interfaces "user interface" userint' \
+    'developer-interfaces: : _describe -t developer-interfaces "developer interfaces" devint'
+}
+
 (( $+functions[__git_aliases] )) ||
 __git_aliases () {
   local -a aliases
@@ -6276,7 +6505,7 @@ __git_date_formats () {
   declare -a date_formats
 
   if compset -P 'format(-local|):'; then
-    _strftime
+    _date_formats
     return
   fi
 
@@ -6366,6 +6595,16 @@ __git_merge_strategies () {
       "git merge -s '' 2>&1")"}:#[Aa]vailable (custom )#strategies are: *}#[Aa]vailable (custom )#strategies are: }%.}:-octopus ours recursive resolve subtree}
 }
 
+(( $+functions[_git_strategy_options] )) ||
+_git_strategy_options() {
+  _values "strategy option" ours theirs ignore-space-change \
+    ignore-all-space ignore-space-at-eol ignore-cr-at-eol \
+    renormalize no-renormalize \
+    'find-renames::similarity threshold' \
+    subtree:path \
+    'diff-algorithm:algorithm:(patience minimal histogram myers)'
+}
+
 (( $+functions[__git_encodings] )) ||
 __git_encodings () {
   # TODO: Use better algorithm, as shown in iconv completer (separate it to a
@@ -6493,20 +6732,6 @@ __git_compression_levels () {
     '9:maximum compression'
 }
 
-(( $+functions[__git_attributes] )) ||
-__git_attributes () {
-  local -a attributes
-
-  attributes=(
-    'crlf:line-ending convention'
-    'ident:ident substitution'
-    'filter:filters'
-    'diff:textual diff'
-    'merge:merging strategy')
-
-  _describe -t attributes attribute attributes $*
-}
-
 (( $+functions[__git_daemon_service] )) ||
 __git_daemon_service () {
   local -a services
@@ -6518,6 +6743,31 @@ __git_daemon_service () {
   _describe -t services service services $*
 }
 
+(( $+functions[_git_log_line_ranges] )) ||
+_git_log_line_ranges() {
+  local sep pos=start op=( / : )
+  if compset -P '*[^,^]:'; then
+    __git_tree_files ${PREFIX:-.} HEAD
+  else
+    compset -P 1 '*,' && pos=end
+    if compset -P '(^|):'; then
+      _message -e functions function
+    elif compset -P '(^|)/'; then
+      _message -e patterns regex
+    else
+      zstyle -s ":completion:${curcontext}:forms" list-separator sep || sep=--
+      sep=' -- '
+      sep="${(q)sep}"
+      _guard "[0-9]#" "$pos line number" && return
+      compset -P \^ || op+=( \^ )
+      _wanted forms expl form compadd -S '' -d "(
+        /\ $sep\ regex
+        :\ $sep\ function
+        ^\ $sep\ search\ from\ start\ of\ file )" $op
+    fi
+  fi
+}
+
 (( $+functions[__git_log_decorate_formats] )) ||
 __git_log_decorate_formats () {
   declare -a log_decorate_formats
@@ -6897,7 +7147,6 @@ __git_heads_remote () {
 
 (( $+functions[__git_commit_objects] )) ||
 __git_commit_objects () {
-  local gitdir expl start
   declare -a commits
 
   if [[ -n $PREFIX[(r)@] ]] || [[ -n $SUFFIX[(r)@] ]]; then
@@ -6919,7 +7168,7 @@ __git_commit_objects () {
 
 (( $+functions[__git_recent_commits] )) ||
 __git_recent_commits () {
-  local gitdir expl start
+  local expl
   declare -a descr tags heads commits argument_array_names commit_opts
   local h i j k ret
   integer distance_from_head
@@ -7004,6 +7253,16 @@ __git_recent_commits () {
   return ret
 }
 
+(( $+functions[_git_fixup] )) ||
+_git_fixup() {
+  local alts
+  alts=( 'commits: :__git_recent_commits' )
+  if ! compset -P '(amend|reword):'; then
+    alts+=( 'actions:action:compadd -S: amend reword' )
+  fi
+  _alternative $alts
+}
+
 (( $+functions[__git_blob_objects] )) ||
 __git_blob_objects () {
   _guard '[[:xdigit:]](#c,40)' 'blob object name'
@@ -7193,6 +7452,16 @@ __git_remote_references () {
   __git_references
 }
 
+(( $+functions[_git_full_references] )) ||
+_git_full_references() {
+
+  if [[ $_git_full_refs_cache_pwd != $PWD ]]; then
+    _git_full_refs_cache=( ${(f)"$(_call_program references 'git for-each-ref --format=%\(refname\)')"} )
+    _git_full_refs_cache_pwd=$PWD
+  fi
+  _multi_parts "$@" / _git_full_refs_cache
+}
+
 (( $+functions[__git_notes_refs] )) ||
 __git_notes_refs () {
   local expl
@@ -7288,6 +7557,19 @@ __git_deleted_files () {
   __git_files --deleted deleted-files 'deleted file' $*
 }
 
+(( $+functions[__git_trailers_tokens] )) ||
+__git_trailers_tokens() {
+  declare -a trailers
+  local i
+
+  local -a gtrailers=( $(_call_program trailers git config --name-only --get-regexp '^trailer\..*\.key$') )
+  for i in $gtrailers; do
+    i=( ${${(@s:.:)i}[2,-2]} )
+    trailers+=( ${(j|.|)i} )
+  done
+  _wanted trailers expl "trailer" compadd -a trailers
+}
+
 (( $+functions[__git_modified_files] )) ||
 __git_modified_files () {
   __git_files --modified modified-files 'modified file' $*
@@ -7506,13 +7788,68 @@ __git_guard_number () {
 
 (( $+functions[__git_guard_bytes] )) ||
 __git_guard_bytes () {
-  _guard '[[:digit:]]#([kKmMgG]|)' ${*:-size}
+  _numbers -u bytes ${*:-size} k m g
 }
 
-(( $+functions[__git_datetimes] )) ||
-__git_datetimes () {
-  # TODO: Use this in more places.
-  _guard '*' 'time specification'
+(( $+functions[_git_approxidates] )) ||
+_git_approxidates() {
+  local MATCH MBEGIN MEND
+  local match mbegin mend
+  local -i date time num
+  local -a months=( January February March April May June July August September
+      October November December )
+  local -a weekdays=( Sunday Monday Tuesday Wednesday Thursday Friday Saturday )
+  local -a numbers=( zero one two three four five six seven eight nine ten )
+  local -a periods=( second minute hour day week month year )
+  local -a suf=( -S. -r "._,+\\ \t\n\-" )
+
+  local -a pexpl
+  zparseopts -D -E X+:=pexpl
+
+  local -a query=(
+    \( /$'*\0[ \t\n]#'/ \)
+    \( '/[]/' ':dates:date:compadd "${pexpl[@]:/-X/-x}"'
+    \| '/(@|[0-9](#c9))/' ':specials:special:compadd -S "" @' '/[]/' ': _message -e epochtimes "seconds since Unix epoch"'
+    \| '/(#i)(now|never)/' '%?%' ':specials:special:(now never)' '/[]/'
+    \| \)
+    \(
+      \( '/(#i)(one|last)/' '%[ ._,+]%' -'num=1'
+      \| '/[0-9](#c2,4)(-|/|.|)[0-9](#c1,2)(-|/|.|)[0-9](#c1,4)(|T)/' -'date=3'
+      \| '/[0-9](#c2)(:|)[0-9](#c2)(:|)[0-9](#c2)(.<->|)/' -'time=1'
+      \| '/20/' -'((!date))' '/[]/' ':dates:date:_dates -f "%y-%m-%d"'
+      \| '/1/' -'num=1'
+      \| '/<->/' -'num=2'
+      \| "/(#i)(${(j.|.)numbers})/" '%[ ._,+]%' -'num=2'
+      \| "/(#i)(${(j.|.)${(@)months//(#b)(???)(*)/$match[1]${match[2]//(#m)?/(|$MATCH}${match[2]//?/)}}})/"
+         '%[ ._,+]%' -'(( num = 0, date |= 2 ))'
+      \| "/(#i)(${(j.|.)${(@)weekdays//(#b)(???)(*)/$match[1]${match[2]//(#m)?/(|$MATCH}${match[2]//?/)}}})(|s)/"
+         '%[ ._,+]%' -'(( num = 0, date |= 1 ))'
+      \| '/(#i)yesterday/' '%[ ._,+]%' -'date=3'
+      \| "/(#i)(${(j.|.)${(@)periods%s}})(|s)/" '%[ ._,+]%' -'num=0'
+      \| '/(#i)(noon|midnight|tea|[ap]m)/' '%[ ._,+]%' -'time=1'
+      \|
+        \( // -'(( !(date&2) ))' // ':months:month:compadd -o nosort $suf -a months' \| \)
+        \( // -'(( num <= 1 && !(date&1) ))' // ':weekdays:weekday:compadd $suf -o nosort -a weekdays' \| \)
+        \( // -'(( num > 1 ))'
+          \( // -'(( date < 3 ))' // ':periods:period:compadd $suf -o nosort ${^periods[4,-1]}s' \| \)
+          \( // -'(( !(date&1) ))' // ':weekdays:weekday:compadd $suf -o nosort ${^weekdays}s' \| \)
+          \( // -'(( !time ))' // ':periods:period:compadd $suf -o nosort ${^periods[1,3]}s' \| \)
+        \| // -'(( num == 1 ))'
+          \( // -'(( date < 3 ))' // ':periods:period:compadd $suf -o nosort -a "periods[4,-1]"' \| \)
+          \( // -'(( !time ))' // ':periods:period:compadd $suf -o nosort -a "periods[1,3]"' \| \)
+        \| // -'(( num == 0 ))'
+          \( // -'(( !time ))' // ':specials:special:compadd $suf noon midnight tea AM PM' \| \)
+          \( // -'(( !date ))' // ':specials:special:compadd $suf yesterday' \| \)
+          // ':specials:special:compadd $suf last' # "last" is equivalent to "one"
+          // ':numbers:number:compadd $suf -n -o nosort -a numbers'
+        \)
+        '/[]/'
+      \) '/([ ._,+]|)/'
+    \) \#
+  )
+
+  _regex_arguments _git_dates "$query[@]"
+  _git_dates
 }
 
 (( $+functions[__git_stages] )) ||
@@ -7532,6 +7869,7 @@ __git_setup_log_options () {
   # TODO: Need to implement -<n> for limiting the number of commits to show.
   log_options=(
     '(- *)-h[display help]'
+    '--clear-decorations[clear all previously-defined decoration filters]'
     '--decorate-refs=[only decorate refs that match pattern]:pattern'
     "--decorate-refs-exclude=[don't decorate refs that match pattern]:pattern"
     '(           --no-decorate)--decorate=-[print out ref names of any commits that are shown]: :__git_log_decorate_formats'
@@ -7539,7 +7877,7 @@ __git_setup_log_options () {
     '(          --no-follow)--follow[follow renames]'
     '(--follow             )--no-follow[do not follow renames]'
     '--source[show which ref each commit is reached from]'
-    '-L+[trace the evolution of a line range or regex within a file]:range'
+    '*-L+[trace evolution of line range, function or regex within a file]: :_git_log_line_ranges'
   )
 }
 
@@ -7572,8 +7910,9 @@ __git_setup_diff_options () {
   local exclusive_diff_options='(--name-only --name-status --check -s --no-patch)'
 
   diff_options=(
-    {-p,-u,--patch}'[generate diff in patch format]'
-    {-U,--unified=}'[generate diff with given lines of context]: :__git_guard_number lines'
+    '(-p -u --patch)'{-p,-u,--patch}'[generate diff in patch format]'
+    '(-U --unified -W --function-context)'{-U-,--unified=-}'[generate diff with given lines of context]:: :__git_guard_number lines'
+    '(-U --unified -W --function-context)'{-W,--function-context}'[show whole function where a match was found]' \
     '--raw[generate default raw diff output]'
     '--patch-with-raw[generate patch but also keep the default raw diff output]'
     $exclusive_diff_options{-s,--no-patch}'[suppress diff output]'
@@ -7622,7 +7961,7 @@ __git_setup_diff_options () {
     '--full-index[show full object name of pre- and post-image blob]'
     '(--full-index)--binary[in addition to --full-index, output binary diffs for git-apply]'
     '--ws-error-highlight=[specify where to highlight whitespace errors]: :__git_ws_error_highlight'
-    '--abbrev=[set minimum SHA1 display-length]: :__git_guard_number length'
+    '--abbrev=[use specified digits to display object names]:digits'
     '(-B --break-rewrites)'{-B-,--break-rewrites=-}'[break complete rewrite changes into pairs of given size]:: :__git_guard_number size'
     '(-M --find-renames)'{-M-,--find-renames=-}'[detect renames with given scope]:: :__git_guard_number size'
     '(-C --find-copies)'{-C-,--find-copies=-}'[detect copies as well as renames with given scope]:: :__git_guard_number size'
@@ -7634,10 +7973,12 @@ __git_setup_diff_options () {
     '--diff-filter=-[select certain kinds of files for diff]: :_git_diff_filters'
     '-S-[look for differences that add or remove the given string]:string'
     '-G-[look for differences whose added or removed line matches the given regex]:pattern'
-    '--find-object=[look for differences that change the number of occurrences of the specified object]:object:__git_blobs'
     '--pickaxe-all[when -S finds a change, show all changes in that changeset]'
     '--pickaxe-regex[treat argument of -S as regular expression]'
     '-O-[output patch in the order of glob-pattern lines in given file]: :_files'
+    '--rotate-to=[show the change in specified path first]:path:_directories'
+    '--skip-to=[skip the output to the specified path]:path:_directories'
+    '--find-object=[look for differences that change the number of occurrences of specified object]:object:__git_blobs'
     '-R[do a reverse diff]'
     '--relative=-[exclude changes outside and output relative to given directory]:: :_directories'
     '(-a --text)'{-a,--text}'[treat all files as text]'
@@ -7645,13 +7986,13 @@ __git_setup_diff_options () {
     '--ignore-cr-at-eol[ignore carriage-return at end of line]'
     '(-b --ignore-space-change -w --ignore-all-space)'{-b,--ignore-space-change}'[ignore changes in amount of white space]'
     '(-b --ignore-space-change -w --ignore-all-space)'{-w,--ignore-all-space}'[ignore white space when comparing lines]'
-    '--ignore-blank-lines[do not show hunks that add or remove blank lines]'
+    '--ignore-blank-lines[ignore changes whose lines are all blank]'
+    \*{-I+,--ignore-matching-lines=}'[ignore changes whose lines all match regex]:regex'
     '--no-indent-heuristic[disable heuristic that shifts diff hunk boundaries to make patches easier to read]'
     '--inter-hunk-context=[combine hunks closer than N lines]:number of lines'
     '--output-indicator-new=[specify the character to indicate a new line]:character [+]'
     '--output-indicator-old=[specify the character to indicate a old line]:character [-]'
     '--output-indicator-context=[specify the character to indicate a context line]:character [ ]'
-    '--exit-code[report exit code 1 if differences, 0 otherwise]'
     '(           --no-ext-diff)--ext-diff[allow external diff helper to be executed]'
     '(--ext-diff              )--no-ext-diff[disallow external diff helper to be executed]'
     '(--textconv --no-textconv)--textconv[allow external text conversion filters to be run when comparing binary files]'
@@ -7660,12 +8001,13 @@ __git_setup_diff_options () {
     '(--no-prefix)--src-prefix=[use given prefix for source]:prefix'
     '(--no-prefix)--dst-prefix=[use given prefix for destination]:prefix'
     '--line-prefix=[prepend additional prefix to every line of output]:prefix'
-    '(--src-prefix --dst-prefix)--no-prefix[do not show any source or destination prefix]'
-
+    "(--src-prefix --dst-prefix)--no-prefix[don't show any source or destination prefix]"
+    '!(--src-prefix --dst-prefix --no-prefix)--default-prefix'
     '(-c --cc)'{-c,--cc}'[combined diff format for merge commits]'
-
-    # TODO: --output is undocumented.
-    '--output[undocumented]:undocumented')
+    '--output=[output to a specific file]: :_files'
+    '--expand-tabs=-[replace each tab with spaces]::tab width [8]'
+    '!(--expand-tabs)--no-expand-tabs'
+  )
 }
 
 (( $+functions[__git_setup_diff_stage_options] )) ||
@@ -7775,11 +8117,15 @@ __git_format_placeholders() {
 
 (( $+functions[__git_setup_revision_options] )) ||
 __git_setup_revision_options () {
-  local -a diff_options
-  __git_setup_diff_options
+  if [[ $1 = "-d" ]]; then # don't include diff options if passed -d
+    revision_options=()
+  else
+    local -a diff_options
+    __git_setup_diff_options
+    revision_options=( $diff_options )
+  fi
 
-  revision_options=(
-    $diff_options
+  revision_options+=(
     '(-v --header)'{--pretty=-,--format=-}'[pretty print commit messages]::format:__git_format_placeholders'
     '(--abbrev-commit --no-abbrev-commit)--abbrev-commit[show only partial prefixes of commit object names]'
     '(--abbrev-commit --no-abbrev-commit)--no-abbrev-commit[show the full 40-byte hexadecimal commit object name]'
@@ -7799,8 +8145,8 @@ __git_setup_revision_options () {
     '--count[display how many commits would have been listed]'
     '(-n --max-count)'{-n+,--max-count=}'[maximum number of commits to display]: :__git_guard_number'
     '--skip=[skip given number of commits before output]: :__git_guard_number'
-    '(--max-age --since --after)'{--since=,--after=}'[show commits more recent than given date]:date'
-    '(--min-age --until --before)'{--until=,--before=}'[show commits older than given date]: :__git_guard_number timestamp'
+    '(--max-age --since --after)'{--since=,--after=}'[show commits more recent than given date]: :_git_approxidates'
+    '(--min-age --until --before)'{--until=,--before=}'[show commits older than given date]: :_git_approxidates'
     '(          --since --after)--max-age=-[maximum age of commits to output]: :__git_guard_number timestamp'
     '(          --until --before)--min-age[minimum age of commits to output]: :__git_guard_number timestamp'
     '*--author=[limit commits to those by given author]:author'
@@ -7827,8 +8173,7 @@ __git_setup_revision_options () {
     '--tags=-[show all commits from refs/tags]::pattern'
     '--remotes=-[show all commits from refs/remotes]::pattern'
     '--glob=[show all commits from refs matching glob]:pattern'
-    '--exclude=[do not include refs matching glob]:pattern'
-    '--exclude=[do not include refs matching glob]:pattern'
+    "--exclude=[don't include refs matching glob]:pattern"
     '--ignore-missing[ignore invalid object an ref names on command line]'
     '--bisect[pretend as if refs/bisect/bad --not refs/bisect/good-* was given on command line]'
     '(-g --walk-reflogs --reverse)'{-g,--walk-reflogs}'[walk reflog entries from most recent to oldest]'
@@ -7856,7 +8201,7 @@ __git_setup_revision_options () {
     '(--left-only --right-only --cherry-pick --cherry-mark --no-merges --merges --max-parents)--cherry[synonym for --right-only --cherry-mark --no-merges]'
     '(-c --cc            )--full-diff[show full commit diffs when using log -p, not only those affecting the given path]'
     '--log-size[print log message size in bytes before the message]'
-    '--use-mailmap[use mailmap file to map author and committer names and email]'
+    --{use-,}mailmap'[use mailmap file to map author and committer names and email]'
 
     '--reflog[show all commits from reflogs]'
     '--single-worktree[examine the current working tree only]'
@@ -7886,13 +8231,14 @@ __git_setup_merge_options () {
     '(-n --no-stat)--stat[show a diffstat at the end of the merge]'
     '(--stat -n --no-stat)'{-n,--no-stat}'[do not show diffstat at the end of the merge]'
     '(         --no-squash)--squash[merge, but do not commit]'
-    '--signoff[add Signed-off-by:]'
+    '--autostash[automatically stash/stash pop before and after]'
+    '--signoff[add Signed-off-by: trailer]'
     '(--squash            )--no-squash[merge and commit]'
     '--ff-only[refuse to merge unless HEAD is up to date or merge can be resolved as a fast-forward]'
     '(-S --gpg-sign --no-gpg-sign)'{-S-,--gpg-sign=-}'[GPG-sign the commit]::key id'
     "(-S --gpg-sign --no-gpg-sign)--no-gpg-sign[don't GPG-sign the commit]"
-    '*'{-s,--strategy=}'[use given merge strategy]:merge strategy:__git_merge_strategies'
-    '*'{-X,--strategy-option=}'[pass merge-strategy-specific option to merge strategy]:option'
+    '*'{-s+,--strategy=}'[use given merge strategy]:merge strategy:__git_merge_strategies'
+    '*'{-X+,--strategy-option=}'[pass merge-strategy-specific option to merge strategy]: :_git_strategy_options'
     '(--verify-signatures)--verify-signatures[verify the commits being merged or abort]'
     '(--no-verify-signatures)--no-verify-signatures[do not verify the commits being merged]'
     '(-q --quiet -v --verbose)'{-q,--quiet}'[suppress all output]'
@@ -7913,6 +8259,7 @@ __git_setup_fetch_options () {
     '--refmap=[specify refspec to map refs to remote tracking branches]:refspec'
     '(-4 --ipv4 -6 --ipv6)'{-4,--ipv4}'[use IPv4 addresses only]'
     '(-4 --ipv4 -6 --ipv6)'{-6,--ipv6}'[use IPv6 addresses only]'
+    '--porcelain[machine-readable output]'
     '--dry-run[show what would be done, without making any changes]'
     '(-f --force)'{-f,--force}'[force overwrite of local reference]'
     '(-k --keep)'{-k,--keep}'[keep downloaded pack]'
@@ -7932,6 +8279,11 @@ __git_setup_fetch_options () {
     '(-q --quiet)--progress[force progress reporting]'
     '--show-forced-updates[check for forced-updates on all updated branches]'
     '--set-upstream[set upstream for git pull/fetch]'
+    '--shallow-since=[deepen history of shallow repository based on time]:time' \
+    '*--shallow-exclude=[deepen history of shallow clone by excluding revision]:revision' \
+    '--deepen[deepen history of shallow clone]:number of commits' \
+    \*{-o+,--server-option=}'[send specified string to the server when using protocol version 2]:option'
+    '--negotiation-tip=[only report refs reachable from specified object to the server]:commit:__git_commits' \
   )
 }
 
@@ -8302,19 +8654,19 @@ _git() {
     # TODO: This needs an update
     # TODO: How do we fix -c argument?
     _arguments -C \
-      '(- :)--version[display version information]' \
+      '(- :)'{-v,--version}'[display version information]' \
       '(- :)--help[display help message]' \
       '-C[run as if git was started in given path]: :_directories' \
-      '*-c[pass configuration parameter to command]: :->configuration' \
+      \*{-c,--config-env=}'[pass configuration parameter to command]: :->configuration' \
       '--exec-path=-[path containing core git-programs]:: :_directories' \
       '(: -)--man-path[print the manpath for the man pages for this version of Git and exit]' \
       '(: -)--info-path[print the path where the info files are installed and exit]' \
       '(: -)--html-path[display path to HTML documentation and exit]' \
       '(-p --paginate -P --no-pager)'{-p,--paginate}'[pipe output into a pager]' \
       '(-p --paginate -P --no-pager)'{-P,--no-pager}"[don't pipe git output into a pager]" \
-      '--git-dir=-[path to repository]: :_directories' \
-      '--work-tree=-[path to working tree]: :_directories' \
-      '--namespace=-[set the Git namespace]:namespace' \
+      '--git-dir=[path to repository]: :_directories' \
+      '--work-tree=[path to working tree]: :_directories' \
+      '--namespace=[set the Git namespace]:namespace' \
       '--bare[use $PWD as repository]' \
       '--no-replace-objects[do not use replacement refs to replace git objects]' \
       '--literal-pathspecs[treat pathspecs literally, rather than as glob patterns]' \
@@ -8361,7 +8713,7 @@ _git() {
 }
 
 # Load any _git-* definitions so that they may be completed as commands.
-declare -gUa _git_third_party_commands
+declare -gA _git_third_party_commands
 _git_third_party_commands=()
 
 local file input
@@ -8383,7 +8735,7 @@ for file in ${^fpath}/_git-*~(*~|*.zwc)(-.N); do
     (( i++ ))
   done < $file
 
-  _git_third_party_commands+=$name$desc
+  _git_third_party_commands+=([$name]=$desc)
 done
 
 _git
diff --git a/Completion/Unix/Command/_global b/Completion/Unix/Command/_global
index ffd8c0dce..4ffd7f8ce 100644
--- a/Completion/Unix/Command/_global
+++ b/Completion/Unix/Command/_global
@@ -9,15 +9,18 @@ _arguments \
   "$cmds"{-I,--idutils}'[print all lines which match pattern using id-utils]:pattern' \
   "$cmds"{-p,--print-dbpath}'[print location of GTAGS]' \
   "$cmds"{-P,--path}'[print paths matching pattern]:pattern:' \
+  "$cmds"'--print[print locate of root/dbpath/conf]:name:(root dbpath conf)' \
   "$cmds"{-u,--update}'[locate tag files and update incrementally]' \
   '(-a --absolute)'{-a,--absolute}'[print absolute path names]' \
   '(--color)--color=-[color matches]::color:(always auto never)' \
+  '(-C --directory)'{-C,--directory}'[change the directory before doing all the work]:dir:_files -/' \
   '(-d --definition)'{-d,--definition}'[print locations of definitions]' \
   '(-e --regexp :)'{-e,--regexp}'[specify pattern]:pattern:_global_tags' \
+  '(-E --extended-regexp -G --basic-regexp)'{-E,--extended-regexp}'[interpret pattern as a extended regular expression]' \
   '(--encode-path)--encode-path=-[encode path characters in hexadecimal representation]:format' \
   '(-F --first-match)'{-f,--first-match}'[stop searching if tag is found in current tag file]' \
   '(--from-here)--from-here=-[decide tag type by context]:line_path:' \
-  '(-G --basic-regexp :)'{-G,--basic-regexp}'[specify basic regexp to use]:word:_global_tags' \
+  '(-E --extended-regexp -G --basic-regexp)'{-G,--basic-regexp}'[interpret pattern as a basic regular expression]' \
   '(--gtagsconf)--gtagsconf=-[set environment variable GTAGSCONF]:file:_files' \
   '(--gtagslabel)--gtagslabel=-[set environment variable GTAGSLABEL]:file:_files' \
   '(-i --ignore-case)'{-i,--ignore-case}'[ignore case in patterns]' \
@@ -27,6 +30,7 @@ _arguments \
   '(-M --match-case)'{-m,--match-case}'[enable case sensitive search]' \
   '(--match-part)--match-part=-[specify how path name completion should match]::part:(first last all)' \
   '(-n --nofilter)'{-n,--nofilter}'[suppress sort filter and path conversion filter]' \
+  '(-N --nearness)'{-N,--nearness=-}'[use nearness sort method for the output]:start:_files' \
   '(-O --only-other)'{-O,--only-other}'[search only text files]' \
   '(-o --other)'{-o,--other}'[search in other files, not just source files (with -g)]' \
   '(--path-style)--path-style=-[specify path style]::style:(relative absolute shorter abslib through)' \
@@ -34,11 +38,12 @@ _arguments \
   '(-q --quiet)'{-q,--quiet}'[quiet mode]' \
   '(-r --reference --rootdir)'{-r,--reference,--rootdir}'[find object references instead of definitions]' \
   '(--result)--result=-[specify result format]::format:(path ctags ctags-x grep cscope)' \
-  '(- :)--single-update=-[updata tag for specified file]:file:_files' \
+  '(- :)--single-update=-[update tag for specified file]:file:_files' \
   '(-s --symbol)'{-s,--symbol}'[find symbols instead of function names]:pattern' \
   '(-t --tags)'{-t,--tags}'[output in standard ctags format]' \
   '(-T --through -s -r -l)'{-T,--through}'[search through all tag files in GTAGSLIBPATH]' \
   '(-v --verbose)'{-v,--verbose}'[verbose mode]' \
+  '(-V --invert-match)'{-V,--invert-match}'[invert the sense of matching, to select non-matching lines]' \
   '(-x --cxref)'{-x,--cxref}'[additionally list line number and contents]' \
   '(- :)--version[display version information]' \
   '(- :)--help[display help information]' \
diff --git a/Completion/Unix/Command/_gnutls b/Completion/Unix/Command/_gnutls
index b9f91264d..9b8bcf6ea 100644
--- a/Completion/Unix/Command/_gnutls
+++ b/Completion/Unix/Command/_gnutls
@@ -4,8 +4,7 @@ local -a args
 
 args=(
   '(- :)'{-h,--help}'[display help information]'
-  '(- :)--version=[display version information]:information:((v\:simple c\:copyright n\:full))'
-  '(- :)-v[display version information]'
+  '(- :)'{-v+,--version=-}'[display version information]:information:((v\:simple c\:copyright n\:full))'
   '(- :)'{-\!,--more-help}'[display help information through a pager]'
   '(-d --debug)'{-d,--debug}'[enable debugging]:debug level'
   \*{-V,--verbose}'[more verbose output]'
@@ -17,6 +16,11 @@ case "$service" in
       '(-p --port)'{-p,--port}'[specify port or service to connect to]:port:_ports'
     )
   ;|
+  gnutls-*|certtool)
+    args+=(
+      '--attime=[perform validation at the timestamp instead of the system time]:timestamp'
+    )
+  ;|
   gnutls-cli*)
     args+=(
       '(--app-proto --starttls-proto)'{--app-proto,--starttls-proto}"=[specify application protocol to use to obtain the server's certificate]:protocol:(https ftp smtp imap ldap xmpp lmtp pop3 nntp sieve postgres)"
@@ -30,6 +34,7 @@ case "$service" in
       '(-u --udp)'{-u,--udp}'[use DTLS (datagram TLS) over UDP]'
       '--mtu=[set MTU for datagram TLS]:mtu'
       '--srtp-profiles=[offer SRTP profiles]:string'
+      '*--compress-cert=[compress certificate]:compression method'
       '(-b --heartbeat)'{-b,--heartbeat}'[activate heartbeat support]'
       '--x509fmtder[use DER format for certificates to read from]'
       '--priority=[specify TLS algorithms and protocols to enable]:(NORMAL PFS SECURE128 SECURE192 SUITEB128 SUITEB192 LEGACY PERFORMANCE NONE)'
@@ -94,7 +99,8 @@ case "$service" in
       '--post-handshake-auth[enable post-handshake authentication under TLS1.3]'
       '--inline-commands[inline commands of the form ^<cmd>^]'
       '--inline-commands-prefix=[change delimiter used for inline commands]:delimiter [^]'
-      '--fips140-mode[report status of FIPS140-2 mode in gnutls library]'
+      '--fips140-mode[report status of FIPS140-3 mode in gnutls library]'
+      '--list-config[report configuration of the library]'
       '--logfile=[redirect informational messages to a specific file]:file:_files'
       '--waitresumption[block waiting for the resumption data under TLS1.3]'
       '--ca-auto-retrieve[enable automatic retrieval of missing CA certificates]'
@@ -127,6 +133,7 @@ case "$service" in
       '--ignore-ocsp-response-errors[ignore any errors when setting the OCSP response]'
       '--recordsize=[specify maximum record size to advertise]:record size (0-16384)'
       '--httpdata=[specify data to use as HTTP response]:file:_files'
+      '--timeout=[specify he timeout period for server]:timeout'
     )
   ;;
 
diff --git a/Completion/Unix/Command/_gpg b/Completion/Unix/Command/_gpg
index 5d54865d5..2161d2d24 100644
--- a/Completion/Unix/Command/_gpg
+++ b/Completion/Unix/Command/_gpg
@@ -93,6 +93,7 @@ fi
   '--no-default-recipient[reset default recipient]'
   '*--encrypt-to[specify recipient]:key:->public-keys'
   '(--encrypt-to)--no-encrypt-to[disable the use of all --encrypt-to keys]'
+  '--group[set up email aliases]:spec'
   '-z[specify compression level]:compression level:((0\:no\ compression 1\:minimum 2 3 4 5 6\:default 7 8 9\:maximum))'
   '(-t --textmode)'{-t,--textmode}'[use canonical text mode]'
   '(-n --dry-run)'{-n,--dry-run}"[don't make any changes]"
@@ -117,6 +118,7 @@ fi
   '--utf8-strings' '--no-utf8-strings[arguments are not in UTF8]'
   '(--no-options)--options[specify file to read options from]:options file:_files'
   "(--options)--no-options[don't read options file]"
+  '--log-file[write server mode logs to file]:file:_files'
   '--'{attribute,passphrase,command}'-fd:file descriptor:_file_descriptors'
   '--sk-comments[include secret key comments when exporting keys]'
   '(--emit-version)--no-emit-version[omit version string in clear text signatures]'
@@ -170,6 +172,9 @@ fi
   '--ctapi-driver[file to use to access smartcard reader]:file:_files'
   '--pcsc-driver[file to use to access smartcard reader]:file:_files'
   '--auto-key-locate:parameters'
+  '--auto-key-import[import missing key from a signature]'
+  '--include-key-block[include the public key in signatures]'
+  '--disable-dirmngr[disable all access to the dirmngr]'
   '--dump-options[show all options]'
 )
 
diff --git a/Completion/Unix/Command/_gprof b/Completion/Unix/Command/_gprof
index a7e602fd5..6b97506a6 100644
--- a/Completion/Unix/Command/_gprof
+++ b/Completion/Unix/Command/_gprof
@@ -4,7 +4,7 @@ local curcontext="$curcontext" state line ret=1
 typeset -A opt_args
 
 _arguments -C -s -{a,b,c,D,h,i,l,L,r,s,T,v,w,x,y,z} \
-           -{A,C,e,E,f,F,J,n,N,O,p,P,q,Q,R,S,t,Z}:'function name:->funcs' \
+           -{A,B,C,e,E,f,F,J,n,N,O,p,P,q,Q,R,S,t,Z}:'function name:->funcs' \
 	   '-I:directory:_dir_list' \
 	   '-d-:debug level:' '-k:function names:->pair' \
 	   '-m:minimum execution count:' \
diff --git a/Completion/Unix/Command/_gradle b/Completion/Unix/Command/_gradle
index adf5e9aa8..280aa243f 100644
--- a/Completion/Unix/Command/_gradle
+++ b/Completion/Unix/Command/_gradle
@@ -1,13 +1,24 @@
 #compdef gradle gradlew
 
-local curcontext="$curcontext" ret=1 state state_descr line
-local gradle_inspect=yes cache_policy tag_order
-local -A opt_args
-local -a gradle_group_tasks gradle_all_tasks
+local -i ret=1
+local curcontext="$curcontext" state state_descr outputline
+local gradle_inspect=yes gradle_buildfile cache_policy cache_name tag_order filter
+local -A opt_args task_map
+local -aU gradle_subprojects gradle_tasks tasks
+local -a match mbegin mend
 
-# Set the caching policy to invalidate cache if the build file is newer than the cache.
 _gradle_caching_policy() {
-    [[ $gradle_buildfile -nt $1 ]]
+    # Invalidate the cache if it cannot be read.
+    [[ -r "$1" ]] ||
+            return 0
+
+    # Invalidate the cache if it's older than the build file.
+    [[ $gradle_buildfile -nt $1 ]] &&
+            return
+
+    # Invalidate the cache if it doesn't contain the required arrays.
+    local cache="$( < $1 )"
+    [[ "$cache" != *'gradle_subprojects=('*')'* || "$cache" != *'gradle_tasks=('*')'* ]]
 }
 
 zstyle -s ":completion:*:*:$service:*" cache-policy cache_policy || \
@@ -59,54 +70,73 @@ _arguments -C \
     '(-)--stop[Stops the Gradle daemon if it is running.]' \
     {-u,--no-search-upward}"[Don't search in parent folders for a settings.gradle file.]" \
     '(-)'{-v,--version}'[Print version info.]' \
-    {-x,--exclude-task}'[Specify a task to be excluded from execution.]:task to exclude:->alltask' \
+    {-x,--exclude-task}'[Specify a task to be excluded from execution.]:task to exclude:->task' \
     '*:task:->task' \
     && ret=0
 
-if [[ $words[CURRENT] != -* ]]; then
+if [[ $state == task && ! -prefix - ]]; then
+    # :<task> runs <task> in the root project only.
+    # :<subproject>:<task> is the same as <subproject>:<task> (without the leading colon).
+    compset -P \:
+
     if [[ $gradle_inspect == yes ]]; then
         # If a build file is specified after '-b' or '--build-file', use this file. Otherwise,
         # default is the file 'build.gradle' in the current directory.
-        local gradle_buildfile=${${(v)opt_args[(i)-b|--build-file]}:-build.gradle}
+        gradle_buildfile=${${(v)opt_args[(i)-b|--build-file]}:-build.gradle}
 
         if [[ -f $gradle_buildfile ]]; then
             # Cache name is constructed from the absolute path of the build file.
-            local cache_name=${${gradle_buildfile:a}//[^[:alnum:]]/_}
+            cache_name=${${gradle_buildfile:a}//[^[:alnum:]]/_}
+
             if _cache_invalid $cache_name || ! _retrieve_cache $cache_name; then
                 zle -R "Generating cache from $gradle_buildfile"
-                local outputline
-                local -a match mbegin mend
+
                 # Run gradle/gradlew and retrieve possible tasks.
-                for outputline in ${(f)"$($service --build-file $gradle_buildfile -q tasks --all)"}; do
-                    if [[ $outputline == [[:blank:]]#(#b)([[:alnum:]]##)' - '(*) ]]; then
-                        # The descriptions of main tasks start at beginning of line, descriptions of
-                        # secondary tasks are indented.
-                        if [[ $outputline == [[:alnum:]]* ]]; then
-                            gradle_group_tasks+=( "$match[1]:$match[2]" )
+                for outputline in ${(f)"$($words[1] --build-file $gradle_buildfile -q tasks --all)"}; do
+
+                    # Tasks and subprojects each start with a lowercase letter, but whereas tasks are in camelCase, each
+                    # subproject consists of one or more sections of kebab-case, with each section ending in a ':'.
+                    # A subproject task is a task prefixed with a subproject and runs in that project only.
+                    # Specifying a task without a subproject prefix runs the task in all subprojects where it exists.
+                    # Tasks prefixed by whitespace are dependencies of the task above them and should be ignored.
+                    if [[ $outputline == (#b)([[:lower:]][-[:lower:][:digit:]]#\:)#([[:lower:]][[:alnum:]]#)(|' - '*) ]]
+                    then
+                        task=$match[-2]
+                        task_descr=${match[-1]# - }
+                        shift -p 2 match
+                        subproject=${(j::)match//:/'\:'}
+
+                        if [[ -n $subproject ]]; then
+                            gradle_subprojects+=( ${subproject%'\:'} )
+                            task_map[$subproject$task]=$task_descr
+
+                            # We cannot count on the description of a subproject task to be representative of the task
+                            # in general.
+                            : ${task_map[$task]=}
                         else
-                            gradle_all_tasks+=( "$match[1]:$match[2]" )
+                            task_map[$task]=$task_descr
                         fi
                     fi
                 done
-                _store_cache $cache_name gradle_group_tasks gradle_all_tasks
+                printf -v gradle_tasks '%s:%s' "${(kv@)task_map}"
+                _store_cache $cache_name gradle_subprojects gradle_tasks
             fi
 
-            if [[ $state == task ]]; then
-                _tags gradle_group gradle_all
-                while _tags; do
-                    # Offer main tasks and secondary tasks in different tags.
-                    _requested gradle_group && _describe 'group task' gradle_group_tasks && ret=0
-                    _requested gradle_all && _describe 'secondary task' gradle_all_tasks && ret=0
-                    (( ret )) || break
-                done
-            elif [[ $state == alltask ]]; then
-                # After '--exclude-task', we don't make a distinction between main tasks and
-                # secondary tasks.
-                _describe 'task' gradle_group_tasks -- gradle_all_tasks && ret=0
+            if [[ $IPREFIX == *: ]] || ! zstyle -T ":completion:${curcontext}:subprojects" prefix-needed; then
+                _describe -t subprojects 'gradle subproject' gradle_subprojects -S \: &&
+                        ret=0
+            fi
+            if [[ $PREFIX == *:* ]] || ! zstyle -T ":completion:${curcontext}:tasks" prefix-needed; then
+                tasks=( $gradle_tasks[@] )
+            else
+                # If no subproject is specified, then filter out all subproject tasks.
+                tasks=( ${gradle_tasks[@]:#*'\:'*} )
             fi
+            _describe -t tasks 'gradle task' tasks &&
+                    ret=0
         fi
     else
-        _describe 'built-in task' '(
+        _describe -t tasks 'built-in task' '(
             "dependencies:Displays all dependencies declared in root project."
             "dependencyInsight:Displays the insight into a specific dependency in root project."
             "help:Displays a help message."
diff --git a/Completion/Unix/Command/_grep b/Completion/Unix/Command/_grep
index 2dcbff4a3..0f1e712fd 100644
--- a/Completion/Unix/Command/_grep
+++ b/Completion/Unix/Command/_grep
@@ -89,7 +89,7 @@ case $variant:$OSTYPE in
   ;|
   gpl2:(freebsd|darwin)*)
     arguments+=(
-      '(--null --no-filename -h)--null[print 0 byte after each filename]'
+      '(--no-filename -h)--null[print 0 byte after each filename]'
       '(-Z --decompress -J --bz2decompress)'{-J,--bz2decompress}"[decompress bzip2'ed input before searching]"
       '(-Z --decompress -J --bz2decompress)'{-Z,--decompress}"[decompress gzip'ed input before searching]"
     )
@@ -129,6 +129,7 @@ case $variant:$OSTYPE in
     arguments=(
       ${(M)arguments:#((#s)|*\))--(context|binary-files|line-buffered|label|max-count)*}
       ${${arguments:#((#s)|*\))(\*|)-[d-]*}/\)-r/\)-R}
+      '(-h)--null[print 0 byte after each filename]'
       "-U[search binary files but don't print them]"
       '-Z[behave as zgrep]'
     )
diff --git a/Completion/Unix/Command/_head b/Completion/Unix/Command/_head
index f25c97c83..8877600f6 100644
--- a/Completion/Unix/Command/_head
+++ b/Completion/Unix/Command/_head
@@ -9,6 +9,7 @@ if _pick_variant gnu=GNU unix --version; then
     '(-n --lines -c --bytes)'{-n+,--lines=}'[print the first (or with -, all but the last) specified lines]:number of lines:->number'
     '(-q --quiet --silent -v --verbose)'{-q,--quiet,--silent}'[never print headers giving file names]'
     '(-q --quiet --silent -v --verbose)'{-v,--verbose}'[always print headers giving file names]'
+    '(-z --zero-terminated)'{-z,--zero-terminated}'[line delimiter is NUL, not newline]'
     '(- *)--help[display help and exit]'
     '(- *)--version[output version information and exit]'
   )
@@ -32,20 +33,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/_iconv b/Completion/Unix/Command/_iconv
index bf04acfe4..fba0b9afe 100644
--- a/Completion/Unix/Command/_iconv
+++ b/Completion/Unix/Command/_iconv
@@ -63,7 +63,7 @@ else
     '1:file:_files' && return 0
 
   if [[ $state = codeset ]]; then
-    if [[ $OSTYPE = freebsd* ]]; then
+    if [[ $OSTYPE = (freebsd|dragonfly|netbsd|darwin)* ]]; then
       codeset=( $(_call_program codesets $words[1] -l) )
     elif [[ -f /usr/lib/iconv/iconv_data ]]; then  # IRIX & Solaris
       codeset=( ${${(f)"$(</usr/lib/iconv/iconv_data)"}%%[[:blank:]]*} )
diff --git a/Completion/Unix/Command/_id b/Completion/Unix/Command/_id
index a0a03faad..c123afcd7 100644
--- a/Completion/Unix/Command/_id
+++ b/Completion/Unix/Command/_id
@@ -41,13 +41,13 @@ else
     darwin*|dragonfly*|freebsd*)
       args+=( '(-)-P[print id in the form of a password file entry]' )
     ;|
-    darwin*|freebsd*)
+    freebsd*)
       args+=(
 	'(-)-A[print process audit user ID]'
 	'(-)-M[print MAC label of the current process]'
+        '(-)-c[print current login class]'
       )
     ;|
-    freebsd*) args+=( '(-)-c[print current login class]' ) ;|
     darwin*|dragonfly*|freebsd*|netbsd*|openbsd*)
       args+=( '(-)-p[human readable output]' )
     ;;
diff --git a/Completion/Unix/Command/_ifconfig b/Completion/Unix/Command/_ifconfig
index 25ddd55bd..86ec46038 100644
--- a/Completion/Unix/Command/_ifconfig
+++ b/Completion/Unix/Command/_ifconfig
@@ -13,17 +13,25 @@ updownlist=(
 
 case $OSTYPE in
   darwin*)
-    args=( -s $updownlist )
+    args=( -s $updownlist
+      '-X+[list interfaces whose names match regular expression]:regex:_net_interfaces'
+    )
     opts=(
       $alias $debug delete dest_address ipdst nsellength
       {,-}trailers {,-}link{0,1,2}
     )
-  ;;
+  ;|
   freebsd*|dragonfly*)
-    args=( -s $updown
-      '(-a -l -u -d -m -L 1 *)-C[list interface cloners]'
-      '(-l -C)-m[list supported media]'
-      '(-l -C)-L[show address lifetime as time offset]'
+    args=( -s $updownlist
+      '(-C)-f+[control the output format]: :_values -s, -S\: format
+        "addr[adjust inet address display]\:format [numeric]\:(default fqdn host numeric)"
+        "ether[adjust ethernet address display]\:format [colon]\:(colon dash dotted default)"
+        "inet[adjust inet subnet mask display]\:format [hex]\:(default cidr dotted hex)"
+        "inet6[adjust inet6 prefix display]\:format [numeric]\:(default cidr numeric)"'
+      '(-C)-G+[exclude members of the specified group]:group'
+      '(-C)-g+[limit output to members of the specified group]:group'
+      '(-C)-k[print keying information for the interface]'
+      '(-C)-n[disable automatic loading of network interface drivers]'
     )
     listopts=(
         active caps chan countries mac mesh regdomain roam txparam txpower
@@ -37,6 +45,17 @@ case $OSTYPE in
       roam roam:rssi roam:rate roaming
     )
   ;|
+  freebsd*|darwin*|dragonfly*)
+    args+=(
+      '(-a -j -f -l -G -g -u -d -m -L 1 *)-C[list interface cloners]'
+      '(-l -C)-m[list supported media]'
+      '(-l -C)-L[show address lifetime as time offset]'
+      '(-C)-v[get more verbose status for an interface]'
+    )
+  ;|
+  freebsd<14->.*)
+    args+=( '(-C)-j+[perform actions inside jail]:jail:_jails' )
+  ;;
   dragonfly*)
     args+=( '-n[disable auto-loading of kernel network interface driver]' )
   ;;
diff --git a/Completion/Unix/Command/_imagemagick b/Completion/Unix/Command/_imagemagick
index b7671fe49..6553868d9 100644
--- a/Completion/Unix/Command/_imagemagick
+++ b/Completion/Unix/Command/_imagemagick
@@ -12,7 +12,7 @@ typeset -A opt_args
 #
 # and certainly many other things...
 
-formats=(jpg jpeg jp2 j2k jpc jpx jpf tif tiff miff ras bmp cgm dcx ps eps fig fits fpx gif mpeg pbm pgm ppm pcd pcl pdf pcx png rad rgb rgba rle sgi html shtml tga ttf uil xcf xwd xbm xpm yuv)
+formats=(jpg jpeg jp2 j2k jpc jpx jpf tif tiff miff ras bmp cgm dcx ps eps fig fits fpx gif mpeg pbm pgm ppm pcd pcl pdf pcx png rad rgb rgba rle sgi html shtml tga ttf uil xcf xwd xbm xpm yuv svg webp)
 
 if (( $# )); then
   _files "$@" -g "*.(#i)(${(j:|:)formats})(-.)"
diff --git a/Completion/Unix/Command/_install b/Completion/Unix/Command/_install
index 364119961..881c99620 100644
--- a/Completion/Unix/Command/_install
+++ b/Completion/Unix/Command/_install
@@ -25,8 +25,9 @@ if _pick_variant gnu='Free Soft' unix --version; then
   args+=(
     $common_args
     '(-b --backup)--backup=[create backup; optionally specify method]:: :->controls'
-    "${lx}--context=-[like -Z, or specify SELinux security context to set]::SELinux security context:_selinux_contexts"
+    "${lx}--context=-[like -Z, or specify SELinux security context to set]::SELinux security context:_selinux_contexts -a file_type"
     '-D[create all leading destination path components]'
+    '--debug[explain how a file is copied. Implies -v]'
     '(: -)--help[display help information]'
     "${lx}--preserve-context[preserve SELinux security context]"
     '--strip-program=[specify program used to strip binaries]:strip program:_files'
diff --git a/Completion/Unix/Command/_iostat b/Completion/Unix/Command/_iostat
index 1152b0d8b..d3943fcb4 100644
--- a/Completion/Unix/Command/_iostat
+++ b/Completion/Unix/Command/_iostat
@@ -34,7 +34,6 @@ case $OSTYPE:l in
     args+=(
       '-x[show extended disk statistics]'
       '-z[omit lines for devices with no activity]'
-      '(* -)-?[display a usage statement and exit]'
     )
     ;;
   dragonfly*)
@@ -126,6 +125,7 @@ case $OSTYPE:l in
     parser=( -s )
     args=(
       '-c[display CPU utilization report]'
+      "--compact[don't break into sub-reports keeping metrics to a single line]"
       '-d[display device utilization report]'
       '--dec=-[specify the number of decimal places to use]:decimal places [2]:(0 1 2)'
       '-f[specify alternative directory to read device statistics from]:directory:_directories'
diff --git a/Completion/Unix/Command/_java b/Completion/Unix/Command/_java
index ff6e82645..325413d87 100644
--- a/Completion/Unix/Command/_java
+++ b/Completion/Unix/Command/_java
@@ -82,7 +82,10 @@ java)
     '(- 1)-X-[non-standard java option]:option' \
     '(- 1)-jar[specify a program encapsulated as jar]:jar:_files -g \*.jar\(-.\)' \
     '-splash\:-[show splash screen with specified image]:image:_files' \
-    '(-):class:_java_class -m main ${(kv)opt_args[(i)(-classpath|-cp)]}' \
+    '--source=[set the version of the source in source-file mode]:version' \
+    '(-):arg: _alternative
+      "classes\:class\:{ (( ! $+opt_args[--source] )) && _java_class -m main ${(kv)opt_args[(i)(-classpath|-cp)]} }"
+      "files\:source file\:_files -g \*.java\(-.\)"' \
     '*::args:= _normal' \
      && return 0
   ;;
@@ -438,8 +441,8 @@ classpath|sourcepath|bootstrapclasspath|docletpath)
   compset -P '*:'
   compset -S ':*'
   _alternative \
-    "classpath:$state:_path_files -qS: -g '*.(jar|zip)(-.)'" \
-    "classpath:$state:_path_files -r': ' -/" && return
+    "classpath:${state}:_path_files -qS: -g '*.(jar|zip)(-.)'" \
+    "classpath:${state}:_path_files -r': ' -/" && return
   ;;
 
 extdirs)
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/_ldd b/Completion/Unix/Command/_ldd
index 3c7b088df..98ac41e14 100644
--- a/Completion/Unix/Command/_ldd
+++ b/Completion/Unix/Command/_ldd
@@ -30,8 +30,7 @@ else
     freebsd*)
       args=(
         '-a[show all objects that are needed by each loaded object]'
-	'-v[verbose listing of the dynamic linking headers]'
-	'-f+[specify format]:format:((%a\:program\ name %A\:environment\ name %o\:library\ name %p\:path\ to\ library %x\:load\ address))'
+	'*-f+[specify format]:format:((%a\:program\ name %A\:environment\ name %o\:library\ name %p\:path\ to\ library %x\:load\ address))'
       )
     ;;
   esac
diff --git a/Completion/Unix/Command/_less b/Completion/Unix/Command/_less
index 0b474b991..8772f5771 100644
--- a/Completion/Unix/Command/_less
+++ b/Completion/Unix/Command/_less
@@ -39,7 +39,7 @@ _arguments -S -s -A "[-+]*"  \
   '(-C --CLEAR-SCREEN -c --clear-screen)'{-c,--clear-screen}'[repaint screen instead of scrolling]' \
   '!(-c --clear-screen)'{-C,--CLEAR-SCREEN} \
   '(-d --dumb)'{-d,--dumb}'[suppress error message if terminal is dumb]' \
-  '*-D+[set screen colors]: :->colors' \
+  '*'{-D+,--color=}'[set screen colors]: :->colors' \
   '(-e -E --quit-at-eof --QUIT-AT-EOF)'{-e,--quit-at-eof}'[exit the second time end-of-file is reached]' \
   '(-e -E --quit-at-eof --QUIT-AT-EOF)'{-E,--QUIT-AT-EOF}'[exit when end-of-file is reached]' \
   '(-f --force)'{-f,--force}'[force opening of non-regular files]' \
@@ -56,7 +56,7 @@ _arguments -S -s -A "[-+]*"  \
   '(-L --no-lessopen)'{-L,--no-lessopen}'[ignore the LESSOPEN environment variable]' \
   '(-M --LONG-PROMPT -m --long-prompt)'{-m,--long-prompt}'[prompt verbosely]' \
   '(-m --long-prompt -M --LONG-PROMPT)'{-M,--LONG-PROMPT}'[prompt very verbosely]' \
-  '(-N --LINE-NUMBERS -n --line-numbers)'{-n,--line-numbers}"[don't keep track of line numbers]" \
+  '(-N --LINE-NUMBERS -n --line-numbers)'{-n,--line-numbers}'[suppress line numbers in prompts and messages]' \
   '(-n --line-numbers -N --LINE-NUMBERS)'{-N,--LINE-NUMBERS}'[show line numbers]' \
   '(* -O --LOG-FILE -o --log-file)'{-o+,--log-file=}'[copy input to file]:file:_files' \
   '(* -o --log-file -O --LOG-FILE)'{-O+,--LOG-FILE=}'[copy input to file, overwriting if necessary]:file:_files' \
@@ -80,21 +80,42 @@ _arguments -S -s -A "[-+]*"  \
   '--no-keypad[disable use of keypad terminal init string]' \
   '(-y --max-forw-scroll)'{-y,--max-forw-scroll}'[specify forward scroll limit]' \
   '(-z --window)'{-z+,--window=}'[specify scrolling window size]:lines' \
-  '(-\" --quotes)'{-\"+,--quotes=}'[change quoting character]:quoting characters' \
+  '(-\" --quotes)'{'-\"+',--quotes=}'[change quoting character]:quoting characters' \
   '(-~ --tilde)'{-~,--tilde}"[don't display tildes after end of file]" \
-  '(-\# --shift)'{-\#+,--shift=}"[specify amount to move when scrolling horizontally]:number" \
+  '(-\# --shift)'{'-\#+',--shift=}"[specify amount to move when scrolling horizontally]:number" \
+  '--exit-follow-on-close[exit F command on a pipe when writer closes pipe]' \
   '--file-size[automatically determine the size of the input file]' \
+  '--header=[set header size]:lines,columns' \
   '--incsearch[search file as each pattern character is typed in]' \
+  '--intr=[specify interrupt character instead of ^X]:char [^X]' \
   '--line-num-width=[set the width of line number field]:width [7]' \
+  '--modelines=[look for vim modelines]:lines to search' \
   '--follow-name[the F command changes file if the input file is renamed]' \
   '--mouse[enable mouse input]' \
   '--no-histdups[remove duplicates from command history]' \
+  "--no-number-headers[don't give line numbers to header lines]" \
+  "--no-search-headers[don't search in header lines or columns]" \
+  "--no-vbell[disable the terminal's visual bell]" \
+  '--redraw-on-quit[redraw final screen when quitting]' \
   '--rscroll=[set the character used to mark truncated lines]:character [>]' \
   '--save-marks[retain marks across invocations of less]' \
+  '--search-options=[set default options for every search]: : _values -s ""
+    "search option"
+    "E[multi-file]" "F[from first line]" "K[highlight]"
+    "N[non-matching]" "R[literal]" "W[wrap]" -' \
+  '--show-preproc-errors[display a message if preprocessor exits with an error status]' \
+  '--proc-backspace[process backspaces for bold/underline]' \
+  '--SPECIAL-BACKSPACE[treat backspaces as control characters]' \
+  '--proc-return[delete carriage returns before newline]' \
+  '--SPECIAL-RETURN[treat carriage returns as control characters]' \
+  '--proc-tab[expand tabs to spaces]' \
+  '--SPECIAL-TAB[treat tabs as control characters]' \
   '--status-col-width=[set the width of the -J status column]:width [2]' \
+  '--status-line[highlight or color the entire line containing a mark]' \
   '--use-backslash[subsequent options use backslash as escape char]' \
   '--use-color[enable colored text]' \
   '--wheel-lines=[specify lines to move for each click of the mouse wheel]:lines' \
+  '--wordwrap[wrap lines at spaces]' \
   "$files[@]" && ret=0
 
 
@@ -104,7 +125,7 @@ if [[ -n "$state" ]]; then
       if compset -P 1 \?; then
         [[ $IPREFIX[-1] != [a-z] ]] || compset -P 1 + || _describe 'color application' '( +:add\ to\ existing\ attribute )'
         suf=( -S '' )
-        compset -P 1 '([a-zA-Z]|*.)' && fgbg=background && suf=()
+        compset -P 1 '([-a-zA-Z]|*.)' && fgbg=background && suf=()
         basic=( B:blue C:cyan G:green K:black M:magenta R:red W:white Y:yellow )
         _describe -t colors "$fgbg color" \
             "( -:default ${(j. .)${(@)basic/:/:light\ }} ${(Lj. .)basic} )" "$suf[@]"  && ret=0
diff --git a/Completion/Unix/Command/_libvirt b/Completion/Unix/Command/_libvirt
index a3ab5a68a..bd605b9c9 100644
--- a/Completion/Unix/Command/_libvirt
+++ b/Completion/Unix/Command/_libvirt
@@ -20,7 +20,6 @@ typeset -A dom_opts
 dom_opts=(
   console " "
   destroy " "
-  edit " "
   managedsave " "
   reboot " "
   reset " "
diff --git a/Completion/Unix/Command/_ln b/Completion/Unix/Command/_ln
index 9d5efcabb..7bd2f7f27 100644
--- a/Completion/Unix/Command/_ln
+++ b/Completion/Unix/Command/_ln
@@ -45,9 +45,11 @@ case $variant; in
       {-h,-n}'[do not dereference destination]'
       '(-f)-i[prompt before removing destination files]')
     ;;
-  darwin*|dragonfly*|freebsd*|netbsd*|openbsd*)
+  darwin*|dragonfly*|*bsd*)
     args+=(
-      {-h,-n}'[do not dereference destination]'
+      {-h,-n}"[don't dereference destination]"
+      '(-L)-P[create hard links directly to symbolic links]'
+      '(-P)-L[create hard links to symbolic link references]'
     )
     ;|
   darwin*|dragonfly*|freebsd*|netbsd*)
@@ -57,12 +59,6 @@ case $variant; in
       '-v[print name of each linked file]'
     )
     ;|
-  dragonfly*|freebsd*|netbsd*|openbsd*)
-    args+=(
-      '(-L)-P[create hard links directly to symbolic links]'
-      '(-P)-L[create hard links to symbolic link references]'
-    )
-    ;|
   dragonfly*|freebsd*|netbsd*)
     args+=(
       "-w[warn if source of a symbolic link doesn't currently exist]"
diff --git a/Completion/Unix/Command/_logger b/Completion/Unix/Command/_logger
new file mode 100644
index 000000000..0d47d2f03
--- /dev/null
+++ b/Completion/Unix/Command/_logger
@@ -0,0 +1,80 @@
+#compdef logger
+
+local variant ign
+local -a args common
+local -a priorities
+
+_pick_variant -r variant linux=util-linux busybox=BusyBox $OSTYPE -V
+
+priorities=( {kern,user,mail,daemon,auth,syslog,lpr,news,uucp,cron,authpriv,ftp,ntp,security,console,local{0..7}}.{emerg,panic,alert,crit,err,error,warn,warning,notice,info,debug} )
+args=( "(--id)-i[log the logger command's pid]" )
+common=(
+  '(-f --file --journald *)'{-f+,--file=}'[log contents of specified file]:file:_files'
+  '(-s --stderr)'{-s,--stderr}'[output message to standard error as well]'
+  '(-P --port)'{-P+,--port}'[use specified port for UDP or TCP connection]:port [514]:_ports'
+  '(-p --priority)'{-p+,--priority}'[mark message with specified priority]:priority:_multi_parts . priorities'
+  '(-t --tag)'{-t+,--tag}"[specify tag to mark log line with]:tag [$USER]"
+)
+
+case $variant in
+  (net|open)bsd*)
+    args+=( ${(M)common:#*\)-[fpst]*}
+      '-c[write the message to the console if unable to use syslogd(8)]'
+    )
+  ;|
+  dragonfly*|freebsd*)
+    args+=(
+      '(-6)-4[use IPv4 addresses only]'
+      '(-4)-6[use IPv6 addresses only]'
+      '-A[send the message to all addresses]'
+    )
+  ;|
+  darwin*|dragonfly*) args+=( ${(M)common:#*\)-[sfpt]*} ) ;|
+  freebsd*)
+    args+=( ${common:#*\)--*}
+      "-H+[set value for hostname in message header]:hostname [${HOST%%.*}]"
+      '-h+[write to specified remote syslog server or socket]: : _alternative
+        "hosts\:server\:_hosts"
+        "sockets\:socket\:_files -g \*\(=\)"'
+      '-S+[specify source address and port when using -h]: :_bind_addresses -0bh'
+    )
+  ;;
+  dragonfly*)
+    args+=( '-h+[write to specified remote syslog server]:server:_hosts' )
+  ;;
+  busybox) args=( ${(M)common:#*\)-[spt]*} ) ;; # no -i
+  solaris*) args+=( ${(M)common:#*\)-[fpt]*} ) ;;
+  netbsd*)
+    args+=(
+      '-d+[log this in the structured data (SD) field]:sd field'
+      '-m+[specify message ID used for the message]:message id'
+      '-n[open log file immediately]'
+    )
+  ;;
+  linux)
+    (( $#words > 2 )) && ign='!'
+    args+=( $common
+      "(-i)--id=-[log the given id, or otherwise the pid]::id [$$]:_pids"
+      '(* -e --skip-empty)'{-e,--skip-empty}"[don't log empty lines when processing files]"
+      '--no-act[do everything except the write the log]'
+      '--octet-count[use rfc6587 octet counting]'
+      '(*)--prio-prefix[look for a prefix on every line read from stdin]'
+      '(-S --size)'{-S+,--size=}'[specify maximum size for a single message]:size [1KiB]'
+      '(-n --server)'{-n+,--server=}'[write to specified remote syslog server]:server:_hosts'
+      '(-T --tcp -d --udp)'{-T,--tcp}'[use TCP only]'
+      '(-d --udp -T --tcp)'{-d,--udp}'[use UDP only]'
+      '(--rfc5424 --msgid --sd-id --sd-param)--rfc3164[use the obsolete BSD syslog protocol]'
+      '(--rfc3164)--rfc5424=-[use the syslog protocol (default for remote)]::without:_sequence compadd - notime notq nohost'
+      '(--rfc3164)*--sd-id=[specify rfc5424 structured data ID]:id'
+      '(--rfc3164)*--sd-param=[specify rfc5424 structured data name=value]:data'
+      '(--rfc3164)--msgid=[set rfc5424 message id field]:message id'
+      '(-u --socket)'{-u,--socket=}'[write to specified Unix socket]:socket:compadd -f -M "r\:|_=* r\:|=*" ${${(M)${(f)"$(</proc/net/unix)"}\:#* /*}##* }'
+      '--socket-errors=-[print connection errors when using Unix sockets]::state:(on off auto)'
+      '(* -f --file)--journald=-[write journald entry]::file:_files'
+      "${ign}(- *)"{-h,--help}'[display usage information]'
+      "${ign}(- *)"{-V,--version}'[display version information]'
+    )
+  ;;
+esac
+
+_arguments -s -S -A "-*" $args '*: :_guard "^-*" message'
diff --git a/Completion/Unix/Command/_ls b/Completion/Unix/Command/_ls
index df14e7e2c..392b8490b 100644
--- a/Completion/Unix/Command/_ls
+++ b/Completion/Unix/Command/_ls
@@ -75,12 +75,12 @@ if ! _pick_variant gnu=gnu unix --help; then
   if [[ $OSTYPE = (dragonfly*|freebsd*|darwin*) ]]; then
     arguments+=(
       '-G[enable colorized output]'
+      '(-A)-I[prevent -A from being automatically set for the super-user]'
       '-P[do not follow symlinks]'
     )
   fi
   if [[ $OSTYPE = (dragonfly*|freebsd*) ]]; then
     arguments+=(
-      '(-A)-I[prevent -A from being automatically set for the super-user]'
       '(-1 -C -m -x)-D+[specify format for date]:format: _date_formats'
     )
   fi
@@ -91,16 +91,19 @@ if ! _pick_variant gnu=gnu unix --help; then
     )
   fi
   if [[ $OSTYPE = (freebsd*|darwin*) ]]; then
-    arguments+=( '(-c -u)-U[file creation time]' )
-  fi
-  if [[ $OSTYPE = freebsd* ]]; then
     arguments+=(
       '-,[print file sizes grouped and separated by thousands]'
+      '(-c -u)-U[file creation time]'
       '-y[with -t, sort filenames in the same order as the time]'
-      '-Z[display MAC label]'
       '--color=-[control use of color]:color:(never always auto)'
     )
   fi
+  if [[ $OSTYPE = freebsd* ]]; then
+    arguments+=(
+      '(-S -f -t -U)-v[sort by version (filename treated numerically)]'
+      '-Z[display MAC label]'
+    )
+  fi
   if [[ $OSTYPE = darwin* ]]; then
     arguments+=(
       '-@[display extended attribute keys and sizes in long listing]'
@@ -108,6 +111,7 @@ if ! _pick_variant gnu=gnu unix --help; then
       '(-l -1 -C -m -x)-o[long listing but without group information]'
       '-O[display file flags]'
       '-v[print raw characters]'
+      '-%[distinguish dataless files and directories with a %]'
     )
   fi
   if [[ $OSTYPE = solaris* ]]; then
@@ -139,8 +143,8 @@ else
     '(--recursive -R)'{--recursive,-R}'[list subdirectories recursively]'
 
     '(--no-group -G)'{--no-group,-G}'[inhibit display of group information]'
-    '(--block-size --human-readable -h --si --kilobytes -k)'{--human-readable,-h}'[print sizes in human readable form]'
-    '(--block-size --human-readable -h --si --kilobytes -k)--si[sizes in human readable form; powers of 1000]'
+    '(--block-size --human-readable -h --si --kibibytes -k)'{--human-readable,-h}'[print sizes in human readable form]'
+    '(--block-size --human-readable -h --si --kibibytes -k)--si[sizes in human readable form; powers of 1000]'
     '(--inode -i)'{--inode,-i}'[print file inode numbers]'
 
     '(--format -l -g -o -1 -C -m -x)-l[long listing]'
@@ -148,40 +152,41 @@ else
     --group-directories-first
     '(--format -l --no-group -G -1 -C -m -x)-o[no group, long]'
     '(--format -l -g -o -C -m -x)-1[single column output]'
-    '(--format -l -g -o -1 -m -x)-C[list entries in columns sorted vertically]'
-    '(--format -l -g -o -1 -C -x)-m[comma separated]'
-    '(--format -l -g -o -1 -C -m)-x[sort horizontally]'
+    '(--format -l -g -o -1 -m -x --block-size --human-readable -h --si --kibibytes -k)-C[list entries in columns sorted vertically]'
+    '(--format -l -g -o -1 -C -x --block-size --human-readable -h --si --kibibytes -k)-m[comma separated]'
+    '(--format -l -g -o -1 -C -m --block-size --human-readable -h --si --kibibytes -k)-x[sort horizontally]'
     '(-l -g -o -1 -C -m -x)--format=[specify output format]:format:(verbose long commas horizontal across vertical single-column)'
 
     '(--size -s -f)'{--size,-s}'[display size of each file in blocks]'
 
     '(--time -u)-c[status change time]'
     '(--time -c)-u[access time]'
-    '(-c -u)--time=[specify time to show]:time:(ctime status use atime access)'
+    '(-c -u)--time=[specify time to show]:time:(ctime status use atime access birth creation)'
     '--time-style=[show times using specified style]:style: _alternative "time-styles\:time style\:(full-iso long-iso iso locale)" $datef'
 
     '(-a --all -U -l --format -s --size -t --sort --full-time)-f[unsorted, all, short list]'
     '(--reverse -r -U -f)'{--reverse,-r}'[reverse sort order]'
 
-    '(--sort -t -U -v -X)-S[sort by size]'
-    '(--sort -S -U -v -X)-t[sort by modification time]'
-    '(--sort -S -t -v -X)-U[unsorted]'
-    '(--sort -S -t -U -X)-v[sort by version (filename treated numerically)]'
-    '(--sort -S -t -U -v)-X[sort by extension]'
-    '(-S -t -U -v -X)--sort=[specify sort key]:sort key:(size time none version extension)'
+    '(--sort -f -t -U -v -X)-S[sort by size]'
+    '(--sort -f -S -U -v -X)-t[sort by modification time]'
+    '(--sort -f -S -t -v -X)-U[unsorted]'
+    '(--sort -f -S -t -U -X)-v[sort by version (filename treated numerically)]'
+    '(--sort -f -S -t -U -v)-X[sort by extension]'
+    '(-S -f -t -U -v -X)--sort=[specify sort key]:sort key:(size time none version extension)'
 
     '--color=-[control use of color]:color:(never always auto)'
     "*--hide=[like -I, but overridden by -a or -A]:pattern: "
     '--hyperlink=[output terminal codes to link files using file::// URI]::when:(none auto always)'
-    '(--classify -F --indicator-style -p --file-type)'{--classify,-F}'[append file type indicators]'
+    '(--classify -F --indicator-style -p --file-type)-F[append file type indicators]'
+    '(--classify -F --indicator-style -p --file-type)--classify=-[append file type indicators]::when [always]:(none auto always)'
     '(--file-type -p --indicator-style -F --classify)--file-type[append file type indicators except *]'
     '(--file-type -p --indicator-style -F --classify)-p[append / to directories]'
     '(-F --classify -p --file-type)--indicator-style=[specify indicator style]:indicator style:(none file-type classify slash)'
 
     '(-f)--full-time[list both full date and full time]'
 
-    '(--block-size --human-readable -h --si --kilobytes -k)'{--kilobytes,-k}'[use block size of 1k]'
-    '(--human-readable -h --si --kilobytes -k)--block-size=[specify block size]:block size (bytes):(K M G T P E Z Y KB MB TB PB EB ZB YB)'
+    '(--block-size --human-readable -h --si --kibibytes -k)'{--kibibytes,-k}'[use block size of 1k]'
+    '(--human-readable -h --si --kibibytes -k -C -x)--block-size=[specify block size]:block size (bytes):(K M G T P E Z Y KB MB TB PB EB ZB YB)'
 
     '(--numeric-uid-gid -n)'{--numeric-uid-gid,-n}'[numeric uid, gid]'
     '(--tabsize -T)'{--tabsize=,-T+}'[specify tab size]:tab size'
@@ -194,6 +199,7 @@ else
 
     '(--hide-control-chars -q --show-control-chars)'{--hide-control-chars,-q}'[hide control chars]'
     '(-q --hide-control-chars)--show-control-chars'
+    '--zero[end each output line with NUL, not newline]'
     '(- :)--help[display help information]'
     '(- :)--version[display version information]'
     '*:file:_files'
diff --git a/Completion/Unix/Command/_lsof b/Completion/Unix/Command/_lsof
index 8afb55e1d..60f59a589 100644
--- a/Completion/Unix/Command/_lsof
+++ b/Completion/Unix/Command/_lsof
@@ -9,6 +9,7 @@ case $OSTYPE in
       '-E[display endpoint info for pipes, sockets and pseudoterminal files but not files of the endpoints]'
       '+E[display endpoint info for pipes, sockets and pseudoterminal files including files of the endpoints]'
       '-X[skip reporting of info on network connections]'
+      '*-Z[display or filter by SELinux security context]::context pattern:_selinux_contexts -a domain'
     )
   ;;
   solaris*)
@@ -23,7 +24,6 @@ _arguments -C -s -S $args \
   '(-)'{-\?,-h}'[list help]' \
   '-a[AND selections]' \
   '-b[avoid kernel blocks]' \
-  '-C[disable reporting of path name components]' \
   '+c[truncate command name to specified characters]:characters' \
   '-c[list files with specified command name beginning]:command name' \
   '+d[search for open instances for contents of specified dir]:search directory:_files -/' \
@@ -31,16 +31,19 @@ _arguments -C -s -S $args \
   '+D[recursively search from specified dir]:search directory:_files -/' \
   '-D[direct use of device cache file]:function:((\?\:report\ device\ cache\ file\ paths b\:build\ the\ device\ cache\ file i\:ignore\ the\ device\ cache\ file r\:read\ the\ device\ cache\ file u\:read\ and\ update\ the\ device\ cache\ file))' \
   '*-+e[exempt filesystem from blocking kernel calls]:file system:_directories' \
+  '-+E[show endpoint information for pipes, sockets, ptys, mqueues and eventfds; with -E, omit endpoint files]' \
   '-f[inhibit listing of kernel file structure info]::info type:->file-structures' \
   '+f[enable listing of kernel file structure info]::info type:->file-structures' \
   '-F[select output fields]:fields:->fields' \
   '-g[select by process group id]::process group id:_sequence -s , _pgids' \
+  '-H[print human readable sizes]' \
   '(*)*-i[select internet files]::address:->addresses' \
   '-K+[select listing of tasks of processes]::value:((i\:ignore\ tasks))' \
   '-k[specify kernel name list file]:kernel file:_files' \
   '-l[inhibit conversion of UIDs to user names]' \
   '-L[list no link counts]' \
   '+L[list all link counts]::max link count for listed files' \
+  '+m[specify or write a mount supplement file]::mount supplement file:_files' \
   '-m[specify kernel memory file]:kernel memory file:_files' \
   '-M[disable reporting of portmapper registrations]' \
   '+M[enable reporting of portmapper registrations]' \
@@ -49,6 +52,7 @@ _arguments -C -s -S $args \
   '(-s)-o[list file offset]::digits for file offset' \
   '-O[avoid overheads of bypassing potential blocking]' \
   '-P[inhibit conversion of port numbers to port names]' \
+  '-Q[ignore failed search terms]' \
   '-p[list files for specified processes]:process ID:_sequence -s , _pids' \
   '-r[repeat listing endlessly]::delay (seconds)' \
   '+r[repeat listing until no files listed]::delay (seconds)' \
diff --git a/Completion/Unix/Command/_lua b/Completion/Unix/Command/_lua
index 7254d3819..3a1ef4fd7 100644
--- a/Completion/Unix/Command/_lua
+++ b/Completion/Unix/Command/_lua
@@ -41,6 +41,7 @@ _lua() {
   _arguments -S -A '-*' : \
     '*-e+[execute specified command string]:command string' \
     '-E[ignore environment variables]' \
+    '-W[turn warnings on]' \
     '-i[enter interactive mode]' \
     '*-l+[specify library or module to require]: :_lua_libraries' \
     '-v[display version information]' \
diff --git a/Completion/Unix/Command/_make b/Completion/Unix/Command/_make
index ae91440f0..99c786dc7 100644
--- a/Completion/Unix/Command/_make
+++ b/Completion/Unix/Command/_make
@@ -1,4 +1,4 @@
-#compdef make gmake pmake dmake freebsd-make bmake
+#compdef make gmake gnumake pmake dmake freebsd-make bmake
 
 # TODO: Based on targets given on the command line, show only variables that
 # are used in those targets and their dependencies.
@@ -118,10 +118,34 @@ _make-parseMakefile () {
   done
 }
 
+_make-parseDataBase () {
+  local input var TAB=$'\t' IFS= skip=0
+
+  while read input
+  do
+    if [[ $skip = 1 ]]; then
+      skip=0
+      continue
+    fi
+    case "$input " in
+      (\# Not a target*|\# environment*)
+        skip=1  # skip next line
+        ;;
+      ([[:alnum:]][[:alnum:]_]#[" "$TAB]#(\?|:|::|)=*)
+        var=${input%%[ $TAB]#(\?|:|::|)=*}
+        VARIABLES[$var]=1
+        ;;
+      ([[*?[:alnum:]$][^$TAB:=%]#:[^=]*)
+        TARGETS+=( ${input%%:*} )
+        ;;
+    esac
+  done
+}
+
 _make() {
 
   local prev="$words[CURRENT-1]" file expl tmp is_gnu incl match basedir nul=$'\0'
-  local context state state_descr line
+  local curcontext=$curcontext state state_descr line
   local -a option_specs
   local -A VARIABLES VAR_ARGS opt_args
   local -aU TARGETS keys
@@ -152,26 +176,28 @@ _make() {
       '(-i --ignore-errors)'{-i,--ignore-errors}'[ignore errors from recipes]'
       '*'{-I,--include-dir=}'[search specified directory for included makefiles]:search path for included makefile:->dir'
       '(-j --jobs)'{-j+,--jobs=}'[allow specified number of parallel jobs; unlimited jobs with no arg]:: : _guard "[0-9]#" "number of jobs"'
+      '--jobserver-style=[select the style of jobserver to use]:style:(fifo pipe sem)'
       '(-k --keep-going)'{-k,--keep-going}"[keep going when some targets can't be made]"
       '(-l --load-average --max-load)'{-l,--load-average=,--max-load}"[don't start multiple jobs unless load is below specified value]:load"
       '(-L --check-symlink-times)'{-L,--check-symlink-times}'[use the latest mtime between symlinks and target]'
       '(-n --just-print --dry-run --recon)'{-n,--just-print,--dry-run,--recon}"[don't actually run any recipe; just print them]"
       '*'{-o,--old-file=,--assume-old=}"[consider specified file to be old and don't remake it]:file not to remake:->file"
       '(-O --output-sync)'{-O-,--output-sync=-}'[synchronize output of parallel jobs]::granularity for grouping output:compadd -E 0 none line target recurse'
-      '(-p --print-data-base)'{-p,--print-data-base}'[print makes internal database]'
+      '(-p --print-data-base)'{-p,--print-data-base}"[print make's internal database]"
       '(-q --question)'{-q,--question}'[run no recipe; exit status says if up to date]'
       '(-r --no-builtin-rules)'{-r,--no-builtin-rules}'[disable the built-in implicit rules]'
+      '--shuffle=-[perform shuffle of prerequisites and goals]::seed (integer) or mode:(random reverse none)'
       '(-R --no-builtin-variables)'{-R,--no-builtin-variables}'[disable the built-in variable settings]'
       '(-s --silent --quiet)'{-s,--silent,--quiet}"[don't echo recipes]"
       '--no-silent[echo recipes (disable --silent mode)]'
       '(-S --no-keep-going --stop)'{-S,--no-keep-going,--stop}'[turns off -k]'
       '(-t --touch)'{-t,--touch}'[touch targets instead of remaking them]'
+      '--trace[print tracing information]'
       '(- *)'{-v,--version}'[print the version number of make and exit]'
       '(-w --print-directory)'{-w,--print-directory}'[print the current directory]'
       '--no-print-directory[turn off -w, even if it was turned on implicitly]'
       '*'{-W,--what-if=,--new-file=,--assume-new=}'[consider specified file to be infinitely new]:file to treat as modified:->file'
       '--warn-undefined-variables[warn when an undefined variable is referenced]'
-      '--warn-undefined-functions[warn when an undefined user function is called]'
     )
   else
     # Basic make options only.
@@ -185,7 +211,7 @@ _make() {
     )
   fi
 
-  _arguments -s $option_specs \
+  _arguments -C -S -s $option_specs \
     '*:make target:->target' && ret=0
 
   [[ $state = cdir ]] && cdir=-2
@@ -214,6 +240,10 @@ _make() {
     ;;
 
     (target)
+    # target name starting with '-' is allowed only after '--'
+    if [[ $words[CURRENT] = -* ]] && (( ${words[(i)--]} > CURRENT )); then
+      return ret
+    fi
     file=${(v)opt_args[(I)(-f|--file|--makefile)]}
     if [[ -n $file ]]
     then
@@ -239,7 +269,7 @@ _make() {
       if [[ $is_gnu == gnu ]] 
       then
         if zstyle -t ":completion:${curcontext}:targets" call-command; then
-          _make-parseMakefile < <(_call_program targets "$words[1]" -nsp --no-print-directory -f "$file" --always-make 2> /dev/null)
+          _make-parseDataBase < <(_call_program targets "$words[1]" -nqp --no-print-directory -f "$file" .DEFAULT 2> /dev/null)
         else
           _make-parseMakefile < $file
         fi
diff --git a/Completion/Unix/Command/_man b/Completion/Unix/Command/_man
index dba1d13dc..190811e41 100644
--- a/Completion/Unix/Command/_man
+++ b/Completion/Unix/Command/_man
@@ -16,7 +16,7 @@
 _man() {
   local dirs expl mrd awk variant noinsert
   local -a context line state state_descr args modes
-  local -aU sects
+  local -aU sects _manpath
   local -A opt_args val_args sect_descs
 
   if [[ $service == man ]]; then
@@ -168,29 +168,40 @@ _man() {
   _arguments -s -S : $args '*::: :->man' && return 0
   [[ -n $state ]] || return 1
 
+  # Override man path
+  [[ -n ${opt_args[-M]} ]] &&
+  _manpath=( ${(s<:>)opt_args[-M]} )
+
+  # Restore cached man path to avoid $(manpath) if we can
   if (( ! $#_manpath )); then
-    local mp
-    mp=( ${(s.:.)$(manpath 2>/dev/null)} )
-    [[ "$mp" == *:* ]] && mp=( ${(s.:.)mp} )
-    if (( $#mp )); then
-      _manpath=( $mp )
-    elif (( $#manpath )); then
-      _manpath=( $manpath )
+    if (( ! $+_manpath_cache )); then
+      typeset -gHA _manpath_cache
     fi
+    if [[ -z $_manpath_cache[$MANPATH] ]]; then
+      local mp
+      mp=( ${(s.:.)$({ command man -w || manpath } 2>/dev/null)} )
+      [[ "$mp" == *:* ]] && mp=( ${(s.:.)mp} )
+      if (( $#mp )); then
+        _manpath_cache[$MANPATH]=${(j.:.)mp}
+      elif (( $#manpath )); then
+        _manpath_cache[$MANPATH]=$MANPATH
+      fi
+    fi
+    _manpath=( ${(s.:.)_manpath_cache[$MANPATH]} )
+  fi
+
+  # Augment man path
+  if [[ -n ${opt_args[-m]} ]]; then
+    [[ $variant == (netbsd|openbsd)* ]] &&
+    _manpath+=( ${(s<:>)opt_args[-m]} )
+  elif [[ $variant == aix* ]]; then
+    # _manpath declared -U so no need to test
+    _manpath+=( /usr/share/man )
   fi
 
   (( $#_manpath )) ||
       _manpath=( /usr/man(-/) /(opt|usr)/(pkg|dt|share|X11R6|local)/(cat|)man(-/) )
 
-  # Override man path
-  [[ -n ${opt_args[-M]} ]] &&
-  _manpath=( ${(s<:>)opt_args[-M]} )
-
-  # Augment man path
-  [[ $variant == (netbsd|openbsd)* ]] &&
-  [[ -n ${opt_args[-m]} ]] &&
-  _manpath+=( ${(s<:>)opt_args[-m]} )
-
   # `sman' is the SGML manual directory for Solaris 7.
   # 1M is system administrator commands on SVR4
 
diff --git a/Completion/Unix/Command/_mktemp b/Completion/Unix/Command/_mktemp
index 03fc89e36..0f66d744e 100644
--- a/Completion/Unix/Command/_mktemp
+++ b/Completion/Unix/Command/_mktemp
@@ -1,43 +1,45 @@
 #compdef mktemp gmktemp
 
 local variant
-local args
+local -a args
 
-_pick_variant -r variant busybox=BusyBox gnu='Free Soft' unix --version
+_pick_variant -r variant busybox=BusyBox gnu='Free Soft' $OSTYPE --version
 
 args=(
   '(-d --directory)'{-d,--directory}'[make directory instead of file]'
-  '(: -)--help[display help information]'
-  '(-p --tmpdir)'{-p+,--tmpdir=}'[make relative to specified directory]: :_directories'
   '(-q --quiet)'{-q,--quiet}'[suppress error messages]'
-  '--suffix=[append specified suffix to template]:template suffix'
-  '-t[interpret template as single path component relative to temp dir]'
   '(-u --dry-run)'{-u,--dry-run}'[print file name only]'
-  '(: -)'{-V,--version}'[display version information]'
-  '1: :_guard "^-*" "template name"'
 )
 
-# Non-GNU variants don't support long options (except BusyBox's --help)
-if [[ $variant == *busybox* ]]; then # See also: _busybox
-  args=( ${args:#((#s)|*\))(\*|)--^help*} )
-elif [[ $variant != gnu ]]; then
-  args=( ${args:#((#s)|*\))(\*|)--*} )
-fi
-
-[[ $variant == gnu ]] || {
-  # BusyBox, OpenBSD, and Solaris have -p, but -t doesn't take an argument
-  if [[ $variant == *busybox* ]] || [[ $OSTYPE == (openbsd|solaris)* ]]; then
-    args=( ${args:#((#s)|*\))(\*|)-t*} )
-    args+=( '-t[generate template relative to temp dir]' )
-  # Dragonfly, FreeBSD, and Darwin take an argument to -t and support any number
-  # of template files. These OSes do not have -p and -V.
-  else
-    args=( ${args:#((#s)|*\))(1:*|(\*|)-[ptV]*)} )
+case $variant in
+  ^(dragonfly|darwin)*)
+    args+=( '(-p --tmpdir)'{-p+,--tmpdir=}'[make relative to specified directory]: :_directories' )
+  ;|
+  gnu)
+    args+=(
+      '--suffix=[append specified suffix to template]:template suffix'
+      '(: -)'{-V,--version}'[display version information]'
+    )
+  ;|
+  # Most variants don't support long options (except BusyBox's --help)
+  ^(gnu|freebsd*))
+    args=( ${args:#((#s)|*\))(\*|)--*} )
+  ;|
+  gnu|*busybox*)
+    args+=( '(: -)--help[display help information]' )
+  ;|
+  (gnu|*busybox|openbsd|solaris)*)
+    args+=(
+      '-t[generate template relative to temp dir]'
+      '1: :_guard "^-*" "template name"'
+    )
+  ;;
+  (dragonfly|netbsd|freebsd|darwin)*)
     args+=(
       '-t[generate template relative to temp dir using specified prefix]:template prefix'
       '*: :_guard "^-*" "template name"'
     )
-  fi
-}
+  ;;
+esac
 
 _arguments -s -S : $args
diff --git a/Completion/Unix/Command/_mosh b/Completion/Unix/Command/_mosh
index 7d1250320..6d0f746f8 100644
--- a/Completion/Unix/Command/_mosh
+++ b/Completion/Unix/Command/_mosh
@@ -7,7 +7,7 @@ _arguments -C \
   '(-)--help[display help information]' \
   '(-)--version[display version information]' \
   "--no-init[don't set terminal init string]" \
-  '--ssh=[specify ssh command to setup session]:ssh command:_normal' \
+  '--ssh=[specify ssh command to setup session]:ssh command: _cmdstring' \
   '--port=[specify server-side port range]:port:_sequence -n 2 -s \: _ports' \
   '(-a -n)--predict=[control speculative local echo]:mode:(adaptive always never)' \
   '(--predict -n)-a[synonym for --predict=always]' \
@@ -22,7 +22,7 @@ _arguments -C \
   '--local[run mosh-server locally without using ssh]' \
   '--experimental-remote-ip=[select method for discovering remote IP address to use for mosh]:method:(local remote proxy)' \
   '1:remote host name:->userhost' \
-  '*:::args:_normal' && ret=0
+  '*::: : _normal -p $service' && ret=0
 
 case $state in
   userhost)
diff --git a/Completion/Unix/Command/_mount b/Completion/Unix/Command/_mount
index 301b9e58e..bf75aa118 100644
--- a/Completion/Unix/Command/_mount
+++ b/Completion/Unix/Command/_mount
@@ -40,12 +40,13 @@ fi
 # are below these table.
 
 local curcontext="$curcontext" state line expl suf ret=1
-local args deffs=iso9660 tmp typeops=-t _nfs_access _fs_nfs _nfs_ufs \
+local deffs=iso9660 tmp typeops=-t _nfs_access _fs_nfs _nfs_ufs \
 _fs_ufs _fs_efs _fs_cd9660 _fs_iso9660 _fs_cachefs _fs_s5fs _fs_tmpfs _fs_pcfs \
 _fs_hsfs _fs_advfs _fs_cdfs _fs_affs _fs_ext2 _fs_fat _fs_ext3 _fs_msdos \
 _fs_msdosfs _fs_umsdos _fs_vfat _fs_hpfs _fs_ntfs _fs_reiserfs _fs_smbfs \
 _fs_xfs _fs_std _fs_devfs _fs_fdesc _fs_kernfs _fs_linprocfs _fs_linsysfs \
 _fs_procfs _fs_btrfs _fs_ext4
+local -a args
 
 typeset -A opt_args
 
@@ -333,9 +334,9 @@ if (( ! $+_fs_any )); then
       'keybits[set number of bits in encryption key]:key size:(64 128 160 192 256)'
       'offset[specify data start for loopback mount]:offset (bytes)'
       '(loud)silent' '(silent)loud'
-      '(fscontext defcontext)context:context'
-      '(context)'{fscontext,defcontext}':context'
-      'rootcontext:context'
+      '(fscontext defcontext)context:context:_selinux_contexts -a file_type'
+      '(context)'{fscontext,defcontext}':context:_selinux_contexts -a file_type'
+      'rootcontext:context:_selinux_contexts -a file_type'
     )
     _fs_adfs=(
       'uid[set owner of root]:user ID'
@@ -735,8 +736,11 @@ if [[ "$service" = mount ]]; then
     deffs=hsfs
     typeops=-F
     ;;
+  darwin*)
+    args=( '-k[follow no symlinks in the provided mount-on directory]' )
+    ;&
   freebsd*|dragonfly*|darwin*)
-    args=( -s
+    args=( -s $args
       '(:)-a[mount all filesystems in fstab]'
       '-d[cause everything to be done except for the actual system call]'
       '-f[forced mount]'
diff --git a/Completion/Unix/Command/_mpc b/Completion/Unix/Command/_mpc
index 7f7adc7b4..c3f93878c 100644
--- a/Completion/Unix/Command/_mpc
+++ b/Completion/Unix/Command/_mpc
@@ -26,6 +26,7 @@ _mpc_command() {
 
   mpc_cmds=(
     add:"append a song to the end of the current playlist"
+    albumart:"download album art for the given song and write to stdout"
     cdprev:"compact disk player-like previous command"
     channels:"list the channels that other clients have subscribed to"
     clear:"clear the current playlist"
@@ -57,6 +58,7 @@ _mpc_command() {
     prio:"change song priorities in the queue"
     queued:"show the next queued song"
     random:"toggle random mode, or specify state"
+    readpicture:"download a picture from the given song and write to stdout"
     repeat:"toggle repeat mode, or specify state"
     single:"toggle single mode, or specify state"
     consume:"toggle consume mode, or specify state"
@@ -205,6 +207,10 @@ _mpc_add() {
   _mpc_helper_files
 }
 
+_mpc_albumart() {
+  _mpc_helper_files
+}
+
 _mpc_del() {
   _mpc_helper_songnumbers
 }
@@ -304,8 +310,14 @@ _mpc_random() {
   _mpc_helper_bool
 }
 
+_mpc_readpicture() {
+  _mpc_helper_files
+}
+
 _mpc_single() {
-  _mpc_helper_bool
+  local state
+  _description states expl state
+  compadd "$@" "$expl[@]" on once off
 }
 
 _mpc_consume() {
diff --git a/Completion/Unix/Command/_mutt b/Completion/Unix/Command/_mutt
index 67b974a8d..82a6e5fa9 100644
--- a/Completion/Unix/Command/_mutt
+++ b/Completion/Unix/Command/_mutt
@@ -1,14 +1,15 @@
-#compdef mutt
+#compdef mutt neomutt
 
-_arguments -s -S \
+# should pass -S but that doesn't work with -- ending -a
+_arguments -s \
   '::recipient:_email_addresses -n mutt' \
   '(- :)-A[expand given alias]:alias:_email_addresses -n mutt' \
-  '*-a[attach file using MIME]::file attachment:_files' \
+  '*-a[attach file using MIME]:*--:file attachment:_files' \
   '*-b[specify a BCC recipient]:BCC recipient:_email_addresses -n mutt' \
   '*-c[specify a CC recipient]:CC recipient:_email_addresses -n mutt' \
   '(- :)-D[print the value of all variables]' \
   '(-x)-E[edit the draft (-H) or include (-i) file]' \
-  '-d+[log debugging output to ~/.muttdebug0]:level:(1 2 3 4 5)' \
+  '-d+[log debugging output to ~/.muttdebug0]:level:(-5 -4 -3 -2 -1 0 1 2 3 4 5)' \
   '-e+[specify a post-init configuration command]:post-init configuration' \
   '-f+[specify mailbox to load]:mailbox: _mailboxes' \
   '-F+[specify an init file]:init file:_files' \
diff --git a/Completion/Unix/Command/_mv b/Completion/Unix/Command/_mv
index 84e43d47e..c52e7a5e4 100644
--- a/Completion/Unix/Command/_mv
+++ b/Completion/Unix/Command/_mv
@@ -13,13 +13,17 @@ case $variant; in
         {existing,nil}"[numbered backups, if they already exist]"
         {simple,never}"[always make simple backups]"'
       '(-b --backup -n --no-clobber)-b[make a backup of each existing destination file]'
+      '(-v)--debug[explain how a file is copied]'
       '(-f --force -i --interactive -n --no-clobber)'{-f,--force}"[don't prompt before overwriting]"
       '(-f --force -i --interactive -n --no-clobber)'{-i,--interactive}'[prompt before overwriting existing file]'
+      '(-f --force -i --interactive -n --no-clobber)'{-n,--no-clobber}"[don't overwrite existing file]"
+      "--no-copy[don't copy if renaming fails]"
       '--strip-trailing-slashes[remove any trailing slashes from each source argument]'
       '(-S --suffix)'{-S+,--suffix=}'[specify the backup suffix]:backup suffix [~]'
       '(-t --target-directory)'{-t+,--target-directory=}'[move all source arguments into specified directory]:directory:_directories'
       '(-T --no-target-directory)'{-T,--no-target-directory}'[treat final argument as a normal file]'
-      '(-u --update)'{-u,--update}'[move only when destination file is older or missing]'
+      '(-u)--update=-[move only when destination file is older or missing]::update files [older]:(all none older)'
+      '(--update)-u[move only when destination file is older or missing]'
       '(-v --verbose)'{-v,--verbose}'[show file names after they are moved]'
       '(- *)--help[display usage information]'
       '(- *)--version[display version information]'
@@ -37,6 +41,7 @@ case $variant; in
   darwin*|dragonfly*|freebsd*)
     args+=(
       "(-f -i)-n[don't overwrite existing file]"
+      "-h[if target is a symlink to a directory, don't follow it]"
     )
     ;|
   darwin*|dragonfly*|*bsd*)
@@ -44,11 +49,6 @@ case $variant; in
       '-v[show file names after they are moved]'
     )
     ;|
-  dragonfly*|freebsd*)
-    args+=(
-      "-h[if target is a symlink to a directory, don't follow it]"
-    )
-    ;;
 esac
 
 _arguments -s -S $aopts $args \
diff --git a/Completion/Unix/Command/_mysql_utils b/Completion/Unix/Command/_mysql_utils
index 9f70687b0..2f5fd3efe 100644
--- a/Completion/Unix/Command/_mysql_utils
+++ b/Completion/Unix/Command/_mysql_utils
@@ -210,6 +210,7 @@ _mysql_utils() {
     "--no-defaults[don't read default options from any options file]"
     '--defaults-file=[read defaults from the given file]:file:_files'
     '--defaults-extra-file=[read specified file after the global files]:defaults file:_files'
+    '--protocol=[connection protocol to use for connecting to the server]:protocol:(tcp socket pipe memory)'
     '(-S --socket)'{-S+,--socket=}'[specify socket file to use for connection]:server socket file:_files'
     '(-h --host)'{-h+,--host=}'[specify server hostname]:hostname:_mysql_hosts'
     '(-P --port)'{-P+,--port=}'[specify port number for connection]:server port:_mysql_ports'
diff --git a/Completion/Unix/Command/_netstat b/Completion/Unix/Command/_netstat
index aa6c92fde..35d639f99 100644
--- a/Completion/Unix/Command/_netstat
+++ b/Completion/Unix/Command/_netstat
@@ -270,7 +270,7 @@ case $OSTYPE in
     sel_rdomains=( '-R[show all rdomains with associated interfaces and routing tables]' )
     sel_wireless=( '-W+[display per-interface IEEE 802.11 wireless statistics]:interface' )
     flist+=( local mpls )
-    tblopt='-T+[select an alternate routing table to query]:routing table'
+    tblopt='-T+[select an alternate routing table to query]:routing table:_routing_tables'
     sockets+=( -l$lopt $tblopt '-B[show buffer sizes for TCP sockets]' )
     routing+=( $Mopts $tblopt
       '-A[show the internal addresses of the routing table]'
@@ -280,7 +280,6 @@ case $OSTYPE in
       '-c+[show specified number of updates, then exit]:count'
       '-e[show only the number of errors on the interface]'
       '-q[only show interfaces that have seen packets]'
-      '-t[show current value of the watchdog timer function]'
     )
     statistics+=( $popt '-r[display routing statistics]' )
     groups+=( -n$nopt )
@@ -303,6 +302,9 @@ case $OSTYPE in
     memory+=( $Xopt) statistics+=( $Xopt )
     pcb+=( $Mopts $popt )
   ;;
+  freebsd<14->.*)
+    args+=( '-j+[run inside a jail]:jail:_jails' )
+  ;&
   freebsd<13->.*)
     sockets+=(
       '-c[show TCP stack used for each session]'
diff --git a/Completion/Unix/Command/_nice b/Completion/Unix/Command/_nice
index 29070697f..b52e5216a 100644
--- a/Completion/Unix/Command/_nice
+++ b/Completion/Unix/Command/_nice
@@ -1,14 +1,23 @@
 #compdef nice
 
-shift words
-(( CURRENT-- ))
+local -a specs=( '*:: : _normal -p $service' )
 
-if [[ $CURRENT -gt 1 && $words[1] = ([-+](-|)|-n)<-> ]]; then
-    shift words
-    (( CURRENT -- ))
-elif [[ $CURRENT -gt 2 && $words[1] = -n ]]; then
-    shift 2 words
-    (( CURRENT -= 2 ))
+# See if the 1st arg is such as -10 --10 or -+10
+if [[ $words[2] = -(-|+|)[0-9]## ]]; then
+  if (( $CURRENT == 2 )); then
+    _message 'niceness increment' && return
+  fi
+  compset -n 2  # Ignore the 1st arg
+else
+  if _pick_variant gnu=GNU unix --version; then
+    specs+=(
+      '(-)'{-n+,--adjustment=}'[adjust niceness]:niceness increment'
+      '(* -)--help[display help and exit]'
+      '(* -)--version[output version information and exit]'
+    )
+  else
+    specs+=( '-n+[specify increment of niceness]:niceness increment' )
+  fi
 fi
 
-_normal
+_arguments : $specs
diff --git a/Completion/Unix/Command/_nkf b/Completion/Unix/Command/_nkf
index 0c4f06fb5..ae79e745a 100644
--- a/Completion/Unix/Command/_nkf
+++ b/Completion/Unix/Command/_nkf
@@ -10,8 +10,8 @@ _arguments -s \
   '(-u)-b[Output is buffered]' \
   '(-b)-u[Output is unbuffered]' \
   '($outputs)'{-j,--jis}'[Output is JIS 7 bit]' \
-  '($outputs)'{-e,--sjis}'[Output is Shift JIS]' \
-  '($outputs)'{-s,--euc}'[Output is EUC-JP]' \
+  '($outputs)'{-s,--sjis}'[Output is Shift JIS]' \
+  '($outputs)'{-e,--euc}'[Output is EUC-JP]' \
   '($outputs)'{-w,--utf8}'[Output is UTF-8 (No BOM)]' \
   '($outputs)-w8[Output is UTF-8 (BOM)]' \
   '($outputs)'{-w16,-w16b0,--utf16}'[Output is UTF-16 (BigEndian; No BOM)]' \
@@ -23,8 +23,8 @@ _arguments -s \
   '($outputs)--mac[Output is for Mac]' \
   '($outputs)--windows[Output is for Windows]' \
   '($inputs)-J[Input assumption is JIS 7 bit]' \
-  '($inputs)-E[Input assumption is Shift JIS]' \
-  '($inputs)-S[Input assumption is EUC-JP]' \
+  '($inputs)-S[Input assumption is Shift JIS]' \
+  '($inputs)-E[Input assumption is EUC-JP]' \
   '($inputs)-W[Input assumption is UTF-8 (No BOM)]' \
   '($inputs)-W8[Input assumption is UTF-8 (BOM)]' \
   '($inputs)-W16[Input assumption is UTF-16 (BigEndian; No BOM)]' \
diff --git a/Completion/Unix/Command/_nm b/Completion/Unix/Command/_nm
index 79f537ac6..a78eb7068 100644
--- a/Completion/Unix/Command/_nm
+++ b/Completion/Unix/Command/_nm
@@ -17,9 +17,8 @@ if _pick_variant -r variant binutils=GNU elftoolchain=elftoolchain elfutils=elfu
     '(- *)'{-V,--version}'[display version information]'
     '(-f --format -P --portability)-B[same as --format=bsd]'
     '(-u --undefined-only)--defined-only[display only defined symbols]'
-    '(-f --format -P)--format=[specify output format]:format:(bsd sysv posix)'
     '(-n --numeric-sort -p --no-sort --size-sort -v)'{-n,--numeric-sort}'[sort symbols numerically by address]'
-    '(-p --no-sort -n -v --numeric-sort -r --reverse-sort --size-sort)'{-p,--no-sort}'[do not sort symbols]'
+    '(-p --no-sort -n -v --numeric-sort -r --reverse-sort --size-sort)'{-p,--no-sort}"[don't sort symbols]"
     '(-P --portability -B -f --format)'{-P,--portability}'[same as --format=posix]'
     '(-r --reverse-sort -p --no-sort)'{-r,--reverse-sort}'[reverse sort order]'
     '(-u --undefined-only --defined-only)'{-u,--undefined-only}'[display only undefined symbols]'
@@ -41,7 +40,7 @@ if _pick_variant -r variant binutils=GNU elftoolchain=elftoolchain elfutils=elfu
       args=( ${args:#*(-C|-o|--portability)\[*}
 	'(-C --demangle)'{-C,--demangle=-}'[decode symbol names]::style:(auto gnu-v2 gnu-v3 arm)'
 	'(-g --extern-only)-e[only display global and static symbols]'
-	'(--format -P)-F+[specify output format]:format:(bsd sysv posix)'
+	'(-B --format -P)'{-F,--format}'[specify output format]:format:(bsd sysv posix)'
 	'-o[with -P, same as -t o; otherwise same as -A]'
 	'(-t --radix)-x[print values in hexadecimal]'
       )
@@ -51,9 +50,9 @@ if _pick_variant -r variant binutils=GNU elftoolchain=elftoolchain elfutils=elfu
         '--mark-special[mark special symbols]'
 	'--color=[use color in output]:color:(always auto never)'
 	'(-C)--demangle[decode symbol names]'
-	'(--format -P)-f+[specify output format]:format:(bsd sysv posix)'
+	'(-B -f --format -P --portability)'{-f,--format}'[specify output format]:format:(bsd sysv posix)'
 	'(- *)--usage[give a short usage message]'
-	'(- *)-\\?[display help information]'
+	'(- *)-?[display help information]'
       )
     ;;
     binutils)
@@ -61,14 +60,19 @@ if _pick_variant -r variant binutils=GNU elftoolchain=elftoolchain elfutils=elfu
       args+=(
         '!(--no-recurse-limit)--recurse-limit'
         '--no-recurse-limit[disable demangling recursion limit]'
-	'(-f --format -P)-f+[specify output format]:format:(bsd sysv posix)'
-	'(-C --no-demangle)--demangle=-[decode symbol names]::style [auto]:(auto gnu lucid arm hp edg gnu-v3 java gnat rust dlang)'
+        '(-f --format -P -j --just-symbols)'{-f+,--format=}'[specify output format]:format [bsd]:(bsd sysv posix just-symbols)'
+        '(-C --no-demangle)--demangle=-[decode symbol names]::style [auto]:(none auto gnu-v3 java gnat dlang rust)'
         '--ifunc-chars=[specify characters to use for indirect function symbols]:characters for global/local indirect function symbols [ii]'
+        '(-B -f --format -P --portability -j --just-symbols)'{-j,--just-symbols}'[same as --format=just-symbols]'
 	'--plugin[load specified plugin]:plugin'
+	'--quiet[suppress no "no symbols" diagnostic]'
 	'--special-syms[include special symbols in the output]'
 	'--synthetic[display synthetic symbols as well]'
 	"--target=[target object format]:target:(${${(@M)${(f)$(_call_program targets nm --help)}:#*supported targets:*}##*: })"
+	'--unicode=[specify how to treat UTF-8 encoded unicode characters]:how_to_treat:(default show invalid hex escape highlight)'
+	'(-W --no-weak)'{-W,--no-weak}'[ignore weak symbols]'
 	'--with-symbol-versions[display version strings after symbol names]'
+	'--without-symbol-versions[not display of symbol version information]'
       )
     ;;
   esac
diff --git a/Completion/Unix/Command/_objdump b/Completion/Unix/Command/_objdump
index e2dde7e4c..94c01eb83 100644
--- a/Completion/Unix/Command/_objdump
+++ b/Completion/Unix/Command/_objdump
@@ -38,8 +38,10 @@ case $variant in
 
       '*-W-[display DWARF info in the file]::dwarf section:->short-dwarf-names'
       '*--dwarf=-[display DWARF info in the file]::dwarf section:->dwarf-names'
+      '(-L --process-links)'{-L,--process-links}'[display the contents of non-debug sections in separate debuginfo files]'
 
-      '--ctf=[display compact C type format info for section]:section'
+      '--ctf=-[display compact C type format info for section]::section'
+      '--sframe=-[display SFrame info from section]::section name [.sframe]'
       '(-t --syms)'{-t,--syms}'[display the contents of the symbol table(s)]'
       '(-T --dynamic-syms)'{-T,--dynamic-syms}'[display the contents of the dynamic symbol table]'
       '(-R --dynamic-reloc)'{-R,--dynamic-reloc}'[display the dynamic relocation entries in the file]'
@@ -59,11 +61,13 @@ case $variant in
       \*{-I+,--include=}'[add directory to search list for source files]:directory:_files -/'
       '(-l --line-numbers)'{-l,--line-numbers}'[include line numbers and filenames in output]'
       '(-F --file-offsets)'{-F,--file-offsets}'[include file offsets when displaying information]'
-      '(-C --demangle)-C[decode mangled/processed symbol names]'
-      '(-C --demangle)--demangle=-[decode mangled/processed symbol names]::style:(auto gnu lucid arm hp edg gnu-v3 java gnat rust dlang)'
+      '(--demangle)-C[decode symbol names]'
+      '(-C)--demangle=-[decode symbol names]::style [auto]:(none auto gnu-v3 java gnat dlang rust)'
       '!(--no-recurse-limit)--recurse-limit'
       '--no-recurse-limit[disable demangling recursion limit]'
       '(-w --wide)'{-w,--wide}'[format output for more than 80 columns]'
+      '-U+[specify how to display unicode characters]:method:(d l e x h i)'
+      '--unicode=[specify how to display unicode characters]:method:(default locale escape hex highlight invalid)'
       '(-z --disassemble-zeroes)'{-z,--disassemble-zeroes}"[don't skip blocks of zeroes when disassembling]"
 
       '--start-address=[only process data whose address is >= ADDR]:address'
@@ -73,15 +77,17 @@ case $variant in
       '(--show-raw-insn --no-show-raw-insn)'--{,no-}show-raw-insn'[display hex alongside symbolic disassembly]'
       '--insn-width=[display specified number of bytes on a single line with -d]:width (bytes)'
       '--adjust-vma=[add offset to all displayed section addresses]:offset'
+      '--show-all-symbols[when disassembling, display all symbols at a given address]'
       '--special-syms[include special symbols in symbol dumps]'
       '--inlines[print all inlines for source line (with -l)]'
       '--prefix=[add prefix to absolute paths for -S]:prefix'
       '--prefix-strip=[strip initial directory names for -S]:level'
       "--dwarf-depth=[don't display DIEs at specified or greater depth]:depth"
       '--dwarf-start=[display DIEs at specified or deeper depth]:depth'
-      '--dwarf-check[perform additional dwarf internal consistency checks]'
+      '--dwarf-check[perform additional dwarf consistency checks]'
       '--ctf-parent=[use specified section as the CTF parent]:section'
       '--visualize-jumps=-[visualize jumps by drawing ASCII art lines]::color:(color extended-color off)'
+      '--disassembler-color=[control use of colored syntax highlighting in disassembly output]:color use [on]:(off terminal on extended)'
     )
   ;;
   elfutils)
diff --git a/Completion/Unix/Command/_openldap b/Completion/Unix/Command/_openldap
new file mode 100644
index 000000000..233d0950e
--- /dev/null
+++ b/Completion/Unix/Command/_openldap
@@ -0,0 +1,222 @@
+#compdef ldapadd ldapcompare ldapdelete ldapexop ldapmodify ldapmodrdn ldappasswd ldapsearch ldapurl ldapwhoami
+
+local curcontext="$curcontext" nm="$compstate[nmatches]"
+local -a args auth state line expl
+
+args=( '*-e[general extensions]:extension:->general-extensions' )
+
+case $service in
+  ldapadd|ldapcompare|ldapdelete|ldapexop|ldapmodify|ldapmodrdn|ldappasswd|ldapsearch|ldapwhoami)
+    if (( $words[(I)-[^Z]#Z[^Z]#] )); then
+      args+=( '*-Z[require success for start TLS request]' )
+    elif (( ! $words[(I)-[^Z]#Z] )); then
+      args+=( '-Z[start TLS request]' )
+    fi
+    args+=(
+      '!(-)-VV' '-V[display version information]'
+      '*-d+[set LDAP debugging level]:level:((1\:trace 2\:packets 4\:args 8\:conns 10\:ber 2048\:parse -1\:all))'
+      "-n[show what would be done but don't actually do it]"
+      '-v[verbose output]'
+      "-N[don't use reverse DNS to canonicalize SASL host name]"
+      '*-o+[specify any ldap.conf options]: : _values option
+        "ldif_wrap[specify width]\:width"
+        "nettimeout[specify timeout]\:timeout (seconds)"'
+    )
+    auth=(
+      '-D[specify bind DN]:binddn'
+      '-H[specify LDAP URIs]:uri'
+      '-P[specify protocol version]:version [3]:(2 3)'
+      + simple
+      '(sasl)-x[use simple authentication]'
+      '(sasl -W -y)-w+[specify bind password]:bind password'
+      '(sasl -w -y)-W[prompt for bind password]'
+      '(sasl -w -W)-y+[read password from file]:file:_files'
+      + sasl
+      '(simple)-O+[specify SASL security properties]: : _values -s , property
+          none noplain noactive nodict noanonymous forwardsec passcred
+          minssf\:factor maxssf\:factor maxbufsize\:factor'
+      '(simple)-X+[specify SASL authorization identity]:authzid:->authzids'
+      '(simple)-Y+[specify SASL mechanism]:mechanism:compadd -M "m:{a-zA-Z}={A-Za-z}" EXTERNAL GSSAPI' # iana has a full list but cyrus support seems limited
+      '(simple)-R+[specify SASL realm]:realm'
+      '(simple)-U+[specify SASL authentication identity]:authcid'
+      '(simple)-I[use SASL Interactive mode]'
+      '(simple)-Q[use SASL Quiet mode]'
+    )
+  ;|
+  ldapadd|ldapcompare|ldapdelete|ldapmodify|ldapmodrdn|ldapsearch)
+    if (( $words[(I)-[^M]#M[^M]#] )); then
+      args+=( '*-M[enable Manage DSA IT control critical]' )
+    elif (( ! $words[(I)-[^M]#M] )); then
+      args+=( '-M[enable Manage DSA IT control]' )
+    fi
+  ;|
+  ldapadd|ldapdelete|ldapmodify|ldapmodrdn|ldapsearch)
+    # ldapexop documents but doesn't implement this
+    args+=( '(1 2 *)-f+[read operations from file]:file:_files' )
+  ;|
+  ldapadd|ldapdelete|ldapmodify|ldapmodrdn|ldapsearch)
+    args+=( "-c[continuous operation mode (don't stop on errors)]" )
+  ;|
+  ldapdelete|ldapsearch)
+    args+=( '-z+[specify size limit]:size limit (entries)' )
+  ;|
+  ldapadd|ldapmodify)
+    args+=(
+      '-S+[write records that are skipped due to an error to file]:file:_files'
+      '*-E+[modify extensions]:extension:->modify-extensions'
+    )
+  ;|
+  ldapurl|ldapsearch)
+    args+=(
+      '(decompose)-s+[specify search scope]:search scope [sub]:(base one sub children)'
+    )
+  ;|
+  ldapdelete|ldapmodrdn|ldapurl|ldapwhoami) args+=( '!*-E+:extension' ) ;|
+
+  ldapadd) args+=( '!-a' ) ;;
+  ldapmodify) args+=( '-a[add new entries]' ) ;;
+  ldapcompare)
+    args+=(
+      '-z[quiet mode - no output aside return status]'
+      '*-E+[compare extensions]:extension:->compare-extensions'
+    )
+  ;;
+  ldapdelete)
+    args+=(
+      '-r[do a recursive delete]'
+      '*: :_guard "^-*" "distinguished name"'
+    )
+  ;;
+  ldapexop) args+=( '*:: :->extended-operations' ) ;;
+  ldapmodrdn)
+    args+=(
+      '-r[remove old RDN values from the entry]'
+      '-s[specify new superior entry to move target to]:entry'
+      '1:distinguished name'
+      '2:relative distinguished name'
+    )
+  ;;
+  ldappasswd)
+    args+=(
+      '(-a -t)-A[prompt for old password]'
+      '(-A -t)-a+[specify old password]:password'
+      '(-A -a)-t+[read old password from file]:file:_files'
+      '(-s -T)-S[prompt for new password]'
+      '(-S -T)-s+[specify new password]:password'
+      '(-S -s)-T+[read new password from file]:file:_files'
+    )
+  ;;
+  ldapsearch)
+    if (( $words[(I)-[^L]#L[^L]#L[^L]#] )); then
+      args+=( '*-L[LDIF format without comments and version]' )
+    elif (( $words[(I)-[^L]#L[^L]#] )); then
+      args+=( '*-L[LDIF format without comments]' )
+    elif ! (( $words[(I)-[^L]#L[^L]#L[^L]#L] )); then
+      args+=( '-L[LDIFv1 format]' )
+    else
+      args+=( '!*-L' )
+    fi
+    if (( $words[(I)-[^t]#t[^t]#] )); then
+      args+=( '*-t[write all retrieved values to files in temporary directory]' )
+    elif (( ! $words[(I)-[^t]#t] )); then
+      args+=( '-t[write binary values to files in temporary directory]' )
+    fi
+
+    args+=(
+      '-a+[specify how aliases dereferencing is done]:deref [never]:(never always search find)'
+      '-A[retrieve attributes only (no values)]'
+      '-b+[specify base dn for search]:basedn'
+      '*-E+[search extensions]:extension:->search-extensions'
+      '-F+[specify URL prefix for temporary files]:prefix [file:///tmp//]'
+      '-l+[specify time limit for search]:time limit (seconds)'
+      '-S+[sort results by specified attribute]:attribute:_ldap_attributes'
+      '-T[write files to specified directory]:path [/tmp]:_directories'
+      '-u[include User Friendly entry names in the output]'
+      '1: :_ldap_filters'
+      '2: : _alternative
+        "attributes:attribute:_ldap_attributes"
+        "attributes:attribute:((1.1\:no\ attributes \*\:all\ user\ attributes \+\:all\ operational\ attributes))"'
+      '*:attribute:_ldap_attributes -F line'
+    )
+  ;;
+  ldapurl)
+    args+=(
+      - compose
+      '-a+[set a list of attribute selectors]:attribute selectors (comma separated)'
+      '-b+[set the searchbase]:search base'
+      '-f+[set the URL filter]:filter:_ldap_filters'
+      '-h+[set the host]:host:_hosts'
+      '-p+[set the tcp port]:port:(389 636)'
+      '-S+[set the URL scheme]:scheme:(ldap ldaps)'
+      - decompose
+      '(-s)-H+[specify URI to be exploded]:uri'
+    )
+  ;;
+esac
+
+_arguments -C -S -s $args $auth
+
+case $state in
+  extended-operations)
+    case $CURRENT:$words[1] in
+      1:*)
+        if compset -P '*::'; then
+          _message -e data 'base64 data'
+        elif compset -P '*:'; then
+          _message -e data data
+        else
+          _alternative \
+            'oids::_guard "(<->(|.))#" oid' \
+            'operations:operation:(whoami cancel refresh)'
+        fi
+      ;;
+      2:cancel) _message -e ids 'cancel id' ;;
+      2:refresh) _message -e names 'distinguished name' ;;
+      3:refresh) _message -e times 'ttl' ;;
+      *) _message 'no more arguments' ;;
+    esac
+  ;;
+  *-extensions)
+    if ! compset -P \!; then
+      _description criticality expl critical
+      compadd -S "" "$expl[@]" \!
+    fi
+  ;|
+  modify-extensions) _values extension 'txn:txn:(abort commit)' ;;
+  compare-extensions) _values extension dontUseCopy ;;
+  search-extensions)
+    _values extension \
+      'mv[matched values filter]:filter:_ldap_filters' \
+      'pr[paged results/prompt]:size[/prompt|noprompt]' \
+      'sss[server side sorting]: :_sequence -s / _ldap_attributes' \
+      'subentries: :(true false)' \
+      'sync:sync[/cookie][/slimit]:((ro\:refreshOnly rp\:refreshAndPersist))' \
+      'vlv[virtual list view]:before/after(/offset/count|\:value' \
+      'deref:derefAttr:_sequence _ldap_attributes' \
+      dontUseCopy domainScope
+  ;;
+  general-extensions)
+    _values extension \
+      'assert:filter:_ldap_filters' \
+      'authzid:authzid:->authzids' \
+      {post,pre}'read: :_sequence _ldap_attributes' \
+      'sessiontracking:username:_users' \
+      'chaining:behavior:(chainingPreferred chainingRequired referralsPreferred referralsRequired)' \
+      bauthzid manageDSAit noop ppolicy relax abandon cancel ignore
+  ;&
+  authzids)
+    if [[ $state != authzids ]]; then
+      : # fall-through from above without the authzids state
+    elif compset -P 'u:'; then
+      _description users expl authzid
+      _users "$expl[@]"
+    elif compset -P 'dn:'; then
+      _message -e ids 'distinguished name'
+    else
+      _description prefixes expl prefix
+      compadd -S: "$expl[@]" u dn
+    fi
+  ;;
+esac
+
+[[ nm -ne "$compstate[nmatches]" ]]
diff --git a/Completion/Unix/Command/_pandoc b/Completion/Unix/Command/_pandoc
index b0fff80d6..797e73eaa 100644
--- a/Completion/Unix/Command/_pandoc
+++ b/Completion/Unix/Command/_pandoc
@@ -113,7 +113,7 @@ _pandoc_defaults_file() {
 
 # choose reference location
 (( $+functions[_pandoc_reference_location] )) ||
-_pandoc_reference_location(){
+_pandoc_reference_location() {
   local -a policies
   policies=(
     'block:place references at the end of the current (top-level) block'
@@ -123,22 +123,16 @@ _pandoc_reference_location(){
   _describe 'location' policies
 }
 
-# choose top level division
-(( $+functions[_pandoc_top_level_division] )) ||
-_pandoc_top_level_division(){
-  _values 'top level division' default section chapter part
-}
-
 # choose email obfusication
 (( $+functions[_pandoc_email_obfusication] )) ||
 _pandoc_email_obfusication(){
   local -a policies
   policies=(
-    'none:leave mailto: links as they are'
-    'javascript:obfuscates them using JavaScript'
-    'references:obfuscates them by printing their letters as decimal or hexadecimal character references'
+    'none:leave mailto: links as-is'
+    'javascript:obfuscate using JavaScript'
+    'references:obfuscate by printing letters as decimal or hexadecimal character references'
   )
-  _describe 'obfuscation policy [none]' policies
+  _describe 'e-mail obfuscation policy [none]' policies
 }
 
 # choose wrapping policy
@@ -181,26 +175,26 @@ _pandoc_track_changes() {
 _arguments -s \
   {-f+,-r+,--from=,--read=}'[specify input format]: :_pandoc_format -T input' \
   {-t+,-w+,--to=,--write=}'[specify output format]: :_pandoc_format -T output' \
-  {-o+,--output=}'[write output to FILE instead of stdout]:file:_files' \
+  {-o+,--output=}'[write output to specified file instead of stdout]:file:_files' \
   '--data-dir=[specify the user data directory to search for pandoc data files]:data directory:_files -/' \
   {-d+,--defaults=}'[read default from YAML file]: :_pandoc_defaults_file' \
   '--shift-heading-level-by=[shift heading levels by specified number]:positive or negative integer: ' \
   '!--base-header-level=:number [1]:(1 2 3 4 5)' \
-  '!--strip-empty-paragraphs[deprecated. Use the +empty_paragraphs extension instead]' \
-  '--indented-code-classes=[classes to use for indented code blocks]:class list (comma-separated)' \
+  '--indented-code-classes=[specify classes to use for indented code blocks]:class list (comma-separated)' \
   '--default-image-extension=[specify a default extension to use when image paths/URLs have no extension]:extension: ' \
   '--file-scope[parse each file individually before combining for multifile documents]' \
+  '--sandbox=-[run in a sandbox, limiting IO operations]::enable:(true false)' \
   {\*-F+,\*--filter=}'[specify an executable to be used as a filter transforming the pandoc AST after the input is parsed and before the output is written]: :_pandoc_filter' \
   {\*-L+,\*--lua-filter=}"[transform the document by using pandoc's built-in lua filtering system]: :_pandoc_lua_filter" \
   {\*-M+,\*--metadata=}'[set the metadata field KEY to the value VALUE]:key\:value: ' \
   '*--metadata-file=[read metadata from file]:YAML or JSON file:_files' \
   {-p,--preserve-tabs}'[preserve tabs instead of converting them to spaces]' \
   '--tab-stop=[specify the number of spaces per tab]:spaces [4]' \
-  '--track-changes=[specifies what to do with insertions, deletions, and comments produced by the MS Word "Track Changes" feature]: :_pandoc_track_changes' \
+  '--track-changes=[specify what to do with insertions, deletions, and comments produced by the MS Word "Track Changes" feature]: :_pandoc_track_changes' \
   '--extract-media=[extract media in source document to specified directory]:directory:_files -/' \
-  '--abbreviations=[specifies a custom abbreviations file]:file:_files ' \
+  '--abbreviations=[specify a custom abbreviations file]:file:_files ' \
   {-s,--standalone}'[produce output with an appropriate header and footer]' \
-  '--template=[use FILE as a custom template for the generated document. Implies --standalone]: :_pandoc_template' \
+  '--template=[use specified file as a custom template for the generated document. Implies --standalone]: :_pandoc_template' \
   {\*-V+,\*--variable=}'[set the variable KEY to the value VALUE]:key\:value: ' \
   '(- :)'{-D+,--print-default-template=}'[print the system default template for an output]:format:( $(pandoc --list-output-formats) )' \
   '(- :)--print-default-data-file=[print a system default data file]:file: ' \
@@ -211,43 +205,48 @@ _arguments -s \
   {--toc,--table-of-contents}'[include an automatically generated table of contents]' \
   '--toc-depth=[specify the number of section levels to include in the table of contents]:number' \
   '--strip-comments[strip out HTML comments in the Markdown or Textile source]' \
-  '--no-highlight[disables syntax highlighting for code blocks and inlines]' \
-  '--highlight-style=[specifies the coloring style to be used in highlighted source code]:style|file:_pandoc_highlight_style' \
+  '--no-highlight[disable syntax highlighting for code blocks and inlines]' \
+  '--highlight-style=[specify coloring style to be used in highlighted source code]: :_pandoc_highlight_style' \
   '(- :)--print-highlight-style=[prints a JSON version of a highlighting style]: :_pandoc_highlight_style' \
   '--syntax-definition=[load a KDE XML syntax definition file]:file:_files -g "*.xml(-.)"' \
-  {\*-H+,\*--include-in-header=}'[include contents of FILE, verbatim, at the end of the header, implies --standalone]:file:_files' \
-  {\*-B+,\*--include-before-body=}'[include contents of FILE, verbatim, at the beginning of the document body, implies --standalone]:file:_files' \
-  {\*-A+,\*--include-end-body=}'[include contents of FILE, verbatim, at the end of the document body, implies --standalone]:file:_files' \
+  \*{-H+,--include-in-header=}'[include contents of file, verbatim, at the end of the header, implies --standalone]:file:_files' \
+  \*{-B+,--include-before-body=}'[include contents of file, verbatim, at the beginning of the document body, implies --standalone]:file:_files' \
+  \*{-A+,--include-end-body=}'[include contents of file, verbatim, at the end of the document body, implies --standalone]:file:_files' \
   '--resource-path=[list of paths to search for images and other resources]:searchpath:_dir_list' \
   '--request-header=[set the request header NAME to the value VAL when making HTTP requests]:name\:val: ' \
   '--no-check-certificate[disable the certificate verification]' \
   '--self-contained[produce a standalone HTML file with no external dependencies, using data: URIs to incorporate the contents of linked scripts, stylesheets, images, and videos. Implies --standalone]' \
+  '--embed-resources=-[produce a standalone HTML document with no external dependencies]::enable:(true false)' \
   '--html-q-tags[use <q> tags for quotes in HTML]' \
   '--ascii[use only ASCII characters in output, supported only for HTML and DocBook output]' \
   '--reference-links[use reference-style links, rather than inline links]' \
   '--reference-location=[specify where footnotes (and references, if reference-links is set) are placed (block|section|document)]: :_pandoc_reference_location' \
   '--markdown-headings[specify style for level1 and 2 headings in markdown output]:style [atx]:(setext atx)' \
-  '!--atx-headers[use ATX-style headers in Markdown and AsciiDoc output]' \
-  '--top-level-division=[treat top-level headers as the given division type in LaTeX, ConTeXt, DocBook, and TEI output]: :_pandoc_top_level_division' \
+  '--list-tables=-[render tables as list tables in RST output]::enable(true false)' \
+  '--top-level-division=[treat top-level headers as given division type in LaTeX, ConTeXt, DocBook and TEI output]:top level division:(default section chapter part)' \
   {-N,--number-sections}'[number section headings in LaTeX, ConTeXt, HTML, or EPUB output]' \
-  '--number-offset=[offset for section headings in HTML output (ignored in other output formats)]:number[number,...] [0]' \
+  '--number-offset=[specify offset for section headings in HTML output (ignored in other output formats)]:number[number,...] [0]' \
   '--listings[use the listings package for LaTeX code blocks]' \
   {-i,--incremental}'[make list items in slide shows display incrementally (one by one)]' \
-  '--slide-level=[specifies that headers with the specified level create slides (for beamer, s5, slidy, slideous, dzslides)]:slide level:(1 2 3 4 5 6)' \
-  '--section-divs[wrap sections in <section> tags (or <div> tags for html4)Use the section-divs package for LaTeX code blocks]' \
-  '--email-obfusication=[treat top-level headers as the given division type in LaTeX, ConTeXt, DocBook, and TEI output (none|javascript|references)]: :_pandoc_email_obfusication' \
+  '--slide-level=[divide into slides for headers above the specified level (for beamer, s5, slidy, slideous, dzslides)]: :_pandoc_header_levels' \
+  '--section-divs[wrap sections in <section> tags (or <div> tags for html4)]' \
+  '--email-obfusication=[specify method for obfusicating mailto: links in HTML documents]: :_pandoc_email_obfusication' \
   '--id-prefix=[specify a prefix to be added to all identifiers and internal links in HTML and DocBook output]:string: ' \
   {-T+,--title-prefix=}'[specify STRING as a prefix at the beginning of the title that appears in the HTML header]:string: ' \
   {\*-c+,\*--css=}'[link to a CSS style sheet]: :_urls' \
-  '--reference-doc=[use the specified file as a style reference in producing a docx or ODT file]:file: ' \
+  '--reference-doc=[use specified file as a style reference in producing a docx or ODT file]:file:_files' \
   '--epub-subdirectory=[specify the subdirectory in the OCF container that is to hold the EPUB-specific contents]:directory:_files -/' \
   '--epub-cover-image=[use the specified image as the EPUB cover]:file:_files' \
+  '--epub-title-page=-[determine whether title page is included in EPUB]::enable [true]:(true false)' \
   '--epub-metadata=[look in the specified XML file for metadata for the EPUB]:file:_files -g "*.xml(-.)"' \
   '*--epub-embed-font=[embed the specified font in the EPUB]:file:_files ' \
+  '--split-level=[specify heading level at which to split an EPUB or chunked HTML into separate files]:heading level' \
+  '--chunk-template=[specify filename template for a chunked html document]:template' \
   '--epub-chapter-level=[specify the header level at which to split the EPUB into separate "chapter" files]:number:(1 2 3 4 5 6)' \
   '--ipynb-output=[specify how to tread ipynb output cells]:method:(all none best)' \
-  '--pdf-engine=[use the specified engine when producing PDF output]:program:_pandoc_pdf_engine' \
-  '*--pdf-engine-opt=[use the given string as a command-line argument to the pdf-engine]:string:_pandoc_pdf_engine_opts' \
+  '--pdf-engine=[use specified engine when producing PDF output]:program:_pandoc_pdf_engine' \
+  '*--pdf-engine-opt=[use given string as a command-line argument to the pdf-engine]:string:_pandoc_pdf_engine_opts' \
+  '(-C --citeproc)'{-C,--citeproc}'[process citations]' \
   "*--bibliography=[set the bibliography field in the document's metadata to specified file]:file:_files -g '*.(bib|bibtex|copac|json|yaml|enl|xml|wos|medline|mods|ris)(-.)'" \
   "--csl=[set the csl field in the document's metadata to specified file]:file:_files -g '*.csl(-.)'" \
   '--citation-abbreviations=[set the citation-abbreviations field in the document'"'"'s metadata to FILE]:file:_files' \
@@ -257,10 +256,10 @@ _arguments -s \
   '--webtex=[convert TeX formulas to <img> tags that link to an external script that converts formulas to images]:: :_urls' \
   '--mathjax=[use MathJax to display embedded TeX math in HTML output]:: :_urls' \
   '--katex=[use KaTeX to display embedded TeX math in HTML output]:: :_urls' \
-  '--gladtex[Enclose TeX math in <eq> tags in HTML output]' \
+  '--gladtex[enclose TeX math in <eq> tags in HTML output]' \
   '--trace[enable tracing]' \
-  '--dump-args[print information about command-line arguments to stdout, then exit]' \
-  '--ignore-args[ignore command-line arguments (for use in wrapper scripts)]' \
+  '!--dump-args' \
+  '!--ignore-args' \
   '--verbose[give verbose debugging output]' \
   '--quiet[suppress warning messages]' \
   '--fail-if-warnings[exit with error status if there are any warnings]' \
@@ -271,6 +270,7 @@ _arguments -s \
   '(- :)--list-extensions=[list supported extensions, one per line, preceded by a + or - indicating whether it is enabled by default in FORMAT]:format:_pandoc_all_formats' \
   '(- :)--list-highlight-languages[list supported languages for syntax highlighting, one per line]' \
   '(- :)--list-highlight-styles[list supported styles for syntax highlighting, one per line]' \
+  '(- :)--print-highlight-style=[print JSON version of a highlighting style]: :_pandoc_highlight_style' \
   '(- :)'{-v,--version}'[print version]' \
   '(- :)'{-h,--help}'[print help]' \
   '*:file:_files'
diff --git a/Completion/Unix/Command/_perl b/Completion/Unix/Command/_perl
index d7e8f1b51..1631560ce 100644
--- a/Completion/Unix/Command/_perl
+++ b/Completion/Unix/Command/_perl
@@ -17,6 +17,7 @@ _perl () {
     '(1 -e)*-E+[like -e but enable all optional features]:one line of program' \
     '-f[disable executing $Config{sitelib}/sitecustomize.pl at startup]' \
     '-F-[split() pattern for autosplit (-a)]:split() pattern, // is optional' \
+    '-g[read all input in one go (slurp), rather than line-by-line (alias for -0777)]' \
     '-h[list help summary]' \
     '-i-[edit <> files in place (make backup if extension supplied)]:backup file extension: ' \
     '*-I-[specify @INC/#include directory (may be used more than once)]:include path:_files -/' \
diff --git a/Completion/Unix/Command/_perlbrew b/Completion/Unix/Command/_perlbrew
new file mode 100644
index 000000000..8bf9ba7cc
--- /dev/null
+++ b/Completion/Unix/Command/_perlbrew
@@ -0,0 +1,315 @@
+#compdef perlbrew
+
+#
+# A zsh completion script for perlbrew (https://metacpan.org/dist/App-perlbrew/)
+#
+
+local curcontext="$curcontext" state state_descr line ret=1
+local -a args_common args_install
+typeset -A opt_args
+# others local variables
+typeset -g perlbrew_subcommands
+
+##
+## get the list of perl available versions
+##
+(( $+functions[_perlbrew_caching_policy] )) ||
+_perlbrew_caching_policy() {
+  # rebuild if cached data are more than one week old
+  local -a newer=( "$1"(Nmw-1) )
+  return $#newer
+}
+
+(( $+functions[_perl_available] )) ||
+_perl_available() {
+  local -a available_versions
+  local update_policy
+
+  zstyle -s ":completion:${curcontext}:" cache-policy update_policy
+  if [[ -z "$update_policy" ]]; then
+    zstyle ":completion:${curcontext}:" cache-policy _perlbrew_caching_policy
+  fi
+
+  if _cache_invalid perlbrew-available-versions || ! _retrieve_cache perlbrew-available-versions; then
+    # this can be slow
+    available_versions=( ${${${${(f)"$(_call_program perl_releases perlbrew available)"}/\# (cp|p)erl/}/(#s)i /}// /} \
+                         perl-stable \
+                         perl-blead )
+    _store_cache perlbrew-available-versions available_versions
+  fi
+  _values 'available version' ${(n)available_versions}
+}
+
+##
+## get the list of local perl installations
+##
+(( $+functions[_perl_installations] )) ||
+_perl_installations() {
+  local text
+  local -a installed alias_link
+
+  case "$1" in
+    (-with-lib)
+      installed=( ${${${(f)"$(_call_program perl_installed perlbrew list)"}/(#s)\*/}// /} )
+      text="perl installation"
+      ;;
+    (-only-lib)
+      installed=( ${(M)${${${(f)"$(_call_program perl_installed perlbrew list)"}/(#s)\*/}// /}:#*@*} )
+      text="perl installation"
+      ;;
+    (-without-lib)
+      installed=( ${${${${(f)"$(_call_program perl_installed perlbrew list)"}/(#s)\*/}// /}:#*@*} )
+      text="perl installation"
+      ;;
+    (-alias)
+      if [[ -n "$PERLBREW_ROOT" ]]; then
+        if [[ -d "$PERLBREW_ROOT/perls" ]]; then
+          alias_link=( $PERLBREW_ROOT/perls/*(@) )
+        fi
+      fi
+      installed=( ${(q)${alias_link:t}[@]} )
+      text="alias"
+      ;;
+  esac
+
+  if [[ ${#installed[@]} -eq 0 ]]; then
+    _message 'no local perl installation found'
+  else
+    case "$2" in
+      (-comma-separated)
+        _values -s , "$text" $installed
+        ;;
+      (*)
+        _values "$text" $installed
+        ;;
+    esac
+  fi
+}
+
+##
+## completion for the alias subcommand
+##
+(( $+functions[_perlbrew_alias] )) ||
+_perlbrew_alias() {
+  local line state ret=1
+
+  _arguments -C \
+    -f'[force]' \
+    "1: :->actions" \
+    "*::arg:->args" && ret 0
+
+  case "$state" in
+    (actions)
+      local -a alias_actions
+      alias_actions=(
+        "create:create an alias for the installation named <name>"
+        "rename:rename the alias to a new name"
+        "delete:delete the given alias"
+      )
+      _describe -t commands 'alias action' alias_actions && ret=0
+      ;;
+    (args)
+      case $line[1] in
+        (create)
+          _arguments \
+            '1:perl installation: _perl_installations -without-lib' \
+            '2: : _message "alias name"' && ret=0
+          ;;
+        (rename)
+          _arguments \
+            '1:perl installation: _perl_installations -alias' \
+            '2: : _message "new name"' && ret=0
+          ;;
+        (delete)
+          _arguments \
+            ':perl installation: _perl_installations -alias' && ret=0
+          ;;
+      esac
+      ;;
+  esac
+}
+
+##
+## completion for the lib subcommand
+##
+(( $+functions[_perlbrew_lib] )) ||
+_perlbrew_lib() {
+  local line state ret=1
+
+  _arguments -C \
+    "1: :->actions" \
+    "*::arg:->args" && ret=0
+
+  case "$state" in
+    (actions)
+      local -a lib_actions
+      lib_actions=(
+        "list:list existing local libs"
+        "create:create a local lib"
+        "delete:delete a local lib"
+      )
+      _describe -t commands 'lib action' lib_actions && ret=0
+      ;;
+    (args)
+      case $line[1] in
+        (list)
+          _nothing && ret=0
+          ;;
+        (create)
+          _message 'lib name' && ret=0
+          ;;
+        (delete)
+          _arguments \
+            ':perl installation: _perl_installations -only-lib' && ret=0
+          ;;
+      esac
+      ;;
+  esac
+}
+
+##
+## main completion script
+##
+
+args_common=(
+  '(-q --quiet)'{-q,--quiet}'[be quiet on informative output message]' \
+  '(-v --verbose)'{-v,--verbose}'[tell me more about it]' \
+  ':perlbrew command:->subcommands' \
+  '*::: := ->option-or-argument'
+)
+
+args_install=(
+  '(-f --force)'{-f,--force}'[force installation]' \
+  -j"[number of building jobs run in parallel]::number" \
+  '(-n --notest)'{-n,--notest}'[skip testing]' \
+  --switch"[automatically switch to this perl version once installed]" \
+  --as"[install the given version of perl by a name]:alias name" \
+  --noman"[skip installation of manpages]" \
+  --thread"[build perl with usethreads enabled]" \
+  --multi"[build perl with usemultiplicity enabled]" \
+  --64int"[build perl with use64bitint enabled]" \
+  --64all"[build perl with use64bitall enabled]" \
+  --ld"[build perl with uselongdouble enabled]" \
+  --debug"[build perl with DEBUGGING enabled]" \
+  --clang"[build perl using the clang compiler]" \
+  --no-patchperl"[skip calling patchperl]" \
+  {-D,-U,-A}"[switches passed to perl Configure script]:value:" \
+  --destdir"[install perl as per 'make install DESTDIR=\$path']: :_files -/" \
+  --sitecustomize"[specify a file to be installed as sitecustomize.pl]: :_files" \
+  --mirror"[specify a CPAN-mirror url]:URL:_urls"
+)
+
+_arguments -C $args_common && ret=0
+
+case $state in
+  (subcommands)
+
+    perlbrew_subcommands=(
+      "init:initialize perlbrew environment"
+      "info:show useful information about the perlbrew installation"
+      "install:install perl"
+      "uninstall:uninstall the given installation"
+      "available:list perls available to install"
+      "lib:manage local::lib directories"
+      "alias:give perl installations a new name"
+      "upgrade-perl:upgrade the current perl"
+      "list:list perl installations"
+      "use:use the specified perl in current shell"
+      "off:turn off perlbrew in current shell"
+      "switch:permanently use the specified perl as default"
+      "switch-off:permanently turn off perlbrew (revert to system perl)"
+      "exec:exec programs with specified perl environments"
+      "clone-modules:re-installs all CPAN modules from one installation to another"
+      "self-install:install perlbrew itself under PERLBREW_ROOT/bin"
+      "self-upgrade:upgrade perlbrew itself"
+      "install-patchperl:install patchperl"
+      "install-cpanm:install cpanm, a friendly companion"
+      "install-cpm:install cpm, a faster but still friendly companion"
+      "install-multiple:install multiple versions and flavors of perl"
+      "download:download the specified perl distribution tarball"
+      "clean:purge tarballs and build directories"
+      "version:display version"
+      "help:read more detailed instructions"
+    )
+
+    _describe -t commands 'perlbrew command' perlbrew_subcommands && ret=0
+
+    ;;
+  (option-or-argument)
+    curcontext=${curcontext%:*}-$line[1]:
+    case $line[1] in
+      (info)
+        _message 'perl module name' && ret=0
+        ;;
+      (install)
+        _arguments \
+           $args_install \
+           '1:perl release: _perl_available' && ret=0
+        ;;
+      (install-multiple)
+        _arguments \
+           $args_install \
+           '*'--both"[perl flavor]: :(thread multi ld 64int 64all debug clang )" \
+           --common-variations"[equivalent to '--both thread --both ld --both 64int']" \
+           --all-variations"[generates all the possible flavor combinations]" \
+           --append"[appends the given string to the generated names]:string" \
+           '*:perl release: _perl_available' && ret=0
+        ;;
+      (uninstall)
+        _arguments \
+          ":perl installation: _perl_installations -without-lib" && ret=0
+        ;;
+      (use|switch)
+        _arguments \
+          ':perl installation: _perl_installations -with-lib' && ret=0
+        ;;
+      (available)
+        _arguments \
+          '--all[list of all perls ever released, including development and RC versions]' \
+          '*: :' && ret=0
+        ;;
+      (alias)
+        _perlbrew_alias && ret=0
+        ;;
+      (exec)
+        _arguments -C \
+          --with'[specify one or more perl installations to use]: : _perl_installations -without-lib -comma-separated' \
+          --min'[minimum perl version]:version number (n.nnnnn):' \
+          --max'[maximum perl version]:version number (n.nnnnn):' \
+          --halt-on-error'[stop on first nonzero exit status]' \
+          "1:command:" \
+          "*:args:" && ret=0
+        ;;
+      (env) # NOTE: Low level command
+        _arguments \
+          ':perl installation: _perl_installations -with-lib' && ret=0
+        ;;
+      (symlink-executables) # NOTE: Low level command
+        _arguments \
+          ':perl installation: _perl_installations -with-lib' && ret=0
+        ;;
+      (lib)
+        _perlbrew_lib && ret=0
+        ;;
+      (download)
+        _arguments \
+          ':perl release: _perl_available' && ret=0
+        ;;
+      (clone-modules)
+        _arguments \
+          '--notest[skip all module tests]' \
+          ':perl installation: _perl_installations -with-lib' \
+          ':perl installation: _perl_installations -with-lib' && ret=0
+        ;;
+      (init|list|off|switch-off|install-cpanm|install-patchperl|self-upgrade|\
+        self-install|clean|version|upgrade-perl|list-modules)
+        _nothing && ret=0
+        ;;
+      (*)
+        _default && ret=0
+        ;;
+    esac
+    ;;
+esac
+
+return ret
diff --git a/Completion/Unix/Command/_pgrep b/Completion/Unix/Command/_pgrep
index afd2fe54b..94c1dae1a 100644
--- a/Completion/Unix/Command/_pgrep
+++ b/Completion/Unix/Command/_pgrep
@@ -5,7 +5,6 @@
 #   (which changed the behaviour of -f and added -a)
 # - We don't really need to keep pgopts and pkopts separate, but it seems like
 #   it should make things a bit easier to follow
-# - @todo We could complete routing tables given to -T
 
 local curcontext="$curcontext" state line ret=1 expl pgopts pkopts no
 typeset -A opt_args
@@ -35,16 +34,18 @@ arguments=(
   '(-P --parent)'{-P+,--parent=}'[match only on specified parent process IDs]: :->ppid'
   '(-l)-q[suppress normal output]'
   '(-r --runstates)'{-r+,--runstates}'[match runstates]:run state:compadd -S "" D I R S T t W X Z'
+  '(-A --ignore-ancestors)'{-A,--ignore-ancestors}'[exclude our ancestors from results]'
   '-S[search also in system processes (kernel threads)]'
   '(-s --session)'{-s+,--session=}'[match only on specified process session IDs]: :->sid'
   # _signals is OK here - we do it differently below
   '(ss)--signal=[specify signal to send to process]: :_signals -s'
-  '-T+[match only on specified routing table]:routing table'
+  '-T+[match only on specified routing table]:routing table:_routing_tables'
   '(-t --terminal)'{-t+,--terminal=}'[match only on specified controlling terminals]: :_sequence _ttys -do'
   '(-U --uid)'{-U+,--uid=}'[match only on specified real user IDs]: :_sequence _users'
   '(-u --euid)'{-u+,--euid=}'[match only on specified effective user IDs]: :_sequence _users'
   '(-v --inverse)'{-v,--inverse}'[negate matching]'
   '(-x --exact)'{-x,--exact}'[match process name or command line (with -f) exactly]'
+  '--cgroup=[match by cgroup v2 names]:cgroup'
   '--ns=[match only on same namespaces as specified PID]: :_pids'
   '--nslist=[match only on specified namespaces (with --ns)]:namespace:(ipc mnt net pid user uts)'
   '(: * -)'{-V,--version}'[display version information]'
@@ -56,6 +57,8 @@ arguments=(
   '(-w --lightweight)'{-w,--lightweight}'[show all thread IDs instead of PID]'
 )
 [[ $service == pkill ]] && arguments+=(
+  '(-H --require-handler)'{-H,--require-handler}'[match only if signal handler is present]'
+  '(-q --queue)'{-q+,--queue=}'[specify value to be sent with the signal]:value'
   '(-e --echo)'{-e,--echo}'[display signalled process]'
   '-l[display kill command]'
 )
@@ -63,8 +66,8 @@ arguments=(
 case $OSTYPE in
   linux*)
     # Note: We deliberately exclude -v but not --inverse from pkill
-    pgopts=acdFfGghLlnoOPrstUuVvwx-
-    pkopts=ceFfGghLnoOPstUuVx-
+    pgopts=AacdFfGghLlnoOPrstUuVvwx-
+    pkopts=AceFfGgHhLnoOPstUuVx-
     arguments=(
       ${arguments:#((#s)|*\))(\*|)-[acl]*}
       '(-c --count)'{-c,--count}'[display count of matching processes]'
diff --git a/Completion/Unix/Command/_php b/Completion/Unix/Command/_php
index c4c4ab3e2..9a8f519b1 100644
--- a/Completion/Unix/Command/_php
+++ b/Completion/Unix/Command/_php
@@ -93,7 +93,7 @@ _php() {
     + '(hv)' # Help/version options; kept separate by convention
     '(- 1 *)'{-h,--help}'[display help information]'
     '(- 1 *)'{-v,--version}'[display version information]'
-    '!(- 1 *)'{-\?,-\\\?,--usage}
+    '!(- 1 *)'{-\?,--usage}
 
     + '(im)' # Info/module options (exclusive with everything but -c/-n)
     '(fi mc pb pf rf rn sc sv *)'{-i,--info}'[display configuration information (phpinfo())]'
diff --git a/Completion/Unix/Command/_ping b/Completion/Unix/Command/_ping
index b371e808f..84bd76b82 100644
--- a/Completion/Unix/Command/_ping
+++ b/Completion/Unix/Command/_ping
@@ -191,7 +191,7 @@ case ${variant}:${${service#ping}:-4} in
       '-e[audible bell for each packet]'
       '-g[provide a visual display of packets received and lost]'
       '-T+[change TOS value]:TOS value:(critical inetcontrol lowdelay netcontrol throughput reliability ef af cs)'
-      '-V+[specify routing table to be used]:routing table'
+      '-V+[specify routing table to be used]:routing table:_routing_tables'
     )
   ;;
   iputils:*)
@@ -199,7 +199,9 @@ case ${variant}:${${service#ping}:-4} in
       '-A[adaptive]'
       '-b[allow pinging a broadcast address]'
       "-B[don't allow ping to change source address]"
+      '-C[call connect() syscall on socket creation]'
       '-D[print timestamp before each line]'
+      '-e+[define identifier for ping session]:identifier'
       '(-4)-F+[allocate and set 20-bit flow label]:flow label (hex)'
       '(-)-h[show usage information]'
       '-I+[specify source interface]:interface:_net_interfaces'
diff --git a/Completion/Unix/Command/_pip b/Completion/Unix/Command/_pip
new file mode 100644
index 000000000..bafc7f9e9
--- /dev/null
+++ b/Completion/Unix/Command/_pip
@@ -0,0 +1,213 @@
+#compdef -P pip[0-9.]#
+
+# To get completion of installable packages, do:
+#     pip install pip-cache
+# and then run:
+#     pip-cache update
+
+local curcontext="$curcontext" ret=1
+local -a state state_descr line
+local -A opt_args
+local python pip
+local -a args subcommands packages
+
+pip=${words[1]}
+python=${${pip}/pip/python}
+[[ $python == $pip ]] && python=python
+
+args=(
+  '(* : -)'{-h,--help}'[display usage information]'
+  '--isolated[ignore environment variables and user configuration]'
+  \*{-v,--verbose}'[give more output]'
+  \*{-q,--quiet}"[give less output]"
+  '--log=[specify log file where a complete record will be kept]:file:_files'
+  '--proxy=[specify a proxy]:proxy ([user\:passwd@]proxy.server\:port)'
+  '--retries=[specify maximum number of retries each connection should attempt]:retries [5]'
+  '--timeout=[set the socket timeout]:timeout (seconds) [15]'
+  '--exists-action=[specify action when a path already exists]:action:((s\:switch i\:ignore w\:wipe b\:backup a\:abort))'
+  '--cert=[specify path to alternate CA bundle]:path:_files'
+  '--client-cert=[specify path to SSL client certificate]:certificate file:_files'
+  '(--no-cache-dir)--cache-dir=[specify location to store the cache data]: :_directories'
+  '(--cache-dir)--no-cache-dir[disable the cache]'
+  "--disable-pip-version-check[don't check whether a new version of pip is available]"
+)
+
+subcommands=(
+  'install:install packages'
+  'download:download packages'
+  'uninstall:uninstall packages'
+  'freeze:output installed packages in requirements format'
+  'list:list installed packages'
+  'show:show information about installed packages'
+  'check:verify installed packages have compatible dependencies'
+  'search:search PyPI for packages'
+  'wheel:build wheels from your requirements'
+  'hash:compute hashes of package archives'
+  'help:show available commands'
+)
+
+_arguments -C $args \
+  '(* : -)'{-V,--version}'[display version information]' \
+  ':subcommand:->subcommand' \
+  '*::options:->options' && ret=0
+
+case $state in
+  subcommand)
+    _describe -t subcommands 'pip subcommand' subcommands && ret=0
+  ;;
+
+  options)
+    curcontext="${curcontext%:*}-$words[2]:"
+
+    case $words[1] in
+      download|install|list|wheel)
+        args+=(
+          '--pre[include pre-release and development versions]'
+          '(-i --index-url)'{-i+,--index-url=}'[base URL of Python Package Index]:url:_urls'
+          '--extra-index-url=[extra URLs of package indexes to use in addition to --index-url]:url:_urls'
+          '--no-index[ignore package index (only looking at --find-links URLs instead)]'
+          '(-f --find-links)'{-f+,--find-links=}'[parse specified URL or HTML file for links to packages]:URL or file:_files -g "*.htm(|l)(-.)"'
+          '--process-dependency-links[enable the processing of dependency links]'
+        )
+      ;|
+      download|(un|)install|freeze|wheel)
+        args+=(
+          '(-r --requirement)'{-r+,--requirement=}'[all the packages listed in the given requirements file]:requirements file:_files -g "(requirement*|*.txt)(-.)"'
+        )
+      ;|
+      download|install|wheel)
+        args+=(
+          '!--use-wheel' '!--no-use-wheel'
+          "*--no-binary=[don't use binary packages]: :->package_list"
+          "*--only-binary=[don't use source packages]: :->package_list"
+          \*{-c+,--constraint=}'[constrain versions using the given constraints file]:constraints file:_files'
+          '(-e --editable)'{-e+,--editable=}'[install a package directly from a checkout]:directory or VCS+REPOS_URL[@REV]#egg=PACKAGE:_files -/'
+          '--src=[check out --editable packages into given directory]: :_directories'
+          '--ignore-requires-python[ignore the Requires-Python information]'
+          "--no-deps[don't install package dependencies]"
+          '(-b --build)'{-https://cloud.kiddleb+,--build=}'[specify directory to unpack packages into]: :_directories'
+          '--global-option=[extra global options to be supplied to the setup.py call before the install command]:options'
+          "--no-clean[don't clean up build directories]"
+          '--require-hashes[require a hash to check each requirement against]'
+        )
+      ;|
+
+      download)
+        args+=(
+          '(-d --dest)'{-d+,--dest=}'[download packages into given directory]: :_directories'
+          '--platform=[only download wheels compatible with platform]::platform'
+          '--python-version=[only download wheels compatible with specified Python interpreter version]:version'
+          '--implementation=[only download wheels compatible with specified Python implementation]:implementation:(pp jy cp ip py)'
+        )
+      ;;
+
+      install)
+        args+=(
+          '(-t --target)'{-t+,--target=}'[specify directory to install packages into]: :_directories'
+          '(-d --download)'{-d+,--download=}'[download packages into directory instead of installing them]: :_directories'
+          '(-U --upgrade)'{-U,--upgrade}'[upgrade all packages to the newest available version]'
+          '--upgrade-strategy=[determine how dependency upgrading should be handled]:strategy:(eager only-if-needed)'
+          '--force-reinstall[when upgrading, reinstall all packages even if they are already up-to-date]'
+          '(-I --ignore-installed)'{-I,--ignore-installed}'[ignore installed packages]'
+          "--no-install[download and unpack all packages, but don't actually install them]"
+          "--no-download[don't download any packages, just install the ones already downloaded]"
+          '--install-option=[extra arguments to be supplied to the setup.py install command]:options'
+          '--user[install to the user install directory, typically ~/.local]'
+          '--egg[install as self contained egg file, like easy_install does]'
+          '--root=[install everything relative to this alternate root directory]: :_directories'
+          '--strip-file-prefix=[strip given prefix from script paths in wheel RECORD]:prefix'
+          '--prefix=[specify installation prefix where lib, bin and other top-level folders are placed]: :_directories'
+          '(--no-compile)--compile[compile py files to pyc]'
+          "(--compile)--no-compile[don't compile py files to pyc]"
+          '*:package name:->packages_or_dirs'
+        )
+      ;;
+
+      uninstall)
+        args+=(
+          '(-y --yes)'{-y,--yes}"[don't ask for confirmation of uninstall deletions]"
+          ':installed package:->installed_packages'
+        )
+      ;;
+
+      freeze)
+        args+=(
+          '(-f --find-links)'{-f+,--find-links=}'[specify URL to look for packages at]:url:_urls'
+          '(-l --local)'{-l,--local}"[if in a virtualenv that has global access, don't list globally-installed packages]"
+          '--user[only output packages installed in user-site]'
+          '--all[include pip, setuptools, distribute and wheel in output]'
+        )
+      ;;
+
+      hash)
+        args+=(
+          '(-a  --algorithm)'{-a+,--algorithm=}'[specify hash algorithm]:algorithm:(sha256 sha384 sha512)'
+          '*: :_files'
+        )
+      ;;
+
+      list)
+        args+=(
+          '(-o --outdated -u --uptodate)'{-o,--outdated}'[list outdated packages (excluding editables)]'
+          '(-u --uptodate -o --outdated)'{-u,--uptodate}'[list uptodated packages (excluding editables)]'
+          '(-e --editable)'{-e,--editable}'[list editable projects]'
+          '(-l --local)'{-l,--local}"[if in a virtualenv that has global access, don't list globally-installed packages]"
+          '--user[only output packages installed in user-site]'
+          '--format=[select the output format]:format [legacy]:(legacy columns freeze json)'
+          '--not-required[list packages that are not dependencies of installed packages]'
+        )
+      ;;
+
+      show)
+        args+=(
+          '(-f --files)'{-f,--files}'[show the full list of installed files for each package]'
+          ':installed package:->installed_packages'
+        )
+      ;;
+
+      search)
+        args+=(
+          '(-i --index)'{-i+,--index=}'[specify base URL of Python Package Index]:URL:_urls'
+        )
+      ;;
+
+      wheel)
+        args+=(
+          '(-w --wheel-dir)'{-w+,--wheel-dir=}"[build wheels into given directory]: :_directories"
+          "--build-option=[extra arguments to be supplied to 'setup.py bdist_wheel']:options"
+        )
+      ;;
+
+      help)
+        _describe -t subcommands 'pip subcommand' subcommands
+        return
+      ;;
+
+      *) args+=( '*: :_default' ) ;;
+    esac
+
+    _arguments -s -S $args && ret=0
+
+    case $state in
+      package_list)
+        packages=( ${(f)"$(_call_program packages pip-cache pkgnames)"} )
+        _sequence _wanted packages expl package compadd - -a packages && ret=0
+      ;;
+
+      packages_or_dirs)
+        [[ -prefix - ]] || packages=( ${(f)"$(_call_program packages pip-cache pkgnames)"} )
+        _alternative \
+          'all-packages:package:compadd -a packages' \
+          'directories:directory with setup.py:_directories' && ret=0
+      ;;
+
+      installed_packages)
+        packages=( $(_call_program fetch-installed \
+          "env COMP_WORDS='pip uninstall' COMP_CWORD=2 PIP_AUTO_COMPLETE=1 $pip") )
+        _wanted installed-packages expl 'installed package' compadd -a packages && ret=0
+      ;;
+    esac
+  ;;
+esac
+
+return ret
diff --git a/Completion/Unix/Command/_pr b/Completion/Unix/Command/_pr
new file mode 100644
index 000000000..2aeeb13b3
--- /dev/null
+++ b/Completion/Unix/Command/_pr
@@ -0,0 +1,103 @@
+#compdef pr
+
+local curcontext=$curcontext variant msg ret=1
+local -a state state_descr line specs optA
+typeset -A opt_args
+
+# take care of '+FIRST_PAGE[:LAST_PAGE]' (GNU) or '+FIRST_PAGE' (POSIX)
+if _pick_variant -r variant gnu=GNU $OSTYPE --version; then
+  msg='FIRST_PAGE[:LAST_PAGE]'
+else
+  msg='first page'
+fi
+
+if [[ $words[CURRENT] = +* ]]; then
+  _message "$msg" && return
+fi
+
+if (( ! ${words[(I)+[0-9]*]} )); then
+  # if +number is not on the command line
+  specs=( '(hv)--pages=[specify first and last page numbers]: : _message $msg' )
+fi
+
+# common specs
+specs+=(
+  '(hv -a --across)'{-a,--across}'[with multi-column output, print columns across rather than down]'
+  '(hv -d --double-space)'{-d,--double-space}'[double space the output]'
+  '(hv -e --expand-tabs)'{-e-,--expand-tabs=-}'[expand tab (or specified char) with specified number of spaces]::number of spaces [8]:->char_number'
+  '(hv -h --header -t --omit-header)'{-h+,--header=}'[specify text used in header]:header: '
+  '(hv -i --output-tabs)'{-i-,--output-tabs=-}'[replace specified number of spaces with tab (or specified char)]::number of spaces [8]:->char_number'
+  '(hv -l --length)'{-l+,--length=}'[specify the page length]:number of lines [66]: '
+  '(hv -m --merge)'{-m,--merge}'[print all files in parallel, one in each column]'
+  '(hv -n --number-lines)'{-n-,--number-lines=-}'[number lines with specified separator and width]::number of digits [5]:->char_number'
+  '(hv -o --indent)'{-o+,--indent=}'[specify left margin]:margin [0]: '
+  '(hv -r -no-file-warnings)'{-r,--no-file-warnings}'[omit warning when a file cannot be opened]'
+  '(hv -s --separator)'{-s-,--separator=-}'[specify column separator character]:character [tab]: '
+  '(hv -t --omit-header -h --header)'{-t,--omit-header}'[omit page headers and trailers]'
+  '(hv -w --width)'{-w+,--width=}'[specify page width for multi-column output]:number of characters [72]: '
+  '(hv)*: :_files'
+)
+# XXX: pr accepts -2 -3 -4 ... for specifying the number of columns.
+#      Here we offer only -2 and -3, and do so only if there is no
+#      -2 -3 -4 ... or --columns on the command line.
+if (( ! ${words[(I)-([0-9]##*|-columns*)]} )); then
+  specs+=( {-2,-3}'[specify number of columns]' )
+fi
+
+if [[ $variant = gnu ]]; then
+  # GNU coreutils 8.32
+  specs+=(
+    '(hv -c --show-control-chars)'{-c,--show-control-chars}'[use hat (^G) and octal backslash notation]'
+    '(hv -D --date-format)'{-D+,--date-format=}'[specify format for the header date]: :_date_formats'
+    '(hv -f -F --form-feed)'{-f,-F,--form-feed}'[use form feeds instead of newlines to separate pages]'
+    '(hv -J --join-lines)'{-J,--join-lines}'[merge full lines in multi-column output]'
+    '(hv -N --first-line-number)'{-N+,--first-line-number=}'[specify the line number of the 1st line]:number: '
+    '(hv -S --sep-string)'{-S-,--sep-string=-}'[specify column separator string]:string: '
+    '(hv -T --omit-pagination)'{-T,--omit-pagination}'[omit page headers and trailers, eliminate any pagination]'
+    '(hv -v --show-nonprinting)'{-v,--show-nonprinting}'[use octal backslash notation]'
+    '(hv -W --page-width)'{-W+,--page-width=}'[specify page width always]:number of characters [72]: '
+  )
+  if (( ! ${words[(I)-[0-9]##*]} )); then
+    # if -2 -3 -4 ... are not on the command line
+    specs+=(
+      '(hv)--columns=[specify number of columns]:number of columns: '
+      + hv
+      '(- *)--help[display help and exit]'
+      '(- *)--version[output version information and exit]'
+    )
+  fi
+else
+  specs=( ${specs:#(|*\))--*} )    # remove long options
+  case $variant in
+    freebsd*|dragonfly*|darwin*|netbsd*)
+      specs+=(
+	'(-f)-F[use form feeds instead of newlines to separate pages]'
+	'(-F)-f[same as -F but pause before the 1st page if stdout is terminal]'
+	'-p[pause before each page if stdout is terminal]'
+      )
+      ;|
+    freebsd*|dragonfly*|darwin*)
+      specs+=( '-L+[specify locale to use]: :_locales' )
+      ;;
+    openbsd*)
+      specs+=( '(-f -F)'{-f,-F}'[use form feeds instead of newlines to separate pages]' )
+      ;;
+  esac
+  optA=( -A '[-+]?*' )  # a single '-' is a valid file name (stdin)
+fi
+
+_arguments -C -s -S $optA : $specs && ret=0
+
+case $state in
+  char_number)
+    # argument for option -e (and -i, -n) can be -e. -e10 or -e.10
+    # where . is any non-digit character
+    if compset -p 1; then
+      _message "$state_descr" && ret=0
+    else
+      _message "a character [tab] (optional), and $state_descr" && ret=0
+    fi
+    ;;
+esac
+
+return ret
diff --git a/Completion/Unix/Command/_ps b/Completion/Unix/Command/_ps
index 9b54cbcc6..c3dfae47d 100644
--- a/Completion/Unix/Command/_ps
+++ b/Completion/Unix/Command/_ps
@@ -105,6 +105,7 @@ case $OSTYPE in
     bsdarg+=( 'M[extract values from specified core]' )
   ;|
   linux-gnu|netbsd*) bsdarg+=( 'k[specify sort order]' ) ;|
+  linux-gnu|openbsd*) bsd+=( 'f[show process hierarchy]' ) ;|
   darwin*|freebsd*)
     bsd+=( 'X[skip processes with no controlling terminal]' )
     bsdarg+=( '*G[select processes by real group]' )
@@ -162,10 +163,12 @@ case $OSTYPE in
       '(-N --deselect)'{-N,--deselect}'[negate selection: all processes except those selected]'
       '*-C[select processes by command name]:command:_sequence -s , _command_names -e'
       '*--ppid[select processes by parent process ID]:parent process:_sequence -S , _pids'
+      '(-D --date-format)'{-D,--date-format=}'[set the date format of the lstart field to format]:format:_strftime'
       '(-f)-F[extra full format listing]'
       '--context[show SELinux security context format]'
       '-M[show security data]'
       '(--forest -H)'{--forest,-H}'[show process hierarchy]'
+      '-P[add psr column]'
       '--headers[repeat header lines, one per page of output]'
       '(--cols --columns --width)'{--cols,--columns,--width}'[set screen width]:width'
       '(--lines --rows)'{--lines,--rows}'[set screen height]'
@@ -188,7 +191,6 @@ case $OSTYPE in
     done
     bsd+=(
       'c[show true command name]'
-      'f[show process hierarchy]'
       'h[suppress header]'
       'm[show threads after processes]'
       'n[numeric output for WCHAN and USER]'
diff --git a/Completion/Unix/Command/_ptx b/Completion/Unix/Command/_ptx
new file mode 100644
index 000000000..12f1d2c9a
--- /dev/null
+++ b/Completion/Unix/Command/_ptx
@@ -0,0 +1,54 @@
+#compdef ptx
+
+local -a specs optA
+
+# common specs
+specs=(
+  '(hv -b --break-file)'{-b+,--break-file=}'[use characters in specified file as word separators]:break file:_files'
+  '(hv -f --ignore-case)'{-f,--ignore-case}'[fold lower case to upper case for sorting]'
+  '(hv -g --gap-size)'{-g+,--gap-size=}'[specify gap size between output fields]:number of chars [3]: '
+  '(hv -i --ignore-file)'{-i+,--ignore-file=}'[ignore keywords listed in specified file]:ignore file:_files'
+  '(hv -o --only-file)'{-o+,--only-file=}'[use only the keywords listed in specified file]:only file:_files'
+  '(hv -r --references)'{-r,--references}'[first field of each line is a reference]'
+  '(hv -w --width)'{-w+,--width=}'[specify page width, reference excluded]:number of characters [72]: '
+)
+
+if _pick_variant gnu=GNU unix --version; then
+  # GNU coreutils 8.32
+  specs+=(
+    '(hv -A --auto-reference)'{-A,--auto-reference}'[output automatically generated references]'
+    '(hv -G --traditional)'{-G,--traditional}"[behave more like System V 'ptx']"
+    '(hv -F --flag-truncation)'{-F+,--flag-truncation=}'[specify string for flagging line truncations]:string [/]: '
+    '(hv -M --macro-name)'{-M+,--macro-name=}"[specify macro name to use instead of 'xx']:macro name: "
+    '(hv)-O[generate output as roff directives]'
+    '(hv -R --right-side-refs)'{-R,--right-side-refs}'[put references at right, not counted in -w]'
+    '(hv -S --sentence-regexp)'{-S+,--sentence-regexp=}'[specify regexp for end of lines/sentences]:regexp: '
+    '(hv)-T[generate output as TeX directives]'
+    '(hv -W --word-regexp -b --break-file)'{-W+,--word-regexp=}'[specify regexp to match each keyword]:regexp: '
+    '(hv)--format=[specify the output format]:format:(roff tex)'
+    !{-t,--typeset-mode}'[not implemented]'
+    + hv
+    '(: * -)--help[display help and exit]'
+    '(: * -)--version[output version information and exit]'
+  )
+  if (( $words[(I)(-G|--traditional)] )); then
+    specs+=( + arg '1:input file:_files'  '2:output file:_files' )
+  else
+    specs+=( + arg '(-G --traditional)*:input file:_files' )
+  fi
+else
+  # The only non-GNU implementation I can find is the one in
+  # heirloom-doctools. FreeBSD has a package for this.
+  specs=( ${specs:#(|*\))--*} )    # remove long options
+  # remove '+' from -b+ -g+ -i+ -o+ -w+
+  local MATCH MBEGIN MEND
+  specs=( ${specs/(#m)-[bgiow]+/$MATCH[1,-2]} )
+  specs+=(
+    '-t[prepare output for typesetter]'
+    '1:input file:_files'
+    '2:output file:_files'
+  )
+  optA=( -A '-?*' )  # a single '-' is a valid file name (stdin)
+fi
+
+_arguments -s -S $optA : $specs
diff --git a/Completion/Unix/Command/_pv b/Completion/Unix/Command/_pv
index 68f8e8586..b21625650 100644
--- a/Completion/Unix/Command/_pv
+++ b/Completion/Unix/Command/_pv
@@ -17,7 +17,9 @@ _arguments -s -S $args \
   '(-I --fineta -F --format)'{-I,--fineta}'[show absolute estimated time of arrival]' \
   '(-r --rate -F --format)'{-r,--rate}'[show data transfer rate counter]' \
   '(-a --average-rate -F --format)'{-a,--average-rate}'[show data transfer average rate counter]' \
-  '(-b --bytes -F --format)'{-b,--bytes}'[show number of bytes transferred]' \
+  '(-m --average-rate-window)'{-m+,--average-rate-window=}'[compute average rate over period]:duration (seconds) [30]' \
+  '(-b --bytes -8 --bits -F --format)'{-b,--bytes}'[show number of bytes transferred]' \
+  '(-8 --bits -b --bytes -F --format)'{-8,--bits}'[show number of bits transferred]' \
   '(-T --buffer-percent -F --format)'{-T,--buffer-percent}'[show percentage of transfer buffer in use]' \
   '(-A --last-written -F --format)'{-A+,--last-written=}'[show number of bytes last written]:number (bytes)' \
   '(-F --format -p --progress -t --timer -e --eta -I --fineta -r --rate -a --average-rate -b --bytes -T --buffer-percent -A --last-written -F --format)'{-F+,--format=}'[set output format]:format:->formats' \
@@ -25,7 +27,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 +36,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 +72,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/_pydoc b/Completion/Unix/Command/_pydoc
index 677c96ad6..626c528cd 100644
--- a/Completion/Unix/Command/_pydoc
+++ b/Completion/Unix/Command/_pydoc
@@ -6,13 +6,14 @@ local -a args
 
 args=(
   '(- *)-k[search keyword]:keyword'
-  '(-k -g -w *)-p[start web server on specified port]:port number'
+  '(-k -g -w)-p[start web server on specified port]:port number'
   '(-)-w[write out HTML in current directory]'
   '(-)*: :->lookup'
 )
 
 if _pick_variant pydoc3='pydoc3 -b' pydoc2 -h; then
-  args+=( '(-k -w *)-b[start server and open browser]' )
+  args+=( '(-k -w)-b[start server and open browser]' )
+  args+=( '(-k -w)-n[start web server with the given hostname]:hostname' )
 else
   args+=( '(- *)-g[start gui]' )
 fi
diff --git a/Completion/Unix/Command/_python b/Completion/Unix/Command/_python
index e5bac18bb..6e209a199 100644
--- a/Completion/Unix/Command/_python
+++ b/Completion/Unix/Command/_python
@@ -1,9 +1,9 @@
 #compdef -P python[0-9.]#
 
 # Python 2.7
-# Python 3.9
+# Python 3.11
 
-local curcontext="$curcontext" state state_descr line
+local curcontext="$curcontext" state state_descr line _compskip="$_compskip"
 typeset -A opt_args
 local -a args
 
@@ -12,7 +12,11 @@ if _pick_variant python3=Python\ 3 python2 --version; then
     '(-bb)-b[issue warnings about str(bytes_instance), str(bytearray_instance) and comparing bytes/bytearray with str]'
     '(-b)-bb[issue errors about str(bytes_instance), str(bytearray_instance) and comparing bytes/bytearray with str]'
     '--check-hash-based-pycs[configure how Python evaluates up-to-dateness of hash-based .pyc files]:mode:(always default never)'
+    '--help-env[print help about Python environment variables and exit]'
+    '--help-xoptions[print help about implementation-specific -X options and exit]'
+    '--help-all[print complete help information and exit]'
     "-I[isolate Python from the user's environment]"
+    '-P[do not prepend a potentially unsafe path to sys.path]'
     '-q[do not print version and copyright messages]'
     '-X[set implementation-specific option]:option'
   )
diff --git a/Completion/Unix/Command/_qemu b/Completion/Unix/Command/_qemu
index 7bc02c30c..6ca11b4fb 100644
--- a/Completion/Unix/Command/_qemu
+++ b/Completion/Unix/Command/_qemu
@@ -51,5 +51,7 @@ _arguments \
   '-no-acpi[disable ACPI]' \
   '-loadvm[start right away with a saved state]:file:_files' \
   '-g[set initial graphic mode]:graphic mode:' \
+  '-enable-kvm[enable KVM full virtualization support]' \
+  '-bios[use specified BIOS image]:bios image:_files' \
   ':disk image:_files'
 
diff --git a/Completion/Unix/Command/_quilt b/Completion/Unix/Command/_quilt
index 8f39dadac..01f8cfb83 100644
--- a/Completion/Unix/Command/_quilt
+++ b/Completion/Unix/Command/_quilt
@@ -261,6 +261,8 @@ case $words[1] in
       '-d[specify path prefix for resulting source tree]:prefix:_files -W / -P /' \
       '--sourcedir[specify location of package sources]:directory:_directories' \
       '--fuzz=[set the maximum fuzz factor]:factor' \
+      '(--fast)--slow[use the original, slow method to process the spec file]' \
+      '(--slow)--fast[use an alternative, faster method to process the spec file]' \
       ':file:_files' && return
   ;;
   snapshot) _arguments $help '-d[only remove current snapshot]' && return ;;
diff --git a/Completion/Unix/Command/_rake b/Completion/Unix/Command/_rake
index 10d621991..49b49c014 100644
--- a/Completion/Unix/Command/_rake
+++ b/Completion/Unix/Command/_rake
@@ -1,12 +1,11 @@
 #compdef rake
 
-# rake, version 0.8.3
+# rake, version 13.0.6
 
 local curcontext="$curcontext" state line expl ret=1
 typeset -A opt_args
 
 _arguments -C -s -S \
-  '(--classic-namespace -C)'{--classic-namespace,-C}'[put Task and FileTask in the top level namespace]' \
   '(--dry-run -n)'{--dry-run,-n}'[do a dry run without executing actions]' \
   '(- *)'{--describe,-D}'[describe the tasks (matching the specified pattern), then exit]:pattern::' \
   '(--execute -e)'{--execute,-e}'[execute some Ruby code and exit]:Ruby code:' \
@@ -15,7 +14,7 @@ _arguments -C -s -S \
   '(- *)'{--help,-h,-H}'[display help information]' \
   \*{--libdir,-I}'[include specified directory in the search path for required modules]:library directory:_files -/' \
   '(--rakelibdir --rakelib -R)'{--rakelibdir,--rakelib,-R}'[auto-import any .rake files in the specified directory. (default is 'rakelib')]:rake library directory:_files -/' \
-  '(--nosearch -N)'{--nosearch,-N}'[do not search parent directories for the Rakefile]' \
+  '(--nosearch --no-search -N)'{--nosearch,--no-search,-N}'[do not search parent directories for the Rakefile]' \
   '(- *)'{--prereqs,-P}'[display the tasks and prerequisites, then exit]' \
   '(--quiet -q --silent -s --verbose -v)'{--quiet,-q}'[do not log messages to standard output]' \
   '(--rakefile -f)'{--rakefile,-f}'[use specified file as the rakefile]:rake file:_files' \
@@ -27,6 +26,18 @@ _arguments -C -s -S \
   '(--trace -t)'{--trace,-t}'[turn on invoke/execute tracing, enable full backtrace]' \
   '(--quiet -q --silent -s --verbose -v)'{--verbose,-v}'[log message to standard output (default)]' \
   '(- *)'{--version,-V}'[display version information]' \
+  '--backtrace=-[enable full backtrace]::out:(stderr stdout)' \
+  '--comments[show commented tasks only]' \
+  '--job-stats[display job statistics]:level' \
+  '--suppress-backtrace[suppress backtrace lines matching regexp PATTERN]:pattern' \
+  '(-A -a)'{-A,--all}'[show all tasks]' \
+  '(-B --build-all)'{-B,--build-all}'[build all prerequisites, including those which are up-to-date]' \
+  '(-C --directory)'{-C,--directory}'[change to DIRECTORY before doing anything]:dir:_files -/' \
+  '(-G --no-system --nosystem)'{-G,--no-system,--nosystem}'[use standard project Rakefile search paths, ignore system wide rakefiles]' \
+  '(-j --jobs)'{-j,--jobs}'[specifies the maximum number of tasks to execute in parallel]::tasks' \
+  '(-m --multitask)'{-m,--multitask}'[treat all tasks as multitasks]' \
+  '(- *)'{-W,--where}'[describe the tasks(matching optional PATTERN) then exit]::pattern' \
+  '(-X --no-deprecation-warnings)'{-X,--no-deprecation-warnings}'[disable the deprecation warnings]' \
   '*:target:->target' && ret=0
 
 case "$state" in
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/_readelf b/Completion/Unix/Command/_readelf
index fc0fb7ce1..b3abdf0a5 100644
--- a/Completion/Unix/Command/_readelf
+++ b/Completion/Unix/Command/_readelf
@@ -16,10 +16,12 @@ args=(
   '(-V --version-info)'{-V,--version-info}'[show version sections (if present)]'
   '(-A --arch-specific)'{-A,--arch-specific}'[show architecture specific information (if any)]'
   '(-c --archive-index)'{-c,--archive-index}'[show symbol/file index in an archive]'
+  '(-D --use-dynamic)'{-D,--use-dynamic}'[use dynamic section info when showing symbols]'
   \*{-x,--hex-dump=}"[dump contents of specified section as bytes]:section:($sections)"
   \*{-p,--string-dump=}"[dump contents of specified section as strings]:section:($sections)"
-  '-w+[show the contents of DWARF2 debug sections]::debug section:(l L i a p r m f F s o O R t U u T g A c k K)'
-  '--debug-dump=[show the contents of DWARF2 debug sections]::section:(rawline decodedline info abbrev pubnames aranges macro frames frames-interp str loc Ranges pubtypes gdb_index trace_info trace_abbrev trace_aranges addr cu_index links follow-links)'
+  '-w+[show the contents of DWARF2 debug sections]::debug section:(a A r c L f F g i o m p t R l s O u T U k K N)'
+  '--debug-dump=[show the contents of DWARF2 debug sections]::section:(abbrev addr aranges cu_index decodedline frames frames-interp gdb_index info loc macro pubnames pubtypes Ranges rawline str str-offsets trace_abbrev trace_aranges trace_info links follow-links no-follow-links)'
+  '(-P --process-links)'{-P,--process-links}'[display the contents of non-debug sections in separate debuginfo files]'
   '(-I --histogram)'{-I,--histogram}'[show histogram of bucket list lengths]'
   '(-W --wide)'{-W,--wide}'[allow output width to exceed 80 characters]'
   '(- *)'{-H,--help}'[display help information]'
@@ -35,7 +37,6 @@ case $variant in
       '(-s --syms --symbols)'{-s,--syms,--symbols}'[show symbol table]'
       '(-n --notes)'{-n,--notes}'[show core notes (if present)]'
       '(-u --unwind)'{-u,--unwind}'[show unwind info (if present)]'
-      '(-D --use-dynamic)'{-D,--use-dynamic}'[use dynamic section info when showing symbols]'
     )
   ;|
   elfutils|binutils)
@@ -50,11 +51,14 @@ case $variant in
   ;|
   binutils)
     args+=(
+      '--sym-base=[force base for symbol sizes]:base:(0 8 10 16)'
       '!(-C --demangle)--no-demangle'
       '(--demangle)-C[decode symbol names]'
-      '(-C)--demangle=-[decode symbol names]::style [auto]:(auto gnu lucid arm hp edg gnu-v3 java gnat)'
+      '(-C)--demangle=-[decode symbol names]::style [auto]:(none auto gnu-v3 java gnat dlang rust)'
       '!(--no-recurse-limit)--recurse-limit'
       '--no-recurse-limit[disable demangling recursion limit]'
+      '-U+[specify how to display unicode characters]:method:(d l e x h i)'
+      '--unicode=[specify how to display unicode characters]:method:(default locale escape hex highlight invalid)'
       '(-L --lint --enable-checks)'{-L,--lint,--enable-checks}'[display warning messages for possible problems]'
       \*{-R,--relocated-dump=}"[dump contents of specified section as relocated bytes]:section:($sections)"
       "--dwarf-depth=[don't show DIEs at greater than specified depth]:depth"
@@ -63,6 +67,7 @@ case $variant in
       '--ctf-parent=[use specified section as the CTF parent]:section'
       '--ctf-symbols=[use specified section as the CTF external symbol table]:section'
       '--ctf-strings=[use specified section as the CTF external string table]:section'
+      '--sframe=-[display SFrame info from section]::section name [.sframe]'
       '(-T --silent-truncation)'{-T,--silent-truncation}"[if a symbol name is truncated, don't add ... suffix]"
     )
   ;;
diff --git a/Completion/Unix/Command/_ri b/Completion/Unix/Command/_ri
index 4d5a72985..fe458e25f 100644
--- a/Completion/Unix/Command/_ri
+++ b/Completion/Unix/Command/_ri
@@ -26,33 +26,22 @@ _arguments -C \
   '*:ri name:->ri-name' && return
 
 if [[ "$state" = ri-name ]]; then
-  local -a ri_dirs ri_ext ri_names ri_wants ri_names
+  local -a ri_dirs ri_names ri_wants ri_names
   local class_dir esc_name dir curtag tag descr expl
 
-  if "ruby${words[1]#ri}" -rrdoc/ri/ri_options -e 1 >/dev/null 2>&1; then
-    # Old-style Ruby 1.8.x RI
-    ri_dirs=( ${(f)"$(_call_program ri-names "ruby${words[1]#ri}" -rrdoc/ri/ri_options -e '"o = RI::Options.instance; o.parse(ARGV); o.path.each { |p| puts p }"' -- ${(kv)opt_args[(I)-d|--doc-dir|--(system|site|gems|home)]})"} )
-    ri_ext=yaml
-  elif "ruby${words[1]#ri}" -rrdoc/ri -rrdoc/ri/store -e 1 >/dev/null 2>&1; then
-    # Newer-style Ruby 1.9.2 RI
-    ri_dirs=( ${(f)"$(_call_program ri-names "$words[1]" ${(kv)opt_args[(I)-d|--doc-dir|--((no-|)(system|site|gems|home)|standard-docs)]} --list-doc-dirs -f bs -T)"} )
-    ri_ext=ri
-  else
-    # New-style Ruby 1.9+ RI
-    ri_dirs=( ${(f)"$(_call_program ri-names "$words[1]" ${(kv)opt_args[(I)-d|--doc-dir|--((no-|)(system|site|gems|home)|standard-docs)]} --list-doc-dirs -f plain -T)"} )
-    ri_ext=yaml
-  fi
+  ri_dirs=( ${(f)"$(_call_program ri-names "$words[1]" ${(kv)opt_args[(I)-d|--doc-dir|--((no-|)(system|site|gems|home)|standard-docs)]} --list-doc-dirs -f bs -T)"} )
 
-  if compset -P '?*(::|\#|.)'; then
+  if compset -P '?*(::|:|\#|.)'; then
     class_dir=${IPREFIX//(::|\#|.)/\/}
   fi
   esc_name=${${(Q)PREFIX}//(#b)([^A-Za-z0-9_])/$(printf %%%x ${(qq)match[1]})}
 
   case "$IPREFIX" in
-    (*::) ri_wants=( 'classes:class names' 'class-methods:class methods' );;
-    (*\#) ri_wants=( 'instance-methods:instance methods' );;
-    (*.) ri_wants=( 'class-methods:class methods' 'instance-methods:instance methods' );;
-    (*) ri_wants=( 'classes:class names' )
+    (*::) ri_wants=( 'classes:class name' 'class-methods:class method' );;
+    (*:) ri_wants=( 'docs:documentation file' );;
+    (*\#) ri_wants=( 'instance-methods:instance method' );;
+    (*.) ri_wants=( 'class-methods:class method' 'instance-methods:instance method' );;
+    (*) ri_wants=( 'classes:class name' 'gems:gem' )
   esac
 
   for curtag in $ri_wants; do
@@ -63,27 +52,36 @@ if [[ "$state" = ri-name ]]; then
     while _tags; do
       while _next_label "$tag" expl "$descr"; do
         ri_wants=()
+        suf=()
         case "$tag" in
+          (gems)
+            ri_wants=( ruby ${${(f)"$(_call_program gems gem${words[1]#ri} list -q --no-versions)"}%% *} )
+            suf=( -S : )
+          ;;
           (classes)
           for dir in $ri_dirs[@]; do
             ri_wants+=( $dir/$class_dir*(-/:t) )
           done
+          suf=( -S '::' )
           ;;
           (class-methods)
           for dir in $ri_dirs[@]; do
-            fnames=( $dir/$class_dir*-c.$ri_ext(-.:t) )
-            ri_wants+=( ${${fnames%-c.$ri_ext}//(#b)%(??)/$(print "\\x$match[1]")} )
+            fnames=( $dir/$class_dir*-c.ri(-.:t) )
+            ri_wants+=( ${${fnames%-c.ri}//(#b)%(??)/$(print "\\x$match[1]")} )
           done
           ;;
           (instance-methods)
           for dir in $ri_dirs[@]; do
-            fnames=( $dir/$class_dir*-i.$ri_ext(-.:t) )
-            ri_wants+=( ${${fnames%-i.$ri_ext}//(#b)%(??)/$(print "\\x$match[1]")} )
+            fnames=( $dir/$class_dir*-i.ri(-.:t) )
+            ri_wants+=( ${${fnames%-i.ri}//(#b)%(??)/$(print "\\x$match[1]")} )
           done
           ;;
+          (docs)
+            ri_wants=( ${${(f)"$(_call_program docs $words[1] ${(kv)opt_args[(I)-d|--doc-dir|--((no-|)(system|site|gems|home)|standard-docs)]} $IPREFIX)"}:#=*} )
+          ;;
         esac
         ri_names=( ${(Q)ri_wants} )
-        compadd -S '' -d ri_names -a "$expl[@]" ri_wants && ret=0
+        compadd $suf -d ri_names -a "$expl[@]" ri_wants && ret=0
       done
       (( ret )) || break
     done
diff --git a/Completion/Unix/Command/_rm b/Completion/Unix/Command/_rm
index e66b77fa4..6dddb5ece 100644
--- a/Completion/Unix/Command/_rm
+++ b/Completion/Unix/Command/_rm
@@ -47,14 +47,10 @@ case $variant; in
   darwin*|dragonfly*|freebsd*|netbsd*)
     args+=(
       '-W[attempt to undelete named files]'
-    )
-    ;|
-  dragonfly*|freebsd*|netbsd*)
-    args+=(
       "-x[don't cross file systems when removing a hierarchy]"
     )
     ;|
-  dragonfly*|freebsd*)
+  darwin*|dragonfly*|freebsd*)
     args+=(
       '(-i)-I[prompt when removing many files]'
     )
diff --git a/Completion/Unix/Command/_route b/Completion/Unix/Command/_route
index 06cca8d99..f0775a5d2 100644
--- a/Completion/Unix/Command/_route
+++ b/Completion/Unix/Command/_route
@@ -135,7 +135,7 @@ case $OSTYPE in
   openbsd*)
     subcmds+=( exec 'execute a command with alternate routing table' )
     args+=(
-      '-T+[select specified alternate routing table]:table id'
+      '-T+[select specified alternate routing table]:routing table:_routing_tables'
     )
     modifiers+=(
       -sa
@@ -196,7 +196,7 @@ if [[ -n $state ]]; then
   if [[ $line[1] = exec ]]; then
     shift words
     (( CURRENT-- ))
-    _normal
+    _normal -p $service && return
   elif [[ $line[1] = (flush|monitor) ]]; then
     sequential=()
   fi
diff --git a/Completion/Unix/Command/_rsync b/Completion/Unix/Command/_rsync
index b1a4f6046..c65266dbd 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' \
@@ -141,8 +141,9 @@ _rsync() {
     '(-X --xattrs)'{-X,--xattrs}'[preserve extended attributes]' \
     '--fake-super[use xattrs to save all file attributes]' \
     '(-d --dirs)'{-d,--dirs}'[transfer directories without recursing]' \
-    {--no-d,--no-dirs}'[turn off --dirs]' \
-    "--mkpath[create the destination's path component]" \
+    '(--no-d --no-dirs)'{--no-d,--no-dirs}'[turn off --dirs]' \
+    '(--old-dirs --old-d)'{--old-dirs,--old-d}'[work like --dirs when talking to old rsync]' \
+    "--mkpath[create destination's missing path components]" \
     '(-l --links)'{-l,--links}'[copy symlinks as symlinks]' \
     {--no-l,--no-links}'[turn off --links]' \
     '(-L --copy-links)'{-L,--copy-links}'[transform symlinks into referent file/dir]' \
@@ -161,8 +162,10 @@ _rsync() {
     '(-g --group)'{-g,--group}'[preserve group]' \
     {--no-g,--no-group}'[turn off --group]' \
     '(--devices --specials)-D[same as --devices --specials]' \
-    '(-D)--devices[preserve devices]' \
+    '(-D --copy-devices --write-devices)--devices[preserve devices]' \
     '--no-devices[turn off --devices]' \
+    '(-D --devices)--copy-devices[copy device contents as a regular file]' \
+    '(-D --devices)--write-devices[write to devices as files (implies --inplace)]' \
     '(-D)--specials[preserve special files]' \
     '--no-specials[turn off --specials]' \
     '--no-D[turn off --devices and --specials]' \
@@ -179,9 +182,9 @@ _rsync() {
     '(-n --dry-run)'{-n,--dry-run}'[show what would have been transferred]' \
     '(-W --whole-file)'{-W,--whole-file}'[copy files whole (without delta-transfer algorithm)]' \
     {--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' \
+    '(--cc --checksum-choice)'{--cc,--checksum-choice}'=[choose the checksum algorithms]:algorithm:_sequence -n 2 compadd - auto xxh128 xxh3 xxh64 xxhash md4 md5 sha1 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 +202,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' \
@@ -233,7 +236,8 @@ _rsync() {
     '*--include=[do not exclude files matching pattern]:pattern' \
     '--files-from=[read list of source-file names from specified file]:file:_files' \
     '(-0 --from0)'{-0,--from0}'[all *-from file lists are delimited by nulls]' \
-    '(-s --protect-args)'{-s,--protect-args}'[no space-splitting; only wildcard special-chars]' \
+    '(-s --secluded-args)'{-s,--secluded-args}'[use the protocol to safely send arguments]' \
+    "--trust-sender[trust the remote sender's file list]" \
     '--copy-as=[specify user & optional group for the copy]:user:_rsync_users_groups' \
     '--version[print version number]' \
     '*'{-h,--human-readable}'[output numbers in a human-readable format]' \
@@ -251,6 +255,7 @@ _rsync() {
     '--list-only[list the files instead of copying them]' \
     '--stop-after=[stop copying after specified time has elapsed]:time (minutes)' \
     '--stop-at=[stop copying when specified point in time is reached]:date/time (YYYY-MM-DDTHH\:MM):_dates -F -S "T"' \
+    '--fsync[fsync every written file]' \
     '(--only-write-batch)--write-batch=[write a batched update to the specified file]:file:_files' \
     '(--write-batch)--only-write-batch=[like --write-batch but w/o updating destination]:file:_files' \
     '--protocol=[force an older protocol version to be used]:number' \
diff --git a/Completion/Unix/Command/_ruby b/Completion/Unix/Command/_ruby
index 0e1f5dbc0..9955253b3 100644
--- a/Completion/Unix/Command/_ruby
+++ b/Completion/Unix/Command/_ruby
@@ -40,38 +40,59 @@ opts=(
   '(-v)--verbose[turn on verbose mode and disable script from stdin]'
   '-x-[strip off text before #!ruby line and perhaps cd to directory]:directory:_files -/'
   '(1 * -)--copyright[print the copyright]'
-  --{en,dis}'able=[enable or disable features]:feature:(gems did_you_mean rubyopt frozen_string_literal jit all)'
+  --{en,dis}'able=[enable or disable features]:feature:(gems error_highlight did_you_mean syntax_suggest rubyopt frozen_string_literal mjit yjit all)'
   \!--{en,dis}able-{gems,rubyopt,all}
-  '--dump=[dump debug information]:information:_sequence compadd - insns yydebug parsetree parsetree_with_comment'
+  '--dump=[dump debug information]:information:_sequence compadd - insns insns_without_opt yydebug parsetree parsetree_with_comment'
   --{external,internal}'-encoding=:charset:->charsets'
+  '--backtrace-limit=[limit the maximum length of backtrace]:number'
   '!'{-y,--yydebug}
   '!--dump=:target:(version copyright usage yydebug syntax parsetree parsetree_with_comment insns)'
-  '--jit[enable jit with default options]'
-  '--jit-warnings[enable printing JIT warnings]'
-  '--jit-debug[enable JIT debugging (very slow)]'
-  '--jit-wait[wait until JIT compilation finishes every time (for testing)]'
-  '--jit-save-temps[save JIT temporary files]'
-  '--jit-verbose=-[print JIT logs of level num or less to stderr]:maximum log level [0]'
-  '--jit-max-cache=-[specify max number of methods to be JIT-ed in a cache]:number [100]'
-  '--jit-min-calls=-[specify number of calls to trigger JIT]:calls [10000]'
+  '(--mjit --yjit)--jit[enable jit for the platform]'
+  '(--jit --yjit)--mjit[enable C compiler-based JIT compiler]'
+  '(--jit --mjit)--yjit[enable in-process JIT compiler]'
+  '--mjit-warnings[enable printing JIT warnings]'
+  '--mjit-debug[enable JIT debugging (very slow)]'
+  '--mjit-wait[wait until JIT compilation finishes every time (for testing)]'
+  '--mjit-save-temps[save JIT temporary files]'
+  '--mjit-verbose=-[print JIT logs of level num or less to stderr]:maximum log level [0]'
+  '--mjit-max-cache=-[specify max number of methods to be JIT-ed in a cache]:number [100]'
+  '--mjit-min-calls=-[specify number of calls to trigger JIT]:calls [10000]'
+  '--yjit-stat[enable collecting YJIT statistics]'
+  '--yjit-exec-mem-size=-[size of executable memory block in MiB]:mem size'
+  '--yjit-call-threshold=-[number of calls to trigger JIT]:number'
+  '--yjit-max-versions=-[maximum number of versions per basic block]:versions'
+  '--yjit-greedy-versioning[greedy versioning mode]'
 )
 
 irb=(
   '-f[suppress read of ~/.irbrc]'
-  '(--noinspect)-m[bc mode (load mathn, fraction, matrix)]'
   $opts[(r)*-d\[*]
   '(--noinspect)--inspect[use inspect for output]'
   "(--inspect)--noinspect[don't use inspect for output]"
-  '(--noreadline)--readline[use readline extension]'
-  "(--readline)--noreadline[don't use readline extension]"
-  '(--prompt --prompt-mode --inf-ruby-mode --simple-prompt --noprompt)'{--prompt,--prompt-mode}'[switch prompt mode]:prompt mode:(default simple xmp inf-ruby)'
+  '(--prompt --prompt-mode --inf-ruby-mode --simple-prompt --noprompt)'{--prompt=,--prompt-mode=}'[switch prompt mode]:prompt mode:(default classic simple inf-ruby xmp null)'
   '(--prompt --prompt-mode --inf-ruby-mode --simple-prompt --noprompt)'{--inf-ruby-mode,--simple-prompt,--noprompt}
   '--tracer[display trace for each command execution]'
   '--back-trace-limit[set limit for backtraces]:limit [16]:'
   '!--irb_debug:level'
   '--context-mode:n'
+  '--extra-doc-dir[add an extra doc dir for the doc dialog]'
   '(--noecho)--echo[show result]'
   "(--echo)--noecho[don't show result]"
+  '(--noecho-on-assignment)--echo-on-assignment[show result on assignment]'
+  "(--echo-on-assignment)--noecho-on-assignment[don't show result on assignment]"
+  '--truncate-echo-on-assignment[show truncated result on assignment]'
+  '(--nomultiline)--multiline[use multiline editor module]'
+  "(--multiline)--nomultiline[don't use multiline editor module]"
+  '(--nosingleline)--singleline[use single line editor module]'
+  "(--singleline)--nosingleline[don't use single line editor module]"
+  '(--nocolorize)--colorize[use color-highlighting]'
+  "(--colorize)--nocolorize[don't use color-highlighting]"
+  '(--noautocomplete)--autocomplete[use auto-completion]'
+  "(--autocomplete)--noautocomplete[don't use auto-completion]"
+  '(--regexp-completor)--type-completor[use regexp based completion]'
+  '(--type-completor)--regexp-completor[use type based completion]'
+  '(--noscript)--script[script mode]'
+  '(--script)--noscript[no script mode]'
   '--single-irb[share self with sub-irb]'
   '(--noverbose)--verbose[show details]'
   "(--verbose)--noverbose[don't show details]"
@@ -81,8 +102,9 @@ erb=(
   "-P[don't evaluate lines which start with %]"
   '-T[specify trim mode]:mode [0]:((0\:EOL\ remains 1\:EOL\ removed\ if\ line\ ends\ with\ %\> 2\:EOL\ removed\ if\ line\ starts\ with\ \<%\ and\ ends\ with\ %\> -\:EOL\ is\ removed\ if\ line\ ends\ with\ -%\>,\ leading\ whitespace\ removed\ after\ \<%-))'
   '(-d --debug)'{-d,--debug}'[set debugging flags (set $DEBUG to true)]'
-  '-n[used with -x, prepends line number to output]'
-  '-x[convert eRuby to Ruby]'
+  '-n[print ruby script with line number]'
+  '-x[print ruby script]'
+  '-v[enable verbose mode]'
 )
 
 case "$service" in
diff --git a/Completion/Unix/Command/_samba b/Completion/Unix/Command/_samba
index 6c7a64e18..a36130cf9 100644
--- a/Completion/Unix/Command/_samba
+++ b/Completion/Unix/Command/_samba
@@ -5,16 +5,29 @@ local -a state line expl msgs args ign
 
 (( CURRENT == 2 )) || ign='!'
 args=(
+  '--debug-stdout[send debug output to stdout]'
   '(-d --debuglevel)'{-d+,--debuglevel=}'[set debug level]:debug level (1..10) [1]'
   '(-s --configfile)'{-s+,--configfile=}'[specify alternate smb.conf file]:config file:_files'
   '(-l --log-basename)'{-l+,--log-basename=}'[specify base name for log files]:base name:_files'
   '*--option=[set smb.conf option from command line]:option=value'
+  '--leak-report[enable talloc leak reporting on exit]'
+  '--leak-report-full[enable full talloc leak reporting on exit]'
   "${ign}(1 2 3 -)"{-\?,--help}'[display usage information]'
   "${ign}(1 2 3 -)--usage[display brief usage information]"
   "${ign}(1 2 3 - *)"{-V,--version}'[display version information]'
 )
 
 case $service in
+  smbclient|nmblookup)
+    args+=(
+      '(2 -R --name-resolve)'{-R+,--name-resolve=}'[specify name resolution order]:name resolution order:_values -s " " "name resolution order" lmhosts host wins bcast'
+      '(-m --max-protocol)'{-m+,--max-protocol=}'[set the max protocol level]:level'
+      '(2 -O --socket-options)'{-O+,--socket-options=}'[specify socket options]:socket options'
+      '(2)--netbios-scope=[specify NetBIOS scope]:scope'
+      '(2 -W --workgroup)'{-W+,--workgroup=}'[specify workgroup name]:workgroup name'
+      '--realm=[set the realm name]:realm'
+    )
+  ;|
   smbcontrol)
     _arguments -C -S $args \
       '(-t --timeout)'{-t+,--timeout=}'[set timeout]:timeout (seconds)' \
@@ -42,12 +55,10 @@ case $service in
   smbclient)
     args+=(
       '(-N -A)2: :_guard "^-*" password'
-      '(2 -R --name-resolve)'{-R+,--name-resolve=}'[specify name resolution order]:name resolution order:_values -s " " "name resolution order" lmhosts host wins bcast'
       '(2 -M --message -L --list -D --directory -T --tar)'{-M+,--message=}'[send message]:host:_hosts'
       '(2 -I --ip-address)'{-I+,--ip-address=}'[specify IP address of server]:IP address'
       '(2 -E --stderr)'{-E,--stderr}'[output messages to stderr]'
       '(2 -M --message -D --directory -T --tar)'{-L+,--list=}'[list services on server]:host:_hosts'
-      '(-m --max-protocol)'{-m+,--max-protocol=}'[set the max protocol level]:level'
       '(2 -T --tar -M --message -L --list)'{-T+,--tar=}'[specify tar options]:tar options'
       '(2 -D --directory -M --message -L --list)'{-D+,--directory=}'[specify initial directory]:initial directory'
       '(2 -c --command)'{-c,--command=}'[specify commands]:command string'
@@ -58,19 +69,18 @@ case $service in
       '(-q --quiet)'{-q,--quiet}'[suppress help message]'
       '(-B --browse)'{-B,--browse}'[browse SMB servers using DNS]'
       '(2 -d --debuglevel)'{-d+,--debuglevel=}'[specify debug level]:debug level:(0 1 2 3 4 5 6 7 8 9 10)'
-      '(2 -O --socket-options)'{-O+,--socket-options=}'[specify socket options]:socket options'
       '(2 -n --netbiosname)'{-n+,--netbiosname=}'[specify local NetBIOS name]:local machine name'
-      '(2 -W --workgroup)'{-W+,--workgroup=}'[specify workgroup]:workgroup'
-      '(2 -i --scope)'{-i+,--scope=}'[specify NetBIOS scope]:scope'
       '(2 -U --user)'{-U+,--user=}'[specify username]:username:_users'
       '(2 -N --no-pass)'{-N,--no-pass}'[suppress password prompt]'
-      '(-k --kerberos)'{-k,--kerberos}'[use kerberos (active directory) authentication]'
+      '--pw-nt-hash[the supplied password is the NT hash]'
       '(2 -A --authentication-file)'{-A+,--authentication-file=}'[specify file containing username/password]:file:_files'
-      '(-S --signing)'{-S+,--signing=}'[set the client signing state]:state:(on off required)'
       '(-P --machine-pass)'{-P,--machine-pass}'[use stored machine account password]'
-      '(-e --encrypt)'{-e,--encrypt}'[encrypt SMB transport]'
-      '(-C --use-ccache)'{-C,--use-ccache}'[use the winbind ccache for authentication]'
-      '--pw-nt-hash[the supplied password is the NT hash]'
+      '--simple-bind-dn=[specify DN to use for a simple bind]:DN'
+      '--use-kerberos=[use Kerberos authentication]:state:(desired required off)'
+      '--use-krb5-ccache=[specify credentials cache location for Kerberos]:file:_files'
+      '--use-winbind-ccache[use the winbind ccache for authentication]'
+      '--client-protection=[configure protection used for client connections]:protection:(sign encrypt off)'
+      '!(--use-kerberos)'{-k,--kerberos}
     )
     (( CURRENT == 2 )) && args+=( '1:service name:_hosts -P // -S /' )
     _arguments -s -S $args
@@ -81,16 +91,13 @@ case $service in
       '(-f --flags)'{-f,--flags}'[list NMB flags returned]' \
       '(-U --unicast)'{-U+,--unicast=}'[specify unicast address]:unicast address' \
       '(-M --master-browser)'{-M,--master-browser}'[search for a master browser]' \
-      '(-R --recursion)'{-R,--recursion}'[set recursion desired in packet]' \
+      '--recursion[set recursion desired in packet]' \
       '(-S --status)'{-S,--status}'[lookup node status as well]' \
       '(-T --translate)'{-T,--translate}'[perform reverse DNS on IP addresses]' \
       '(-r --root-port)'{-r,--root-port}'[use root port 137]' \
       '(-A --lookup-by-ip)'{-A,--lookup-by-ip}'[query node status on IP address]' \
       '(-d --debuglevel)'{-d+,--debuglevel=}'[specify debug level]:debug level:(0 1 2 3 4 5 6 7 8 9 10)' \
-      '(-O --socket-options)'{-O+,--socket-options=}'[specify socket options to use]:socket option' \
       '(-n --netbiosname)'{-n+,--netbiosname=}'[specify primary netbios name]:netbios name' \
-      '(-W --workgroup)'{-W+,--workgroup=}'[specify workgroup name]:workgroup name' \
-      '(-i --scope)'{-i+,--scope=}'[specify NetBIOS scope]:scope' \
       '(h)*:NetBIOS name:_hosts'
   ;;
   smbstatus)
diff --git a/Completion/Unix/Command/_sccs b/Completion/Unix/Command/_sccs
index 4083fe54e..20222a5c1 100644
--- a/Completion/Unix/Command/_sccs
+++ b/Completion/Unix/Command/_sccs
@@ -1,4 +1,4 @@
-#compdef sccs admin cdc comb delta get help prs prt rmdel sact sccsdiff unget val what
+#compdef sccs sccsdiff
 
 (( $+functions[_sccs_files] )) ||
 _sccs_files() {
diff --git a/Completion/Unix/Command/_scons b/Completion/Unix/Command/_scons
index 77fe6dfb0..2e465216c 100644
--- a/Completion/Unix/Command/_scons
+++ b/Completion/Unix/Command/_scons
@@ -24,14 +24,14 @@ _arguments -s -S \
   '(--implicit-cache --implicit-deps-changed)--implicit-deps-changed[rescan dependencies]' \
   '(--implicit-cache --implicit-deps-unchanged)--implicit-deps-unchanged[ignore changes to scanned dependencies]' \
   '--interactive[start interactive mode]' \
-  '(-j --jobs)-'{j,jobs=}'[specify no of jobs to run in parallel]' \
+  '(-j --jobs)-'{j,-jobs=}'[specify no of jobs to run in parallel]:number of jobs' \
   '(-k --keep-going)-'{k,-keep-going}'[continue after an error]' \
   '--max-drift=[set the maximum clock drift]:drift (seconds)' \
   '--md5-chunksize=[set chunksize for MD5 signature computation]:size (kB)' \
   '(-n --just-print --dry-run --recon)-'{n,-just-print,-dry-run,-recon}"[print commands but don't run them]" \
   "--no-site-dir[don't use the usual site_scons directory]" \
   '--profile=[profile scons]:output file:_files' \
-  '(-q --question)-'{q,question}'[query whether up-to-date]' \
+  '(-q --question)-'{q,-question}'[query whether up-to-date]' \
   '-Q[suppress progress messages]' \
   '--random[build dependencies in random order]' \
   '(-s --silent --quiet)-'{s,-silent,-quiet}"[don't print commands]" \
diff --git a/Completion/Unix/Command/_screen b/Completion/Unix/Command/_screen
index 6d47d2638..9336ae82d 100644
--- a/Completion/Unix/Command/_screen
+++ b/Completion/Unix/Command/_screen
@@ -107,7 +107,7 @@ if [[ -n $state ]]; then
       elif (( CURRENT > 2 )) && [[ ${words[1]} == /dev/* ]]; then
 	  _message "no more parameters"
       else
-	  _normal
+	  _normal -p $service
       fi
     ;;
     attached-sessions)
diff --git a/Completion/Unix/Command/_script b/Completion/Unix/Command/_script
index 7a3960be0..d38d56f2e 100644
--- a/Completion/Unix/Command/_script
+++ b/Completion/Unix/Command/_script
@@ -47,7 +47,7 @@ case $OSTYPE in
       '-q[be quiet: suppress display of starting and ending lines]'
       '(-a -r -k)-d[suppress sleeps when playing back a session]'
       '(-a -r -k -t)-p[play back a recorded session]'
-      '(-d -p)-r[record a session with input, output and timing data]'
+      '(-d -p -T)-r[record a session with input, output and timing data]'
     )
   ;|
   netbsd*|openbsd*)
@@ -60,7 +60,9 @@ case $OSTYPE in
   ;|
   freebsd*)
     args+=(
+      '-e[return exit status of the child process]'
       '-f[use filemon(4)]'
+      '(-a -r -k -t)-T[play back a recorded session, reporting only timestamps]: :_date_formats'
     )
   ;|
   darwin*|dragonfly*|freebsd*)
@@ -68,11 +70,9 @@ case $OSTYPE in
       '-F[send output to specified named pipe]:fifo:_files -g "*(p)"'
       '-t+[specify interval of data flushing]:interval (seconds)'
       '-k[log keys sent to the program as well as output]'
-      '*:::arguments: _normal'
+      '*:::arguments: _normal $service'
     )
   ;|
-  darwin*|freebsd*)
-  ;|
   *)
     args+=(
       '(-p -d)-a[append output]'
diff --git a/Completion/Unix/Command/_sed b/Completion/Unix/Command/_sed
index 79a010c92..ef3aaf2fd 100644
--- a/Completion/Unix/Command/_sed
+++ b/Completion/Unix/Command/_sed
@@ -104,14 +104,13 @@ else
   case $OSTYPE in
     openbsd*|freebsd*|netbsd*|darwin*|dragonfly*)
       args+=(
-	'(-r -E)'-E$extended
+	'(-r -E)'{-E,-r}$extended
 	'-a[delay opening files listed with w function]'
       )
     ;|
-    openbsd*|freebsd*|netbsd*|dragonfly*) args+=( '(-r -E)'-r$extended ) ;|
     darwin*|freebsd*|netbsd*|openbsd*|dragonfly*) args+=( '-i+'$inplace ) ;|
     darwin*|freebsd*|netbsd*|dragonfly*) args+=( '-l[make output line buffered]' ) ;|
-    freebsd*|dragonfly*) args+=( '-u[disable data buffering]' ) ;|
+    darwin*|freebsd*|dragonfly*) args+=( '-u[disable data buffering]' ) ;|
     freebsd*|netbsd*|dragonfly*)
       args+=(
         '-I+[edit files in-place, treating all files as a single input stream]:: :_guard "^(*[@/; \\\]*|?(#c6,)|-*)" "suffix for backup"'
diff --git a/Completion/Unix/Command/_service b/Completion/Unix/Command/_service
index 1216f57a8..28563429b 100644
--- a/Completion/Unix/Command/_service
+++ b/Completion/Unix/Command/_service
@@ -10,8 +10,11 @@ zstyle -T  ":completion:${ctx}" tag-order && \
   zstyle ":completion:${ctx}" tag-order init
 
 case $OSTYPE in
+  freebsd<14->.*)
+    args=( '-E+[set environment variable before executing the rc.d script]:variable:_parameters -g "*export*~*readonly*" -S=' )
+  ;&
   freebsd<11->.*)
-    args=( '-j+[perform actions in specified jail]:jail:_jails' )
+    args+=( '-j+[perform actions in specified jail]:jail:_jails' )
   ;&
   freebsd*|dragonfly*)
     actions=(
diff --git a/Completion/Unix/Command/_split b/Completion/Unix/Command/_split
index c5ab0dc9b..5d5afa436 100644
--- a/Completion/Unix/Command/_split
+++ b/Completion/Unix/Command/_split
@@ -8,7 +8,7 @@ _pick_variant -r variant gnu=GNU $OSTYPE --version
 
 args=(
   '-a+[generate suffixes of specified length]:length [2]' \
-  '(-l -p -n)-b+[put specified size in bytes in each output file]:size (bytes)' \
+  '(-l -p -n)-b+[put specified size in bytes in each output file]: :_numbers -u bytes size k m g' \
   '(-b -p -n)-l+[put specified number of lines/records in each output file]:lines' \
   '1:file:_files' \
   '2: :_guard "^-*" "prefix [x]"'
@@ -19,8 +19,8 @@ case $variant in
     args=( -C
       '(H -a --suffix-length)'{-a+,--suffix-length=}'[generate suffixes of specified length]:length [2]'
       '(H)--additional-suffix=[append an additional suffix to file names]:suffix'
-      '(H -b --bytes -C --line-bytes -l --lines -n --number)'{-b+,--bytes=}'[put specified size in bytes in each output file]:size (bytes)'
-      '(H -b --bytes -C --line-bytes -l --lines -n --number)'{-C+,--line-bytes=}'[put whole lines/records up to size limit in each output file]:size (bytes)'
+      '(H -b --bytes -C --line-bytes -l --lines -n --number)'{-b+,--bytes=}'[put specified size in each output file]: :_numbers -M "m\:{a-zA-Z}={A-Za-z}" -u bytes size {K,M,G,T,P,E,Z}{,B}' \
+      '(H -b --bytes -C --line-bytes -l --lines -n --number)'{-C+,--line-bytes=}'[put whole lines/records up to size limit in each output file]: :_numbers -M "m\:{a-zA-Z}={A-Za-z}" -u bytes size {K,M,G,T,P,E,Z}{,B}'
       '(H --numeric-suffixes -x --hex-suffixes)-d[use numeric suffixes starting at 0]'
       '(H -d -x --hex-suffixes)--numeric-suffixes=-[use numeric suffixes]::start value [0]'
       '(H -d --numeric-suffixes --hex-suffixes)-x[use hex suffixes starting at 0]'
@@ -39,15 +39,20 @@ case $variant in
       '(- 1 2)--version[display version information]'
     )
   ;;
-  (free|net)bsd*)
+  (free|net)bsd*|darwin*)
     args+=( '(-b -l -p)-n+[generate specified number of output files]:output files' )
   ;|
   darwin*|freebsd*)
     args+=(
+      '-d[use numeric suffixes]'
       '(-b -l -n)-p+[split the file whenever a line matches specified pattern]:pattern'
     )
   ;|
-  freebsd*) args+=( '-d[use numeric suffixes]' ) ;;
+  freebsd*)
+    args+=(
+      "-c[continue creating files and don't overwrite existing output files]"
+    )
+  ;;
 esac
 
 _arguments -s -S $args && ret=0
diff --git a/Completion/Unix/Command/_sqlite b/Completion/Unix/Command/_sqlite
index 7ef3c6daa..6f0b1de94 100644
--- a/Completion/Unix/Command/_sqlite
+++ b/Completion/Unix/Command/_sqlite
@@ -12,7 +12,7 @@ dashes=( '' )
 
 options=(
   '(-init --init)'$^dashes'-init[startup file]:file containing SQLite commands:_files'
-  $^dashes'-echo[echo commands]'
+  $^dashes'-echo[print inputs before execution]'
 )
 
 exclusive=( {,-}-{no,}header )
@@ -55,9 +55,13 @@ options+=(
   $^dashes'-mmap[set default mmap size]:size'
   $^dashes'-newline[set output row separator]:separator [\n]'
   $^dashes'-nofollow[refuse to open symbolic links to database files]'
+  $^dashes'-nonce[set the safe-mode escape nonce]:string'
   $^dashes'-pagecache[specify size and number of slots for page cache memory]:size (bytes): :slots'
+  $^dashes'-pcachetrace[trace all page cache operations]'
   $^dashes'-readonly[open the database read-only]'
+  $^dashes'-safe[enable safe-mode]'
   $^dashes'-stats[print memory stats before each finalize]'
+  $^dashes'-unsafe-testing[allow unsafe commands and modes for testing]'
   $^dashes'-vfs[use specified default VFS]:vfs:(unix-dotfile unix-excl unix-none unix-namedsem)'
   $^dashes'-zip[open the file as a ZIP Archive]'
 )
@@ -68,12 +72,14 @@ if [[ -n $words[(r)-A*] ]]; then
     '(1 -a --append -f --file)'{-f+,--file=}'[specify archive file]:archive file:_files'
     '(1 -a --append -f --file)'{-a,--append=}'[operate on specified file opened using the apndvfs VFS]:archive file:_files'
     '(-C --directory)'{-C+,--directory=}'[change to specified directory to read/extract files]:directory:_directories'
+    '(-g --glob)'{-g,--glob}'[use glob matching for names in archive]'
     '(-n --dryrun)'{-n,--dryrun}'[show the SQL that would have occurred]'
     '*:file:_files'
     + '(commands)' \
     '(-c --create)'{-c,--create}'[create a new archive]'
     '(-u --update)'{-u,--update}'[update or add files to an existing archive]'
     '(-i --insert)'{-i,--insert}'[like -u but always add even if mtime unchanged]'
+    '(-r --remove)'{-r,--remove}'[remove files from archive]'
     '(-t --list)'{-t,--list}'[list contents of archive]'
     '(-x --extract)'{-x,--extract}'[extract files from archive]'
   )
diff --git a/Completion/Unix/Command/_ssh b/Completion/Unix/Command/_ssh
index 20087174c..5e6e60573 100644
--- a/Completion/Unix/Command/_ssh
+++ b/Completion/Unix/Command/_ssh
@@ -18,14 +18,18 @@ _ssh () {
     '*-o+[specify extra options]:option string:->option'
   )
   common_transfer=(
+    '(-O)-D+[connect directly to a local sftp server]:sftp server path:_command_names -e'
     '-J+[connect via a jump host]: :->userhost'
     '-l+[limit used bandwidth]:bandwidth (Kbit/s)'
     '-P+[specify port on remote host]:port number on remote host'
     '-p[preserve modification times, access times and modes]'
     '-q[disable progress meter and warnings]'
     '-r[recursively copy directories (follows symbolic links)]'
-    '-S+[specify ssh program]:path to ssh:_command_names -e' \
+    '-S+[specify ssh program]:path to ssh:_command_names -e'
     '-v[verbose mode]'
+    '(-O)*-X+[specify sftp protocol option]: : _values "sftp option"
+      "nrequests[set max concurrent SFTP read or write requests]\:requests [64]"
+      "buffer[set max buffer size for a single SFTP read/write operation]\: \:_numbers -l 0 -m 256K -d 32K -u bytes -f size \:B\:bytes \:K\:kilobytes"'
   )
   algopt='-E+[specify hash algorithm for fingerprints]:algorithm:(md5 sha256)'
 
@@ -53,12 +57,12 @@ _ssh () {
       "-N[don't execute a remote command]" \
       '-n[redirect stdin from /dev/null]' \
       '-O+[control an active connection multiplexing master process]:multiplex control command:((check\:"check master process is running" exit\:"request the master to exit" forward\:"request forward without command execution" stop\:"request the master to stop accepting further multiplexing requests" cancel\:"cancel existing forwardings with -L and/or -R" proxy))' \
-      '-P[use non privileged port]' \
+      '-P+[specify a tag name that may be used to select configuration]:tag' \
       '-p+[specify port on remote host]:port number on remote host' \
       '(-v)*-q[quiet operation]' \
       '*-R+[specify remote port forwarding]:remote port forwarding:->forward' \
       '-S+[specify location of control socket for connection sharing]:path to control socket:_files' \
-      '-Q+[query parameters]:query option:((cipher\:"supported symmetric ciphers" cipher-auth\:"supported symmetric ciphers that support authenticated encryption" mac\:"supported message integrity codes" kex\:"key exchange algorithms" key\:"key types" key-cert\:"certificate key types" key-plain\:"non-certificate key types" protocol-version\:"supported SSH protocol versions" sig\:"supported signature algorithms" help\:"show supported queries"))' \
+      '-Q+[query parameters]:query option:((cipher\:"supported symmetric ciphers" cipher-auth\:"supported symmetric ciphers that support authenticated encryption" compression mac\:"supported message integrity codes" kex\:"key exchange algorithms" kex-gss\:"GSSAPI key exchange algorithms" key\:"key types" key-cert\:"certificate key types" key-plain\:"non-certificate key types" key-sig\:"all key types and signature algorithms" protocol-version\:"supported SSH protocol versions" sig\:"supported signature algorithms" help\:"show supported queries" HostbasedAcceptedAlgorithms HostKeyAlgorithms KexAlgorithms MACs PubkeyAcceptedAlgorithms))' \
       '-s[invoke subsystem]' \
       '(-t)-T[disable pseudo-tty allocation]' \
       "(-T)*-t[force pseudo-tty allocation${tdesc}]" \
@@ -76,21 +80,35 @@ _ssh () {
   scp)
     _arguments -C -s \
       '-3[copy through local host, not directly between the remote hosts]' \
-      '-B[batch mode (don'\''t ask for passphrases)]' \
+      "-B[batch mode (don't ask for passwords or passphrases)]" \
+      '(-D -X)-O[use the original SCP protocol instead of the SFTP protocol]' \
       '-T[disable strict filename checking]' \
       '*:file:->file' "$common[@]" "$common_transfer[@]" && ret=0
     ;;
   ssh-add)
-    [[ $OSTYPE == darwin* ]] && args=(
-      '-A[add identities from keychain]'
-      '-K[update keychain when adding/removing identities]'
+    if [[ $OSTYPE != darwin* || $APPLE_SSH_ADD_BEHAVIOR == openssh ]]; then
+      args=(
+        '-K[load resident keys from a FIDO authenticator]'
+      )
+    else
+      [[ ${APPLE_SSH_ADD_BEHAVIOR:-macos} == macos ]] && args=(
+        '-A[add identities from keychain]'
+        '-K[update keychain when adding/removing identities]'
+      )
+    fi
+    [[ $OSTYPE == darwin<20->.* ]] && args+=(
+      '--apple-load-keychain[add identities from keychain]'
+      '--apple-use-keychain[update keychain when adding/removing identities]'
     )
-    _arguments -s : $args \
+    _arguments -C -s : $args \
+      '-C[process certificates only]' \
       '-c[identity is subject to confirmation via SSH_ASKPASS]' \
       '-D[delete all identities]' \
       '-d[remove identity]' \
       $algopt \
       '-e+[remove keys provided by the PKCS#11 shared library]:library:_files -g "*.(so|dylib)(|.<->)(-.)"' \
+      '*-H[specify a known hosts file to look up hostkeys]:known hosts file:_files' \
+      '*-h[constrain keys to specific hosts or destinations]:destination:->destinations' \
       '-k[load plain private keys only and skip certificates]' \
       '-K[load resident keys from a FIDO authenticator]' \
       '-L[list public key parameters of all identities in the agent]'\
@@ -99,14 +117,13 @@ _ssh () {
       '-M+[specify maximum number of signatures]:number' \
       '-S+[use specified library when adding FIDO authenticator-hosted keys]:library:_files' \
       '-s+[add keys provided by the PKCS#11 shared library]:library:_files -g "*.(so|dylib)(|.<->)(-.)"' \
-      '-t+[set maximum lifetime for identity]:maximum lifetime (in seconds or time format):' \
+      '-t+[set maximum lifetime for identity]: :_numbers -u seconds "maximum lifetime" \:s\:seconds m\:minutes h\:hours d\:days w\:weeks' \
       "-T[test usability of identity files' private keys]:*:public key file:_files -g '*.pub(-.)'" \
       '*-v[verbose mode]' \
       '-q[be quiet after a successful operation]' \
       '-X[unlock the agent]' \
       '-x[lock the agent with a password]' \
-      '*:SSH identity file:_files'
-    return
+      '*:SSH identity file:_files' && ret=0
     ;;
   ssh-agent)
     _arguments -s \
@@ -118,9 +135,9 @@ _ssh () {
       '-k[kill current agent]' \
       '(-k)-P[specify PKCS#11 shared library whitelist]:PKCS#11 library whitelist pattern' \
       '(-k -c)-s[force sh-style shell]' \
-      '-t[set default maximum lifetime for identities]:maximum lifetime (in seconds or time format):' \
+      '-t+[set default maximum lifetime for identities]: :_numbers -u seconds "maximum lifetime" \:s\:seconds m\:minutes h\:hours d\:days w\:weeks' \
       '-v[verbose mode]' \
-      '*::command: _normal'
+      '*::command: _normal -p $service'
     return
     ;;
   ssh-keygen)
@@ -173,15 +190,13 @@ _ssh () {
       case ${words[arg]#-Y} in
         ^find-*) sigargs+=( "$p1-n+[specify namespace]:namespace" ) ;|
 	check*|find*|verify)
-	  sigargs+=( "$p1-s+[specify signature file]:signature file:-files" )
+	  sigargs+=( "$p1-s+[specify signature file]:signature file:_files" )
 	;|
+        match*|verify) sigargs+=( '-I+[specify signer identity]:identity' ) ;|
 	sign) sigargs+=( '*:file:_files' ) ;;
 	verify)
 	  args=()
-	  sigargs+=(
-	    '-I+[specify signer identity]:identity'
-	    '-r+[specify revocation file]:revocation file:_files'
-	  )
+	  sigargs+=( '-r+[specify revocation file]:revocation file:_files' )
 	;;
       esac
     fi
@@ -200,7 +215,7 @@ _ssh () {
       "(${${(@)cmds:#-p}} -v ${${(@)cms:#-[qt]}})-N+[provide new passphrase]:new passphrase" \
       "(${${(@)cmds:#-c}} -v $cms)-C+[provide new comment]:new comment" \
       "(-D -I -h -n -V -A)-f+[$file file]:$file file:_files" \
-      "$p1(${${(@)cmds:#-[FE]}} ${${(@)cmn:#-v}} ${${(@)cms:#-E}})-l[show fingerprint of key file]" \
+      "(${${(@)cmds:#-[FE]}} ${${(@)cmn:#-v}} ${${(@)cms:#-E}})-l[show fingerprint of key file]" \
       "$p1(${${(@)cmds:#-[iep]}} $cms)-m+[specify conversion format]:format [RFC4716]:(PEM PKCS8 RFC4716)" \
       "$p1*-O+[specify a key/value option]: : _values 'option' $options" \
       "(${${(@)cmds:#-[lGT]}} ${${(@)cmn:#-[bv]}} -f)*-v[verbose mode]" \
@@ -225,12 +240,6 @@ _ssh () {
       "($cmn)-L[print the contents of a certificate]" \
       "(${${(@)cmn:#-a}})-A[generate host keys for all key types]" \
       "($cmn)-Q[test whether keys have been revoked in a KRL]" \
-      "($cmn)-Y+[signature action]:action:((
-        find-principals\:find\ the\ principal\ associated\ with\ the\ public\ key\ of\ a\ signature
-        sign\:sign\ a\ file\ using\ SSH\ key
-        verify\:verify\ a\ signature\ generated\ using\ the\ sign\ option
-        check-novalidate\:check\ signature\ structure
-      ))" \
       - finger \
       "$p1($cmn)$algopt" \
       - create \
@@ -250,6 +259,13 @@ _ssh () {
       "($cmn -I -h -n -D -O -U -V)-k[generate a KRL file]" \
       "$p1($cmn -I -h -n -D -O -U -V)-u[update a KRL]" \
       - signature \
+      "(${${(@)cmn:#-O}})-Y+[signature action]:action:((
+        find-principals\:find\ the\ principal\ associated\ with\ the\ public\ key\ of\ a\ signature
+        sign\:sign\ a\ file\ using\ SSH\ key
+        verify\:verify\ a\ signature\ generated\ using\ the\ sign\ option
+        check-novalidate\:check\ signature\ structure
+        match-principals\:find\ matching\ principal
+      ))" \
       $sigargs
     return
   ;;
@@ -261,8 +277,10 @@ _ssh () {
       '-D[print keys found as SSHFP DNS records]' \
       '*-f+[read hosts from file, one per line]:file:_files' \
       '-H[hash all hostnames and addresses in the output]' \
+      '-O+[specify a key/value option]: : _values option
+        "hashalg[select a hash algorithm to use with -D]\:algorithm [both]\:(sha1 sha256)"' \
       '-p+[specify port on remote host]:port number on remote host' \
-      '-T+[specify timeout]:timeout (seconds) [5]' \
+      '-T+[specify timeout]: :_numbers -u seconds -d 5 timeout \:s\:seconds m\:minutes h\:hours d\:days w\:weeks' \
       '-t+[specify key types to fetch from scanned hosts]:key type:_sequence compadd - rsa dsa ecdsa ed25519' \
       '-v[verbose mode]'
     return
@@ -272,7 +290,6 @@ _ssh () {
       '-a[attempt to continue interrupted transfers]' \
       '-B+[specify buffer size]:buffer size (bytes) [32768]' \
       '-b+[specify batch file to read]:batch file:_files' \
-      '-D+[connect directly to a local sftp server]:sftp server path' \
       '-f[request that files be flushed immediately after transfer]' \
       '-N[disable implicit quiet mode set by -b]' \
       '-R+[specify number of outstanding requests]:number of requests [64]' \
@@ -299,22 +316,37 @@ _ssh () {
     option)
       if compset -P 1 '*='; then
         case "${IPREFIX#-o}" in
-          (#i)(ciphers|macs|kexalgorithms|hostkeyalgorithms|pubkeyacceptedkeytypes|hostbasedkeytypes)=)
-          if ! compset -P '[+-]'; then
-            _wanted prefix expl 'relative to default' compadd - + - && ret=0
+          (#i)(ciphers|macs|kexalgorithms|hostkeyalgorithms|pubkeyacceptedalgorithms)=)
+          local sep
+          zstyle -s ":completion:${curcontext}:" list-separator sep || sep=--
+          if ! compset -P '[+-^]'; then
+            _wanted prefix expl 'relative to default' compadd -S '' -d \
+                "(
+                   +\ $sep\ append\ to\ default\ list
+                   -\ $sep\ remove\ from\ default\ list
+                   ^\ $sep\ insert\ at\ head\ of\ default\ list
+                )" - + - \^ && ret=0
           fi
           ;;
         esac
         case "${IPREFIX#-o}" in
-        (#i)(afstokenpassing|batchmode|canonicalizefallbacklocal|challengeresponseauthentication|checkhostip|clearallforwardings|compression|enablesshkeysign|exitonforwardfailure|fallbacktorsh|forward(agent|x11)|forwardx11trusted|gatewayports|gssapiauthentication|gssapidelegatecredentials|gssapikeyexchange|gssapirenewalforcesrekey|gssapitrustdns|hashknownhosts|hostbasedauthentication|identitiesonly|kbdinteractiveauthentication|(tcp|)keepalive|nohostauthenticationforlocalhost|passwordauthentication|permitlocalcommand|proxyusefdpass|pubkeyauthentication|rhosts(|rsa)authentication|rsaauthentication|streamlocalbindunlink|usersh|kerberos(authentication|tgtpassing)|useprivilegedport|visualhostkey)=*)
+        (#i)(batchmode|canonicalizefallbacklocal|checkhostip|clearallforwardings|compression|enableescapecommandline|enablesshkeysign|exitonforwardfailure|fallbacktorsh|forkafterauthentication|forward(agent|x11)|forwardx11trusted|gatewayports|gssapiauthentication|gssapidelegatecredentials|gssapikeyexchange|gssapirenewalforcesrekey|gssapitrustdns|hashknownhosts|hostbasedauthentication|identitiesonly|kbdinteractiveauthentication|tcpkeepalive|nohostauthenticationforlocalhost|passwordauthentication|permitlocalcommand|permitremoteopen|proxyusefdpass|stdinnull|streamlocalbindunlink|visualhostkey)=*)
           _wanted values expl 'truth value' compadd yes no && ret=0
           ;;
+        (#i)addkeystoagent=*)
+          _alternative \
+            'timeouts: :_numbers -u seconds "time interval" :s:seconds m:minutes h:hours d:days w:weeks' \
+            'values:value:(yes no ask confirm)' && ret=0
+        ;;
         (#i)addressfamily=*)
           _wanted values expl 'address family' compadd any inet inet6 && ret=0
           ;;
         (#i)bindaddress=*)
           _wanted bind-addresses expl 'bind address' _bind_addresses && ret=0
           ;;
+        (#i)bindinterface=*)
+          _wanted bind-interfaces expl 'bind interface' _network_interfaces && ret=0
+        ;;
         (#i)canonicaldomains=*)
           _message -e 'canonical domains (space separated)' && ret=0
           ;;
@@ -330,23 +362,27 @@ _ssh () {
         (#i)ciphers=*)
           state=ciphers
           ;;
+        (#i)certificatefile=*)
+          _description files expl 'file'
+          _files "$expl[@]" && ret=0
+        ;;
         (#i)connectionattempts=*)
           _message -e 'connection attempts' && ret=0
           ;;
         (#i)connecttimeout=*)
-          _message -e 'connection timeout' && ret=0
+          _numbers -u seconds timeout :s:seconds m:minutes h:hours d:days w:weeks && ret=0
           ;;
         (#i)controlmaster=*)
-          _wanted values expl 'truthish value' compadd yes no auto autoask && ret=0
+          _wanted values expl 'truthish value' compadd yes no auto ask autoask && ret=0
           ;;
         (#i)controlpath=*)
           _description files expl 'path to control socket'
           _files "$expl[@]" && ret=0
           ;;
         (#i)controlpersist=*)
-          _message -e 'timeout'
-          ret=0
-          _wanted values expl 'truth value' compadd yes no && ret=0
+          _alternative \
+            'timeouts: :_numbers -u seconds timeout :s:seconds m:minutes h:hours d:days w:weeks' \
+            'values:truth value:(yes no)' && ret=0
           ;;
         (#i)escapechar=*)
           _message -e 'escape character (or `none'\'')'
@@ -367,9 +403,10 @@ _ssh () {
         (#i)hostname=*)
           _wanted hosts expl 'real host name to log into' _ssh_hosts && ret=0
           ;;
-        (#i)(hostbasedkeytypes|hostkeyalgorithms|pubkeyacceptedkeytypes)=*)
-	  _wanted key-types expl 'key type' _sequence compadd - $(_call_program key-types ssh -Q key) && ret=0
-          ;;
+        (#i)identityagent=*)
+          _description files expl 'socket file'
+          _files -g "*(-=)" "$expl[@]" && ret=0
+        ;;
         (#i)identityfile=*)
           _description files expl 'SSH identity file'
           _files "$expl[@]" && ret=0
@@ -400,13 +437,16 @@ _ssh () {
           _values -s , 'keyboard-interactive authentication method' \
               'bsdauth' 'pam' 'skey' && ret=0
           ;;
-        (#i)(kexalgorithms|gssapikexalgorithms)=*)
+        (#i)kexalgorithms=*)
           _wanted algorithms expl 'key exchange algorithm' _sequence compadd - \
               $(_call_program algorithms ssh -Q kex) && ret=0
           ;;
-        (#i)localcommand=*)
-          _description commands expl 'run command locally after connecting'
-          _command_names && ret=0
+        (#i)gssapikexalgorithms=*)
+          _wanted algorithms expl 'key exchange algorithm' _sequence compadd - \
+              $(_call_program algorithms ssh -Q kex-gss) && ret=0
+        ;;
+        (#i)(local|knownhosts)command=*)
+          _command_names -e && ret=0
           ;;
         (#i)loglevel=*)
           _values 'log level' QUIET FATAL ERROR INFO VERBOSE\
@@ -419,8 +459,8 @@ _ssh () {
           _message -e 'number of password prompts'
           ret=0
           ;;
-        (#i)pkcs11provider=*)
-          _description files expl 'PKCS#11 shared library'
+        (#i)(pkcs11|securitykey)provider=*)
+          _description files expl 'shared library'
           _files -g '*.(so|dylib)(|.<->)(-.)' "$expl[@]" && ret=0
           ;;
         (#i)port=*)
@@ -431,6 +471,17 @@ _ssh () {
           _values -s , 'authentication method' gssapi-with-mic \
               hostbased publickey keyboard-interactive password && ret=0
           ;;
+        (#i)proxyjump=*)
+          compset -P "* "
+          state=userhost
+        ;;
+        (#i)(hostkey|(hostbased|pubkey)accepted)algorithms=*)
+	  _wanted key-types expl 'key type' _sequence compadd - \
+              $(_call_program key-types ssh -Q key-sig) && ret=0
+        ;;
+        (#i)pubkeyauthentication=*)
+          _wanted values expl 'enable' compadd yes no unbound host-bound && ret=0
+        ;;
         (#i)protocol=*)
           _values -s , 'protocol version' \
               '1' \
@@ -440,7 +491,13 @@ _ssh () {
           _cmdstring && ret=0
           ;;
         (#i)rekeylimit=*)
-          _message -e 'maximum number of bytes transmitted before renegotiating session key'
+          if compset -P "* "; then
+            _numbers -u seconds "maximum time before renegotiating session key" \
+                :s:seconds h:hours d:days w:weeks
+          else
+            _numbers -u bytes "maximum amount of data transmitted before renegotiating session key" \
+                K:kilobytes M:megabytes G:gigabytes
+          fi
           ret=0
           ;;
         (#i)requesttty=*)
@@ -450,6 +507,9 @@ _ssh () {
               'force[always request a TTY]' \
               'auto[request a TTY when opening a login session]' && ret=0
           ;;
+        (#i)requiredrsasize=)
+          _wanted sizes expl 'minimum size [1024]' compadd 1024 2048 4096 && ret=0
+        ;;
         (#i)revokedhostkeys=*)
           _description files expl 'revoked host keys file'
           _files "$expl[@]" && ret=0
@@ -468,6 +528,9 @@ _ssh () {
         (#i)streamlocalbindmask=*)
           _message -e 'octal mask' && ret=0
           ;;
+        (#i)sessiontype=*)
+          _wanted session-types expl "session type" compadd none subsystem default && ret=0
+        ;;
         (#i)stricthostkeychecking=*)
           _wanted values expl 'value' compadd yes no ask accept-new off && ret=0
           ;;
@@ -502,15 +565,18 @@ _ssh () {
           _description files expl 'xauth program'
           _files "$expl[@]" -g '*(-*)' && ret=0
           ;;
+        *) _message -e values value ;;
         esac
       else
-        # old options are after the empty "\"-line
+        # Include, Host and Match not supported from the command-line
+        # final GSSAPI options are not in upstream but are widely patched in
         _wanted values expl 'configure file option' \
             compadd -M 'm:{a-z}={A-Z} r:[^A-Z]||[A-Z]=* r:|=*' -q -S '=' - \
                 AddKeysToAgent \
                 AddressFamily \
                 BatchMode \
                 BindAddress \
+                BindInterface \
                 CanonicalDomains \
                 CanonicalizeFallbackLocal \
                 CanonicalizeHostname \
@@ -518,7 +584,6 @@ _ssh () {
                 CanonicalizePermittedCNAMEs \
                 CASignatureAlgorithms \
                 CertificateFile \
-                ChallengeResponseAuthentication \
                 CheckHostIP \
                 Ciphers \
                 ClearAllForwardings \
@@ -529,10 +594,12 @@ _ssh () {
                 ControlPath \
                 ControlPersist \
                 DynamicForward \
+                EnableEscapeCommandline \
                 EnableSSHKeysign \
                 EscapeChar \
                 ExitOnForwardFailure \
                 FingerprintHash \
+                ForkAfterAuthentication \
                 ForwardAgent \
                 ForwardX11 \
                 ForwardX11Timeout \
@@ -540,19 +607,13 @@ _ssh () {
                 GatewayPorts \
                 GlobalKnownHostsFile \
                 GSSAPIAuthentication \
-                GSSAPIClientIdentity \
                 GSSAPIDelegateCredentials \
-                GSSAPIKeyExchange \
-                GSSAPIRenewalForcesRekey \
-                GSSAPIServerIdentity \
-                GSSAPITrustDns \
-                GSSAPIKexAlgorithms \
                 HashKnownHosts \
+                HostbasedAcceptedAlgorithms \
                 HostbasedAuthentication \
-                HostbasedKeyTypes \
                 HostKeyAlgorithms \
                 HostKeyAlias \
-                HostName \
+                Hostname \
                 IdentitiesOnly \
                 IdentityAgent \
                 IdentityFile \
@@ -561,33 +622,38 @@ _ssh () {
                 KbdInteractiveAuthentication \
                 KbdInteractiveDevices \
                 KexAlgorithms \
+                KnownHostsCommand \
                 LocalCommand \
                 LocalForward \
                 LogLevel \
+                LogVerbose \
                 MACs \
                 NoHostAuthenticationForLocalhost \
                 NumberOfPasswordPrompts \
                 PasswordAuthentication \
                 PermitLocalCommand \
+                PermitRemoteOpen \
                 PKCS11Provider \
                 Port \
                 PreferredAuthentications \
                 ProxyCommand \
                 ProxyJump \
                 ProxyUseFdpass \
-                PubkeyAcceptedKeyTypes \
                 PubkeyAuthentication \
+                PubkeyAcceptedAlgorithms \
                 RekeyLimit \
                 RemoteCommand \
                 RemoteForward \
                 RequestTTY \
+                RequiredRSASize \
                 RevokedHostKeys \
-                RhostsRSAAuthentication \
-                RSAAuthentication \
+                SecurityKeyProvider \
                 SendEnv \
                 ServerAliveCountMax \
                 ServerAliveInterval \
                 SetEnv \
+                SessionType \
+                StdinNull \
                 StreamLocalBindMask \
                 StreamLocalBindUnlink \
                 StrictHostKeyChecking \
@@ -596,24 +662,17 @@ _ssh () {
                 Tunnel \
                 TunnelDevice \
                 UpdateHostKeys \
-                UsePrivilegedPort \
                 User \
                 UserKnownHostsFile \
                 VerifyHostKeyDNS \
                 VisualHostKey \
                 XAuthLocation \
-                \
-                AFSTokenPassing \
-                FallBackToRsh \
-                KeepAlive \
-                KerberosAuthentication \
-                KerberosTgtPassing \
-                PreferredAuthentications \
-                ProtocolKeepAlives \
-                RhostsAuthentication \
-                SetupTimeOut \
-                SmartcardDevice \
-                UseRsh \
+                GSSAPIClientIdentity \
+                GSSAPIKeyExchange \
+                GSSAPIRenewalForcesRekey \
+                GSSAPIServerIdentity \
+                GSSAPITrustDns \
+                GSSAPIKexAlgorithms \
                 && ret=0
       fi
       ;;
@@ -680,9 +739,13 @@ _ssh () {
       local -a _comp_priv_prefix
       shift 1 words
       (( CURRENT-- ))
-      _normal
+      _normal -p $service
       return
       ;;
+    destinations)
+      compset -P 1 '*>'
+      compset -S '>*'
+    ;& # fall-through
     userhost)
       if compset -P '*@'; then
         _wanted hosts expl 'remote host name' _ssh_hosts && ret=0
diff --git a/Completion/Unix/Command/_stat b/Completion/Unix/Command/_stat
index 03b4552de..03abe88a3 100644
--- a/Completion/Unix/Command/_stat
+++ b/Completion/Unix/Command/_stat
@@ -29,7 +29,7 @@ case $variant in
       '(-n)-N[never show names of files]'
       '-o[print file modes in octal rather than decimal]'
       '-r[print raw data]'
-      '-s[print mode, UID, GID, and times as strings]'
+      '(-o)-s[print mode, UID, GID, and times as strings]'
       '(-T)-t[always show type names]'
       '(-t)-T[never show type names]'
       '*: :_files'
diff --git a/Completion/Unix/Command/_stdbuf b/Completion/Unix/Command/_stdbuf
index a18938ee1..32b3cae2f 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}" )
@@ -25,6 +27,6 @@ for ((i=1;i<=3;i++)); do
     "(${short[i]})${long[i]}=${(e)opt}"
   )
 done
-(( CURRENT > 2 )) && args+=( '*::command:_normal' )
+(( CURRENT > 2 )) && args+=( '*::command: _normal -p $service' )
 
 _arguments -s -S $args
diff --git a/Completion/Unix/Command/_stgit b/Completion/Unix/Command/_stgit
deleted file mode 100644
index e31af460a..000000000
--- a/Completion/Unix/Command/_stgit
+++ /dev/null
@@ -1,52 +0,0 @@
-#compdef stg
-
-typeset -a subcmds
-
-subcmds=( ${${${(M)${(f)"$(stg help 2> /dev/null)"}## *}#  }/#(#b)([^[:space:]]##)[[:space:]]##(*)/$match[1]:$match[2]} )
-
-local curcontext="$curcontext" expl
-local subcmd
-local ret=1
-
-if (( CURRENT == 2 )); then
-  _describe -t commands 'stgit command' subcmds && ret=0
-else
-  shift words
-  (( CURRENT-- ))
-  subcmd="$words[1]"
-  curcontext="${curcontext%:*}-${subcmd}:"
-
-  case $subcmd in
-    (push)
-      _wanted -V unapplied-patches expl "patch" \
-       	compadd ${${(M)${(f)"$(stg series 2> /dev/null)"}##- *}#- } \
-		&& ret=0
-    ;;
-    (pop)
-      _wanted -V applied-patches expl "patch" \
-	compadd ${${(M)${(f)"$(stg series 2> /dev/null)"}##[+>] *}#[+>] } \
-		&& ret=0
-    ;;
-    (edit|files|goto|rename|log|float|delete|sink|mail|sync|show|pick|hide|squash)
-      _wanted -V patches expl "patch" \
-	compadd $(stg series --noprefix 2> /dev/null) \
-		&& ret=0
-    ;;
-    (ref*)
-      last_word="$words[$CURRENT-1]"
-      refresh_patch_options=( -p --patch )
-      if [[ -n ${refresh_patch_options[(r)$last_word]} ]]; then
-	_wanted -V applied-patches expl "patch" \
-	  compadd ${${(M)${(f)"$(stg series 2> /dev/null)"}##[+>] *}#[+>] } \
-		  && ret=0
-      else
-	_files && ret=0
-      fi
-    ;;
-    (*)
-      _files && ret=0
-    ;;
-  esac
-fi
-
-return ret
diff --git a/Completion/Unix/Command/_strings b/Completion/Unix/Command/_strings
index af95af52f..685daa286 100644
--- a/Completion/Unix/Command/_strings
+++ b/Completion/Unix/Command/_strings
@@ -45,7 +45,7 @@ if _pick_variant -r variant binutils=GNU elftoolchain=elftoolchain elfutils=elfu
     elfutils)
       args+=(
 	'(- *)--usage[display a short usage message]'
-	'(- *)-\\?[display help information]'
+	'(- *)-?[display help information]'
       )
     ;;
   esac
diff --git a/Completion/Unix/Command/_strip b/Completion/Unix/Command/_strip
index 3e1a6b698..cc67ae49a 100644
--- a/Completion/Unix/Command/_strip
+++ b/Completion/Unix/Command/_strip
@@ -1,55 +1,68 @@
 #compdef strip
 
-local curcontext=$curcontext state line ret=1
+local curcontext=$curcontext state line variant ret=1
 declare -A opt_args
 declare -a args
 
-if _pick_variant gnu=GNU solaris --version; then
-  if [[ -prefix @* ]]; then
-    compset -P '@'
+if _pick_variant -r variant gnu=GNU elftoolchain=elftoolchain $OSTYPE --version; then
+  case $variant in
+    gnu|elftoolchain)
+      args=(
+        '(-g -S -d --strip-debug)'{-g,-S,-d,--strip-debug}'[remove debugging symbols]'
+        '(-I --input-target)'{-I+,--input-target=}'[object code format of input]:bfd name:->bfdnames'
+        '*'{-K+,--keep-symbol=}'[keep given symbol]:symbol name'
+        '*'{-N+,--strip-symbol=}'[strip given symbol]:symbol name'
+        '(-O --output-target)'{-O+,--output-target=}'[object code format of output]:bfd name:->bfdnames'
+        '(-p --preserve-dates)'{-p,--preserve-dates}'[preserve access and modification dates]'
+        '*'{-R+,--remove-section=}'[remove given sections]:section name'
+        '(-s --strip-all)'{-s,--strip-all}'[remove all symbols]'
+        '(-w --wildcard)'{-w,--wildcard}'[permit wildcards in symbol names]'
+        '(-X --discard-locals)'{-X,--discard-locals}'[remove compiler-generated local symbols]'
+        '(-x --discard-all)'{-x,--discard-all}'[remove non-global symbols]'
+        '--only-keep-debug[remove everything except debugging information]'
+        '--strip-unneeded[remove symbols not needed for relocation processing]'
+        '(- 1 *)'{-V,--version}'[display version information and exit]'
+      )
+    ;|
+    gnu)
+      if [[ -prefix @* ]]; then
+        compset -P '@'
 
-    local expl
+        local expl
 
-    _description files expl 'command-line-options file'
-    _files "$expl[@]"
-    return
-  fi
-  args=(
-    '(-F --target)'{-F+,--target=}'[object code format to use]:bfd name:->bfdnames'
-    '(-)--help[display usage information]'
-    '(-)--info[display list of architectures and object formats]'
-    '(-I --input-target)'{-I+,--input-target=}'[object code format of input]:bfd name:->bfdnames'
-    '(-O --output-target)'{-O+,--output-target=}'[object code format of output]:bfd name:->bfdnames'
-    '(-D --enable-deterministic-archives -U --disable-deterministic-archives)'{-U,--disable-deterministic-archives}'[disable -D behavior]'
-    '(-D --enable-deterministic-archives -U --disable-deterministic-archives)'{-D,--enable-deterministic-archives}'[produce deterministic output when stripping archives (zero file metadata)]'
-    '*'{-R+,--remove-section=}'[remove given sections]:section name'
-    '--remove-relocations=[remove relocations from specified section]:section'
-    '(-s --strip-all)'{-s,--strip-all}'[remove all symbols]'
-    '(-g -S -d --strip-debug)'{-g,-S,-d,--strip-debug}'[remove debugging symbols]'
-    '--strip-dwo[remove all DWARF .dwo sections]'
-    '--strip-unneeded[remove symbols not needed for relocation processing]'
-    '!(--no-merge-notes)'{-M,--merge-notes}
-    "--no-merge-notes[don't attempt to remove redundant notes]"
-    '*'{-K+,--keep-symbol=}'[keep given symbol]:symbol name'
-    '*'{-N+,--strip-symbol=}'[strip given symbol]:symbol name'
-    "*--keep-section=[don't strip given section]:section"
-    '(*)-o+[output file]:output file:_files'
-    '(-p --preserve-dates)'{-p,--preserve-dates}'[preserve access and modification dates]'
-    '(-w --wildcard)'{-w,--wildcard}'[permit wildcards in symbol names]'
-    '(-x --discard-all)'{-x,--discard-all}'[remove non-global symbols]'
-    '(-X --discard-locals)'{-X,--discard-locals}'[remove compiler-generated local symbols]'
-    '--keep-file-symbols[retain symbols specifying source file names]'
-    '--only-keep-debug[remove everything except debugging information]'
-    '(-)'{-V,--version}'[display version information and exit]'
-    '(-v --verbose)'{-v,--verbose}'[list all object files modified or members of archives]')
-else
-  case $OSTYPE in
+        _description files expl 'command-line-options file'
+        _files "$expl[@]"
+        return
+      fi
+      args+=(
+        '(-F --target)'{-F+,--target=}'[object code format to use]:bfd name:->bfdnames'
+        '(-)--help[display usage information]'
+        '(-)--info[display list of architectures and object formats]'
+        '(-D --enable-deterministic-archives -U --disable-deterministic-archives)'{-U,--disable-deterministic-archives}'[disable -D behavior]'
+        '(-D --enable-deterministic-archives -U --disable-deterministic-archives)'{-D,--enable-deterministic-archives}'[produce deterministic output when stripping archives (zero file metadata)]'
+        '--remove-relocations=[remove relocations from specified section]:section'
+        '--strip-dwo[remove all DWARF .dwo sections]'
+        '!(--no-merge-notes)'{-M,--merge-notes}
+        "--no-merge-notes[don't attempt to remove redundant notes]"
+        "*--keep-section=[don't strip given section]:section"
+        '(*)-o+[output file]:output file:_files'
+        '--keep-section-symbols[retain section symbols]'
+        '--keep-file-symbols[retain symbols specifying source file names]'
+        '(-v --verbose)'{-v,--verbose}'[list all object files modified or members of archives]')
+    ;;
+    elftoolchain)
+      args+=(
+        '(- 1 *)'{-h,--help}'[display usage information]'
+        '(*)'{-o+,--output-file=}'[specify output file]:output file:_files'
+      )
+    ;;
     solaris*)
       args=(
 	'-l[strip line information only]'
 	'-V[display version information on stderr and exit]'
-	'-x[do not strip the symbol table]')
-      ;;
+	'-x[do not strip the symbol table]'
+      )
+    ;;
     darwin*)
       local -a arch
       arch=( ${(z)${${"$(_call_program architectures
@@ -73,12 +86,13 @@ else
 	'-no_uuid[remove only LC_UUID load command]'
 	'-no_split_info[remove LC_SEGMENT_SPLIT_INFO load command]'
 	'-no_code_signature_warning[not warn when code signature would be invalid in the output]'
-	'-arch[specify the architecture]:architecture:( $arch )' )
-      ;;
+	'-arch[specify the architecture]:architecture:( $arch )'
+      )
+    ;;
   esac
 fi
 
-_arguments \
+_arguments -C \
   $args \
   '1:executable:_files -g "*(-*)"' \
   '*::executable:_files -g "*(-*)"' && ret=0
diff --git a/Completion/Unix/Command/_subversion b/Completion/Unix/Command/_subversion
index 26eef500f..ccaf310fa 100644
--- a/Completion/Unix/Command/_subversion
+++ b/Completion/Unix/Command/_subversion
@@ -68,7 +68,6 @@ _svn () {
     ;;
     args)
       local cmd args usage idx
-      typeset -gHA _cache_svn_status _cache_svn_mtime
 
       cmd="${${(k)_svn_cmds[(R)*:$words[1]:*]}:-${(k)_svn_cmds[(i):$words[1]:]}}"
       if (( $#cmd )); then
@@ -123,7 +122,7 @@ _svn () {
         case $cmd in;
           (add)
             args+=(
-              '*:file:_files -g "*(e:_svn_uncontrolled:)"'
+              '*:file: _svn_modified "addable"'
             )
           ;;
           (auth)
@@ -140,18 +139,18 @@ _svn () {
           ;;
           (commit)
             args=(
-	      ${args/(#b)(*--file*):arg:/$match[1]:file:_files}
-              '*:file:_files -g "*(e:_svn_status:)"'
+	      ${args/(#b)(*--file*):arg:/${match[1]}:file:_files}
+              '*:file: _svn_modified "committable"'
             )
           ;;
           (delete)
             args+=(
-              '*:file:_files -g ".svn(/e:_svn_deletedfiles:)"'
+              '*:file:_files -g "*(e:_svn_controlled:)"'
             )
           ;;
           (diff)
             args+=(
-	      '*: : _alternative "files:file:_files -g \*\(e:_svn_status:\)" "urls:URL:_svn_urls"'
+	      '*: : _alternative "files:file: _svn_modified revertable" "urls:URL:_svn_urls"'
 	    )
           ;;
           (help)
@@ -190,7 +189,7 @@ _svn () {
 	    args=(
 	    ':propname:(svn:ignore svn:keywords svn:executable svn:eol-style svn:mime-type svn:externals svn:needs-lock svn:global-ignores svn:auto-props)'
 	    ':propval:->propset_propval'
-	    ${args/(#b)(*--file*):arg:/$match[1]:file:_files}
+	    ${args/(#b)(*--file*):arg:/${match[1]}:file:_files}
 	    '*:path or url: _alternative "files:file:_files" "urls:URL:_svn_urls"'
 	    )
 	  ;;
@@ -201,7 +200,7 @@ _svn () {
           ;;
           (revert)
             args+=(
-              '*:file:_files -g "(.svn|*)(/e:_svn_deletedfiles:,e:_svn_status:)"'
+              '*:file: _svn_modified "revertable"'
             )
           ;;
           (x-unshelve)
@@ -319,6 +318,9 @@ _svnadmin () {
           # Test cases:
           #   svnadmin freeze . rsync --<TAB> offers --file
           #   svnadmin freeze -- . rsync -<TAB> offers rsync's options
+          #   svnadmin freeze . -- rsync -<TAB> should do the same (but currently doesn't)
+          #
+          # TODO: Fix the third case.
           #
           # Note: the NORMARG calculations here include one positional argument
           # (the '.') before the command.
@@ -351,50 +353,76 @@ _svn_controlled() {
   # because 1.6 has been deprecated for 8 years and EOL for 6 years, we opt to DTRT
   # for >=1.7.  Therefore:
 
-  # TODO: Reimplement this function and _svn_uncontrolled for svn>=1.7.
+  # TODO: Reimplement this function for svn>=1.7.
   # (Use 'svn st' or 'svn info', not 'svn ls')
   return 0
 }
 
 
-(( $+functions[_svn_uncontrolled] )) ||
-_svn_uncontrolled() {
-  # TODO: See comments in _svn_controlled
-  return 0
-}
-
 (( $+functions[_svn_conflicts] )) ||
 _svn_conflicts() {
-  () { (( $# > 0 )) } $REPLY.(mine|r<->)(NY1)
+  # ### These strings are actually translatable
+  #
+  # The asterisks are to support an optional extension; see
+  # "preserved-conflict-file-exts" in ~/.subversion/config.
+  () { (( $# > 0 )) } $REPLY.(mine|r<->|working*|merge-left*|merge-right*)(NY1)
 }
 
-(( $+functions[_svn_deletedfiles] )) ||
-_svn_deletedfiles() {
-  # Typical usage would be _files -g '.svn(/e:_svn_deletedfiles:)'
-  local cont controlled
-  reply=( )
-  [[ $REPLY = (*/|).svn ]] || return
-  controlled=( $REPLY/text-base/*.svn-base(N:r:t) )
-  for cont in ${controlled}; do
-    [[ -e $REPLY:h/$cont ]] || reply+=( ${REPLY%.svn}$cont )
-  done
-}
+(( $+functions[_svn_modified] )) ||
+_svn_modified() {
+  setopt localoptions extendedglob
 
-(( $+functions[_svn_status] )) ||
-_svn_status() {
-  local dir=$REPLY:h
-  local pat="${1:-([ADMR~]|?M)}"
+  local depth dir expl maybe_quiet partial_word space=' '
 
-  zmodload -F zsh/stat b:zstat 2>/dev/null
-  local key="$(zstat +device $dir):$(zstat +inode $dir)"
-  local mtime="$(zstat +mtime $dir/.svn/entries)"
+  local svn_context=$1
 
-  if (( ! $+_cache_svn_status[$key] || _cache_svn_mtime[$key] != mtime )); then
-    _cache_svn_status[$key]="$(_call_program files svn status -N $dir)"
-    _cache_svn_mtime[$key]="$mtime"
+  local partial_word=${(Q)words[CURRENT]}
+  if [[ -z $partial_word ]]; then
+    dir="./"
+  elif [[ -d $partial_word ]]; then
+    dir=$partial_word
+  else
+    dir=${partial_word:h}
   fi
 
-  (( ${(M)#${(f)_cache_svn_status[$key]}:#(#s)${~pat}*$REPLY} ))
+  if zstyle -T ":completion:${curcontext}:${curtag}" verbose; then
+    depth=infinity
+  else
+    depth=immediates
+  fi
+
+  if [[ $svn_context = addable ]]; then
+    maybe_quiet=""
+  else
+    maybe_quiet="-q"
+  fi
+
+  local -a status_lines
+  # Run 'status'
+  status_lines=( ${(f)"$(_call_program modified-files "svn status $maybe_quiet --depth=${(q)depth} -- ${(q)dir}")"} )
+  # Filter to only the right set of statuses
+  case $svn_context in
+    (committable)
+      status_lines=( ${(M)status_lines:#(#s)([ADMR]?|?M)${space}???${space}${space}*} )
+      ;;
+    (revertable)
+      status_lines=( ${(M)status_lines:#(#s)([ACDMR~!]?|?[CM])${space}????${space}*} )
+      ;;
+    (addable)
+      # The 'D' is just in case there's an unversioned file of the same name as the deleted file
+      status_lines=( ${(M)status_lines:#(#s)[?ID]${space}${space}???${space}${space}*} )
+      ;;
+  esac
+  # Strip the 7 status-letter columns and the column of spaces
+  status_lines=( ${status_lines#????????} )
+  # Strip one leading space.  This is in case `svn status` ever adds another
+  # column.  If that hasn't happened and you're reading this comment because
+  # the following line broke your use of filenames that start with a literal
+  # space, well, nice to meet you!  I didn't know you existed.
+  status_lines=( ${status_lines#${space}} )
+
+  _wanted svn-modified expl 'modified files in svn' \
+    compadd - "${status_lines[@]}"
 }
 
 (( $+functions[_svn_remote_paths] )) ||
diff --git a/Completion/Unix/Command/_sudo b/Completion/Unix/Command/_sudo
index 29e5e6d75..c334c6765 100644
--- a/Completion/Unix/Command/_sudo
+++ b/Completion/Unix/Command/_sudo
@@ -1,9 +1,7 @@
 #compdef sudo sudoedit
 
-setopt localoptions extended_glob
-
-local environ e cmd cpp
-local -a args _comp_priv_prefix
+local curcontext="$curcontext" environ e cmd cpp ret=1
+local -a context state line args _comp_priv_prefix
 local -A opt_args
 
 zstyle -a ":completion:${curcontext}:" environ environ
@@ -20,20 +18,21 @@ args=(
   '(-g --group)'{-g+,--group=}'[run command as the specified group name or ID]:group:_groups'
   '(-)'{-h,--help}'[display help message and exit]'
   '(-h --host)'{-h+,--host=}'[run command on host]:host:_hosts'
-  '(-K --remove-timestamp)'{-K,--remove-timestamp}'[remove timestamp file completely]'
-  '(-k --reset-timestamp)'{-k,--reset-timestamp}'[invalidate timestamp file]'
+  '(-k --reset-timestamp -K --remove-timestamp -N --no-update)'{-K,--remove-timestamp}'[remove timestamp file completely]'
+  '(-k --reset-timestamp -K --remove-timestamp -N --no-update)'{-k,--reset-timestamp}'[invalidate timestamp file]'
   \*{-l,--list}"[list user's privileges or check a specific command]"
   '(-n --non-interactive)'{-n,--non-interactive}'[non-interactive mode, no prompts are used]'
+  '(-k --reset-timestamp -K --remove-timestamp -N --no-update)'{-N,--no-update}"[don't update user's cached credentials]"
   '(-p --prompt)'{-p+,--prompt=}'[use the specified password prompt]:prompt'
   '(-R --chroot)'{-R+,--chroot=}'[change the root directory before running command]:directory:_directories'
   '(-r --role)'{-r+,--role=}'[create SELinux security context with specified role]: :_selinux_roles'
   '(-S --stdin)'{-S,--stdin}'[read password from standard input]'
   '(-t --type)'{-t+,--type=}'[create SELinux security context with specified type]: :_selinux_types'
   '(-T --command-timeout)'{-T+,--command-timeout=}'[terminate command after specified time limit]:timeout'
-  '(-U --other-user)'{-U+,--other-user=}'[in list mode, display privileges for user]:user:_users'
+  '(-U --other-user -v --validate)'{-U+,--other-user=}'[in list mode, display privileges for user]:user:_users'
   '(-u --user)'{-u+,--user=}'[run command (or edit file) as specified user]:user:_users'
   '(-)'{-V,--version}'[display version information and exit]'
-  '(-v --validate)'{-v,--validate}"[update user's timestamp without running a command]"
+  '(-v --validate -U --other-user *)'{-v,--validate}"[update user's timestamp without running a command]"
 )
 
 # Does -e appears before the first word that doesn't begin with a hyphen?
@@ -45,10 +44,6 @@ if [[ $service = sudoedit ]] || (( $words[(i)-e] < $words[(i)^(*sudo|-[^-]*)] ))
   args=( -A "-*" $args '!(-V --version -h --help)-e' '*:file:_files' )
 else
   cmd="$words[1]"
-  cpp='_comp_priv_prefix=(
-    $cmd -n
-    ${(kv)opt_args[(I)(-[ugHEP]|--(user|group|set-home|preserve-env|preserve-groups))]}
-  )'
   args+=(
     '(-e --edit 1 *)'{-e,--edit}'[edit files instead of running a command]' \
     '(-s --shell)'{-s,--shell}'[run shell as the target user; a command may also be specified]' \
@@ -58,9 +53,40 @@ else
     '(-E -i --login -s --shell -e --edit)--preserve-env=-[preserve user environment when running command]::environment variable:_sequence _parameters -g "*export*"' \
     '(-H --set-home -i --login -s --shell -e --edit)'{-H,--set-home}"[set HOME variable to target user's home dir]" \
     '(-P --preserve-groups -i -login -s --shell -e --edit)'{-P,--preserve-groups}"[preserve group vector instead of setting to target's]" \
-    "(-)1: :{ $cpp; _command_names -e }"
-    "*:: :{ $cpp; _normal }"
+    '*:: :->normal'
+  )
+fi
+
+_arguments -s -S $args && ret=0
+
+if [[ $state = normal ]]; then
+  _comp_priv_prefix=(
+    $cmd -n
+    ${(kv)opt_args[(I)(-[ugHEP]|--(user|group|set-home|preserve-env|preserve-groups))]}
   )
+  if (( $+opt_args[-l] || $+opt_args[--list] )); then
+    _normal -p $service
+    return
+  fi
+  while [[ $words[1] = *=* ]]; do
+    if (( CURRENT == 1 )); then
+      compstate[parameter]="${PREFIX%%\=*}"
+      compset -P 1 '*='
+      _value && ret=0
+      return ret
+    fi
+    shift words
+    (( CURRENT-- ))
+  done
+  if (( CURRENT == 1 )); then
+    curcontext="${curcontext%:*:*}:-command-:"
+    _alternative \
+      'commands:: _command_names -e' \
+      'options:option:(-s --shell -l --login)' \
+      'parameters: :_parameters -g "*export*~*readonly*" -qS=' && ret=0
+  else
+    _normal
+  fi
 fi
 
-_arguments -s -S $args
+return ret
diff --git a/Completion/Unix/Command/_sysctl b/Completion/Unix/Command/_sysctl
index 0416ca05e..442953c4d 100644
--- a/Completion/Unix/Command/_sysctl
+++ b/Completion/Unix/Command/_sysctl
@@ -28,6 +28,12 @@ case $OSTYPE in
       '(- :)'{-V,--version}'[display version info and exit]' \
       '*:sysctl variable:_files -W /proc/sys'
   ;;
+  freebsd<14->.*)
+    args+=(
+      '-F[print the format of the variable]'
+      '(-N)-l[show the length of variables along with their values]'
+    )
+  ;|
   freebsd<11->.*)
     args+=(
       '-B[specify buffer size for reading]:buffer size'
@@ -53,7 +59,7 @@ case $OSTYPE in
       '-d[print the description of the variable instead of its value]' \
       '(-N -n)-e[separate name and value with =]' \
       "-i[silently exit if variable doesn't exist]" \
-      '(-n)-N[show only variable names]' \
+      '(-n -l)-N[show only variable names]' \
       '(-N)-n[show only variable values]' \
       '(-x)-o[show opaques as well (values suppressed)]' \
       '-q[suppress some warnings]' \
diff --git a/Completion/Unix/Command/_tail b/Completion/Unix/Command/_tail
index 6d6e9b2d5..f8006abbc 100644
--- a/Completion/Unix/Command/_tail
+++ b/Completion/Unix/Command/_tail
@@ -16,6 +16,7 @@ if _pick_variant gnu=GNU unix --version; then
     '(-q --quiet --silent -v --verbose)'{-q,--quiet,--silent}'[never output headers giving file names]'
     '(-q --quiet --silent -v --verbose)'{-v,--verbose}'[always output headers giving file names]'
     '--retry[keep trying to open a file even when it becomes inaccessible]'
+    '(-z --zero-terminated)'{-z,--zero-terminated}'[line delimiter is NUL, not newline]'
     '(- *)--help[display help and exit]'
     '(- *)--version[output version information and exit]'
   )
@@ -53,20 +54,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/_tar b/Completion/Unix/Command/_tar
index f9901c0c9..1cabd9713 100644
--- a/Completion/Unix/Command/_tar
+++ b/Completion/Unix/Command/_tar
@@ -158,7 +158,7 @@ elif [[ ( "$_tar_cmd" = *[xt]* || -n $del ) && -n "$tf" ]]; then
   fi
 
   if [[ $tf != $_tar_cache_name && -f $tf ]]; then
-    _tar_cache_list=("${(@f)$($words[1] $largs $tf)}")
+    _tar_cache_list=("${(@f)$($words[1] ${words[(r)--force-local]} $largs $tf)}")
     _tar_cache_name=$tf
   fi
 
diff --git a/Completion/Unix/Command/_tex b/Completion/Unix/Command/_tex
index 9943fe10c..1a70b5058 100644
--- a/Completion/Unix/Command/_tex
+++ b/Completion/Unix/Command/_tex
@@ -1,4 +1,4 @@
-#compdef tex latex slitex pdftex pdflatex jadetex pdfjadetex xetex=tex xelatex=latex latexmk
+#compdef tex latex slitex pdftex pdflatex jadetex pdfjadetex xetex=tex xelatex=latex latexmk lualatex
 
 _arguments : \
     '-enc[enable encTeX extensions]' \
@@ -26,4 +26,4 @@ _arguments : \
     '-8bit[make all characters printable by default]' \
     '-help[display this help and exit]' \
     '-version[output version information and exit]' \
-    '*:TeX or LaTeX file:_files -g "*.(tex|TEX|texinfo|texi)(-.)"'
+    '*:TeX or LaTeX file:_files -g "*.(tex|TEX|texinfo|texi|dtx)(-.)"'
diff --git a/Completion/Unix/Command/_texinfo b/Completion/Unix/Command/_texinfo
index 7dfa32e45..2f5d0f91f 100644
--- a/Completion/Unix/Command/_texinfo
+++ b/Completion/Unix/Command/_texinfo
@@ -41,7 +41,7 @@ case $service in
       '(: -)'{-k+,--apropos=}'[look up string in indices]:search string: ' \
       \*{-d+,--directory=}'[add directory to infopath]:info dir:_files -/' \
       '--dribble=[record keystrokes]:file with keystrokes:_files' \
-      '(-f --file 1)'{-f+,--file=}'[specify Info manual to visit]:info manual:->infofiles' \
+      '(-f --file 1)'{-f+,--file=}'[specify Info manual to visit]:info manual:->infofiles+' \
       '(: - -h --help)'{-h,--help}'[display usage]' \
       '(-o --output -O)--index-search=[search for matching index entry]:search string:->index-entries' \
       '(--index-search -o --output -O)'{-o+,--output=}'[dump selected nodes to filename]:filename:_files -g "*(-.)"' \
@@ -289,7 +289,11 @@ if [[ -n $state ]]; then
     items=( ${${${(M)${(f)"$(_call_program menu-items info -o-)"}:#(#s)\* *: \(*}#??}%%\)*} )
     files+=( ${items##*\(} )
     tags=( info-files )
-    if [[ $state != infofiles ]]; then
+    if [[ $state = infofiles+ && $PREFIX$SUFFX = */* ]]; then
+      # local files allowed
+      tags+=(files)
+    fi
+    if [[ $state != infofiles* ]]; then
       tags+=( menu-items )
       items=( ${items%:*} )
     fi
@@ -317,6 +321,7 @@ if [[ -n $state ]]; then
     _requested menu-items expl 'menu item' compadd -M 'm:{a-zA-Z}={A-Za-z}' -a items && ret=0
     _requested -x index-entries expl 'index entry' compadd -M 'm:{a-zA-Z}={A-Za-z}' -a items && ret=0
     _requested info-nodes expl 'node' compadd -M 'm:{a-zA-Z}={A-Za-z}' ${nodes#*:} && ret=0
+    _requested files expl 'file' && _files -g '*.info(|.gz|.bz2)'
 
     (( ret )) || break
   done
diff --git a/Completion/Unix/Command/_tiff b/Completion/Unix/Command/_tiff
index ef12777de..1aeff3ff7 100644
--- a/Completion/Unix/Command/_tiff
+++ b/Completion/Unix/Command/_tiff
@@ -159,6 +159,7 @@ tiffinfo)
     '-f+[force fill order]:fill order:(lsb2msb msb2lsb)' \
     '-w[display raw data in words]' \
     '-z[enable strip chopping]' \
+    '-M+[set the memory allocation limit]:limit (MiB), 0 for unlimited' \
     '*:input TIFF file:_files -g "*.(#i)tif(|f)(-.)"' && ret=0
   ;;
 tiffmedian)
@@ -172,6 +173,7 @@ tiffmedian)
   ;;
 tiffsplit)
   _arguments \
+    '-M+[set the memory allocation limit]:limit (MiB), 0 for unlimited' \
     ':input file:_files -g "*.(#i)tif(|f)(-.)"' \
     ':output file prefix' && ret=0
   ;;
diff --git a/Completion/Unix/Command/_timeout b/Completion/Unix/Command/_timeout
index 223059e4d..9c7f1a004 100644
--- a/Completion/Unix/Command/_timeout
+++ b/Completion/Unix/Command/_timeout
@@ -2,8 +2,8 @@
 
 local args
 
-if [[ $service = g* || $OSTYPE != *(freebsd|netbsd)* ]]; then
-  # GNU coreutils or DFly as opposed to Free/NetBSD implementation
+if [[ $service = g* || $OSTYPE != *(freebsd|netbsd|openbsd)* ]]; then
+  # GNU coreutils or DFly as opposed to Free/Net/OpenBSD implementation
   args=(
     '(-v --verbose)'{-v,--verbose}'[indicate when signal is sent upon timeout]'
     '(- *)--help[display usage information]'
@@ -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' \
-  '*:::command:_normal'
+  '1: :_numbers -f -u seconds duration :s:seconds m:minutes h:hours d:days' \
+  '*:::command: _normal -p $service'
diff --git a/Completion/Unix/Command/_tmux b/Completion/Unix/Command/_tmux
index 844af58fc..b9c220f17 100644
--- a/Completion/Unix/Command/_tmux
+++ b/Completion/Unix/Command/_tmux
@@ -130,6 +130,8 @@ _tmux_aliasmap=(
     popup       display-popup
 
     # buffers
+    clearphist  clear-prompt-history
+    showphist   show-prompt-history
     clearhist   clear-history
     deleteb     delete-buffer
     lsb         list-buffers
@@ -143,7 +145,6 @@ _tmux_aliasmap=(
     if          if-shell
     lock        lock-server
     run         run-shell
-    info        server-info
     wait        wait-for
 )
 
@@ -267,6 +268,11 @@ _tmux-clear-history() {
   _arguments '-t+[specify target pane]:pane:__tmux-panes'
 }
 
+_tmux-clear-prompt-history() {
+  [[ -n ${tmux_describe} ]] && print "remove history of values for command line prompts" && return
+  _arguments '-T+[specify prompt type]:prompt type:(command search target window-target)'
+}
+
 _tmux-clock-mode() {
   [[ -n ${tmux_describe} ]] && print "enter clock mode" && return
   _arguments '-t+[specify target pane]:pane:__tmux-panes'
@@ -282,8 +288,7 @@ _tmux-command-prompt() {
     '-I+[specify list of initial inputs]:initial-text (comma-separated list)' \
     '-p+[specify list of prompts]:prompts (comma-separated list)' \
     '-t+[specify target client]:client:__tmux-clients' \
-    '(-W)-T[prompt is for a target - tab complete as appropriate]' \
-    '(-T)-W[prompt is for a window - tab complete as appropriate]' \
+    '-T+[specify prompt type]:prompt type:(command search target window-target)' \
     '*:::template:= _tmux'
 }
 
@@ -388,13 +393,19 @@ _tmux-display-panes() {
 _tmux-display-popup() {
   [[ -n ${tmux_describe} ]] && print "display a popup box over a pane" && return
   _arguments -s \
+    "-B[don't surround the popup by a border]" \
     '-C[close any popup on the client]' \
     '-c+[specify target client]:client:__tmux-clients' \
     '-d+[specify working directory for the command]:directory:_directories' \
+    '*-e[specify environment variable]:environment variable:_parameters -g "*export*" -qS=' \
     '-E[close the popup when the command exits]' \
+    '(-E)-EE[only close the popup when the command exits successfully]' \
     '-w+[specify width]:width' \
     '-h+[specify height]:height' \
+    '-s+[specify the style for the popup]:style:__tmux-style' \
+    '-S+[specify the style for the popup border]:style:__tmux-style' \
     '-t+[specify target pane]:pane:__tmux-panes' \
+    '-T+[specify popup title (supports formats)]:format:__tmux-formats' \
     '-x+[specify horizontal position]:position' \
     '-y+[specify vertical position]:position' \
     ':shell command:_cmdstring'
@@ -865,7 +876,11 @@ _tmux-send-prefix() {
     '-t+[specify target pane]:pane:__tmux-panes'
 }
 
-_tmux-server-info() {
+# NOTE: this is actually an alias for "show-messages -JT", but until the
+# aliasmap system in check-tmux-state can properly handle aliases which are
+# more complex than a single word, it's best to leave this here.
+
+_tmux-server-access() {
   [[ -n ${tmux_describe} ]] && print "show server information" && return
   __tmux-nothing-else
 }
@@ -1041,6 +1056,11 @@ _tmux-show-options() {
   return ret
 }
 
+_tmux-show-prompt-history() {
+  [[ -n ${tmux_describe} ]] && print "show status prompt history" && return
+  _arguments '-T+[specify prompt type]:prompt type:(command search target window-target)'
+}
+
 _tmux-show-window-options() {
   [[ -n ${tmux_describe} ]] && print "show window options" && return
   local curcontext="$curcontext" state line ret=1
@@ -1530,7 +1550,6 @@ function __tmux-option-guard() {
             'status-right-style:__tmux-style'
             'status-style:__tmux-style'
             'update-environment:MSG:string listing env. variables'
-            'user-keys:MSG:key'
             'visual-activity:DESC:on off'
             'visual-bell:DESC:on off'
             'visual-silence:DESC:on off'
@@ -1549,6 +1568,7 @@ function __tmux-option-guard() {
             'message-limit:'${int_guard}
             'set-clipboard:DESC:on off'
             'terminal-overrides:MSG:overrides string'
+            'user-keys:MSG:key'
         )
     else
         options=(
@@ -1633,6 +1653,7 @@ function __tmux-session-options() {
         'lock-after-time:lock sessions after N seconds'
         'lock-command:command to run for locking a client'
         'message-command-style:status line message command style'
+        'message-line:status message and command prompt position'
         'message-style:status line message style'
         'mouse:enable mouse support'
         'prefix:primary prefix key'
@@ -1643,6 +1664,8 @@ function __tmux-session-options() {
         'set-titles-string:format used by set-titles'
         'silence-action:set action on window silence when monitor-silence is on'
         'status:show or hide the status bar'
+        'status-bg:set the background style used by the status bar'
+        'status-fg:set the foreground style used by the status bar'
         'status-format:specify the format to be used for each line of the status line'
         'status-interval:interval (in seconds) for status bar updates'
         'status-justify:position of the window list in status bar'
@@ -1656,7 +1679,6 @@ function __tmux-session-options() {
         'status-right-style:style of right part of status line'
         'status-style:style status line'
         "update-environment:list of variables to be copied to a session's environment"
-        'user-keys:set list of user-defined key escape sequences'
         'visual-activity:display status line messages upon activity'
         'visual-bell:use visual bell instead of audible'
         'visual-silence:print a message if monitor-silence is on'
@@ -1701,20 +1723,28 @@ function __tmux-panes() {
     fi
 }
 
+
 function __tmux-server-options() {
     local -a tmux_server_options
     tmux_server_options=(
+        'backspace:set key sent by tmux for backspace'
         'buffer-limit:number of buffers kept per session'
         'command-alias:custom command aliases'
+        'copy-command:specify the default command when "copy-pipe" is called without arguments'
         'default-terminal:default terminal definition string'
         'escape-time:set timeout to detect single escape characters (in msecs)'
+        'editor:specify the command used when tmux runs an editor'
         'exit-unattached:make server exit if it has no attached clients'
         'exit-empty:exit when there are no active sessions'
+        'extended-keys:control whether tmux will send extended keys through to the terminal'
         'focus-events:request focus events from terminal'
         'history-file:tmux command history file name'
         'message-limit:set size of message log per client'
+        'prompt-history-limit:set the number of history items to save in the history file'
         'set-clipboard:use esc sequences to set terminal clipboard'
+        'terminal-features:set terminal features not detected by terminfo'
         'terminal-overrides:override terminal descriptions'
+        'user-keys:set list of user-defined key escape sequences'
     )
     _describe -t tmux-server-options 'tmux server option' tmux_server_options
 }
@@ -1768,14 +1798,25 @@ function __tmux-window-options() {
     local -a tmux_window_options
     tmux_window_options=(
         'aggressive-resize:aggressively resize windows'
+        'allow-passthrough:allow programs in the pane to bypass tmux'
         'allow-rename:allow programs to change window titles'
         'alternate-screen:allow alternate screen feature to be used'
-        'automatic-rename:attempt to automatically rename windows'
         'automatic-rename-format:format for automatic renames'
+        'automatic-rename:attempt to automatically rename windows'
         'clock-mode-colour:set clock colour'
         'clock-mode-style:set clock hour format (12/24)'
+        'copy-mode-current-match-style:set the style of the current search match in copy mode'
+        'copy-mode-mark-style:set the style of the line containing the mark in copy mode'
+        'copy-mode-match-style:set the style of search matches in copy mode'
+        'cursor-colour:set the colour of the cursor'
+        'cursor-style:set the style of the cursor'
+        'fill-character:set the character used to fill unused window areas'
         'main-pane-height:set height for main-* layouts'
         'main-pane-width:set width for main-* layouts'
+        'menu-style:set the menu style'
+        'menu-selected-style:set the selected menu item style'
+        'menu-border-style:set the menu border style'
+        'menu-border-lines:set the type of characters used for drawing menu borders'
         'mode-keys:mode to use in copy and choice modes (vi/emacs)'
         'mode-style:set window modes style'
         'monitor-activity:monitor window activity'
@@ -1786,11 +1827,20 @@ function __tmux-window-options() {
         'pane-active-border-style:style of border of active pane'
         'pane-base-index:integer at which to start indexing panes'
         'pane-border-format:set pane border format string'
+        'pane-border-indicators:set the indicator style for the active pane in a two pane split'
+        'pane-border-lines:set the type of characters used for drawing pane borders'
         'pane-border-status:turn border status off or set its position'
         'pane-border-style:style of border pane'
+        "pane-colours:an array used to configure tmux's colour palette"
+        'popup-border-lines:set the type of line used to draw popup borders'
+        "popup-border-style:set the style for the popup's border"
+        'popup-style:set the popup style'
         "remain-on-exit:don't destroy windows after the program exits"
+        "remain-on-exit-format:set the text shown at bottom of exited panes"
+        'scroll-on-clear:scroll previous contents into history before clear'
         'synchronize-panes:send input to all panes of a window'
         'window-active-style:style of active window'
+        'window-size:indicate how to automatically size windows'
         'window-status-activity-style:style of status bar activity tag'
         'window-status-bell-style:style of status bar bell tag'
         'window-status-current-format:set status line format for active window'
@@ -1799,7 +1849,6 @@ function __tmux-window-options() {
         'window-status-last-style:style of last window in status bar'
         'window-status-separator:separator drawn between windows in status line'
         'window-status-style:general status bar style'
-        'window-size:indicate how to automatically size windows'
         'window-style:style of window'
         'wrap-search:search wrap around at the end of a pane'
         'xterm-keys:generate xterm-style function key sequences'
diff --git a/Completion/Unix/Command/_todo.sh b/Completion/Unix/Command/_todo.sh
index 99b6bb695..fc84ee076 100644
--- a/Completion/Unix/Command/_todo.sh
+++ b/Completion/Unix/Command/_todo.sh
@@ -74,7 +74,7 @@ case $state in
     "replace:replace in NUMBER the TEXT."
     "remdup:remove exact duplicates from todo.txt."
     "report:adds the number of open and done items to report.txt."
-    "showhelp:list the one-line usage of all built-in and add-on actions."
+    "shorthelp:list the one-line usage of all built-in and add-on actions."
   )
   _describe -t todo-commands 'todo.sh command' cmdlist
   ;;
@@ -97,7 +97,7 @@ case $state in
 	;;
 	(replace)
 	item=${words[CURRENT-1]##0##}
-	compadd -Q -- "${(qq)$(todo.sh -p list "^[ 0]*$item " | sed '/^--/,$d')##<-> (\([A-Z]\) |)}"
+	compadd -Q -- "${(qq)$(todo.sh -p command list "^[ 0]*$item " | sed '/^--/,$d')##<-> (\([A-Z]\) |)}"
 	;;
       esac
     fi
@@ -144,7 +144,7 @@ case $nextstate in
   ;;
 
   (item)
-  itemlist=(${${(M)${(f)"$(todo.sh -p list | sed '/^--/,$d')"}##<-> *}/(#b)(<->) (*)/${match[1]}:${match[2]}})
+  itemlist=(${${(M)${(f)"$(todo.sh -p command list | sed '/^--/,$d')"}##<-> *}/(#b)(<->) (*)/${match[1]}:${match[2]}})
   _describe -t todo-items 'todo item' itemlist
   ;;
 
@@ -173,6 +173,6 @@ case $nextstate in
   # the + or @ (which may not even be there yet).
   compset -P '*[[:space:]]'
   _wanted search expl $projmsg \
-    compadd $(todo.sh lsprj) $(todo.sh lsc)
+    compadd $(todo.sh command listproj) $(todo.sh command listcon)
   ;;
 esac
diff --git a/Completion/Unix/Command/_top b/Completion/Unix/Command/_top
index af3deb6c7..692df790d 100644
--- a/Completion/Unix/Command/_top
+++ b/Completion/Unix/Command/_top
@@ -96,7 +96,7 @@ case $OSTYPE in
       '-C[show command arguments as well as process name]'
       '-g+[filter processes by the specified string]:string'
       '-o+[sort process display by the specified field]:field:->sortkey'
-      '-T+[filter processes by the specified routing table]:routing table'
+      '-T+[filter processes by the specified routing table]:routing table:_routing_tables'
       '-U+[filter processes by the specified user]: :_users -M "L\:|-="'
     );;
   darwin*)
diff --git a/Completion/Unix/Command/_touch b/Completion/Unix/Command/_touch
index 9b9144756..47190c579 100644
--- a/Completion/Unix/Command/_touch
+++ b/Completion/Unix/Command/_touch
@@ -28,7 +28,7 @@ case $variant in
   darwin*|dragonfly*|freebsd*|netbsd*)
     args+=( '-h[act on symbolic links themselves]' )
   ;|
-  dragonfly*|freebsd*|openbsd*|solaris*)
+  darwin*|dragonfly*|freebsd*|openbsd*|solaris*)
     args+=( '(-r -t 1)-d+[use specified date/time]:date/time' )
   ;|
   darwin*|dragonfly*|freebsd*|netbsd*|solaris*)
diff --git a/Completion/Unix/Command/_tr b/Completion/Unix/Command/_tr
index 1cfe1200a..6d899431c 100644
--- a/Completion/Unix/Command/_tr
+++ b/Completion/Unix/Command/_tr
@@ -16,6 +16,7 @@ case $variant in
       '(-c -C --complement)'{-c,-C,--complement}"${descr[-c]}"
       '(-d --delete 2)'{-d,--delete}"${descr[-d]}"
       '(-s --squeeze-repeats)'{-s,--squeeze-repeats}"${descr[-s]}"
+      '(-t --truncate-set1)'{-t,--truncate-set1}'[first truncate ARRAY1 to length of ARRAY2]'
       '(- 1 2)--help[display help information]'
       '(- 1 2)--version[display version information]'
     )
diff --git a/Completion/Unix/Command/_trash b/Completion/Unix/Command/_trash
new file mode 100644
index 000000000..bef6e5838
--- /dev/null
+++ b/Completion/Unix/Command/_trash
@@ -0,0 +1,57 @@
+#compdef trash
+
+local variant
+
+_pick_variant -r variant ali='(Rantakari|hasseg)' steven='(Steven|vanZyl)' other --version
+
+case $variant in
+  ali)
+    # The hidden options here are options to rm that trash silently (and
+    # undocumentedly) ignores. Some options are not made mutually exclusive where
+    # they technically could be, for compatibility with aliases, etc.
+    _arguments -s -S -A '-*' : \
+      '!-'{d,f,i,r,P,R,W} \
+      '(: * -F -l -v)-e[empty trash]' \
+      '-F[use Finder instead of system API]' \
+      '(: * -e -F -s -y)-l[list items in trash]' \
+      '(: * -F -l -v)-s[securely empty trash]' \
+      '-v[increase output verbosity]' \
+      '-y[skip confirmation prompts (with -e or -s)]' \
+      '*: :_files'
+    return
+    ;;
+  steven)
+    local trash_dir="${TRASH_D_DIR:-${XDG_DATA_HOME:-$HOME/.local/share}/Trash}/files"
+
+    local -a args=(
+      '(-v --verbose)'{-v,--verbose}'[print more information]'
+
+      + options
+      '(-d --dir)'{-d,--dir}'[remove empty directories]'
+      '(-r -R --recursive)'{-r,-R,--recursive}'[delete directories and their contents]'
+      '--rm[permanently delete files]'
+
+      + '(interactive)'
+      {-i,--interactive}'[ask before each deletion]'
+      {-I,--interactive-once}'[ask before deleting 3 or more files, or deleting recursively]'
+      {-f,--force}'[don'\''t prompt and ignore errors]'
+
+      + '(actions)'
+      '(options input info interactive)--list[list out the files in the trash]'
+      '(options input info interactive)--orphans[list orphaned files in the trash]'
+      '(options input info)--restore[restore specified file from the trash]:trashed file:_files -W "$trash_dir"'
+      '(options input info)--delete[delete specified file from the trash]:trashed file:_files -W "$trash_dir"'
+      '(options input info)--empty[empty the trash bin]'
+
+      + info
+      '(- *)'{-h,--help}'[display help information]'
+      '(- *)--version[output the version and exit]'
+
+      + input
+      '(actions)*: :_files'
+    )
+    _arguments -s -S : $args
+    return
+    ;;
+  *) _default ;;
+esac
diff --git a/Completion/Unix/Command/_truncate b/Completion/Unix/Command/_truncate
new file mode 100644
index 000000000..117be9702
--- /dev/null
+++ b/Completion/Unix/Command/_truncate
@@ -0,0 +1,69 @@
+#compdef truncate
+
+local curcontext=$curcontext variant rs ret=1
+local -a state state_descr line specs optA
+typeset -A opt_args
+
+_pick_variant -r variant gnu=GNU $OSTYPE --version
+[[ $variant != gnu ]] && rs='-r -s' # -r/-s mutually exclusive
+
+# common specs
+specs=(
+  '(hv -c --no-create)'{-c,--no-create}'[do not create any files]'
+  "(hv $rs -r --reference)"{-r+,--reference=}'[base size on the specified file]:reference file:_files'
+  "(hv $rs -s --size)"{-s+,--size=}'[set or adjust the file size by specified bytes]:size:->size'
+  '(hv)*: :_files'
+)
+
+case $variant in
+  gnu) # GNU coreutils 8.32
+    specs+=(
+      '(hv -o --io-blocks)'{-o,--io-blocks}'[treat the specified size as number of IO blocks instead of bytes]'
+      + 'hv'
+      '(- *)--help[display help and exit]'
+      '(- *)--version[output version information and exit]'
+    )
+    ;;
+  *) # FreeBSD/DragonFly
+    specs=( ${specs:#(|*\))--*} )    # remove long options
+    optA=( -A '-*' )
+    ;;
+esac
+
+_arguments -C -s -S : $specs && ret=0
+
+case $state in
+  size)
+    local unit=bytes
+    (( ${#opt_args[(I)(-o|--io-blocks)]} )) && unit=blocks
+    local -a suffix=( K:1024 M G T )
+    local -a prefix=( '+:extend by' '-:reduce by' )
+    local prefix_char='[-+]'
+    case $variant in
+      gnu|freebsd*)
+	prefix+=( '/:round down to multiple of' '%:round up to multiple of' )
+	;|
+      gnu)
+	suffix=( K:1024 KB:1000 {M,G,T,P,E,Z,Y}{,B} )
+	prefix+=( '<:at most' '>:at least' )
+	prefix_char='([-+/%]|\\[<>])'
+	;;
+      freebsd*)
+	prefix_char='[-+/%]'
+	;;
+    esac
+    local -a numbers=( _numbers -u $unit size $suffix )
+
+    if compset -P "$prefix_char"; then
+      $numbers && ret=0
+    elif (( ${#opt_args[(I)(-r|--reference)]} )); then
+      # prefix is required if the reference file is given
+      _describe -t 'prefixes' 'prefix' prefix && ret=0
+    else
+      _alternative "prefixes:prefix:((${(@q)prefix}))" \
+      		   "sizes: :$numbers" && ret=0
+    fi
+  ;;
+esac
+
+return ret
diff --git a/Completion/Unix/Command/_truss b/Completion/Unix/Command/_truss
index b798f03cb..b69e174e6 100644
--- a/Completion/Unix/Command/_truss
+++ b/Completion/Unix/Command/_truss
@@ -16,7 +16,11 @@ args=(
 
 case $OSTYPE in
   solaris2.<11->)
-    args+=( '(-c)-A[include absolute timestamps in output]' )
+    args+=(
+      '(-c)-A[include absolute timestamps in output]'
+      '-I[interpret system calls to well-known rather than underlying names]'
+      '-N[report only system calls that returned an error]'
+    )
   ;|
   aix*|solaris*)
     args+=(
diff --git a/Completion/Unix/Command/_uniq b/Completion/Unix/Command/_uniq
index e123a94cd..479b3848d 100644
--- a/Completion/Unix/Command/_uniq
+++ b/Completion/Unix/Command/_uniq
@@ -25,7 +25,7 @@ if ! _pick_variant gnu=Free\ Soft unix --version; then
   if [[ "$OSTYPE" == (darwin|dragonfly|freebsd|openbsd)* ]]; then
     optchars+=i
   fi
-  [[ $OSTYPE = freebsd* ]] && optchars+=D
+  [[ $OSTYPE = (darwin|freebsd)* ]] && optchars+=D
   args=( ${(M)args:#(|\*)(|\(*\))-[$optchars]*} )
 fi
 
diff --git a/Completion/Unix/Command/_user_admin b/Completion/Unix/Command/_user_admin
index db1c977ad..d5a53af7c 100644
--- a/Completion/Unix/Command/_user_admin
+++ b/Completion/Unix/Command/_user_admin
@@ -12,7 +12,7 @@ case ${service%???}:${(M)service%???}:$OSTYPE in
       shells=( ${(M)commands:#*/(|[abckz]|tc|ba)sh} )
     fi
     args+=(
-      '(-D -c --commend)'{-c+,--comment=}'[comment]:comment'
+      '(-D -c --comment)'{-c+,--comment=}'[comment]:comment'
       '(-D -d --home -b --base-dir)'{-d+,--home=}"[specify home directory]:home directory:_directories -W /"
       '(-D -e --expiredate)'{-e+,--expiredate}'[specify expiration date]:expiration date (YYYY-MM-DD)'
       '(-D -f --inactive)'{-f+,--inactive=}'[specify inactive days]:inactive days'
@@ -41,6 +41,8 @@ case ${service%???}:${(M)service%???}:$OSTYPE in
       SYS_GID_MIN SYS_UID_MAX SYS_UID_MIN UID_MAX UID_MIN UMASK
     )
     args+=(
+      '--btrfs-subvolume-home[use BTRFS subvolume for home directory]'
+      '(-F --add-subids-for-system)'{-F,--add-subids-for-system}'[add entries to sub[ud]id even when adding a system user]'
       '(-l --no-log-init)'{-l,--no-log-init}"[don't add user to lastlog and faillog databases]"
       '(-m --create-home -M --no-create-home)'{-M,--no-create-home}"[don't create user's home directory, regardless of /etc/login.defs]"
       '(-N --no-user-group -U --user-group)'{-N,--no-user-group}"[don't create a group with the same name as the user]"
@@ -103,6 +105,7 @@ case ${service%???}:${(M)service%???}:$OSTYPE in
   user:mod:linux*)
     args+=(
       '(-a --append)'{-a,--append}'[add user to supplementary groups without removing from other groups]'
+      '(-r --remove)'{-r,--remove}'[remove user from supplementary groups without removing from other groups]'
       \*{-v,--add-subuids}'[add a range of subordinate uids]:uids (first-last)'
       \*{-V,--del-subuids}'[remove a range of subordinate uids]:uids (first-last)'
       \*{-w,--add-subgids}'[add a range of subordinate gids]:gids (first-last)'
@@ -118,9 +121,16 @@ case ${service%???}:${(M)service%???}:$OSTYPE in
   ;|
   user:*:linux*)
     args+=(
+      '(-b --badname)'{-b,--badname}"[don't check for bad names]"
       '(-U --unlock --lock -L -p)'{-L,--lock}"[lock user's password]"
       '(-U --unlock --lock -L -p)'{-U,--unlock}"[unlock user's password]"
-      '(-Z --selinux-user)'{-Z,--selinux-user}"[specify SELinux user for the user's login]:user"
+      '(-Z --selinux-user)'{-Z,--selinux-user}"[specify SELinux user for the user's login]:user:_selinux_users"
+      "--selinux-range[specify SELinux MLS range for the user's login]:range"
+    )
+  ;|
+  group:*:linux*)
+    args+=(
+      '(-U --users)'{-U+,--users=}'[specify users to add as members of the group]:user:_sequence _users'
     )
   ;|
   group:*)
@@ -164,6 +174,9 @@ case ${service%???}:${(M)service%???}:$OSTYPE in
       ':group:_groups'
     )
   ;|
+  group:mod:linux*)
+    args+=( '(-a --append)'{-a,--append}'[append the users mentioned by -U without removing existing members]' )
+  ;|
   ^*:linux*)
     args=( ${(R)args:#(|\*)(|\(*\))--*} )    # remove long options
   ;|
diff --git a/Completion/Unix/Command/_vmstat b/Completion/Unix/Command/_vmstat
index e05bc88bc..6db776e62 100644
--- a/Completion/Unix/Command/_vmstat
+++ b/Completion/Unix/Command/_vmstat
@@ -8,7 +8,7 @@ case $OSTYPE in
       '(-t --timestamp)'{-t,--timestamp}'[show timestamp]'
       '(-n --one-header)'{-n,--one-header}'[do not redisplay header]'
       '(-S --unit)'{-S+,--unit=}'[specify unit for displayed sizes]:unit prefix [K]:((k\:1000 K\:1024 m\:1000000 M\:1048576))'
-      '(-C --full-cache)'{-C,--full-cache}'[add further cache lines to main cache]'
+      '(-y --no-first)'{-y,--no-first}'[skip first line of output]'
       '1: :_guard "[0-9]#" "interval (seconds)"' '2:count'
       + '(action)' \
       '(- :)'{-h,--help}'[display help information]'
diff --git a/Completion/Unix/Command/_vorbis b/Completion/Unix/Command/_vorbis
index 6c94469f9..fca218a51 100644
--- a/Completion/Unix/Command/_vorbis
+++ b/Completion/Unix/Command/_vorbis
@@ -32,7 +32,6 @@ case $service in
       '(-q --quality)'{-q+,--quality=}'[set encoding quality]:quality:(0 1 2 3 4 5 6 7 8 9 10)' \
       '--resample=[resample input to the given sample rate before encoding]:sample rate (Hz)' \
       '--downmix[down mix input from stereo to mono]' \
-      '--scale=[set input scaling factor]:scaling factor' \
       '(-s --serial)'{-s+,--serial=}'[force a specific serial number in the output stream]:serial number' \
       "--discard-comments[don't copy comments from FLAC file to output Ogg Vorbis file]" \
       '--ignorelength[ignore the datalength in Wave headers]' \
@@ -74,10 +73,6 @@ case $service in
       '(-q --quiet -v --verbose)'{--quiet,-q}'[quiet mode]' \
       '(-q --quiet)*'{-v,--verbose}'[increase verbosity]' \
       '(- *)'{-V,--version}'[display version information]' \
-      \*{-c-,--config=-}'[specify config options]: :_values option
-        "default_device\:device"
-        "shuffle\:value\:(0 1)"
-        "repeat\:value\:(0 1)"' \
       '*:sound file or directory:->urls-or-files' && ret=0
   ;;
   ogginfo)
diff --git a/Completion/Unix/Command/_w b/Completion/Unix/Command/_w
index 69751c5e5..e82c84f57 100644
--- a/Completion/Unix/Command/_w
+++ b/Completion/Unix/Command/_w
@@ -1,6 +1,6 @@
 #compdef w
 
-local args
+local -a args
 
 case $OSTYPE in
   linux*)
@@ -11,7 +11,7 @@ case $OSTYPE in
       '(H -o --old-style -s --short)'{-o,--old-style}'[old style output format]'
       '(H -s --short -o --old-style)'{-s,--short}'[use short output format]'
       '(H -u --no-current)'{-u,--no-current}'[ignore the username while figuring out the current process and cpu times]'
-      '(H -n --no-truncat)'{-n,--no-truncat}'[non-truncated listing (large)]'
+      '(H -p --pids)'{-p,--pids}'[show process IDs]'
       + H
       '(-)--help[display help information]'
       '(-)'{-V,--version}'[display version information]'
diff --git a/Completion/Unix/Command/_watch b/Completion/Unix/Command/_watch
index fff3d56f6..e12add520 100644
--- a/Completion/Unix/Command/_watch
+++ b/Completion/Unix/Command/_watch
@@ -18,7 +18,10 @@ case $variant in
       '(-g --chgexit)'{-g,--chgexit}'[exit on command output change]' \
       '(-n --interval)'{-n+,--interval=}'[specify update interval]:update interval (seconds) [2]' \
       '(-p --precise)'{-p,--precise}'[run command at precise intervals]' \
+      '(-q --equexit)'{-q+,--equexit=}'[exit when output of command does not change for the given cycles]:cycles' \
+      '(-r --no-rerun)'{-r,--no-rerun}'[do not run the program on terminal resize]' \
       '(-t --no-title)'{-t,--no-title}'[disable header]' \
+      '(-w --no-wrap)'{-w,--no-wrap}'[disable line wrapping]' \
       '(-x --exec)'{-x,--exec}'[pass command to exec(2) instead of `sh -c`]' \
       '(-)*::: :->cmd' \
     && ret=0
@@ -31,7 +34,7 @@ case $variant in
     then
       _cmdstring && ret=0
     else
-      _normal && ret=0
+      _normal -p watch && ret=0
     fi
     ;;
   # watch(1) has completely different semantics on freebsd compared to linux, hence:
diff --git a/Completion/Unix/Command/_wc b/Completion/Unix/Command/_wc
index 49a03ba2c..a1897e289 100644
--- a/Completion/Unix/Command/_wc
+++ b/Completion/Unix/Command/_wc
@@ -13,6 +13,7 @@ if _pick_variant gnu=GNU unix --version; then
   args+=(
     '(*)--files0-from=[read NUL-terminated file list from specified file]:file:_files'
     '(-L --max-line-length)'{-L,--max-line-length}'[print longest line lengths]'
+    '--total=[when to print a line with total counts]:when:(auto always only never)'
   )
 else
   args=( -A "-*" "${(@)args:#(|\(*\))(|\*)--*}" )
diff --git a/Completion/Unix/Command/_wget b/Completion/Unix/Command/_wget
index 50fd7791a..acc8d5c6e 100644
--- a/Completion/Unix/Command/_wget
+++ b/Completion/Unix/Command/_wget
@@ -23,6 +23,7 @@ _arguments -C -s \
   '(--config)--no-config' '--rejected-log=:file:_files' \
   '(--tries -t)'{--tries=,-t+}'[set number of retries]:number of retries' \
   '--retry-connrefused[retry even if connection is refused]' \
+  '--retry-on-host-error[consider host errors as non-fatal, transient errors]' \
   '--retry-on-http-error=[specify list of HTTP errors to retry]:http error' \
   '(--output-document -O)'{--output-document=,-O+}'[specify file to write documents to]:output file:_files' \
   '(--continue -c)'{--continue,-c}'[continue getting an existing file]'  \
@@ -98,7 +99,7 @@ _arguments -C -s \
   '--content-disposition[honor the Content-Disposition header when choosing local file names]'  \
   '--content-on-error[output received content on server errors]' \
   "--auth-no-challenge[send basic HTTP authentication without first waiting for server's challenge]" \
-  '--secure-protocol=[choose secure protocol]:protocol:(SSLv2 SSLv3 TLSv1 TLSv1_1 TLSv1_2 PFS)' \
+  '--secure-protocol=[choose secure protocol]:protocol:(SSLv2 SSLv3 TLSv1 TLSv1_1 TLSv1_2 TLSv1_3 PFS)' \
   --https-only \
   "--no-check-certificate[don't check the server certificate]" \
   '--certificate=[specify client certificate]:client certificate file:_files' \
diff --git a/Completion/Unix/Command/_xargs b/Completion/Unix/Command/_xargs
index 8e23a04bb..30e5f8daa 100644
--- a/Completion/Unix/Command/_xargs
+++ b/Completion/Unix/Command/_xargs
@@ -25,7 +25,7 @@ case $variant in
       '-R[specify maximum arguments that -I will replace in]:replacements'
     )
   ;|
-  freebsd*|netbsd*|dragonfly*)
+  darwin*|freebsd*|netbsd*|dragonfly*)
     args+=(
       '-S[space that -I can use for replacements]:size (bytes) [255]'
     )
diff --git a/Completion/Unix/Command/_xfconf-query b/Completion/Unix/Command/_xfconf-query
new file mode 100644
index 000000000..fa535401f
--- /dev/null
+++ b/Completion/Unix/Command/_xfconf-query
@@ -0,0 +1,33 @@
+#compdef xfconf-query
+local curcontext="$curcontext" state state_descr line ret=1
+typeset -A opt_args
+
+_arguments -C -s -w : \
+  '(-c --channel)'{-c,--channel}'[select channel to query/modify]:channel:( ${$(xfconf-query -l)\:#Channels\:} )' \
+  '(-p --property)'{-p,--property}'[select property to query/modify]:property:->property' \
+  '(-v --verbose)'{-v,--verbose}'[print property and value (with -l/-m)]' \
+  '(-t --type)'{-t,--type}'[specify the property value type]:type:(empty string bool {,u}int{,16,64} double array {,u}char float)' \
+  '(-R --recursive)'{-R,--recursive}'[recursively reset properties (with -r)]' \
+  + '(operations)' \
+  {-h,--help}'[show help options]' \
+  {-V,--version}'[show version information]' \
+  {-s,--set}'[define the value of a property]:value' \
+  {-l,--list}'[list properties or channels]' \
+  {-n,--create}'[create a new property]:new property name' \
+  {-r,--reset}'[reset property]' \
+  {-T,--toggle}'[invert boolean property]' \
+  {-m,--monitor}'[monitor a channel for property changes]' && return
+
+case $state in
+  property)
+    # if -c/--channel is currently on the line, use it to complete an property.
+    if [[ -v opt_args[(i)-(c|-channel)] ]]; then
+      local expl
+      _wanted properties expl property compadd "$@" -- ${(f)"$(xfconf-query -c ${(v)opt_args[(i)-(c|-channel)]} -l)"} && ret=0
+    else # just display a message
+      _message -e properties property && ret=0
+    fi
+  ;;
+esac
+
+return ret
diff --git a/Completion/Unix/Command/_xmlsoft b/Completion/Unix/Command/_xmlsoft
index 08b123e54..b8cf92700 100644
--- a/Completion/Unix/Command/_xmlsoft
+++ b/Completion/Unix/Command/_xmlsoft
@@ -40,6 +40,7 @@ case $service in
       '--maxdepth[increase the maximum depth]:depth' \
       '--maxvars[increase the maximum variables]:variables' \
       '--maxparserdepth[increase the maximum parser depth]:depth' \
+      '--huge[relax hardcoded limits of the parser]' \
       '--seed-rand[initialise random number generator]:seed' \
       '--html[input document is an HTML file]' \
       '--encoding[the input document character encoding]:encoding:(${encoding[@]})' \
diff --git a/Completion/Unix/Command/_xxd b/Completion/Unix/Command/_xxd
index 31d26ab64..e9015a081 100644
--- a/Completion/Unix/Command/_xxd
+++ b/Completion/Unix/Command/_xxd
@@ -24,7 +24,7 @@ arguments=(
   # output options
   '(-b -bits            -i -include -p -postscript -plain -ps -r -revert -u -uppercase)'{-b,-bits}'[output in binary digits, rather than hex]'
   '(         -E -EBCDIC -i -include -p -postscript -plain -ps -r -revert              )'{-E,-EBCDIC}'[print human-readable part in EBCDIC rather than ASCII]'
-  '(-i -include -p -postscript -plain -ps -r -revert)'{-e,-endian}'[little-endian dump]'
+  '(-i -include -p -postscript -plain -ps -r -revert)-e[little-endian dump]'
   '(-b -bits -E -EBCDIC -i -include -p -postscript -plain -ps -r -revert              )'{-i,-include}'[output in C include file style]'
   '(-b -bits -E -EBCDIC -i -include -p -postscript -plain -ps -C -capitalize          )'{-p,-postscript,-plain,-ps}'[read or write a plain hexdump (no line numbers or ASCII rendering)]'
 
@@ -35,12 +35,14 @@ arguments=(
   '(- :)'{-v,-version}'[show program version]'
   '*'{-a,-autoskip}"[a single '*' replaces runs of NUL (toggleable)]"
   '(-C -capitalize)'{-C,-capitalize}'[capitalize variable names in C include file style]'
-  {-c+,-cols}'[specify number of octets per line]: :_guard "[0-9a-fA-Fx]#" "number of octets per line"'
-  {-g+,-groupsize}'[specify the number of octets per group]: :_guard "[0-9]#" "number of octets per group"'
-  {-l+,-len}'[specify number of octets to output]: :_guard "[0-9]#" "number of octets to output"'
-  {-o+,-offset}'[add specified offset to displayed file position]:offset'
+  '(-c -cols)'{-c+,-cols}'[specify number of octets per line]: :_guard "(0x|)[0-9a-fA-Fx]#" "number of octets per line"'
+  '(-g -groupsize)'{-g+,-groupsize}'[specify the number of octets per group]: :_guard "(0x|)[0-9a-fA-F]#" "number of octets per group"'
+  '(-l -len)'{-l+,-len}'[specify number of octets to output]: :_guard "(0x|)[0-9a-fA-F]#" "number of octets to output"'
+  '(-n -name)'{-n+,-name}'[override the variable name output when -i is used]:variable name'
+  '(-o -offset)'{-o+,-offset}'[add specified offset to displayed file position]:offset'
   '-d[show offset in decimal instead of hex]'
-  {-s,-skip,-seek}'[specify file offset to dump from]: :_guard "[0-9]#" "file offset to dump from (absolute or relative)"'
+  '-R+[colorize the output]:when:(always auto never)'
+  '(-s -skip -seek)'{-s+,-skip,-seek}'[specify file offset to dump from]: :_guard "(0x|)[0-9a-fA-F]#" "file offset to dump from (absolute or relative)"'
 
   ': :_files'
 )
diff --git a/Completion/Unix/Command/_xz b/Completion/Unix/Command/_xz
index a4dfea1f5..6e68e0f69 100644
--- a/Completion/Unix/Command/_xz
+++ b/Completion/Unix/Command/_xz
@@ -22,20 +22,20 @@ case "$service" in
     '(I)*'{-v,--verbose}'[verbose mode]' \
     '(I * --files --files0)--files=-[read list of files to process from file]::file:_files' \
     '(I * --files --files0)--files0=-[read null terminated list of files to process from file]::file:_files' \
-    '(I -F --format)'{-F,--format}'=[specify file format]:format:(auto xz lzma raw)' \
+    '(I -F --format)'{-F+,--format=}'[specify file format]:format:(auto xz lzma lzip raw)' \
     '(I -T --threads)'{-T+,--threads=}'[use specified number of threads]:threads [1]' \
-    '(I -M --memlimit --memory)'{-M+,--memlimit=,--memory=}'[set memory usage limit]:memory usage' \
+    '(I -M --memlimit --memory)'{-M+,--memlimit=,--memory=}'[set memory usage limit]: :_numbers -u bytes "memory limit" KiB MiB GiB %\:percentage\ of\ available\ RAM' \
     '(I)--no-adjust[give error if settings exceed memory limit]' \
     '(I -Q --no-warn)'{-Q,--no-warn}'[make warnings not affect exit status]' \
     + 'comp' \
     "(I decomp)"{-z,--compress}'[compress]' \
     '(I decomp -e --extreme)'{-e,--extreme}'[try to improve compression ratio by using more CPU time]' \
     '(I decomp -S --suffix)'{-S+,--suffix=}'[use specified suffix for compressed files]:suffix [.xz]' \
-    '(I decomp -C --check)'{-C,--check}'=[integrity check type]:check type:(none crc32 crc64 sha256)' \
+    '(I decomp -C --check)'{-C+,--check=}'[integrity check type]:check type:(none crc32 crc64 sha256)' \
     '(I decomp)--block-size=[start a new .xz block after specified bytes of input]:size' \
     '(I decomp)--block-list=[start a new .xz block after specified intervals of uncompressed data]:size' \
     '(I decomp)--flush-timeout=[specify maximum time between flushing of output]:time (ms) [0]' \
-    '(I decomp)--memlimit-compress=[set memory usage limit for compression]:memory usage' \
+    '(I decomp)--memlimit-compress=[set memory usage limit for compression]: :_numbers -u bytes "memory limit" KiB MiB GiB %\:percentage\ of\ available\ RAM' \
     + 'decomp' \
     '(I comp level filters)'{-d,--decompress}'[decompress]' \
     '(I comp level filters)'{-t,--test}'[test compressed file integrity]' \
@@ -43,7 +43,8 @@ case "$service" in
     "(I comp level filters)--ignore-check[don't verify integrity when decompressing]" \
     '(I comp level filters)--single-stream[decompress only the first stream]' \
     "(I comp level filters)--no-sparse[don't create sparse files when decompressing]" \
-    '(I comp level filters)--memlimit-decompress=[set memory usage limit for decompression]:memory usage' \
+    '(I comp level filters)--memlimit-decompress=[set memory usage limit for decompression]: :_numbers -u bytes "memory limit" KiB MiB GiB %\:percentage\ of\ available\ RAM' \
+    '(I comp level filters)--memlimit-mt-decompress=[set memory usage limit for multi‐threaded decompression]: :_numbers -u bytes "memory limit" KiB MiB GiB %\:percentage\ of\ available\ RAM' \
     + '(I)' \
     '(* comp decomp level filters common)--info-memory[display amount of RAM and memory usage limits]' \
     '(- *)'{-h,--help}'[display help message]' \
@@ -52,7 +53,7 @@ case "$service" in
     + '(level)' \
     '(I filters decomp)-'{-best,-fast,1,2,3,4,5,6,7,8,9} \
     + filters \
-    '(I level decomp --extreme)'--{x86,powerpc,ia64,arm,armthumb,sparc}=-'[add a branch/call/jump filter]::option:->bcj-options' \
+    '(I level decomp --extreme)'--{x86,powerpc,ia64,arm,armthumb,arm64,sparc}=-'[add a branch/call/jump filter]::option:->bcj-options' \
     '(I level decomp --extreme)'--lzma{1,2}=-'[add lzma filter]::option:->lzma-options' \
     '(I level decomp --extreme)--delta=-[add delta filter]::option:->delta-options' && ret=0
   ;;
@@ -64,10 +65,10 @@ case $state in
     [[ -n ${(k)opt_args[(i)decomp*]} ]] && unset decompress
     if [[ -z "$decompress" ]]; then
       _description files expl 'compressed file'
-      _files "$expl[@]" -g '*.(xz|txz|lzma|tlz)(-.)' && return
+      _files "$expl[@]" -g '*.(xz|txz||lz|lzma|tlz)(-.)' && return
     else
       _description files expl 'file to compress'
-      _files "$expl[@]" -g '^*.(xz|txz|lzma|tlz)(-.)' && return
+      _files "$expl[@]" -g '^*.(xz|txz|lz|lzma|tlz)(-.)' && return
     fi
   ;;
   lzma-options)
diff --git a/Completion/Unix/Command/_zfs b/Completion/Unix/Command/_zfs
index 452e1160d..c09435a1f 100644
--- a/Completion/Unix/Command/_zfs
+++ b/Completion/Unix/Command/_zfs
@@ -1,553 +1,1427 @@
-#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: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:"
-		"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:" # <size>
-		"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]:blocksize:' \
-			'-V[Set size]:size:' \
-			':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 zstream
+
+local curcontext="$curcontext" implementation nm="$compstate[nmatches]"
+local -a state curstate line state_descr expl alts args
+local -a devices features
+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
+local -a ro_vdev_props rw_vdev_props
+
+_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}'
+)
+
+ro_vdev_props=(
+  capacity state guid asize psize ashift size free allocated expandsize
+  fragmentation parity devid physpath encpath fru parent children numchildren
+  read_errors write_errors checksum_errors initialize_errors
+  null_ops read_ops write_ops free_ops claim_ops trim_ops
+  null_bytes read_bytes write_bytes free_bytes claim_bytes trim_bytes
+  removing
+)
+rw_vdev_props=(
+  {checksum,io}'_n:number of errors' {checksum,io}'_t:threshold (seconds)'
+  {comment,bootsize}:value
+  {allocating,failfast}':value:(on off)'
+  'path:device path:_files -g "*(-%)" -P / -W /'
+)
+
+case $service:$implementation in
+  *:openzfs)
+    ds_types+=( bookmark )
+    sum_algorithms+=( noparity sha512 skein edonr blake3 )
+    comp_algorithms+=( zstd zstd-{1..19} zstd-fast zstd-fast-{{1..9}{,0},100,500,1000} )
+    dedup_algorithms+=( {sha512,skein,blake3}{,\,verify} edonr,verify )
+    share_rw_properties=( sharesmb:option sharenfs:option )
+    ro_po_props+=(
+      'bcloneratio[block cloning ratio for saved space]'
+      'bclonesaved[amount of storage spared by use of block cloning]'
+      'bcloneused[amount of storage used by cloned blocks]'
+      '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)'
+      'feature@'
+    )
+    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 snapshots_changed
+      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
+    )
+  ;;
+  zstream:*)
+    subcmds+=( dump decompress redup token recompress )
+  ;;
+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 -a file_type'
+    )
+  ;;
+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|zstream)
+    _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 --proctitle)'{-V,--proctitle}'[set the process title to a per-second report of how much data has been sent]'
+        \*{-X,--exclude}'[exclude datasets (with -R)]:dataset:_sequence _zfs_dataset -t fs'
+        '(-s --skip-missing)'{-s,--skip-missing}'[continue even when snapshots missing in the hierarchy]'
+        '-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]'
+      '-p[use (parsable) numeric output for timestamps]'
+    )
+    [[ $OSTYPE = freebsd<-12>.* ]] && args+=(
+      # features were lost with the openzfs rebase
+      '(-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]'
+    )
+    [[ $implementation = openzfs ]] && args=(
+      "-h[don't"' \\0ooo-escape non-ASCII paths]'
+    )
+    _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 ${ro_vdev_props%:*}' \
+      ':pool:_zfs_pool' \
+      '::vdev:->pool-vdevs-all' \
+      '*:pool:_zfs_pool -F line'
+  ;;
+
+  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]' \
+      '(-u --uninit)'{-u,--uninit}'[clear initialization state 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]'
+      '-e[only scrub files with known data errors]'
+    )
+    _arguments -A "-*" -S $args \
+      '(-p)-s[stop scrubbing]' \
+      '*:pool:_zfs_pool'
+  ;;
+
+  zpool:set)
+    _arguments -C -A "-*" -S \
+      ':property:->set-pool-properties' \
+      ':pool:_zfs_pool' \
+      ':vdev:->pool-vdevs'
+  ;;
+
+  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'
+  ;;
+
+  zstream:dump)
+    _arguments -A "-*" -S \
+      '-C[suppress the validation of checksums]' \
+      '(-d)-v[print metadata for each record]' \
+      '(-v)-d[dump data contained in each record]' \
+      ':file:_files'
+  ;;
+
+  zstream:token)
+    _message -e tokens 'resume token'
+  ;;
+
+  zstream:decompress)
+    _arguments -A "-*" -S \
+      '-v[print summary of decompressed records]' \
+      '*:offset'
+  ;;
+
+  zstream:redup)
+    _arguments -A "-*" -S \
+      '-v[print summary of converted records]' \
+      ':file:stream file'
+  ;;
+
+  zstream:recompress)
+    _arguments -A "-*" -S \
+      '-l+[specify compression level]:level' \
+      '*:algorithm:compadd -a comp_algorithms'
+  ;;
+
+  *)
+    _default
+  ;;
+esac
+
+while (( $#state )); do
+  curstate=$state
+  state=()
+  devices=()
+  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-vdevs-all) devices=( all-vdevs ) ;&
+    pool-vdevs) # same as pool-devices but on OpenZFS 2.2+ only features
+      # path field is also valid
+      devices+=( $(_call_program devices zpool get -H -o name state $line[CURRENT-2] all-vdevs) )
+      _description devices expl "$state_descr"
+      compadd "$expl[@]" -a devices
+    ;;
+
+    pool-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 $rw_vdev_props ) ;|
+
+    *-properties)
+      if compset -P 1 '(#m)*@'; then
+        if compset -P 1 '*='; then
+          case $MATCH in
+            *feature@) _wanted states expl state compadd active enabled disabled ;;
+            *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
+            feature@)
+              features=( ${${${${${(f)"$(_call_program features zpool upgrade -v)"}[(r)---*,(R)VER *]}[2,-3]}:# *}%% *} )
+              _wanted features expl feature compadd -qS= -a features
+            ;;
+            user*@) _users -qS= ;;
+            group*@) _groups -qS= ;;
+            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/_zip b/Completion/Unix/Command/_zip
index bc9aab1a5..cfa51be36 100644
--- a/Completion/Unix/Command/_zip
+++ b/Completion/Unix/Command/_zip
@@ -115,7 +115,7 @@ case $service in
       '(-U)-UU[ignore any Unicode fields]' \
       '-W[modify pattern matching so only ** matches /]' \
       '-\:[allow extraction outside of extraction base directory]' \
-      '-\\\^[allow control characters in extracted entries]' \
+      '-^[allow control characters in extracted entries]' \
       '-i[include the following names]:*-*:pattern' \
       '-x[exclude the following names]:*-*:pattern' \
       "(-p -f -u -l -t -z -n -o -j -C -X -q -qq -a -aa -v -L -M)1:zip file:_files -g '(#i)*.(zip|xpi|[ejw]ar)(-.)'" \
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:" # <size>
-		"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/_canonical_paths b/Completion/Unix/Type/_canonical_paths
index a8fbbb524..1444bc165 100644
--- a/Completion/Unix/Type/_canonical_paths
+++ b/Completion/Unix/Type/_canonical_paths
@@ -42,7 +42,8 @@ _canonical_paths_add_paths () {
     # ### Ideally, this codepath would do what the 'if' above does,
     # ### but telling compadd to pretend the "word on the command line"
     # ### is ${"the word on the command line"/$origpref/$canpref}.
-    matches+=(${${(M)files:#$canpref*}/$canpref/$origpref})
+    # ### The following approximates that.
+    matches+=(${(q)${(M)files:#$canpref*}/$canpref/$origpref})
   fi
 
   for subdir in $expref?*(@); do
diff --git a/Completion/Unix/Type/_diff_options b/Completion/Unix/Type/_diff_options
index dfa9889f2..03ea1d7fe 100644
--- a/Completion/Unix/Type/_diff_options
+++ b/Completion/Unix/Type/_diff_options
@@ -1,6 +1,6 @@
 #autoload
 
-local of ofwuc ouc oss ofwy ofwg ofwl cmd variant
+local of ofwuc ouc oss ofwy ofwg ofwl cmd variant ign
 local -a args
 
 cmd="$1"
@@ -25,7 +25,10 @@ _diff_palette() {
   return ret
 }
 
-if _pick_variant -r variant -c $cmd gnu=GNU unix -v || [[ $OSTYPE = freebsd<12->.* ]]; then
+if _pick_variant -r variant -c $cmd gnu=GNU unix -v ||
+  [[ $OSTYPE = (freebsd<12->|darwin<22->).* ]]; then
+  (( $#words > 2 )) && ign='!'
+
   # output formats
   of="-y --side-by-side -n --rcs -e -f --ed -q --brief -c -C --context -u -U \
   --unified --old-group-format --new-group-format --changed-group-format \
@@ -61,29 +64,28 @@ if _pick_variant -r variant -c $cmd gnu=GNU unix -v || [[ $OSTYPE = freebsd<12->
   --unchanged-group-format"
 
   if [[ $variant = gnu ]]; then
-    (( $#words > 2 )) || args+=(
-      '(-v --version)'{-v,--version}'[display version information]'
-      '--help[display usage information]'
-    )
     args+=(
       '(-H --speed-large-files)'{-H,--speed-large-files}'[assume large files and many small changes]'
       '(-E --ignore-tab-expansion)'{-E,--ignore-tab-expansion}'[ignore changes due to tab expansion]'
       '(-Z --ignore-trailing-space)'{-Z,--ignore-trailing-space}'[ignore white space at line end]'
-      "($ofwuc $oss -F --show-function-line)"{-F+,--show-function-line=}'[show the most recent line matching regex]:regex'
       "($ofwy $ouc)--left-column[output only left column of common lines]"
       "($ofwg $ouc $oss)--old-group-format=[set old group format]:old group format"
       "($ofwg $ouc $oss)--new-group-format=[set new group format]:new group format"
       "($ofwl $ouc $oss)--unchanged-line-format=[set unchanged line format]:unchanged line format"
-      '(--to-file)--from-file=[compare specified file to all operands]:from file:_files' \
-      '(--from-file)--to-file=[compare all operands to specified file]:to file:_files' \
-      '--color=-[use colors in output]::when [auto]:(never always auto)'
+      '(--to-file)--from-file=[compare specified file to all operands]:from file:_files'
+      '(--from-file)--to-file=[compare all operands to specified file]:to file:_files'
       '--palette=[specify colors to use]:color:_diff_palette'
+      "${ign}(1 2)-v[display version information]"
     )
   else
     args+=( '!--speed-large-files' )
+    if [[ $OSTYPE = darwin<22->.* ]]; then
+      args+=( '(-A --algorithm)'{-A+,--algorithm=}'[specify the algorithm to use]:algorithm:(myers patience stone)' )
+    fi
   fi
 
   _arguments -s $args \
+    '--color=-[use colors in output]::when [auto]:(never always auto)' \
     '(-i --ignore-case)'{-i,--ignore-case}'[case insensitive]' \
     '--ignore-file-name-case[ignore case when comparing file names]' \
     '!(--ignore-file-name-case)--no-ignore-file-name-case' \
@@ -99,6 +101,7 @@ if _pick_variant -r variant -c $cmd gnu=GNU unix -v || [[ $OSTYPE = freebsd<12->
     "($of $oss)-u[output a unified diff]" \
     "($ofwuc $oss)*"{-L+,--label=}'[set label to use instead of file name and timestamp]:label' \
     "($ofwuc $oss -p --show-c-function)"{-p,--show-c-function}'[show C function of each change]' \
+    "($ofwuc $oss -F --show-function-line)"{-F+,--show-function-line=}'[show the most recent line matching regex]:regex' \
     "($of $ouc $oss)"{-q,--brief}'[output only whether files differ]' \
     "($of $ouc $oss -e --ed)"{--ed,-e}'[output an ed script]' \
     "!($of $ouc $oss)--normal" \
@@ -127,39 +130,52 @@ if _pick_variant -r variant -c $cmd gnu=GNU unix -v || [[ $OSTYPE = freebsd<12->
     "($of $ouc)"{-y,--side-by-side}'[output in two columns]' \
     "($ofwy $ouc)--suppress-common-lines[don't output common lines]" \
     "($ofwy $ouc --width -W)"{--width=,-W+}'[set size of line]:number of characters per line' \
+    "${ign}(1 2)--version[display version information]" \
+    "${ign}(1 2)--help[display usage information]" \
     "$@"
 else
   of='-c -e -f'
   case $OSTYPE in
     openbsd*|solaris2.<9->)
       of+=' -u -U'
+    ;|
+    openbsd*|solaris*)
+      of+=' -n -C -D'
+    ;|
+    solaris*)
+      of+=' -h'
+    ;|
+    openbsd*)
+      of+=' -q'
+    ;|
+    # modifications to "$of" should be done above this line so that it is
+    # uniformly defined while constructing $args
+    openbsd*|solaris2.<9->)
       args+=(
-	"($of)-u[output a unified diff]"
-	"($of)-U+[output a unified diff]:lines of context"
+        "($of)-u[output a unified diff]"
+        "($of)-U+[output a unified diff]:lines of context"
       )
     ;|
     openbsd*|solaris*)
       args+=(
-	"($of)-C+[output a context diff]:lines of context"
-	"($of)-D+[output merged file with preprocessor directives]:preprocessor symbol"
-	'-i[case insensitive]'
-	'-l[long output format (paginate with pr(1))]'
-	'-s[report on identical files]'
-	'-t[expand tabs in output lines]'
+        "($of)-C+[output a context diff]:lines of context"
+        "($of)-D+[output merged file with preprocessor directives]:preprocessor symbol"
+        '-i[case insensitive]'
+        '-s[report on identical files]'
+        '-t[expand tabs in output lines]'
       )
     ;|
     solaris*)
-      of+=' -h -n'
       args+=(
-	'-w[ignore all white space]'
-	"($of)-h[do a fast, half-hearted job]"
-	"($of)-n[output a reversed ed script]"
+        '-w[ignore all white space]'
+        "($of)-h[do a fast, half-hearted job]"
+        "($of)-n[output a reversed ed script]"
         '-S+[set first file in comparison]:start with file:_files'
+        '-l[long output format (paginate with pr(1))]'
       )
     ;;
     openbsd*)
-      of+=' -n -q -u -C -D -U'
-      args=(
+      args+=(
         "($of)-n[output an rcsdiff(1)-compatible diff]"
         "($of)-q[only print a line when the files differ; does not produce a list of changes]"
         '-a[treat all files as ASCII text]'
@@ -173,7 +189,7 @@ else
         '-P[treat absent files in the second directory as if they were empty]'
         '-S[start a directory diff from a file name]:file name:_files'
         '*-X[exclude files and subdirectories whose basenames match lines in a file]:file name:_files'
-        '-x[exclude files and subdirectories whose basenames match a pattern]:pattern'
+        '*-x[exclude files and subdirectories whose basenames match a pattern]:pattern'
       )
     ;;
   esac
diff --git a/Completion/Unix/Type/_files b/Completion/Unix/Type/_files
index 4ddec1e12..f03b4a148 100644
--- a/Completion/Unix/Type/_files
+++ b/Completion/Unix/Type/_files
@@ -92,7 +92,10 @@ for def in "$pats[@]"; do
     pat="${${sdef%%:${tag}*}//\\:/:}"
 
     if [[ "$sdef" = *:${tag}:* ]]; then
+      # If the file-patterns spec includes a description, use it and give the
+      # group/description options from it precedence over passed in parameters.
       descr="${(Q)sdef#*:${tag}:}"
+      end=
     else
       if (( $opts[(I)-X] )); then
         descr=
@@ -108,26 +111,30 @@ for def in "$pats[@]"; do
       while _next_label "$tag" expl "$descr"; do
         _comp_ignore=( $_comp_ignore $ign )
         if [[ -n "$end" ]]; then
-          if _path_files -g "$pat" "$opts[@]" "$expl[@]"; then
-	    ret=0
-	  elif [[ $PREFIX$SUFFIX != */* ]] && zstyle -a ":completion:${curcontext}:$tag" recursive-files rfiles; then
-	    for rfile in $rfiles; do
-	      if [[ $PWD/ = ${~rfile} ]]; then
-		if [[ -z $subtree ]]; then
-		  subtree=( **/*(/) )
-		fi
-		for prepath in $subtree; do
-		  oprefix=$PREFIX
-		  PREFIX=$prepath/$PREFIX
-		  _path_files -g "$pat" "$opts[@]" "$expl[@]" && ret=0
-		  PREFIX=$oprefix
-		done
-		break
-	      fi
-	    done
-	  fi
+          expl=( "$opts[@]" "$expl[@]" )
         else
-          _path_files "$expl[@]" -g "$pat" "$opts[@]" && ret=0
+          expl+=( "$opts[@]" )
+        fi
+
+        if _path_files -g "$pat" "$expl[@]"; then
+          ret=0
+        elif [[ $PREFIX$SUFFIX != */* ]] && \
+            zstyle -a ":completion:${curcontext}:$tag" recursive-files rfiles
+        then
+          for rfile in $rfiles; do
+            if [[ $PWD/ = ${~rfile} ]]; then
+              if [[ -z $subtree ]]; then
+                subtree=( **/*(/) )
+              fi
+              for prepath in $subtree; do
+                oprefix=$PREFIX
+                PREFIX=$prepath/$PREFIX
+                _path_files -g "$pat" "$expl[@]" && ret=0
+                PREFIX=$oprefix
+              done
+              break
+            fi
+          done
         fi
       done
       (( ret )) || break
diff --git a/Completion/Unix/Type/_ldap_attributes b/Completion/Unix/Type/_ldap_attributes
new file mode 100644
index 000000000..0711cfbf1
--- /dev/null
+++ b/Completion/Unix/Type/_ldap_attributes
@@ -0,0 +1,27 @@
+#autoload
+
+local -a expl attrs
+
+# These come from dumping attributes from basic installations of both openldap
+# and FreeIPA and combining results. It is possible to have custom additions so
+# a definitive list is not possible Hence the use of -x with compadd.
+#
+attrs=(
+  associatedDomain authenticationMethod automountInformation automountKey
+  automountMapName bindTimeLimit cACertificate;binary cn dc defaultSearchBase
+  defaultServerList description displayName dn followReferrals gecos gidNumber
+  givenName homeDirectory info initials ipaCertIssuerSerial ipaCertSubject
+  ipaConfigString ipaKeyExtUsage ipaKeyTrust ipaNTSecurityIdentifier
+  ipaPublicKey ipaUniqueID ipHostNumber loginShell mail member memberUid
+  mepManagedBy nisDomain nisNetgroupTriple o objectClass objectClassMap ou
+  pwdAllowUserChange pwdAttribute pwdCheckQuality pwdExpireWarning
+  pwdFailureCountInterval pwdGraceAuthNLimit pwdInHistory pwdLockout
+  pwdLockoutDuration pwdMaxAge pwdMaxFailure pwdMinAge pwdMinLength
+  pwdMustChange pwdSafeModify searchTimeLimit serviceSearchDescriptor sn
+  telephoneNumber uid uidNumber userCertificate;binary userPKCS12
+  userSMIMECertificate
+)
+
+_description ldap-attributes expl "ldap attribute"
+compadd "${@:/-X/-x}" "${expl[@]:/-X/-x}" \
+    -M 'm:{a-zA-Z}={A-Za-z} r:[^A-Z]||[A-Z]=* r:|=*' -a attrs
diff --git a/Completion/Unix/Type/_ldap_filters b/Completion/Unix/Type/_ldap_filters
new file mode 100644
index 000000000..5e0e30f01
--- /dev/null
+++ b/Completion/Unix/Type/_ldap_filters
@@ -0,0 +1,91 @@
+#autoload
+
+# LDAP search filters conforming to RFC4515
+
+local -a expl excl optype disp end pre
+local -i nest=0
+local open='(' close=')' andop='&' orop='|'
+
+[[ -prefix - ]] && return 1
+
+local -a matchingrules=( # From RFC4517
+  bitStringMatch booleanMatch caseExactIA5Match
+  caseExactMatch caseExactOrderingMatch caseExactSubstringsMatch
+  caseIgnoreIA5Match caseIgnoreIA5SubstringsMatch caseIgnoreListMatch
+  caseIgnoreListSubstringsMatch caseIgnoreMatch caseIgnoreOrderingMatch
+  caseIgnoreSubstringsMatch directoryStringFirstComponentMatch
+  distinguishedNameMatch generalizedTimeMatch generalizedTimeOrderingMatch
+  integerFirstComponentMatch integerMatch integerOrderingMatch keywordMatch
+  numericStringMatch numericStringOrderingMatch numericStringSubstringsMatch
+  objectIdentifierFirstComponentMatch objectIdentifierMatch octetStringMatch
+  octetStringOrderingMatch telephoneNumberMatch telephoneNumberSubstringsMatch
+  uniqueMemberMatch wordMatch
+)
+local -a classes=( # Sampled from real servers, arbitrary other values allowed
+  automount automountMap cosTemplate dcObject device dnaSharedConfig domain
+  domainRelatedObject DUAConfigProfile extensibleObject groupOfNames
+  groupOfPrincipals ieee802device inetOrgPerson inetuser ipaassociation ipaca
+  ipacaacl ipaCertificate ipaCertMapConfigObject ipacertprofile ipaConfigObject
+  ipaDomainIDRange ipaDomainLevelConfig ipaGuiConfig ipahbacrule ipahbacservice
+  ipahbacservicegroup ipahost ipahostgroup ipaIDrange ipaKeyPolicy
+  ipakrbprincipal ipaNameResolutionData ipaNTDomainAttrs ipaNTGroupAttrs
+  ipaNTUserAttrs ipaobject ipaPublicKeyObject ipaReplTopoManagedServer
+  ipaservice ipaSshGroupOfPubKeys ipasshhost ipasshuser ipasudorule
+  ipaSupportedDomainLevelConfig ipaTrustedADDomainRange ipaUserAuthTypeClass
+  ipausergroup ipHost krbContainer krbprincipal krbprincipalaux
+  krbrealmcontainer krbTicketPolicyAux mepManagedEntry mepOriginEntry
+  nestedGroup nisDomainObject nisNetgroup nsContainer nsDS5Replica nshost
+  organization organizationalPerson organizationalRole organizationalUnit
+  person pilotObject pkiCA pkiuser posixAccount posixGroup pwdPolicy
+  shadowAccount simpleSecurityObject top
+)
+
+compquote open close andop orop
+open=${(q)open} close=${(q)close}
+# default to double rather than backslash quoting
+[[ -z $compstate[quote] && -z $PREFIX ]] && pre='"('
+
+zstyle -s ":completion:${curcontext}:operators" list-separator sep || sep=--
+print -v disp -f "%s $sep %s" \| or \& and \! not
+end=( ") $sep end" )
+excl=( ! \\\| \& ) # compadd -F uses globs: only | needs quoting
+
+local -a query=(
+  \( /$'*\0[ \t\n]#'/ \) # strip off any preceding arguments
+  \(
+    \( "/${open}!/" -'optype[++nest]=1;pre=""'
+    \| "/${open}${(q)orop}/" -'optype[++nest]=2;pre=""'
+    \| "/${open}${andop}/" -'optype[++nest]=3;pre=""'
+    \| '/[]/' ':operators:operator:compadd -F "( ${(q)excl[optype[nest]]} )" -d disp -P ${pre:-${(Q)open}} -S ${(Q)open} \| \& \!' \)
+  \|
+    \( "/${open}[^\\)]##/" "%$close%" # pass over whole var=value, needed due to lack of backtracking after the following
+    \| "/${open}(#i)homeDirectory=/" '/[]/' ':directories:directory:_directories -P / -W / -r ") \t\n\-"'
+    \| "/${open}(#i)loginShell=/" '/[]/' ':shells:shell:compadd -S ${(Q)close} ${(f)^"$(</etc/shells)"}(N)'
+    \| "/${open}(#i)mail=/" '/[]/' ':email-addresses:mail:_email_addresses -S ${(Q)close}'
+    \| "/${open}(#i)objectClass=/" '/[]/' ':object-classes:class:compadd -S ${(Q)close} -M "m:{a-zA-Z}={A-Za-z} r:[^A-Z]||[A-Z]=* r:|=*" -a classes'
+    \| "/${open}(#i)(automountKey|(member|)uid)=/" '/[]/' ':users:username:_users -S ${(Q)close}'
+    \| "/${open}(#i)cn=/" '/[]/' ':cn:cn: _alternative "users:user:_users -S ${close}" "groups:group:_groups -S ${close}" "hosts:host:_hosts -S ${close}"'
+    \|
+      '/[^:=<>~]##/' '%[=:<>~]%' -'pre=""'
+      ':object-types:object type:_ldap_attributes -P ${pre:-${(Q)open}}  -S = -r ":=~<> \t\n\-"'
+      \(
+        '/:/'
+        '/[^:]##:=/' ':matching-rules:matching rule:compadd -S ":=" -a matchingrules'
+      \|
+        '/([~<>]|)=/' ':operators:operator:compadd -S "" "<=" \>= \~='
+      \)
+      '/[^\\)]##/' "%$close%" ': _message -e object-values "object value (* for presence check)"'
+    \)
+    "/$close/" -'(( nest ))' ':brackets:bracket:compadd ${=query[nest]:+-S ""} \)'
+    \(
+      # This use of -P/-d and an empty match works around a limitation/bug where
+      # mixed use of -P removes any quoting
+      "/$close/" ':operators:operator:compadd ${=query[nest-1]:+-S ""} -d end -P ${(Q)close} ""'
+      \( // -'(( --nest ))' \| '//' -'((!nest))' '/[]/' ': compadd ""' \)
+    \) \#
+    // -'(( nest && optype[nest] > 1 ))'
+  \) \#
+)
+
+_regex_arguments _ldap_search_filters "$query[@]"
+_ldap_search_filters
diff --git a/Completion/Unix/Type/_path_commands b/Completion/Unix/Type/_path_commands
index 66795ae0f..4d5a6c5af 100644
--- a/Completion/Unix/Type/_path_commands
+++ b/Completion/Unix/Type/_path_commands
@@ -87,18 +87,19 @@ fi
 # 'if' block move up to the "_command_names -" branch of _command_names?
 if [[ -o path_dirs ]]; then
   local -a path_dirs
-  path_dirs=(${^path}/*(/N:t))
-  (( ${#path_dirs} )) &&
-  _wanted path-dirs expl 'directory in path' compadd "$@" -a path_dirs && ret=0
 
   if [[ $PREFIX$SUFFIX = */* ]]; then
+    path_dirs=( ${path:#.} )
     # Find command from path, not hashed
-    _wanted commands expl 'external command' _path_files -W path -g '*(*)' &&
-    ret=0
+    _wanted commands expl 'external command' _path_files -W path_dirs -g '*(-*)' && ret=0
+  else
+    path_dirs=(${^path}/*(/N:t))
+    (( ${#path_dirs} )) &&
+        _wanted path-dirs expl 'directory in path' compadd "$@" -S / -a path_dirs && ret=0
   fi
 fi
 
-return $ret
+return ret
 }
 
 _path_commands "$@"
diff --git a/Completion/Unix/Type/_path_files b/Completion/Unix/Type/_path_files
index 06d9d8d51..d46dcbe5a 100644
--- a/Completion/Unix/Type/_path_files
+++ b/Completion/Unix/Type/_path_files
@@ -734,7 +734,7 @@ for prepath in "$prepaths[@]"; do
 	      compadd "$tmp4[@]" -s "${Uopt:+$ISUFFIX}" $listopts - "$tmpdisp"
 	    done
           else
-            [[ -n "$compstate[pattern_match]" ]] && SUFFIX="${SUFFIX:s./.*/}*"
+            [[ -n "$compstate[pattern_match]" ]] && SUFFIX="${SUFFIX:gs./.*/}*"
 
             for i in "$tmp1[@]"; do
 	      _list_files i "$prepath$realpath$testpath"
diff --git a/Completion/Unix/Type/_remote_files b/Completion/Unix/Type/_remote_files
index b537406a0..93e1b7f43 100644
--- a/Completion/Unix/Type/_remote_files
+++ b/Completion/Unix/Type/_remote_files
@@ -85,12 +85,15 @@ if zstyle -T ":completion:${curcontext}:files" remote-access; then
     remdispf=( ${(M)remdispf:#${~glob[2]}} )
   fi
 
+  local -a autoremove
+  [[ -o autoremoveslash ]] && autoremove=(-r "/ \t\n\-")
+
   _tags remote-files
   while _tags; do
     while _next_label remote-files expl ${suf:-remote directory}; do
       [[ -n $suf ]] &&
           compadd "$args[@]" "$expl[@]" -d remdispf -- ${(q)remdispf%[*=|]} && ret=0
-      compadd ${suf:+-S/} -r "/ \t\n\-" "$args[@]" "$expl[@]" -d remdispd \
+      compadd ${suf:+-S/} $autoremove "$args[@]" "$expl[@]" -d remdispd \
 	-- ${(q)remdispd%/} && ret=0
     done
     (( ret )) || return 0
diff --git a/Completion/Unix/Type/_ssh_hosts b/Completion/Unix/Type/_ssh_hosts
index bd5366425..b50e1c16a 100644
--- a/Completion/Unix/Type/_ssh_hosts
+++ b/Completion/Unix/Type/_ssh_hosts
@@ -20,10 +20,11 @@ if [[ -r $config ]]; then
   local key line host
   local -a lines=("${(@f)$(<"$config")}") 2>/dev/null
   local -a match_args
-  while (($#lines)); do
-    IFS=$'=\t ' read -r key line <<<"${lines[1]}"
+  local idx=1
+  while (( idx <= $#lines )); do
+    IFS=$'=\t ' read -r key line <<<"${lines[idx]}"
     if [[ "$key" == ((#i)match) ]]; then
-      match_args=(${(z)line})
+      match_args=( ${(Z.C.)line} )
       while [[ $#match_args -ge 2 ]]; do
 	if [[ "${match_args[1]}" == (#i)(canonical|final|(|original)host) ]]; then
 	  key="Host"
@@ -35,15 +36,12 @@ if [[ -r $config ]]; then
     fi
     case "$key" in
     ((#i)include)
-      lines[1]=("${(@f)$(cd $HOME/.ssh; cat ${(z)~line})}") 2>/dev/null;;
+      lines[idx]=( "${(@f)$(cd $HOME/.ssh; cat ${(Z.C.)~line} 2>/dev/null)}" ) ;;
     ((#i)host(|name))
-      for host in ${(z)line}; do
-	case $host in
-	(*[*?]*) ;;
-	(*) config_hosts+=("$host") ;;
-	esac
+      for host in ${(Z.C.)line}; do
+        [[ $host != *[*?%]* ]] && config_hosts+=( $host )
       done ;&
-    (*) shift lines;;
+    (*) (( ++idx ));;
     esac
   done
   if (( ${#config_hosts} )); then
diff --git a/Completion/Unix/Type/_tar_archive b/Completion/Unix/Type/_tar_archive
index 00555156b..bc49c4a3a 100644
--- a/Completion/Unix/Type/_tar_archive
+++ b/Completion/Unix/Type/_tar_archive
@@ -23,7 +23,7 @@ if [[ "$1" = *[urtx]* ]]; then
   elif [[ "$_cmd_variant[$service]" == gnu ]]; then
     _files "$expl[@]" -g '*.((tar|TAR)(.gz|.GZ|.Z|.bz2|.lzma|.xz|.zst|lzo|)|(tbz|tgz|txz|tzst|taz|taZ|tz2|tbz2|tlz))(-.)'
   elif [[ "$_cmd_variant[$service]" == libarchive ]]; then
-    _files "$expl[@]" -g '*.((tar|TAR)(.gz|.GZ|.Z|.bz2|.lzma|.xz|.zst|lzo|)|(tbz|tgz|txz|zip|tzst|tzo|taz|tbz2|tz2|tlz|tZ))(-.)'
+    _files "$expl[@]" -g '*.((tar|TAR|cpio)(.gz|.GZ|.Z|.bz2|.lzma|.xz|.zst|lzo|)|(tbz|tgz|txz|tzst|tzo|taz|tbz2|tz2|tlz|tZ|7z|ar|iso|deb|cab|lha|mtree|rar|warc|xar|zip))(-.)'
   else
     _files "$expl[@]" -g '*.(tar|TAR)(-.)'
   fi
diff --git a/Completion/Unix/Type/_time_zone b/Completion/Unix/Type/_time_zone
index cd924bbc7..a7b63adcd 100644
--- a/Completion/Unix/Type/_time_zone
+++ b/Completion/Unix/Type/_time_zone
@@ -6,4 +6,5 @@ if (( ! $+_zoneinfo_dirs )); then
   _zoneinfo_dirs=( /usr/{share,lib,share/lib}/{zoneinfo*,locale/TZ}(/) )
 fi
 
-_wanted time-zones expl 'time zone' _files -W _zoneinfo_dirs "$@" -
+_wanted time-zones expl 'time zone' \
+  _files -g '[A-Z]*' -M 'm:{a-z}={A-Z}' -W _zoneinfo_dirs "$@" -
diff --git a/Completion/Unix/Type/_umountable b/Completion/Unix/Type/_umountable
index 7ffce5bb4..0111555b6 100644
--- a/Completion/Unix/Type/_umountable
+++ b/Completion/Unix/Type/_umountable
@@ -1,15 +1,21 @@
 #autoload
 local tmp
-local dev_tmp dpath_tmp mp_tmp mline
+local -a dev_tmp dpath_tmp mp_tmp mline
 
 case "$OSTYPE" in
-linux*|irix*)
+linux*)
+  tmp=( "${(@f)$(< /proc/self/mounts)}" )
+  dev_tmp=( "${(@)${(@)tmp%% *}:#none}" )
+  mp_tmp=( "${(@)${(@)tmp#* }%% *}" )
+  ;;
+irix*)
   tmp=( "${(@f)$(< /etc/mtab)}" )
   dev_tmp=( "${(@)${(@)tmp%% *}:#none}" )
   mp_tmp=( "${(@)${(@)tmp#* }%% *}" )
   ;;
 freebsd*|dragonfly*)
   /sbin/mount | while read mline; do
+    [[ $mline[(w)1] = map ]] && continue
     dev_tmp+=( $mline[(w)1] )
     mp_tmp+=( $mline[(w)3] )
   done
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
diff --git a/Completion/X/Command/_evince b/Completion/X/Command/_evince
index 21b493360..49f11f341 100644
--- a/Completion/X/Command/_evince
+++ b/Completion/X/Command/_evince
@@ -15,6 +15,7 @@ _arguments -s -S \
   '--g-fatal-warnings[make all warnings fatal]' \
   '--gtk-debug=[specify GTK+ debugging flags to set]:flag' \
   '--gtk-no-debug=[specify GTK+ debugging flags to unset]:flag' \
+  '(-o --new-window)'{-o,--new-window}'[open a new window]' \
   '(-p --page-label -i --page-index -n --named-dest)'{-p,--page-label=}'[specify page label of the document to display]' \
   '(-p --page-label -i --page-index -n --named-dest)'{-i,--page-index=}'[specify page number of the document to display]' \
   '(-p --page-label -i --page-index -n --named-dest)'{-n,--named-dest=}'[specify named destination to display]' \
diff --git a/Completion/X/Command/_gnome-gv b/Completion/X/Command/_gnome-gv
index 25de6fadf..b1b66e2a4 100644
--- a/Completion/X/Command/_gnome-gv
+++ b/Completion/X/Command/_gnome-gv
@@ -1,6 +1,6 @@
 #compdef gnome-gv ggv
 
 _arguments \
-  '(--help)-\\?[help]' \
+  '(--help)-?[help]' \
   '(--windows)-w[number of empty windows]:number:' \
   '*:file: _pspdf -z' --
diff --git a/Completion/X/Command/_qiv b/Completion/X/Command/_qiv
index 35ceec09a..5d0aa8faf 100644
--- a/Completion/X/Command/_qiv
+++ b/Completion/X/Command/_qiv
@@ -10,6 +10,7 @@ _arguments -s \
   '(-C --cycle)'{-C,--cycle}"[don't cycle after last image]" \
   '(-w --fixed_width -W --fixed_zoom)'{-w,--fixed_width}'[use window with specified width]:width' \
   '(-w --fixed_width -W --fixed_zoom)'{-W,--fixed_zoom}'[use window with specified zoom factor]:zoom (percentage)' \
+  '--highDPIfactor[specify resize factor to compensate for high (or also low) DPI screens]:factor' \
   '(-x -y -z --root --root_t --root_s -f --file *)'{-x,--root}'[use image as the current desktop background, centered]:image file:_files' \
   '(-x -y -z --root --root_t --root_s -f --file *)'{-y,--root_t}'[use image on the current desktop background, tiled]:image file:_files' \
   '(-x -y -z --root --root_t --root_s -f --file *)'{-z,--root_s}'[use image as the current desktop background, stretched]:image file:_files' \
@@ -22,6 +23,9 @@ _arguments -s \
   '(-n --no_filter)'{-n,--no_filter}'[disable filtering of images by extension]' \
   '(-i --no_statusbar -I --statusbar)'{-i,--no_statusbar}'[disable statusbar]' \
   '(-i --no_statusbar -I --statusbar)'{-I,--statusbar}'[enable statusbar]' \
+  '(-J --showJPEGcomments)'{-J,--showJPEGcomments}'[enable display of JPEG comments]' \
+  '(-E --showArtistName)'{-E,--showArtistName}'[enable display of artist (author) name]' \
+  "--artist_ignore[don't show specified artist name]:artist" \
   '(-p --transparency)'{-p,--transparency}'[enable transparency]' \
   '(-a --do_grab)'{-a,--do_grab}'[grab the pointer in windowed mode]' \
   '(-G --disable_grab)'{-G,--disable_grab}'[disable pointer grabbing in fullscreen mode]' \
@@ -47,4 +51,4 @@ _arguments -s \
   '(-Y --source_profile)'{-Y,--source_profile}'[specify colour profile file as source profile]:colour profile file:_files' \
   '(-Z --display_profile)'{-Z,--display_profile}'[specify colour profile file as display profile]:colour profile file:_files' \
   '--vikeys[enable movement with h/j/k/l]' \
-  '*:image file:_files -g "*.(#i)(bmp|eim|gif|ico|jp([eg]|eg)|pcx|png|p[pngb]m|pjpeg|svg|tif(|f)|wmf|x[pb]m)(-.)"'
+  '*:image file:_files -g "*.(#i)(bmp|eim|gif|hei[cf]|ico|jp([eg]|eg)|pcx|png|p[pngb]m|pjpeg|svg|tif(|f)|webp|wmf|x[pb]m)(-.)"'
diff --git a/Completion/X/Command/_xdvi b/Completion/X/Command/_xdvi
index c33e67bcc..ed5982bcc 100644
--- a/Completion/X/Command/_xdvi
+++ b/Completion/X/Command/_xdvi
@@ -2,15 +2,22 @@
 
 _xt_arguments \
   -+{allowshell,copy,expert,hush{,chars,checksums,specials},keep,l,no{ghostscript,grey,gssafer,makepk,postscript,scan},safer,thorough,underlink,version} \
-  +{altfont,base,browser,cr,debug,density,gamma,gspalette,hl,icongeometry,interpreter,margin,mfmode,offsets,p,paper,shrink,S,sidemargin,topmargin,xoffset,yoffset,grid{1,2,3},mgs{,1,2,3,4,5}} \
+  +{altfont,background,bg,browser,cr,debug,density,dvispath,editor,gamma,gspalette,hl,icongeometry,interpreter,margin,mfmode,offsets,p,paper,shrink,S,sidemargin,topmargin,xoffset,yoffset,grid{1,2,3},mgs{,1,2,3,4,5}} \
   '-altfont:default font' \
-  '-base:base URL' \
+  -{bg,background}':color:_x_color' \
   '-browser:WWW browser:_command_names -e' \
   '-cr:cursor color:_x_color' \
-  '-debug:debugging bitmask:((1\:bitmaps 2\:dvi\ translation 4\:pk\ reading 8\:batch\ operation 16\:events 32\:file\ opening 64\:PostScript\ communication 128\:Kpathsea\ statistics 256\:Kpathsea\ hash\ table\ lookups 512\:Kpathsea\ path\ definitions 1024\:Kpathsea\ path\ expansion 2048\:Kpathsea\ searches))' \
+  '-debug:debugging bitmask:((1\:bitmaps 2\:dvi\ translation 4\:pk\ reading 8\:batch\ operation 16\:events 32\:file\ opening 64\:PostScript\ communication 128\:Kpathsea\ statistics 256\:Kpathsea\ hash\ table\ lookups 512\:Kpathsea\ path\ definitions 1024\:Kpathsea\ path\ expansion 2048\:Kpathsea\ searches ))' \
   '-density:font shrink density' \
+  '-dvispath:dvips program:_command_names -e' \
+  '-editor:text editor:_cmdstring' \
+  '-expertmode:display bitmask:((1\:statusline 2\:scrollbars 4\:pagelist 8\:toolbar 16\:menubar))' \
+  -{fg,foreground}':color:_x_color' \
+  '-findstring:string' \
+  '-font:font:_x_font' \
+  '-fullscreen' \
   '-gamma:anti-aliasing factor [1.0]' \
-  -grid{1,2,3}':grid color:_x_color' \
+  '-gsalpha' \
   '-gspalette:Ghostscript palette:(Color Greyscale Monochrome)' \
   '-hl:page highlight color:_x_color' \
   '-icongeometry:icon geometry:_x_geometry' \
@@ -21,6 +28,9 @@ _xt_arguments \
   '-offsets:offset size' \
   '-p:font size (pixel per inch)' \
   '-paper:paper size (<width>x<height> or ...):(us usr legal foolscap a1 a2 a3 a4 a5 a6 a7 b1 b2 b3 b4 b5 b6 b7 c1 c2 c3 c4 c5 c6 c7 a1r a2r a3r a4r a5r a6r a7r)' \
+  '-ps2pdfpath:ps2pdf program:_command_names -e' \
+  '-rulecolor:color' \
+  '-rv' \
   '-shrink:shrink factor' \
   '-S:font shrink density' \
   '-sidemargin:side margin' \
diff --git a/Completion/X/Command/_xinput b/Completion/X/Command/_xinput
index 00a976d5d..2bbadd65a 100644
--- a/Completion/X/Command/_xinput
+++ b/Completion/X/Command/_xinput
@@ -106,8 +106,7 @@ case $state in
 
     if [[ $PREFIX$SUFFIX = [^-]*[^0-9]* ]]; then
       # match based on the names but insert IDs
-      compadd "$expl[@]" -M 'b:=* m:{[:lower:]}={[:upper:]}' -D ids -a names
-      compadd "$expl[@]" -M 'b:=* m:{[:lower:]}={[:upper:]}' -D disp -a names
+      compadd "$expl[@]" -M 'b:=* m:{[:lower:]}={[:upper:]}' -D ids -D disp -a names
       compadd "$expl[@]" -U -ld disp -a ids && ret=0
 
       zstyle -s ":completion:${curcontext}:input-devices" insert-ids out || out=menu
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/Completion/Zsh/Command/_cd b/Completion/Zsh/Command/_cd
index 46237e73d..9ca846c8f 100644
--- a/Completion/Zsh/Command/_cd
+++ b/Completion/Zsh/Command/_cd
@@ -70,8 +70,15 @@ else
 
     tmpcdpath=(${${(@)cdpath:#.}:#$PWD})
 
-    (( $#tmpcdpath )) &&
-      alt=( 'path-directories:directory in cdpath:_path_files -W tmpcdpath -/' )
+    if zstyle -t ":completion:${curcontext}:path-directories" separate-sections; then
+      local elem
+      for ((elem=1; elem <= $#tmpcdpath; elem++)); do
+        alt+=( "path-directories-${elem}:directory in ${tmpcdpath[$elem]}:_path_files -W 'tmpcdpath[$elem]' -/" )
+      done
+    else
+      (( $#tmpcdpath )) &&
+        alt=( 'path-directories:directory in cdpath:_path_files -W tmpcdpath -/' )
+    fi
 
     # With cdablevars, we can complete foo as if ~foo/
     if [[ -o cdablevars && -n "$PREFIX" && "$PREFIX" != <-> ]]; then
diff --git a/Completion/Zsh/Command/_compadd b/Completion/Zsh/Command/_compadd
index 9c92cda76..4456cf71e 100644
--- a/Completion/Zsh/Command/_compadd
+++ b/Completion/Zsh/Command/_compadd
@@ -31,7 +31,7 @@ args=(
   '-n[hide matches in completion listing]'
   '-O+[populate array with matches instead of adding them]:array:_parameters -g "*array*"'
   '-A+[populate array with expanded matches instead of adding them]:array:_parameters -g "*array*"'
-  '-D+[delete elements from array corresponding to non-matching candidates]:array:_parameters -g "*array*"'
+  '*-D+[delete elements from array corresponding to non-matching candidates]:array:_parameters -g "*array*"'
 )
 
 case $service in
diff --git a/Completion/Zsh/Command/_fc b/Completion/Zsh/Command/_fc
index dd014e7d7..626d35956 100644
--- a/Completion/Zsh/Command/_fc
+++ b/Completion/Zsh/Command/_fc
@@ -40,7 +40,7 @@ fc_hist=(
   '(-A -R -W -e -d -E -i -t -a -p -P)-f[mm/dd/yyyy format time-stamps]'
   '(-A -R -W -e -d -f -i -t -a -p -P)-E[dd.mm.yyyy format time-stamps]'
   '(-A -R -W -e -d -f -E -t -a -p -P)-i[yyyy-mm-dd format time-stamps]'
-  '(-A -R -W -e -d -f -E -i -a -p -P)-t[print time-stamps in specified format]:date format'
+  '(-A -R -W -e -d -f -E -i -a -p -P)-t[print time-stamps in specified format]: : _date_formats zsh'
   '(-A -R -W -e -a -p -P)-D[print elapsed times]'
 
   '(-A -R -W -I -e -d -f -i -l -m -n -r -D -E -t -P)-a[with -p, automatically pop history on function return]'
@@ -59,7 +59,8 @@ case $service in
   ;;
   *)
     _arguments "$fc_common[@]" "$fc_hist[@]" "$fc_r" \
-      '(-A -R -W -a -l -n -d -f -E -i -r -t -D -p -P)-e+[specify editor to invoke]:editor to invoke:_command_names -e' \
+      '(-A -R -W -a -l -n -d -f -E -i -r -t -D -p -P -s)-e+[specify editor to invoke]:editor to invoke:_command_names -e' \
+      '(-A -R -W -a -l -n -d -f -E -i -r -t -D -p -P -e)-s[re-execute command without invoking editor (like -e-)]' \
       '(-a -l -L -m -e -r -n -d -f -t -E -i -R -D -A -W -p -P *)-'{\
 'R[read history from file]',\
 'A[append history to file]',\
diff --git a/Completion/Zsh/Command/_kill b/Completion/Zsh/Command/_kill
index b9dfde3f0..3b5c02151 100644
--- a/Completion/Zsh/Command/_kill
+++ b/Completion/Zsh/Command/_kill
@@ -4,9 +4,11 @@ local curcontext="$curcontext" line state ret=1
 typeset -A opt_args
 
 _arguments -C \
-  '(-s -l 1)-n[specify signal number]:signal number' \
-  '(-n -l 1)-s[specify signal name]:signal:_signals -s' \
-  '(-n -s)-l[list signal names or numbers of specified signals]:*:signal:_signals' \
+  '(-s -l -L 1)-n[specify signal number]:signal number' \
+  '(-l -L)-q[send the specified integer with the signal using sigqueue]:value' \
+  '(-n -l -L 1)-s[specify signal name]:signal:_signals -s' \
+  '-l[list signal names or numbers of specified signals]:*:signal:_signals' \
+  '(- *)-L[list each signal and corresponding number]' \
   '(-n -s -l)1::signal:_signals -p -s' \
   '*:processes:->processes' && ret=0
   
diff --git a/Completion/Zsh/Command/_vared b/Completion/Zsh/Command/_vared
index aba64880a..e7072ca6d 100644
--- a/Completion/Zsh/Command/_vared
+++ b/Completion/Zsh/Command/_vared
@@ -10,5 +10,7 @@ _arguments -s -A "-*" \
   '-f+[specify finish widget]:widget:_widgets' \
   '-h[allow access to history]' \
   '-e[exit on EOF (^D)]' \
+  '-M+[specify keymap to link to main]:keymap:compadd -a keymaps' \
+  '-m+[specify keymap to link to vicmd]:keymap:compadd -a keymaps' \
   '1:parameter spec:_vars'
 
diff --git a/Completion/Zsh/Command/_zle b/Completion/Zsh/Command/_zle
index 0b8ef7a15..97ec8c875 100644
--- a/Completion/Zsh/Command/_zle
+++ b/Completion/Zsh/Command/_zle
@@ -23,6 +23,7 @@ _arguments -s -S \
     \(${(j. .)opts:#-[La]}')-l+[list user-defined widgets]:*:-:->listing' \
     \(${(j. .)opts:#-l}')-a[with -l, list all widgets]' \
     "(: * ${(j. .)opts:#-[Lw]})-F[install file descriptor handler]:file descriptor:_file_descriptors::handler:_functions" \
+    "($opts)-I[invalidate the current zle display]" \
     "!($opts)-K:keymap:compadd -a keymaps" \
     "($opts)-M[display message]:message: " \
     "($opts)-N[define new widget]:widget name:->widget-or-function ::widget shell function:->function" \
diff --git a/Completion/Zsh/Context/_brace_parameter b/Completion/Zsh/Context/_brace_parameter
index d4b750c3d..66be4f7cd 100644
--- a/Completion/Zsh/Context/_brace_parameter
+++ b/Completion/Zsh/Context/_brace_parameter
@@ -140,7 +140,7 @@ if [[ $PREFIX = *'${('[^\)]# ]]; then
     flags+=("m:count number of character code points in padding calculation")
   fi
   flags+=(
-    "#:evaluate as numeric expression"
+    "#:interpret numeric expression as character code"
     "@:prevent double-quoted joining of arrays"
     "*:enable extended globs for pattern"
     "A:assign as an array parameter"
@@ -156,7 +156,8 @@ if [[ $PREFIX = *'${('[^\)]# ]]; then
     "i:sort case-insensitively"
     "k:substitute keys of associative arrays"
     "L:lower case all letters"
-    "n:sort decimal integers numerically"
+    "n:sort positive decimal integers numerically"
+    "-:sort decimal integers numerically"
     "o:sort in ascending order (lexically if no other sort option)"
     "O:sort in descending order (lexically if no other sort option)"
     "P:use parameter value as name of parameter for redirected lookup"
diff --git a/Completion/Zsh/Context/_dynamic_directory_name b/Completion/Zsh/Context/_dynamic_directory_name
index f449c3b12..5e0d73a8d 100644
--- a/Completion/Zsh/Context/_dynamic_directory_name
+++ b/Completion/Zsh/Context/_dynamic_directory_name
@@ -1,15 +1,29 @@
 #autoload
+local -a dirfuncs=(
+    ${(k)functions[zsh_directory_name]}
+    $zsh_directory_name_functions
+)
+local descr='dynamically named directory'
 
-local func
-integer ret=1
+if (( $#dirfuncs )); then
+  local -a expl
+  local -i ret
+  local func suf tag=dynamically-named-directories
 
-if [[ -n $functions[zsh_directory_name] || \
-  ${+zsh_directory_name_functions} -ne 0 ]] ; then
-  [[ -n $functions[zsh_directory_name] ]] && zsh_directory_name c && ret=0
-  for func in $zsh_directory_name_functions; do
-    $func c && ret=0
+  [[ $ISUFFIX != \]* ]] &&
+      suf=-S]
+
+  _tags "$tag"
+  while _tags; do
+    while _next_label "$tag" expl "$descr" $suf; do
+      for func in $dirfuncs; do
+        $func c && ret=0
+      done
+    done
+    (( ret )) || break
   done
   return ret
+
 else
-  _message 'dynamic directory name: implemented as zsh_directory_name c'
+  _message "${descr}: implement as zsh_directory_name c"
 fi
diff --git a/Completion/Zsh/Context/_parameter b/Completion/Zsh/Context/_parameter
index 7e7788535..b08d665f5 100644
--- a/Completion/Zsh/Context/_parameter
+++ b/Completion/Zsh/Context/_parameter
@@ -1,3 +1,8 @@
 #compdef -parameter-
 
+if compset -P '*:'; then
+  _history_modifiers p
+  return
+fi
+
 _parameters -e
diff --git a/Completion/Zsh/Context/_redirect b/Completion/Zsh/Context/_redirect
index e6da5d115..520a7666e 100644
--- a/Completion/Zsh/Context/_redirect
+++ b/Completion/Zsh/Context/_redirect
@@ -15,4 +15,5 @@ if [[ "$CURRENT" != "1" ]]; then
   fi
 fi
 
-_dispatch -redirect-,{${compstate[redirect]},-default-},${^strs}
+_dispatch -redirect-,${compstate[redirect]},$_comp_command \
+	  -redirect-,{${compstate[redirect]},-default-},${^strs}
diff --git a/Completion/Zsh/Type/_command_names b/Completion/Zsh/Type/_command_names
index b1c35f013..d445be06e 100644
--- a/Completion/Zsh/Type/_command_names
+++ b/Completion/Zsh/Type/_command_names
@@ -4,7 +4,7 @@
 # complete only external commands and executable files. This and a
 # `-' as the first argument is then removed from the arguments.
 
-local args defs ffilt
+local args defs expl ffilt verbose
 
 zstyle -t ":completion:${curcontext}:commands" rehash && rehash
 
@@ -16,8 +16,12 @@ defs=(
   'commands:external command:_path_commands'
 )
 
-[[ -n "$path[(r).]" || $PREFIX = */* ]] &&
-    defs+=( 'executables:executable file:_files -g \*\(-\*\)' )
+if [[ -n "$path[(r).]" || $PREFIX = */* ]]; then
+  defs+=( 'executables:executable file:_files -g \*\(-\*\)' )
+else
+  # this is ignored but exists to facilitate the use of the fake style
+  _description executables expl 'executable file'
+fi
 
 if [[ "$1" = -e ]]; then
   shift
@@ -29,13 +33,19 @@ else
   defs=( "$defs[@]"
     'builtins:builtin command:compadd -Qk builtins'
     "functions:shell function:compadd -k 'functions$ffilt'"
-    'aliases:alias:compadd -Qk aliases'
     'suffix-aliases:suffix alias:_suffix_alias_files'
     'reserved-words:reserved word:compadd -Qk reswords'
     'jobs:: _jobs -t'
     'parameters:: _parameters -g "^*(readonly|association)*" -qS= -r "\n\t\- =[+"'
     'parameters:: _parameters -g "*association*~*readonly*" -qS\[ -r "\n\t\- =[+"'
   )
+
+  if zstyle -T ":completion:${curcontext}:aliases" verbose; then
+    printf -v verbose %s:%s\  ${(@q+)${(kv)aliases}[@]//\:/\\:}
+    defs+=( "aliases:alias:(( $verbose ))" )
+  else
+    defs+=( 'aliases:alias:compadd -Qk aliases' )
+  fi
 fi
 
 args=( "$@" )
@@ -58,7 +68,7 @@ fi
 if (( $#cmdpath )); then
   local -a +h path
   local -A +h commands
-  path=( $cmdpath )
+  path=( $cmdpath:A )
 fi
 
 _alternative -O args "$defs[@]"
diff --git a/Completion/Zsh/Type/_globquals b/Completion/Zsh/Type/_globquals
index 915f97c1c..beb47ed30 100644
--- a/Completion/Zsh/Type/_globquals
+++ b/Completion/Zsh/Type/_globquals
@@ -127,16 +127,14 @@ while [[ -n $PREFIX ]]; do
 	alts+=( "time-specifiers:time specifier:compadd -E 0 -d tdisp -S '' -a tmatch" )
       fi
       if ! compset -P '[-+]' && [[ -z $PREFIX ]]; then
-	sdisp=( before exactly since )
-	smatch=( - '' + )
 	if zstyle -t ":completion:${curcontext}:senses" verbose; then
 	  zstyle -s ":completion:${curcontext}:senses" list-separator sep || sep=--
 	  default=" [default exactly]"
-	  sdisp=( "- $sep before" "+ $sep since" )
-	  smatch=( - + )
+          sdisp=( "+ $sep before (older files)" "- $sep since (newer files)" )
+	  smatch=( + - )
 	else
 	  sdisp=( before exactly since )
-	  smatch=( - '' + )
+	  smatch=( + '' - )
 	fi
         alts+=( "senses:sense${default}:compadd -E 0 -d sdisp -S '' -a smatch" )
       fi
@@ -270,6 +268,7 @@ case $state in
     "P:prepend word"
     "Y:+ at most ARG matches"
     "[:+ range of files"
+    ",:logical OR"
     "):end of qualifiers"
     "\::modifier"
     )
diff --git a/Completion/Zsh/Type/_parameters b/Completion/Zsh/Type/_parameters
index b5da45c58..7b7692a3c 100644
--- a/Completion/Zsh/Type/_parameters
+++ b/Completion/Zsh/Type/_parameters
@@ -6,11 +6,6 @@
 # If you specify a -g option with a pattern, the pattern will be used to
 # restrict the type of parameters matched.
 
-if compset -P '*:'; then
-  _history_modifiers p
-  return
-fi
-
 local i pfilt
 local -i nm=$compstate[nmatches]
 local -a expl pattern=( -g \* ) normal described verbose faked fakes tmp
@@ -21,7 +16,7 @@ zstyle -t ":completion:${curcontext}:parameters" prefix-needed &&
 _description parameters expl parameter
 zparseopts -D -K -E g:=pattern
 
-if zstyle -t ":completion:${curcontext}:parameters" extra-verbose; then
+if zstyle -t ":completion:${curcontext}:parameters" verbose; then
   described=(
       "${(@M)${(@k)parameters[(R)$~pattern[2]~*(hideval|local|special)*]}:#$~pfilt*}"
   )
diff --git a/Completion/Zsh/Type/_ps1234 b/Completion/Zsh/Type/_ps1234
index 0ea2cdda9..e4391dc00 100644
--- a/Completion/Zsh/Type/_ps1234
+++ b/Completion/Zsh/Type/_ps1234
@@ -1,17 +1,18 @@
-#compdef -value-,PROMPT,-default- -value-,PROMPT2,-default- -value-,PROMPT3,-default- -value-,PROMPT4,-default- -value-,RPROMPT,-default- -value-,RPROMPT2,-default- -value-,PS1,-default- -value-,PS2,-default- -value-,PS3,-default- -value-,PS4,-default- -value-,RPS1,-default- -value-,RPS2,-default- -value-,SPROMPT,-default-
+#compdef -value-,PROMPT,-default- -value-,PROMPT2,-default- -value-,PROMPT3,-default- -value-,PROMPT4,-default- -value-,RPROMPT,-default- -value-,RPROMPT2,-default- -value-,PS1,-default- -value-,PS2,-default- -value-,PS3,-default- -value-,PS4,-default- -value-,RPS1,-default- -value-,RPS2,-default- -value-,SPROMPT,-default- -value-,PROMPT_EOL_MARK,-default-
 
-local -a specs ccol
-local expl grp cols bs suf pre changed=1 ret=1
+local -a specs ccol suf
+local expl grp cols bs pre changed=1 ret=1
 local -A ansi
 
 [[ -z $compstate[quote] ]] && bs='\'
+suf=( -S '' )
 
 # first strip off any complete prompt specifications leaving only the
 # current, incomplete, one
 while (( changed )); do
   changed=0
-  compset -P '%[DFK](\\|){[^}]#}' && changed=1 # formats with arg: %x{...}
-  compset -P '%[0-9-\\]#[^DFK(0-9-<>\\\[]' && changed=1 # normal formats
+  compset -P '%[DFHK](\\|){[^}]#}' && changed=1 # formats with arg: %x{...}
+  compset -P '%[0-9-\\]#[^DFHK(0-9-<>\\\[]' && changed=1 # normal formats
   compset -P '%[0-9-\\]#(<[^<]#<|>[^>]#>|\[[^\]]#\])' && changed=1 # truncations
   compset -P '%[0-9-\\]#(\\|)\([0-9-]#[^0-9]?|[^%]' && changed=1 # start of ternary
   compset -P '[^%]##' && changed=1 # sundry other characters
@@ -41,15 +42,15 @@ if compset -P '%[FK]'; then
   grp="$expl[expl[(i)-J]+1]"
   print -v ccol -f "($grp)=%s=%s" ${(kv)ansi}
   _comp_colors+=( $ccol )
-  compadd "$expl[@]" $suf $pre -k ansi && ret=0
-  if (( $#suf )) && compset -P "(<->|%v)"; then
+  compadd "$expl[@]" "$suf[@]" $pre -k ansi && ret=0
+  if [[ $ISUFFIX != (\\|)}* ]] && compset -P "(<->|%v)"; then
     _wanted ansi-colors expl 'closing brace' compadd -S '' \} && ret=0
   elif (( $+terminfo[colors] )); then
     (( cols = $terminfo[colors] - 1 ))
     (( cols = cols > 255 ? 255 : cols ))
     _description -V terminal-colors expl 'terminal color'
     grp="$expl[expl[(i)-J]+1]"
-    compadd "$expl[@]" $suf $pre {0..$cols}
+    compadd "$expl[@]" "$suf[@]" $pre {0..$cols}
     for c in {0..$cols}; do
       _comp_colors+=( "($grp)=${c}=${${${(%):-%F{$c\}}#?\[}%m}" )
     done
@@ -93,11 +94,14 @@ elif compset -P '%[0-9-\\]#(\\|)\([0-9-]#'; then
     'w:day of week (Sunday = 0)'
   )
   [[ $IPREFIX != *- ]] && _describe -t ternary-prompt-expressions \
-      'ternary prompt format test character' specs $suf && ret=0
+      'ternary prompt format test character' specs "$suf[@]" && ret=0
   _message -e numbers number
 elif compset -P '%D(\\|){'; then
   compset -S '(\\|)}*'
   _date_formats zsh && ret=0
+elif compset -P '%H(\\|){'; then
+  compset -S '(\\|)}*' || suf=( -S "$bs}" )
+  _wanted highlight-groups expl 'highlight group' compadd "$suf[@]" -k .zle.hlgroups && ret=0
 elif [[ -prefix '%' ]] ||
       ! zstyle -t ":completion:${curcontext}:prompt-format-specifiers" prefix-needed
 then
@@ -152,6 +156,7 @@ then
       'B:start bold'
       'b:stop bold'
       'E:clear to end of line'
+      'H{:use highlight group'
       'U:start underline'
       'u:stop underline'
       'S:start standout'
diff --git a/Completion/Zsh/Type/_suffix_alias_files b/Completion/Zsh/Type/_suffix_alias_files
index 1c2c8ebb5..b6fa4e7f5 100644
--- a/Completion/Zsh/Type/_suffix_alias_files
+++ b/Completion/Zsh/Type/_suffix_alias_files
@@ -16,6 +16,7 @@ else
     tmpa=(${(kq)saliases})
     pat="*.(${(kj.|.)tmpa})"
 fi
+[[ -o autocd ]] || pat+='(#q^/)'
 
 # _wanted is called for us by _command_names
 _path_files "$@" -g $pat
diff --git a/Completion/bashcompinit b/Completion/bashcompinit
index b278ac8f4..adb659ca1 100644
--- a/Completion/bashcompinit
+++ b/Completion/bashcompinit
@@ -24,9 +24,10 @@ _bash_complete() {
     if [[ ${argv[${argv[(I)filenames]:-0}-1]} = -o ]]; then
       compset -P '*/' && matches=( ${matches##*/} )
       compset -S '/*' && matches=( ${matches%%/*} )
-      compadd -Q -f "${suf[@]}" -a matches && ret=0
+      compadd -f "${suf[@]}" -a matches && ret=0
     else
-      compadd -Q "${suf[@]}" -a matches && ret=0
+      compadd "${suf[@]}" - "${(@)${(Q@)matches}:#*\ }" && ret=0
+      compadd -S ' ' - ${${(M)${(Q)matches}:#*\ }% } && ret=0
     fi
   fi
 
diff --git a/Completion/compdump b/Completion/compdump
index e0dc8b805..5af5174f1 100644
--- a/Completion/compdump
+++ b/Completion/compdump
@@ -16,7 +16,7 @@
 emulate -L zsh
 setopt extendedglob noshglob
 
-typeset _d_file _d_f _d_bks _d_line _d_als _d_files _d_name _d_tmp
+typeset _d_file _d_f _d_fd _d_bks _d_line _d_als _d_files _d_name _d_tmp
 
 _d_file=${_comp_dumpfile-${0:h}/compinit.dump}.$HOST.$$
 [[ $_d_file = //* ]] && _d_file=${_d_file[2,-1]}
@@ -33,44 +33,45 @@ if [[ -n "$_comp_secure" ]]; then
   (( $#_d_wdirs ))  && _d_files=( "${(@)_d_files:#(${(j:|:)_d_wdirs})/*}" )
 fi
 
-print "#files: $#_d_files\tversion: $ZSH_VERSION" > $_d_file
+exec {_d_fd}>$_d_file
+print "#files: $#_d_files\tversion: $ZSH_VERSION" >& $_d_fd
 
 # Dump the arrays _comps, _services and _patcomps.  The quoting
 # hieroglyphics ensure that a single quote inside a variable is itself
 # correctly quoted.
 
-print "\n_comps=(" >> $_d_file
+print "\n_comps=(" >& $_d_fd
 for _d_f in ${(ok)_comps}; do
   print -r - "${(qq)_d_f}" "${(qq)_comps[$_d_f]}"
-done >> $_d_file
-print ")" >> $_d_file
+done >& $_d_fd
+print ")" >& $_d_fd
 
-print "\n_services=(" >> $_d_file
+print "\n_services=(" >& $_d_fd
 for _d_f in ${(ok)_services}; do
   print -r - "${(qq)_d_f}" "${(qq)_services[$_d_f]}"
-done >> $_d_file
-print ")" >> $_d_file
+done >& $_d_fd
+print ")" >& $_d_fd
 
-print "\n_patcomps=(" >> $_d_file
+print "\n_patcomps=(" >& $_d_fd
 for _d_f in ${(ok)_patcomps}; do
   print -r - "${(qq)_d_f}" "${(qq)_patcomps[$_d_f]}"
-done >> $_d_file
-print ")" >> $_d_file
+done >& $_d_fd
+print ")" >& $_d_fd
 
 _d_tmp="_postpatcomps"
-print "\n_postpatcomps=(" >> $_d_file
+print "\n_postpatcomps=(" >& $_d_fd
 for _d_f in ${(ok)_postpatcomps}; do
   print -r - "${(qq)_d_f}" "${(qq)_postpatcomps[$_d_f]}"
-done >> $_d_file
-print ")" >> $_d_file
+done >& $_d_fd
+print ")" >& $_d_fd
 
-print "\n_compautos=(" >> $_d_file
+print "\n_compautos=(" >& $_d_fd
 for _d_f in "${(ok@)_compautos}"; do
   print -r - "${(qq)_d_f}" "${(qq)_compautos[$_d_f]}"
-done >> $_d_file
-print ")" >> $_d_file
+done >& $_d_fd
+print ")" >& $_d_fd
 
-print >> $_d_file
+print >& $_d_fd
 
 # Now dump the key bindings. We dump all bindings for zle widgets
 # whose names start with a underscore.
@@ -90,15 +91,15 @@ zle -lL |
       print -r - ${_d_line}
       _d_bks+=(${_d_line[3]})
     fi
-  done >> $_d_file
+  done >& $_d_fd
 bindkey |
   while read -rA _d_line; do
     if [[ ${_d_line[2]} = (${(j.|.)~_d_bks}) ]]; then
       print -r "bindkey '${_d_line[1][2,-2]}' ${_d_line[2]}"
     fi
-  done >> $_d_file
+  done >& $_d_fd
 
-print >> $_d_file
+print >& $_d_fd
 
 
 # Autoloads: look for all defined functions beginning with `_' (that also
@@ -109,29 +110,30 @@ _d_als=($^fpath/(${(o~j.|.)$(typeset +fm '_*')})(N:t))
 # print them out:  about five to a line looks neat
 
 integer _i=5
-print -n autoload -Uz >> $_d_file
+print -n autoload -Uz >& $_d_fd
 while (( $#_d_als )); do
   if (( ! $+_compautos[$_d_als[1]] )); then
-    print -n " $_d_als[1]"
+    print -rn " ${(q-)_d_als[1]}"
     if (( ! --_i && $#_d_als > 1 )); then
       _i=5
       print -n ' \\\n           '
     fi
   fi
   shift _d_als
-done >> $_d_file
+done >& $_d_fd
 
-print >> $_d_file
+print >& $_d_fd
 
 local _c
 for _c in "${(ok@)_compautos}"; do
-  print "autoload -Uz $_compautos[$_c] $_c" >> $_d_file
+  print -r "autoload -Uz ${(q-)_compautos[$_c]} $_c" >& $_d_fd
 done
 
-print >> $_d_file
+print >& $_d_fd
 
-print "typeset -gUa _comp_assocs" >> $_d_file
-print "_comp_assocs=( ${(qq)_comp_assocs} )" >> $_d_file
+print "typeset -gUa _comp_assocs" >& $_d_fd
+print -r "_comp_assocs=( ${(qq)_comp_assocs} )" >& $_d_fd
+exec {_d_fd}>&-
 
 mv -f $_d_file ${_d_file%.$HOST.$$}
 
diff --git a/Completion/compinit b/Completion/compinit
index 1f2e7c634..51e9d88b8 100644
--- a/Completion/compinit
+++ b/Completion/compinit
@@ -301,7 +301,7 @@ compdef() {
     if [[ -z "$eval" ]] && [[ "$1" = *\=* ]]; then
       while (( $# )); do
         if [[ "$1" = *\=* ]]; then
-	  cmd="${1%%\=*}"
+	  cmd="${(q)${1%%\=*}}"
 	  svc="${1#*\=}"
           func="$_comps[${_services[(r)$svc]:-$svc}]"
           [[ -n ${_services[$svc]} ]] &&
@@ -329,7 +329,7 @@ compdef() {
     # and probably do autoloading.
 
     func="$1"
-    [[ -n "$autol" ]] && autoload -Uz "$func"
+    [[ -n "$autol" ]] && autoload -rUz "$func"
     shift
 
     case "$type" in
@@ -412,7 +412,7 @@ compdef() {
 	      svc=
             fi
             if [[ -z "$new" || -z "${_comps[$1]}" ]]; then
-              _comps[$cmd]="$func"
+              _comps[$cmd]="${(q)func}"
 	      [[ -n "$svc" ]] && _services[$cmd]="${1#*\=}"
 	    fi
             ;;
@@ -451,7 +451,7 @@ typeset _i_wdirs _i_wfiles
 _i_wdirs=()
 _i_wfiles=()
 
-autoload -Uz compaudit
+autoload -RUz compaudit
 if [[ -n "$_i_check" ]]; then
   typeset _i_q
   if ! eval compaudit; then
@@ -467,19 +467,17 @@ Ignore insecure $_i_q and continue [y] or abort compinit [n]? "; then
 
           return 1
         fi
-        _i_wfiles=()
-	_i_wdirs=()
-      else
-        (( $#_i_wfiles )) && _i_files=( "${(@)_i_files:#(${(j:|:)_i_wfiles%.zwc})}"  )
-        (( $#_i_wdirs ))  && _i_files=( "${(@)_i_files:#(${(j:|:)_i_wdirs%.zwc})/*}" )
       fi
+      fpath=(${fpath:|_i_wdirs})
+      (( $#_i_wfiles )) && _i_files=( "${(@)_i_files:#(${(j:|:)_i_wfiles%.zwc})}"  )
+      (( $#_i_wdirs ))  && _i_files=( "${(@)_i_files:#(${(j:|:)_i_wdirs%.zwc})/*}" )
     fi
     typeset -g _comp_secure=yes
   fi
 fi
 
 # Make sure compdump is available, even if we aren't going to use it.
-autoload -Uz compdump compinstall
+autoload -RUz compdump compinstall
 
 # If we have a dump file, load it.
 
@@ -538,7 +536,7 @@ if [[ -z "$_i_done" ]]; then
 	fi
 	;;
       (\#autoload)
-	autoload -Uz "$_i_line[@]" ${_i_name}
+	autoload -rUz "$_i_line[@]" ${_i_name}
 	[[ "$_i_line" != \ # ]] && _compautos[${_i_name}]="$_i_line"
 	;;
       esac
@@ -570,6 +568,6 @@ if [[ ${_i_line[2]} = expand-or-complete ]] &&
 fi
 
 unfunction compinit compaudit
-autoload -Uz compinit compaudit
+autoload -RUz compinit compaudit
 
 return 0