Subject: PATCH: update options in various completion functions
From: Oliver Kiddle <[email-masked]>
To: Zsh workers <[email-masked]>
Date: Fri, 19 Aug 2016 17:24:32 +0200
List-Id: Zsh Workers List <zsh-workers.zsh.org>

This updates a few functions. Mostly nothing more significant than
adding options from newer versions.

_arping: updated to 2.15, options in iputils arping are unchanged
  Also fixed where this had been broken for the -i/-I option.
  _pick_variant must have gone wrong for someone or perhaps there's
  a third arping implementation.
_augeas: updated options to 1.6.0
_diff_options: update uptions, diffutils 3.4
_dbus: would be updated to 1.11.2 if the documentation wasn't crap
  Is it --address or --bus/--peer?
_gpasswd: this mostly just amounts to using _sequence. valid to 4.2.1
_grep: updated options to GNU grep 2.20 and fixes for zgrep
_less: updated options to 481
_make: updated options up to GNU make 4.2.1
_mutt: updated options 1.6.2
_rsync: updated to 3.1.2, mostly correcting options applicable with --daemon
_scl: updated to 2.0.1
_sed: add -z option (GNU sed 4.2.2)
_sort: only an exclusion list change, verified options against 8.25
_ss: updated options up to 160111
_ssh: updated for OpenSSH 7.3p1, mostly ssh-keygen
_tree: update options to 1.7.0
_tmux: updated for new sub-commands up to 2.2. Also needed lots of
  trivial changes like + after options that take and argument and
  the case of descriptions. So the patch for this is quite long but
  there's little real substance to it.
_uniq: --group option (coreutils 8.25)
_user_admin: updated options for shadow-utils 4.2.1 and Solaris 11.3
  also checked options against online manpages for net/openbsd
_wget: still out-of-date but the one change has sat on my git branch for a while
_xargs: --process-slot-var (4.6.0)
_zip: updated options for InfoZip zip 3.0 / unzip 6.0

Oliver

diff --git a/Completion/Linux/Command/_gpasswd b/Completion/Linux/Command/_gpasswd
index 9b4bede..24fe361 100644
--- a/Completion/Linux/Command/_gpasswd
+++ b/Completion/Linux/Command/_gpasswd
@@ -1,21 +1,12 @@
 #compdef gpasswd
-local curcontext=$curcontext state state_descr line
-typeset -A opt_args
 
-_arguments -C -w -s \
+_arguments -s \
   '(-a --add -d --delete)'{-a,--add}'[add user to group]: : _users' \
   '(-d --delete -a --add)'{-d,--delete}'[remove user from group]: : _users' \
-  '(-h --help)'{-h,--help}'[display help]' \
-  '(-Q --root)'{-Q,--root}'[directory to chroot into]: : _files -/' \
+  '(-)'{-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 --restrict)'{-R,--restrict}'[restrict access to GROUP to its members]' \
-  '(-M --members -A --administrators)'{-M,--members}'[set the list of members of GROUP]: :->users' \
-  '(-A --administrators -M --members)'{-A,--administrators}'[set the list of admins for GROUP]: :->users' \
+  '(-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' \
   '1: : _groups'
-
-if [[ $state == users ]]; then
-  local -a ignore
-  compset -P '*,'; compset -S ',*'
-  ignore=( ${(s:,:)IPREFIX} ${(s:,:)ISUFFIX} )
-  _users -F ignore -qS ,
-fi
diff --git a/Completion/Linux/Command/_ss b/Completion/Linux/Command/_ss
index 95aa798..520fd4b 100644
--- a/Completion/Linux/Command/_ss
+++ b/Completion/Linux/Command/_ss
@@ -19,6 +19,11 @@ _arguments -C -s \
   "($info -p --processes)"{-p,--processes}'[show process using each socket]' \
   "($info -i --info)"{-i,--info}'[show internal TCP information]' \
   "($info -s --summary)"{-s,--summary}'[print summary statistics]' \
+  "($info -b --bpf)"{-b,--bpf}'[show bpf filter socket information]' \
+  "($info -E --events)"{-E,--events}'[continually display sockets as they are destroyed]' \
+  "($info -Z --context)"{-Z,--context}'[display process SELinux security contexts]' \
+  "($info -z --contexts)"{-z,--contexts}'[display process and socket SELinux security contexts]' \
+  "($info -N --net)"{-N,--net}'[switch to specified network namespace]:network namespace' \
   "($info -4 --ipv4 -6 --ipv6)"{-4,--ipv4}'[display only IP version 4 sockets]' \
   "($info -4 --ipv4 -6 --ipv6)"{-6,--ipv6}'[display only IP version 6 sockets]' \
   "($info -0 --packet)"{-0,--packet}'[display PACKET sockets]' \
@@ -28,7 +33,7 @@ _arguments -C -s \
   "($info -w --raw)"{-w,--raw}'[display RAW sockets]' \
   "($info -x --unix)"{-x,--unix}'[display Unix domain sockets]' \
   "($info -f --family)"{-f,--family}'[display sockets of specified type]:family:(unix inet inet6 link netlink)' \
-  "($info -A --query --socket)"{-A,--query,--socket}'[specify socket tables to show]: :_values -s , socket\ table all inet tcp udp raw unix packet netlink unix_dgram unix_stream packet_raw packet_dgram' \
+  "($info -A --query --socket)"{-A,--query,--socket}'[specify socket tables to show]: :_values -s , socket\ table all inet tcp udp raw unix packet netlink unix_dgram unix_stream unix_seqpacket packet_raw packet_dgram' \
   "($info -D)"{-D,--diag=}'[dump raw info to file]:file:_files' \
   "($info -F)"{-F,--filter=}'[read filter information from a file]:file:_files' \
   "($info)*: :->filter" && ret=0
diff --git a/Completion/Redhat/Command/_scl b/Completion/Redhat/Command/_scl
index e1a4b69..b7bba2b 100644
--- a/Completion/Redhat/Command/_scl
+++ b/Completion/Redhat/Command/_scl
@@ -8,7 +8,8 @@ local -a state line force alts cmd
 
 _arguments -C $force \
   '(- 1)'{-l,--list}'[list installed software collections or packages within a collection]' \
-  '(-l --list)1:action:(enable register deregister)' \
+  '(-l --list)1:action:(enable run load unload list-collections list-packages man register deregister)' \
+  '(- *)--help' \
   '(-)*:collections:->collections' && ret=0
 
 if [[ -n $state ]]; then
@@ -31,7 +32,7 @@ if [[ -n $state ]]; then
     cmd='command:command:_cmdstring'
 
   _alternative 'collections:collection:compadd
-      $(_call_program collections ${words[1]} -l)' \
+      $(_call_program collections "${words[1]} list-collections || ${words[1]} -l")' \
       $cmd && ret=0
 fi
 
diff --git a/Completion/Unix/Command/_arping b/Completion/Unix/Command/_arping
index 5edda21..bd9bc8c 100644
--- a/Completion/Unix/Command/_arping
+++ b/Completion/Unix/Command/_arping
@@ -1,6 +1,6 @@
 #compdef arping
 
-if _pick_variant iputils=iputils unix -V; then
+if _pick_variant iputils=iputils thabets -V; then
 
 _arguments -s \
   '-f[quit on first reply]' \
@@ -18,25 +18,35 @@ _arguments -s \
 
 else
 
-_arguments -s \
-  '(-)-h[display help information]' \
+_arguments -s -S  -A "-*" \
+  '(-)'{-h,--help}'[display help information]' \
   '-q[only display error messages]' \
   '-a[audible ping]' \
   '*-v[verbose output]' \
   '-r[raw output: only the MAC/IP address displayed]' \
   '-R[like -r but shows "the other one"]' \
   '-d[find duplicate replies]' \
+  '-D[display answers as exclamation marks and missing packets as dots]' \
+  '-e[like -a but beep when there is no reply]' \
+  "-F[don't try to be smart about the interface name]" \
+  '-m+[specify type of timestamp for incoming packets]:timestamp type' \
   '(:)-B[255.255.255.255]' \
   '-0[source 0.0.0.0]' \
   '-b[source 255.255.255.255]' \
-  '-S[set source IP]:source IP address:_hosts' \
-  '-T[target IP]:target IP address:_hosts' \
+  '-S+[set source IP]:source IP address:_hosts' \
+  '-T+[target IP]:target IP address:_hosts' \
   '-p[turn on promiscuous mode]' \
   '-s[set source MAC address]:source MAC address' \
   '-t[set target MAC address]:target MAC address' \
   '-c[send this many requests]:count' \
-  '-I[interface]:interface:_net_interfaces' \
+  '-C[only wait for specified replies]:reply count' \
+  '-i+[interface]:interface:_net_interfaces' \
   '-A[only count addresses matching requested address]' \
+  '-P[send ARP replies instead of requests]' \
+  '-u[show index=received/sent instead of just index=received when pinging MACs]' \
+  '-U[send unsolicited ARP]' \
+  '-w+[specify time to wait between pings (ms)]:time (ms)' \
+  '-W+[specify time to wait between pings (seconds)]:time (seconds)' \
   '(-B):address:_hosts'
  
 fi
diff --git a/Completion/Unix/Command/_augeas b/Completion/Unix/Command/_augeas
index 622fa34..f9c0521 100644
--- a/Completion/Unix/Command/_augeas
+++ b/Completion/Unix/Command/_augeas
@@ -9,6 +9,8 @@ _arguments -C -s \
   '(-n --new)'{-n,--new}'[leave files untouched but save changes with a .augnew extension]' \
   '(-r --root)'{-r,--root=}'[specify filesystem root]:root directory:_files -/' \
   \*{-I+,--include=}'[add directory containing lenses to search path]:directory:_files -/' \
+  \*{-t+,--transform=}'[add a file transform]:xfm' \
+  '(-l --load-file)'{-l+,--load-file=}'[load individual file in the tree]:file:_files' \
   '(-f --file *)'{-f+,--file=}'[read commands from specified file]:file:_files' \
   '(-i --interactive)'{-i,--interactive}'[read commands from the terminal]' \
   '(-e --echo)'{-e,--echo}'[echo commands read from a file or stdin]' \
@@ -17,6 +19,7 @@ _arguments -C -s \
   '(-L --noload)'{-L,--noload}'[do not load any files into the tree on startup]' \
   '(-A --noautoload)'{-A,--noautoload}'[do not autoload modules from the search path]' \
   '--span[load span positions for nodes related to a file]' \
+  '--timing[after executing each command, show how long it took]' \
   '(- *)--version[print version information]' \
   '(-)'{-h,--help}'[print help information]' \
   '*:: :->subcommands' && ret=0
@@ -25,7 +28,7 @@ _arguments -C -s \
 
 if [[ CURRENT -eq 1 || $words[1] == help ]]; then
   local -a subcmds
-  subcmds=( ${${${(f)"$(_call_program subcommands augtool help 2>/dev/null)"}[2,-2]## #}// #- /:} )
+  subcmds=( ${${${(M)${(f)"$(_call_program subcommands augtool help 2>/dev/null)"}:#  *}## #}// #- /:} )
   _describe -t subcommands "augtool command" subcmds && ret=0
   return ret
 fi
diff --git a/Completion/Unix/Command/_dbus b/Completion/Unix/Command/_dbus
index bdd7613..b24a6e9 100644
--- a/Completion/Unix/Command/_dbus
+++ b/Completion/Unix/Command/_dbus
@@ -13,16 +13,19 @@ case $service in
       '--print-reply=-::format:(literal)' \
       '--reply-timeout=-:timeout (ms)' \
       '--type=-:type:(method_call signal)' \
+      '(* -)--help' \
       ':object path:->objectpaths' \
       ':message name:->methods' \
       ':content:->contents' && ret=0
   ;;
   dbus-monitor)
     _arguments -A "--*" -C \
-      '(--session)--system' '(--system)--session' \
+      '*:watch expression:->expressions' \
+      - '(bus)' \
+      --system --session
       '--address=-:bus address:->addresses' \
-      '(--profile)--monitor' '(--monitor)--profile' \
-      '*:watch expression:->expressions' && ret=0
+      - '(format)' \
+      --monitor --profile --pcap --binary && ret=0
   ;;
 esac
 
@@ -30,7 +33,7 @@ case $state in
   addresses)
     compset -P '*;'
     if compset -P '*='; then
-      _files  && ret=0
+      _files && ret=0
     else
       _message -e addresses address
     fi
diff --git a/Completion/Unix/Command/_grep b/Completion/Unix/Command/_grep
index d987c2b..5d548b5 100644
--- a/Completion/Unix/Command/_grep
+++ b/Completion/Unix/Command/_grep
@@ -1,4 +1,4 @@
-#compdef grep egrep fgrep bsdgrep zgrep, zegrep, zfgrep -value-,GREP_OPTIONS,-default-
+#compdef grep egrep fgrep bsdgrep zgrep zegrep zfgrep -value-,GREP_OPTIONS,-default-
 # Ulrik Haugen 2001
 
 local arguments matchers command
@@ -9,14 +9,16 @@ if [[ $service = *GREP_OPT* ]]; then
   (( CURRENT++ ))
   command=grep
 else
-  arguments=(
-    '(-e --regexp -f --file)1: :_guard "^--*" pattern'
-    '*:files:_files'
-  )
+  arguments=( '(-e --regexp -f --file)1: :_guard "^--*" pattern' )
+  if [[ $service = z* ]]; then
+    arguments+=( '*:files:_files -g "*.gz(-.)"' )
+  else
+    arguments+=( '*:files:_files' )
+  fi
   command="$words[1]"
 fi
 
-if [[ $service != [ef]grep ]]; then
+if [[ $service != (|z)[ef]grep ]]; then
   matchers='(--extended-regexp --fixed-strings --basic-regexp --perl-regexp -E -F -G -P)'
   arguments+=(
     $matchers{--extended-regexp,-E}'[use extended regular expression]'
@@ -26,15 +28,18 @@ if [[ $service != [ef]grep ]]; then
   )
 fi
 
-arguments=( $arguments[@]
+arguments+=(
   '(--after-context -A)'{--after-context=,-A+}'[specify lines of trailing context]:lines'
   '(--text -a --binary-files -I)'{--text,-a}'[process binary file as if it were text]'
   '(--before-context -B)'{--before-context=,-B+}'[specify lines of leading context]:lines'
   '(--context,-C)'{--context=,-C-}'[specify lines of context]:lines'
   '(--color --colour)--'{color,colour}'=-[distinguish matching string]::when:(always never auto)'
+  '(--no-group-separator)--group-separator=[specify separator between blocks of context]:separator [--]'
+  "(--group-separator)--no-group-separator[don't separate context blocks]"
   '(--byte-offset -b -c)'{--byte-offset,-b}'[print the byte offset with output lines]'
   '(--text -a -I)--binary-files=[specify type to assume for binary files]:file type:(binary without-match text)'
   '(--count -c --byte-offset -b --line-number -n)'{--count,-c}'[only print a count of matching lines]'
+  '(-T --initial-tab)'{-T,--initial-tab}'[make tabs line up (if needed)]'
   '(--directories -d -r --recursive)'{--directories=,-d+}'[specify handling of directories]:action on directory:(read skip recurse)'
   '(--devices -D)'{--devices=,-D+}'[specify handling of devices, FIFOs and sockets]:action on device:(read skip)'
   '(1)*'{--regexp=,-e+}'[specify pattern]:pattern'
@@ -51,7 +56,8 @@ arguments=( $arguments[@]
   '(--line-number -n -c)'{--line-number,-n}'[prefix output with line numbers]'
   '(--only-matching -o)'{--only-matching,-o}'[show only matching part of line]'
   '(--quiet --silent -q)'{--quiet,--silent,-q}'[suppress normal output]'
-  '(--recursive -r -R -d --directories)'{--recursive,-r,-R}'[recurse subdirectories]'
+  '(--recursive -r --dereference-recursive -R -d --directories)'{--recursive,-r}'[recurse subdirectories]'
+  '(--recursive -r --dereference-recursive -R -d --directories)'{--dereference-recursive,-R}'[recurse subdirectories, following symlinks]'
   '*--include=[examine files matching specified pattern]:file pattern'
   '*--exclude=[skip files matching specified pattern]:file pattern'
   '*--exclude-from=[skip files matching pattern in specified file]:file:_files'
@@ -63,7 +69,6 @@ arguments=( $arguments[@]
   '(--line-regexp -x --word-regexp -w)'{--line-regexp,-x}'[force pattern to match only whole lines]'
   '(--null -Z --no-filename -h)'{--null,-Z}'[print 0 byte after FILE name]'
   '--help[display help]'
-  '--mmap[memory map input]'
 )
 
 # remove long options?
diff --git a/Completion/Unix/Command/_less b/Completion/Unix/Command/_less
index a3ba8f6..9092010 100644
--- a/Completion/Unix/Command/_less
+++ b/Completion/Unix/Command/_less
@@ -32,7 +32,8 @@ fi
 
 _arguments -S -s -A "[-+]*"  \
   '(-? --help)'{-\?,--help}'[display summary of less commands]' \
-  '(-a --search-skip-screen)'{-a,--search-skip-screen}'[begin forward searches after last displayed line]' \
+  '(-a --search-skip-screen)'{-a,--search-skip-screen}'[skip current screen in searches]' \
+  '(-A --SEARCH-SKIP-SCREEN)'{-A,--SEARCH-SKIP-SCREEN}"[start searches just after target line]" \
   '(-b --buffers)'{-b+,--buffers=}'[specify amount of buffer space used for each file]:buffer space (kilobytes)' \
   '(-B --auto-buffers)'{-B,--auto-buffers}"[don't automatically allocate buffers for pipes]" \
   '(-C --CLEAR-SCREEN -c --clear-screen)'{-c,--clear-screen}'[repaint screen instead of scrolling]' \
@@ -44,12 +45,14 @@ _arguments -S -s -A "[-+]*"  \
   '(-F --quit-if-one-screen)'{-F,--quit-if-one-screen}'[exit if entire file fits on first screen]' \
   '(-G --HILITE-SEARCH -g --hilite-search)'{-g,--hilite-search}'[highlight only one match for searches]' \
   '(-g --hilite-search -G --HILITE-SEARCH)'{-G,--HILITE-SEARCH}'[disable highlighting of search matches]' \
+  '--old-bot[revert to the old bottom of screen behavior]' \
   '(-h --max-back-scroll)'{-h+,--max-back-scroll=}'[specify backward scroll limit]:backward scroll limit (lines)' \
   '(-I --IGNORE-CASE -i --ignore-case)'{-i,--ignore-case}'[ignore case in searches that lack uppercase]' \
   '(-i --ignore-case -I --IGNORE-CASE)'{-I,--IGNORE-CASE}'[ignore case in all searches]' \
   '(-j --jump-target)'{-j+,--jump-target}'[specify screen position of target lines]:position (line)' \
   '(-J --status-column)'{-J,--status-column}'[display status column on the left]' \
   \*{-k+,--lesskey-file=}'[use specified lesskey file]:lesskey file:_files' \
+  '(-K --quit-on-intr)'{-K,--quit-on-intr}'[exit less in response to ctrl-c]' \
   '(-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]' \
@@ -80,6 +83,8 @@ _arguments -S -s -A "[-+]*"  \
   '(-\" --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" \
+  '--follow-name[the F command changes file if the input file is renamed]' \
+  '--use-backslash[subsequent options use backslash as escape char]' \
   "$files[@]" && ret=0

diff --git a/Completion/Unix/Command/_make b/Completion/Unix/Command/_make
index c3f3961..d10c8ee 100644
--- a/Completion/Unix/Command/_make
+++ b/Completion/Unix/Command/_make
@@ -186,7 +186,8 @@ _make() {
       '(-l --load-average --max-load)'{-l,--load-average=,--max-load}"[don't start multiple jobs unless load is below N]:load"
       '(-L --check-symlik-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 FILE to be very old and don't remake it]:file not to remake:->file"
+      '*'{-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]'
       '(-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]'
diff --git a/Completion/Unix/Command/_mutt b/Completion/Unix/Command/_mutt
index 3d433a0..67b974a 100644
--- a/Completion/Unix/Command/_mutt
+++ b/Completion/Unix/Command/_mutt
@@ -7,11 +7,12 @@ _arguments -s -S \
   '*-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)' \
   '-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' \
-  '-h[display help]' \
+  '(- :)-h[display help]' \
   '-H+[specify a draft file for message]:draft file:_files' \
   '-i+[specify file to include in message]:include file:_files' \
   '-m+[specify default mailbox type]:mailbox type:(mbox MMDF MH Maildir)' \
@@ -20,8 +21,8 @@ _arguments -s -S \
   '(- :)-Q+[query a configuration variable]:variable:(${${(f)"$(_call_program variables mutt -D 2>/dev/null)"}%%( is|=)*})' \
   '-R[open in read-only mode]' \
   '-s+[specify a subject]:subject:' \
-  '-v[display mutt version]' \
-  '-x[emulate mailx compose]' \
+  '(- :)-v[display mutt version]' \
+  '(-E)-x[emulate mailx compose]' \
   '-y[start listing mailboxes]' \
   '-z[start only if new messages]' \
   '-Z[open first mailbox with new mail]'
diff --git a/Completion/Unix/Command/_readelf b/Completion/Unix/Command/_readelf
index a474a8d..15d5145 100644
--- a/Completion/Unix/Command/_readelf
+++ b/Completion/Unix/Command/_readelf
@@ -51,6 +51,7 @@ case $variant in
       '--elf-section[used specified section as ELF input data]::section'
       '(-e --exception)'{-e,--exception}'[show sections for exception handling]'
       '(-N --numeric-addresses)'{-N,--numeric-addresses}"[don't find symbol names for addresses in DWARF data]"
+      '(-z --decompress)'{-z,--decompress}'[show compression information; decompress before dumping data]'
     )
   ;;
 esac
diff --git a/Completion/Unix/Command/_rsync b/Completion/Unix/Command/_rsync
index 79d8243..f79ec1d 100644
--- a/Completion/Unix/Command/_rsync
+++ b/Completion/Unix/Command/_rsync
@@ -66,6 +66,20 @@ fi
 
 }
 
+_rsync_info() {
+  local opts
+  opts=( ${${(M)${(f)"$(_call_program values $words[1] --info=help)"}:#*Mention*}/ ##Me/[me} )
+  (( $#opts )) && opts=( '(ALL NONE HELP)'${^opts}\] )
+  _values -s , 'info options' $opts ALL NONE HELP
+}
+
+_rsync_debug() {
+  local opts
+  opts=( ${${(M)${(f)"$(_call_program values $words[1] --debug=help)"}:#*Debug*}/ ##De/[de} )
+  (( $#opts )) && opts=( '(ALL NONE HELP)'${^opts}\] )
+  _values -s , 'debug options' $opts ALL NONE HELP
+}
+
 _rsync_files() {
   _alternative "files:file:_files" "remote-files:remote file:_rsync_remote_files"
 }
@@ -78,6 +92,8 @@ _rsync() {
     '--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' \
+    '--log-file-format=[log updates using specified format]:format' \
+    '--log-file=[log what rsync is doing to the specified file]:file:_files' \
     '(-T --temp-dir)'{-T,--temp-dir=}'[create temporary files in specified directory]:directory:_directories' \
     '--sockopts=[specify custom TCP options]' \
     '(-4 -6 --ipv4 --ipv6)'{-4,--ipv4}'[prefer IPv4]' \
@@ -87,6 +103,7 @@ _rsync() {
     '--config=[specify alternate rsyncd.conf file]:file:_files' \
     '--daemon[run as an rsync daemon]' \
     '--detach[detach from the parent]' \
+    '(-M --dparam)'{-M,--dparam=}'[override global daemon config parameter]:config parameter' \
     '--no-detach[do not detach from the parent]' \
    - client \
     '(-)--help[display help information]' \
@@ -205,15 +222,13 @@ _rsync() {
     '(-i --itemize-changes)'{-i,--itemize-changes}'[output a change-summary for all updates]' \
     '--log-format=[deprecated version of --out-format]' \
     '--out-format=[output updates using specified format]:format' \
-    '--log-file-format=[log updates using specified format]:format' \
-    '--log-file=[log what rsync is doing to the specified file]:file:_files' \
     '--password-file=[read daemon-access password from file]:file:_files' \
     '--list-only[list the files instead of copying them]' \
     '(--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' \
-    '--info=[fine-grained informational verbosity]:comma-separated list' \
-    '--debug=[fine-grained debug verbosity]:comma-separated list' \
+    '--info=[fine-grained informational verbosity]:info option:_rsync_info' \
+    '--debug=[fine-grained debug verbosity]:debug option:_rsync_debug' \
     '--msgs2stderr[special output handling for debugging]' \
     '--munge-links[munge symlinks to make them safer, but unusable]' \
     '--ignore-missing-args[ignore missing source args without error]' \
diff --git a/Completion/Unix/Command/_sed b/Completion/Unix/Command/_sed
index cc7a963..259477f 100644
--- a/Completion/Unix/Command/_sed
+++ b/Completion/Unix/Command/_sed
@@ -26,8 +26,9 @@ elif _pick_variant gnu=GNU unix --version; then
     '(-r --regexp-extended)'{-r,--regexp-extended}$extended
     '(-s --separate)'{-s,--separate}'[consider files separately instead of as a combined stream]'
     '(-u --unbuffered)'{-u,--unbuffered}'[disable data buffering]'
+    '(-z --null-data)'{-z,--null-data}'[separate lines by NUL characters]'
     '(- 1 :)--help[print program usage]'
-    '(- 1 :)'{-V,--version}'[print program version]'
+    '(- 1 :)--version[print program version]'
   )
 else
   args=( "${(@)args:#(|\(*\))(|\*)--*}" )
diff --git a/Completion/Unix/Command/_sort b/Completion/Unix/Command/_sort
index 1ad57f4..a35de17 100644
--- a/Completion/Unix/Command/_sort
+++ b/Completion/Unix/Command/_sort
@@ -46,7 +46,7 @@ case $variant in
       '--batch-size=[maximum inputs to merge]:number'
       '--compress-program=[specify program to compress temporary files with]:program:(gzip bzip2 lzop xz)'
       '--debug[annotate the of the line used to sort]'
-      '--files0-from=[read input files from file]:file:_files'
+      '(*)--files0-from=[read input files from file]:file:_files'
       '(-S --buffer-size)'{-S+,--buffer-size=}'[specify size for main memory buffer]:size'
       '(- *)--help[display help and exit]'
       '(- *)--version[output version information and exit]'
diff --git a/Completion/Unix/Command/_ssh b/Completion/Unix/Command/_ssh
index 1f8f62c..727fd35 100644
--- a/Completion/Unix/Command/_ssh
+++ b/Completion/Unix/Command/_ssh
@@ -1,12 +1,10 @@
 #compdef ssh slogin=ssh scp ssh-add ssh-agent ssh-keygen sftp ssh-copy-id
 
-# Completions currently based on OpenSSH 7.0 (released on 2015-08-11).
-#
-# TODO: update ssh-keygen (not based on 5.9)
 # TODO: sshd, ssh-keyscan, ssh-keysign
 
 _ssh () {
-  local curcontext="$curcontext" state line expl common tmp cmds suf ret=1
+  local curcontext="$curcontext" state line expl suf ret=1
+  local args common tmp p1 file cmn cmds sdesc
   typeset -A opt_args
 
   common=(
@@ -44,6 +42,7 @@ _ssh () {
       '-g[allow remote hosts to connect to local forwarded ports]' \
       '-G[output configuration and exit]' \
       '-I+[specify smartcard device]:device:_files' \
+      '-J+[connect via a jump host]: :->userhost' \
       '-K[enable GSSAPI-based authentication and forwarding]' \
       '-k[disable forwarding of GSSAPI credentials]' \
       '*-L[specify local port forwarding]:local port forwarding:->forward' \
@@ -84,6 +83,7 @@ _ssh () {
       '-c[identity is subject to confirmation via SSH_ASKPASS]' \
       '-D[delete all identities]' \
       '-d[remove identity]' \
+      '-E[specify hash algorithm for fingerprints]:algorithm:(md5 sha256)' \
       '-e[remove keys provided by the PKCS#11 shared library]:library:' \
       '-k[load plain private keys only and skip certificates]' \
       '-L[lists public key parameters of all identities in the agent]'\
@@ -107,32 +107,83 @@ _ssh () {
     return
     ;;
   ssh-keygen)
-    cmds=( -p -i -e -y -c -l -B -D -U )
-    _arguments -s \
-      '-q[silence ssh-keygen]' \
-      "($cmds -P)-b[specify number of bits in key]:bits in key" \
-      "($cmds -P)-t[specify the type of the key to create]:key type:(rsa1 rsa dsa ecdsa ed25519)" \
-      "(${cmds#-p })-N[provide new passphrase]:new passphrase" \
-      "($cmds -b -t)-C[provide new comment]:new comment" \
-      '(-D)-f[key file]:key file:_files' \
-      '('${(j. .)cmds:#-[pc]}' -t -b)-P[provide old passphrase]:old passphrase' \
-      "($cmds -q -b -t -C)-p[change passphrase of private key file]" \
-      "($cmds -q -b -t -N -C -P)-i[import key to OpenSSH format]" \
-      "($cmds -q -b -t -N -C -P)-e[export key to SECSH file format]" \
-      "($cmds -q -b -t -N -C -P)-y[get public key from private key]" \
-      "($cmds -q -b -t -N)-c[change comment in private and public key files]" \
-      "($cmds -q -b -t -N -C -P)-l[show fingerprint of key file]" \
-      "($cmds -q -b -t -N -C -P)-B[show the bubblebabble digest of key]" \
-      "($cmds -q -b -t -N -C -P -f)-D[download key stored in smartcard reader]:reader" \
-      "($cmds -q -b -t -N -C -P)-U[upload key to smartcard reader]:reader"
+    # options can be in any order but use ! to limit those shown for the first argument
+    (( CURRENT == 2 )) && p1='!'
+    args=( '!-z:number' )
+    sdesc='certify keys with CA key'
+    (( $+words[(r)-s] )) && args=( '-z[specify serial number]:serial number' )
+    (( $+words[(r)-[ku]] )) && args=( '-z[specify version number]:version number' ) &&
+        sdesc='specify CA public key file'
+    file=key
+    (( $+words[(r)-[HR]] )) && file=known_hosts
+    (( $+words[(r)-T] )) && file=input
+    if (( $+words[(r)-[kQ]] )); then
+      file=krl
+      args+=( '*:file:_files' )
+    fi
+    cmds=( -p -i -e -y -c -l -B -D -H -R -r -G -T -s -L -A -k -Q ) # basic commands
+    cmn=( -b -P -N -C -m -v ) # options common to many basic commands (except -f which is common to most)
+    cms=( -E -q -t -g -M -S -a -J -j -K -W -I -h -n -O -V -u ) # options specific to one basic command
+    _arguments -s $args \
+      "(${${(@)cmds:#-G}} -P -m ${${(@)cms:#-[MS]}})-b[specify number of bits in key]:bits in key" \
+      "$p1(${${(@)cmds:#-[pc]}} -b -C $cms)-P[provide old passphrase]:old passphrase" \
+      "(${${(@)cmds:#-p}} -m -v ${${(@)cms:#-[qt]}})-N[provide new passphrase]:new passphrase" \
+      "(${${(@)cmds:#-c}} -m -v $cms)-C[provide new comment]:new comment" \
+      "(-D -G -M -S -I -h -n -O -V -A)-f[$file file]:$file file:_files" \
+      "$p1(${${(@)cmds:#-[ie]}})-m[specify conversion format]:format:(PEM PKCS7 RFC4716)" \
+      "(${${(@)cmds:#-[lGT]}} ${${(@)cmn:#-[bv]}} -f)*-v[verbose mode]" \
+      - '(commands)' \
+      "(-b -P -C -v)-p[change passphrase of private key file]" \
+      '(-b -P -N -C -v)-i[import key to OpenSSH format]' \
+      '(-b -P -N -C -v)-e[export key to SECSH file format]' \
+      "($cmn)-y[get public key from private key]" \
+      '(-b -N -m -v)-c[change comment in private and public key files]' \
+      "($cmn)-B[show the bubblebabble digest of key]" \
+      "(-)-D[download key stored in smartcard reader]:reader" \
+      "($cmn)-H[hash names in known_hosts file]" \
+      "($cmn)-R[remove host from known_hosts file]:host:_ssh_hosts" \
+      "($cmn)-L[print the contents of a certificate]" \
+      "(-)-A[generate host keys for all key types]" \
+      "($cmn)-Q[test whether keys have been revoked in a KRL]" \
+      - finger \
+      "($cmn)-l[show fingerprint of key file]" \
+      "$p1($cmn)-E[specify hash algorithm for displayed fingerprints]:hash algorithim:(md5 sha256)" \
+      - create \
+      '(-P -m)-q[silence ssh-keygen]' \
+      "(-P -m)-t[specify the type of the key to create]:key type:(rsa1 rsa dsa ecdsa ed25519)" \
+      - dns \
+      "($cmn)-r[print DNS resource record]:hostname:_hosts" \
+      "$p1($cmn)-g[use generic DNS format]" \
+      - primes \
+      "(-P -N -C -m -f)-G[generate candidates for DH-GEX moduli]" \
+      "$p1(-P -N -C -m -f)-M[specify amount of memory to use for generating DH-GEX moduli]:memory (MB)" \
+      "$p1(-P -N -C -m -f)-S[specify start point]:start point (hex)" \
+      - screen \
+      "(${${(@)cmn:#-v}})-T[screen candidates for DH-GEX moduli]:output file:_files" \
+      "${p1}(${${(@)cmn:#-v}})-a[specify number of rounds]:rounds" \
+      "${p1}(${${(@)cmn:#-v}})-J[exit after screening specified number of lines]" \
+      "${p1}(${${(@)cmn:#-v}})-j[start screening at the specified line number]:line number" \
+      "${p1}(${${(@)cmn:#-v}})-K[write the last line processed to file]:file:_files" \
+      "${p1}(${${(@)cmn:#-v}})-W[specify desired generator]:generator" \
+      - certify \
+      "($cmn)-s[$sdesc]:CA key:_files" \
+      "$p1($cmn -f -u)-I[specify key identifier to include in certificate]:key id" \
+      "$p1($cmn -f -u)-h[generate host certificate instead of a user certificate]" \
+      "$p1($cmn -f -u)-n[specify user/host principal names to include in certificate]:principals" \
+      "$p1($cmn -f -u)-O[specify a certificate option]:option" \
+      "$p1($cmn -f -u)-V[specify certificate validity interval]:interval" \
+      "($cmn -I -h -n -O -V)-k[generate a KRL file]" \
+      "$p1($cmn -I -h -n -O -V)-u[update a KRL]"
     return
     ;;
   sftp)
     _arguments -C -s \
-      '-B+[specify buffer size]:buffer size in bytes (default\: 32768):' \
+      '-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:' \
-      '-R[specify number of outstanding requests]:number of requests (default\: 64):' \
+      '-D[connect directly to a local sftp server]:sftp server path' \
+      '-f[request that files be flushed immediately after transfer]' \
+      '-R[specify number of outstanding requests]:number of requests [64]' \
       '-s[SSH2 subsystem or path to sftp server on the remote host]' \
       '1:file:->rfile' '*:file:->file' "$common[@]" "$common_transfer[@]" && ret=0
     ;;
@@ -398,6 +449,7 @@ _ssh () {
         # old options are after the empty "\"-line
         _wanted values expl 'configure file option' \
             compadd -M 'm:{a-z}={A-Z}' -q -S '=' - \
+	        AddKeysToAgent \
                 AddressFamily \
                 BatchMode \
                 BindAddress \
@@ -406,6 +458,7 @@ _ssh () {
                 CanonicalizeHostname \
                 CanonicalizeMaxDots \
                 CanonicalizePermittedCNAMEs \
+		CertificateFile \
                 ChallengeResponseAuthentication \
                 CheckHostIP \
                 Cipher \
@@ -440,6 +493,7 @@ _ssh () {
                 HostKeyAlias \
                 HostName \
                 IdentitiesOnly \
+		IdentityAgent \
                 IdentityFile \
                 IgnoreUnknown \
                 IPQoS \
@@ -459,6 +513,7 @@ _ssh () {
                 PreferredAuthentications \
                 Protocol \
                 ProxyCommand \
+		ProxyJump \
                 ProxyUseFdpass \
                 PubkeyAcceptedKeyTypes \
                 PubkeyAuthentication \
diff --git a/Completion/Unix/Command/_tmux b/Completion/Unix/Command/_tmux
index 93b5c7f..79ba61d 100644
--- a/Completion/Unix/Command/_tmux
+++ b/Completion/Unix/Command/_tmux
@@ -51,7 +51,7 @@
 
 # Global variables; setup the first time _tmux is called.
 # For $_tmux_commands[] generation, see the very end of this file.
-typeset -ga _tmux_commands _tmux_aliases
+typeset -ga _tmux_commands=() _tmux_aliases=()
 typeset -gA _tmux_aliasmap
 
 _tmux_aliasmap=(
@@ -147,7 +147,7 @@ _tmux_aliasmap=(
 
 # --- Sub-command functions ---
 # These *must* be called _tmux-*(); The description generation relies on
-# them being names that way. *No* other functions may match that pattern.
+# them being named that way. *No* other functions may match that pattern.
 # Other utility functions should be named __tmux-*() (see below).
 #
 # Another thing, the description generation needs, is handling of
@@ -161,956 +161,758 @@ _tmux_aliasmap=(
 # _tmux_aliasmap associative array above (if the comand in fact has an
 # alias). The rest should just work[tm].
 
-function _tmux-attach-session() {
-    [[ -n ${tmux_describe} ]] && print "Attach or switch to a session" && return
-    local -a args
+_tmux-attach-session() {
+  [[ -n ${tmux_describe} ]] && print "attach or switch to a session" && return
 
-    args=(
-        '-c[specify working directory for the session]:directory:_path_files -g "*(-/)"'
-        '-d[detach other clients attached to target session]'
-        '-r[put the client into read-only mode]'
-        '-t[choose a target session]:target session:__tmux-sessions'
-    )
-    _arguments : ${args}
+  _arguments -s \
+    '-c+[specify working directory for the session]:directory:_directories' \
+    '-d[detach other clients attached to target session]' \
+    '-r[put the client into read-only mode]' \
+    '-t+[specify target session]:target session:__tmux-sessions' \
+    "-E[don't apply update-environment option]"
 }
 
-function _tmux-bind-key() {
-    [[ -n ${tmux_describe} ]] && print "Bind a key to a command" && return
-    local curcontext="${curcontext}" state
-    local -a args
-
-    args=(
-        '-c[bind to command mode instead of normal mode]'
-        '-n[make the binding work without the need for the prefix key]'
-        '-r[the key may repeat]'
-        '-t[choose a key table for the binding]:key tables:__tmux-key-tables'
-        '1: :->key'
-        '*:: :->command_and_args'
-    )
-    _arguments -C : ${args} && return
-
-    if [[ ${state} == 'key' ]]; then
-        _message "key"
-    else
-        # quite cool, that this works. :-)
-        _tmux
-    fi
+_tmux-bind-key() {
+  [[ -n ${tmux_describe} ]] && print "bind a key to a command" && return
+  _arguments -s -A "-*" \
+    '-c[bind to command mode instead of normal mode]' \
+    '-n[make the binding work without the need for the prefix key]' \
+    '-r[the key may repeat]' \
+    '-t+[specify mode table for the binding]:mode table:__tmux-mode-tables' \
+    '-T+[specify key table for the binding]:key table' \
+    '1:key' \
+    '*:::template:_tmux'
 }
 
-function _tmux-break-pane() {
-    [[ -n ${tmux_describe} ]] && print "Break a pane from an existing into a new window" && return
-    local -a args
-    args=(
-        '-d[do not make the new window become the active one]'
-        '-F[specify format of output]:format:__tmux-format__tmux-format'
-        '-P[print information of new window after it has been created]'
-        '-t[choose a target pane]:panes:__tmux-panes'
-    )
-    _arguments : ${args}
+_tmux-break-pane() {
+  [[ -n ${tmux_describe} ]] && print "break a pane from an existing into a new window" && return
+  _arguments -s \
+    "-d[don't make the new window become the active one]" \
+    '-F+[specify output format]:format:__tmux-format__tmux-format' \
+    '-P[print information of new window after it has been created]' \
+    '-s+[specify source pane]:pane:__tmux-panes' \
+    '-t+[specify destination window]:pane:__tmux-panes'
 }
 
-function _tmux-capture-pane() {
-    [[ -n ${tmux_describe} ]] && print "Capture the contents of a pane to a buffer" && return
-    local -a args
-    args=(
-        '-a[use alternate screen]'
-        '-b[choose target buffer]:target buffer:__tmux-buffers'
-        '-C[escape non-printable characters as octal \\ooo]'
-        '-e[include escape sequences for attributes etc]'
-        '-E[specify last line to capture. - means last line of pane]'
-        '-J[join wrapped lines and preserver trailing space]'
-        '-q[ignore errors when trying to access alternate screen]'
-        '-p[print data to stdout]'
-        '-P[only capture that is the beginning of an as-yet incomplete esc seq]'
-        '-S[specify start line to capture. - means first line of scrollback]'
-        '-t[choose source pane]:source pane:__tmux-panes'
-    )
-    _arguments : ${args}
+_tmux-capture-pane() {
+  [[ -n ${tmux_describe} ]] && print "capture the contents of a pane to a buffer" && return
+  _arguments -s \
+    '-a[use alternate screen]' \
+    '-b+[choose target buffer]:target buffer:__tmux-buffers' \
+    '-C[escape non-printable characters as octal \\ooo]' \
+    '-e[include escape sequences for attributes etc]' \
+    '-E[specify last line to capture. - means last line of pane]' \
+    '-J[join wrapped lines and preserver trailing space]' \
+    '-q[ignore errors when trying to access alternate screen]' \
+    '-p[print data to stdout]' \
+    '-P[only capture that is the beginning of an as-yet incomplete esc seq]' \
+    '-S[specify start line to capture. - means first line of scrollback]' \
+    '-t+[choose source pane]:source pane:__tmux-panes'
 }
 
-function _tmux-choose-buffer() {
-    [[ -n ${tmux_describe} ]] && print "Put a window into buffer choice mode" && return
-    local -a args
-    args=(
-        '-F[specify format of output]:format:__tmux-format'
-        '-t[choose a target window]:sessions:__tmux-windows'
-        '*:: :->tmpl'
-    )
-    _arguments : ${args} && return
+_tmux-choose-buffer() {
+  [[ -n ${tmux_describe} ]] && print "put a window into buffer choice mode" && return
+  _arguments -s \
+    '-F+[specify output format]:format:__tmux-format' \
+    '-t+[specify target window]:session:__tmux-windows' \
+    '*:::template:_tmux'
 }
 
-function _tmux-choose-client() {
-    [[ -n ${tmux_describe} ]] && print "Put a window into client choice mode" && return
-    local -a args
-    args=(
-        '-F[specify format of output]:format:__tmux-format'
-        '-t[choose a target window]:sessions:__tmux-windows'
-        '*:: :->tmpl'
-    )
-    _arguments : ${args} && return
+_tmux-choose-client() {
+  [[ -n ${tmux_describe} ]] && print "put a window into client choice mode" && return
+  _arguments -s \
+    '-F+[specify output format]:format:__tmux-format' \
+    '-t+[specify target window]:session:__tmux-windows' \
+    '*:::template:_tmux'
 }
 
-function _tmux-choose-session() {
-    [[ -n ${tmux_describe} ]] && print "Put a window into session choice mode" && return
-    local -a args
-    args=(
-        '-F[specify format of output]:format:__tmux-format'
-        '-t[choose a target window]:sessions:__tmux-windows'
-        '*:: :->tmpl'
-    )
-    _arguments : ${args} && return
+_tmux-choose-session() {
+  [[ -n ${tmux_describe} ]] && print "put a window into session choice mode" && return
+  _arguments -s \
+    '-F+[specify output format]:format:__tmux-format' \
+    '-t+[specify target window]:session:__tmux-windows' \
+    '*:::template:_tmux'
 }
 
-function _tmux-choose-tree() {
-    [[ -n ${tmux_describe} ]] && print "Put a window into tree choice mode" && return
-    local -a args
-    args=(
-        '-b[override default session command]:session-command:'
-        '-c[override default window command]:window-command:'
-        '-S[specify session format]:session-format:__tmux-formats'
-        '-s[choose among sessions]'
-        '-t[choose a target window]:sessions:__tmux-windows'
-        '-u[show generated tree uncollapsed at startup]'
-        '-W[specify window format]:window-format:__tmux-formats'
-        '-w[choose among windows]'
-        '*:: :->tmpl'
-    )
-    _arguments : ${args} && return
+_tmux-choose-tree() {
+  [[ -n ${tmux_describe} ]] && print "put a window into tree choice mode" && return
+  _arguments -s \
+    '-b+[override default session command]:session-command' \
+    '-c+[override default window command]:window-command' \
+    '-S+[specify session format]:session-format:__tmux-formats' \
+    '-s[choose among sessions]' \
+    '-t+[specify target window]:session:__tmux-windows' \
+    '-u[show generated tree uncollapsed at startup]' \
+    '-W+[specify window format]:window-format:__tmux-formats' \
+    '-w[choose among windows]' \
+    '*:::template:_tmux'
 }
 
-function _tmux-choose-window() {
-    [[ -n ${tmux_describe} ]] && print "Put a window into window choice mode" && return
-    local -a args
-    args=(
-        '-F[specify format of output]:format:__tmux-format'
-        '-t[choose a target window]:sessions:__tmux-windows'
-        '*:: :->tmpl'
-    )
-    _arguments : ${args} && return
+_tmux-choose-window() {
+  [[ -n ${tmux_describe} ]] && print "put a window into window choice mode" && return
+  _arguments -s \
+    '-F=[specify output format]:format:__tmux-format' \
+    '-t+[specify target window]:session:__tmux-windows' \
+    '*:::template:_tmux'
 }
 
-function _tmux-clear-history() {
-    [[ -n ${tmux_describe} ]] && print "Remove and clear history for a pane" && return
-    local -a args
-    args=('-t[choose a target pane]:panes:__tmux-panes')
-    _arguments : ${args}
+_tmux-clear-history() {
+  [[ -n ${tmux_describe} ]] && print "remove and clear history for a pane" && return
+  _arguments '-t+[specify target pane]:pane:__tmux-panes'
 }
 
-function _tmux-clock-mode() {
-    [[ -n ${tmux_describe} ]] && print "Enter clock mode" && return
-    local -a args
-    args=('-t[choose a target pane]:panes:__tmux-panes')
-    _arguments : ${args}
+_tmux-clock-mode() {
+  [[ -n ${tmux_describe} ]] && print "enter clock mode" && return
+  _arguments '-t+[specify target pane]:pane:__tmux-panes'
 }
 
-function _tmux-command-prompt() {
-    [[ -n ${tmux_describe} ]] && print "Open the tmux command prompt in a client" && return
-    local state
-    local -a args
-    args=(
-        '-I[comma separated list of initial inputs]:initial-text:->ilist'
-        '-p[list of prompts]:prompts:->plist'
-        '-t[choose a target client]:clients:__tmux-clients'
-        '*:: :->tmpl'
-    )
-    _arguments -C : ${args} && return
-    if [[ ${state} == 'plist' ]]; then
-        _message "comma seperated list of prompts"
-        return
-    elif [[ ${state} == 'ilist' ]]; then
-        _message "comma seperated list of initial text"
-        return
-    fi
-    __tmux-lastarg ${state} 'tmpl' 1 "command template"
+_tmux-command-prompt() {
+  [[ -n ${tmux_describe} ]] && print "open the tmux command prompt in a client" && return
+  _arguments -s \
+    '-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' \
+    '*:::template:_tmux'
 }
 
-function _tmux-confirm-before() {
-    [[ -n ${tmux_describe} ]] && print "Run a command but ask for confirmation before" && return
-    local state
-    local -a args
-    args=(
-        '-p[specify prompt]:prompt:->prompt'
-        '-t[choose a target client]:clients:__tmux-clients'
-        '*:: :->command_and_args'
-    )
-    _arguments -C : ${args} && return
-    if [[ ${state} == 'prompt' ]]; then
-        _message 'prompt string'
-        return
-    fi
-    __tmux-lastarg ${state} 'command_and_args' 1 "command string"
+_tmux-confirm-before() {
+  [[ -n ${tmux_describe} ]] && print "run a command but ask for confirmation before" && return
+  _arguments -s \
+    '-p+[specify prompt]:prompt string' \
+    '-t+[specify target client]:client:__tmux-clients' \
+    '*:::command:_tmux'
 }
 
-function _tmux-copy-mode() {
-    [[ -n ${tmux_describe} ]] && print "Enter copy mode" && return
-    local -a args
-    args=(
-        '-t[choose a target pane]:panes:__tmux-panes'
-        '-u[scroll up one page]'
-    )
-    _arguments : ${args}
+_tmux-copy-mode() {
+  [[ -n ${tmux_describe} ]] && print "enter copy mode" && return
+  _arguments -s \
+    '-t+[specify target pane]:pane:__tmux-panes' \
+    '-u[scroll up one page]' \
+    '-M[begin a mouse drag]'
 }
 
-function _tmux-delete-buffer() {
-    [[ -n ${tmux_describe} ]] && print "Delete a paste buffer" && return
-    local -a args
-    args=('-b[choose a target buffer index]:buffers:__tmux-buffers')
-    _arguments : ${args} && return
+_tmux-delete-buffer() {
+  [[ -n ${tmux_describe} ]] && print "delete a paste buffer" && return
+  _arguments '-b+[specify target buffer name]:buffer:__tmux-buffers'
 }
 
-function _tmux-detach-client() {
-    [[ -n ${tmux_describe} ]] && print "Detach a client from the server" && return
-    local -a args
-    args=(
-        '-a[kill all clients except for the named by -t]'
-        '-P[send SIGHUP to parent process]'
-        '-s[choose a target session and kill its clients]:sessions:__tmux-sessions'
-        '-t[choose a target client]:clients:__tmux-clients'
-    )
-    _arguments : ${args}
+_tmux-detach-client() {
+  [[ -n ${tmux_describe} ]] && print "detach a client from the server" && return
+  _arguments -s \
+    '-a[kill all clients except for the named by -t]' \
+    '-P[send SIGHUP to parent process]' \
+    '-s+[specify target session and kill its clients]:session:__tmux-sessions' \
+    '-t+[specify target client]:client:__tmux-clients'
 }
 
-function _tmux-display-message() {
-    [[ -n ${tmux_describe} ]] && print "Display a message in the status line" && return
-    local -a args
-    args=(
-        '-c[choose a target client]:clients:__tmux-clients'
-        '-p[print message to stdout]'
-        '-t[choose a target client]:clients:__tmux-clients'
-        '*:: :->msg'
-    )
-    _arguments : ${args} && return
-    __tmux-lastarg ${state} 'msg' 1 "message"
+_tmux-display-message() {
+  [[ -n ${tmux_describe} ]] && print "display a message in the status line" && return
+  _arguments -s -S \
+    '-c+[specify target client]:client:__tmux-clients' \
+    '-p[print message to stdout]' \
+    '-t+[specify target client]:client:__tmux-clients' \
+    '-F+[specify output format]:format:__tmux-format' \
+    ':message'
 }
 
-function _tmux-display-panes() {
-    [[ -n ${tmux_describe} ]] && print "Display an indicator for each visible pane" && return
-    local -a args
-    args=('-t[choose a target client]:clients:__tmux-clients')
-    _arguments : ${args}
+_tmux-display-panes() {
+  [[ -n ${tmux_describe} ]] && print "display an indicator for each visible pane" && return
+  _arguments '-t+[specify target client]:client:__tmux-clients'
 }
 
-function _tmux-find-window() {
-    [[ -n ${tmux_describe} ]] && print "Search for a pattern in windows" && return
-    local curcontext="${curcontext}" state
-    local -a args
-    args=(
-        '-C[match visible contents]'
-        '-F[specify format of output]:format:__tmux-format'
-        '-N[match window name]'
-        '-T[match window title]'
-        '-t[choose a target window]:windows:__tmux-windows'
-        '*:: :->pattern'
-    )
-    _arguments : ${args} && return
-    __tmux-lastarg ${state} 'pattern' 1 "window search pattern"
+_tmux-find-window() {
+  [[ -n ${tmux_describe} ]] && print "search for a pattern in windows" && return
+  _arguments -s \
+    '-C[match visible contents]' \
+    '-F+[specify output format]:format:__tmux-format' \
+    '-N[match window name]' \
+    '-T[match window title]' \
+    '-t+[specify target window]:window:__tmux-windows' \
+    ':window search pattern'
 }
 
-function _tmux-has-session() {
-    [[ -n ${tmux_describe} ]] && print "Check and report if a session exists on the server" && return
-    local -a args
-    args=('-t[choose a target session]:sessions:__tmux-sessions')
-    _arguments : ${args}
+_tmux-has-session() {
+  [[ -n ${tmux_describe} ]] && print "check and report if a session exists on the server" && return
+  _arguments '-t+[specify target session]:session:__tmux-sessions'
 }
 
-function _tmux-if-shell() {
-    [[ -n ${tmux_describe} ]] && print "Execute a tmux command if a shell-command succeeded" && return
-    local -a args
-    args=(
-        '-b[run shell command in background]'
-        '-F[do not execute shell command but use it as a string-value]'
-        '1:shell command:'
-        '2:tmux command:'
-    )
-    _arguments : ${args}
+_tmux-if-shell() {
+  [[ -n ${tmux_describe} ]] && print "execute a tmux command if a shell-command succeeded" && return
+  local curcontext="$curcontext" state line ret=1
+  _arguments -C -s \
+    '-b[run shell command in background]' \
+    "-F[don't execute shell command but use it as a string-value]" \
+    '-t+[specify target pane]:pane:__tmux-panes' \
+    '1:shell command:_cmdstring' \
+    '2:tmux command (success):->tmuxcmd' \
+    '3:tmux command (failure):->tmuxcmd' && ret=0
+  if [[ -n $state ]]; then
+    compset -q
+    _tmux && ret=0
+  fi
 }
 
-function _tmux-join-pane() {
-    [[ -n ${tmux_describe} ]] && print "Split a pane and move an existing one into the new space" && return
-    local -a args
-    args=(
-        '-b[join source pane left of or above target pane]'
-        '-d[do not make the new window become the active one]'
-        '-h[split horizontally]'
-        '-v[split vertically]'
-        '-l[define new pane'\''s size]: :_guard "[0-9]#" "numeric value"'
-        '-p[define new pane'\''s size in percent]: :_guard "[0-9]#" "numeric value"'
-        '-s[choose source pane]:window:__tmux-panes'
-        '-t[choose target pane]:window:__tmux-panes'
-    )
-    _arguments : ${args} && return
+_tmux-join-pane() {
+  [[ -n ${tmux_describe} ]] && print "split a pane and move an existing one into the new space" && return
+  _arguments -s \
+    '-b[join source pane left of or above target pane]' \
+    "-d[don't make the new window become the active one]" \
+    '-h[split horizontally]' \
+    '-v[split vertically]' \
+    "-l+[define new pane's size]: :_guard '[0-9]#' 'numeric value'" \
+    "-p+[define new pane's size in percent]: :_guard '[0-9]#' 'numeric value'" \
+    '-s+[specify source pane]:pane:__tmux-panes' \
+    '-t+[specify target pane]:pane:__tmux-panes'
 }
 
-function _tmux-kill-pane() {
-    [[ -n ${tmux_describe} ]] && print "Destroy a given pane" && return
-    local -a args
-    args=(
-        '-a[kill all panes except the one specified by -t]'
-        '-t[choose a target pane]:panes:__tmux-panes'
-    )
-    _arguments : ${args}
+_tmux-kill-pane() {
+  [[ -n ${tmux_describe} ]] && print "destroy a given pane" && return
+  _arguments -s \
+    '-a[kill all panes except the one specified by -t]' \
+    '-t+[specify target pane]:pane:__tmux-panes'
 }
 
-function _tmux-kill-server() {
-    [[ -n ${tmux_describe} ]] && print "Kill clients, sessions and server" && return
+_tmux-kill-server() {
+  [[ -n ${tmux_describe} ]] && print "kill clients, sessions and server" && return
+  __tmux-nothing-else
+}
+
+_tmux-kill-session() {
+  [[ -n ${tmux_describe} ]] && print "destroy a given session" && return
+  _arguments -s \
+    '-a[kill all session except the one specified by -t]' \
+    '-t+[specify target session]:session:__tmux-sessions' \
+    '-C[clear alerts (bell, activity, silence) in all windows linked to the session]'
+}
+
+_tmux-kill-window() {
+  [[ -n ${tmux_describe} ]] && print "destroy a given window" && return
+  _arguments -s \
+    '-a[kill all windows except the one specified by -t]' \
+    '-t+[specify target window]:window:__tmux-windows'
+}
+
+_tmux-last-pane() {
+  [[ -n ${tmux_describe} ]] && print "select the previously selected pane" && return
+  _arguments -s \
+    '-d[disable input to the pane]' \
+    '-e[enable input to the pane]' \
+    '-t+[specify session]:session:__tmux-sessions'
+}
+
+_tmux-last-window() {
+  [[ -n ${tmux_describe} ]] && print "select the previously selected window" && return
+  _arguments '-t+[specify session]:session:__tmux-sessions'
+}
+
+_tmux-link-window() {
+  [[ -n ${tmux_describe} ]] && print "link a window to another" && return
+  _arguments -s \
+    "-d[don't make the new window become the active one]" \
+    '-k[kill the target window if it exists]' \
+    '-s+[specify source window]:window:__tmux-windows' \
+    '-t+[specify destination window]:window:__tmux-windows'
+}
+
+_tmux-list-buffers() {
+  [[ -n ${tmux_describe} ]] && print "list paste buffers of a session" && return
+  _arguments '-F+[specify output format]:format:__tmux-format' 
+}
+
+_tmux-list-clients() {
+  [[ -n ${tmux_describe} ]] && print "list clients attached to server" && return
+  _arguments -s \
+    '-F+[specify output format]:format:__tmux-format' \
+    '-t+[specify session]:session:__tmux-sessions'
+}
+
+_tmux-list-commands() {
+    [[ -n ${tmux_describe} ]] && print "list supported sub-commands" && return
     __tmux-nothing-else
 }
 
-function _tmux-kill-session() {
-    [[ -n ${tmux_describe} ]] && print "Destroy a given session" && return
-    local -a args
-    args=(
-        '-a[kill all session except the one specified by -t]'
-        '-t[choose a target session]:sessions:__tmux-sessions'
-    )
-    _arguments : ${args}
+_tmux-list-keys() {
+  [[ -n ${tmux_describe} ]] && print "list all key-bindings" && return
+  _arguments -s \
+    '-t+[specify mode table]:mode table:__tmux-mode-tables' \
+    '-T+[specify key table]:key table'
 }
 
-function _tmux-kill-window() {
-    [[ -n ${tmux_describe} ]] && print "Destroy a given window" && return
-    local -a args
-    args=(
-        '-a[kill all windows except the one specified by -t]'
-        '-t[choose a target window]:windows:__tmux-windows'
-    )
-    _arguments : ${args}
+_tmux-list-panes() {
+  [[ -n ${tmux_describe} ]] && print "list panes of a window" && return
+  local -a args
+  if (( ${+words[(r)-*s*]} )); then
+    args=( '-t+[specify target session]:session:__tmux-sessions' )
+  else
+    args=( '-t+[specify target window]:window:__tmux-windows' )
+  fi
+  _arguments -s $args \
+    '-a[list all panes the server possesses]' \
+    '-F+[specify output format]:format:__tmux-format' \
+    '-s[if specified, -t chooses a session]'
 }
 
-function _tmux-last-pane() {
-    [[ -n ${tmux_describe} ]] && print "Select the previously selected pane" && return
-    local -a args
-    args=(
-        '-d[disable input to the pane]'
-        '-e[enable input to the pane]'
-        '-t[choose a session]:sessions:__tmux-sessions'
-    )
-    _arguments : ${args} && return
+_tmux-list-sessions() {
+  [[ -n ${tmux_describe} ]] && print "list sessions managed by server" && return
+  _arguments '-F+[specify output format]:format:__tmux-format'
 }
 
-function _tmux-last-window() {
-    [[ -n ${tmux_describe} ]] && print "Select the previously selected window" && return
-    local -a args
-    args=('-t[choose a session]:sessions:__tmux-sessions')
-    _arguments : ${args} && return
+_tmux-list-windows() {
+  [[ -n ${tmux_describe} ]] && print "list windows of a session" && return
+  _arguments -s \
+    '-a[list all windows the tmux server possesses]' \
+    '-F[specify output format]:format:__tmux-format' \
+    '-t+[specify session]:session:__tmux-sessions'
 }
 
-function _tmux-link-window() {
-    [[ -n ${tmux_describe} ]] && print "Link a window to another" && return
-    local -a args
-    args=(
-        '-d[do not make the new window become the active one]'
-        '-k[kill the target window if it exists]'
-        '-s[choose source window]:window:__tmux-windows'
-        '-t[choose destination window]:window:__tmux-windows'
-    )
-    _arguments : ${args}
+_tmux-load-buffer() {
+  [[ -n ${tmux_describe} ]] && print "load a file into a paste buffer" && return
+  _arguments -A "-*" -S \
+    '-b+[specify target buffer name]:buffer:__tmux-buffers' \
+    '1:file:_files'
 }
 
-function _tmux-list-buffers() {
-    [[ -n ${tmux_describe} ]] && print "List paste buffers of a session" && return
-    local -a args
-    args=('-F[specify format of output]:format:__tmux-format')
-    _arguments : ${args} && return
+_tmux-lock-client() {
+  [[ -n ${tmux_describe} ]] && print "lock a client" && return
+  _arguments '-t+[specify client]:client:__tmux-clients'
 }
 
-function _tmux-list-clients() {
-    [[ -n ${tmux_describe} ]] && print "List clients attached to server" && return
-    local -a args
-    args=(
-        '-F[specify format of output]:format:__tmux-format'
-        '-t[choose a session]:sessions:__tmux-sessions'
-    )
-    _arguments : ${args} && return
+_tmux-lock-server() {
+  [[ -n ${tmux_describe} ]] && print "lock all clients attached to the server" && return
+  __tmux-nothing-else
 }
 
-function _tmux-list-commands() {
-    [[ -n ${tmux_describe} ]] && print "List supported sub-commands" && return
-    __tmux-nothing-else
+_tmux-lock-session() {
+  [[ -n ${tmux_describe} ]] && print "lock all clients attached to a session" && return
+  _arguments '-t+[specify session]:session:__tmux-sessions'
 }
 
-function _tmux-list-keys() {
-    [[ -n ${tmux_describe} ]] && print "List all key-bindings" && return
-    local -a args
-    args=('-t[choose a key table]:key table:__tmux-key-tables')
-    _arguments : ${args} && return
+_tmux-move-pane() {
+  [[ -n ${tmux_describe} ]] && print "move a pane into a new space" && return
+  _arguments -s \
+    '-b[join source pane left of or above target pane]' \
+    "-d[don't make the new window become the active one]" \
+    '-h[split horizontally]' \
+    '-v[split vertically]' \
+    "-l+[define new pane's size]:numeric value" \
+    "-p+[define new pane's size in percent]:numeric value" \
+    '-s+[specify source pane]:pane:__tmux-panes' \
+    '-t+[specify target pane]:pane:__tmux-panes'
 }
 
-function _tmux-list-panes() {
-    [[ -n ${tmux_describe} ]] && print "List panes of a window" && return
-    local -a args
-    args=(
-        '-a[list all panes the server possesses]'
-        '-F[specify format of output]:format:__tmux-format'
-        '-s[if specified, -t chooses a session]'
-        # TODO: Use __tmux-windows or __tmux-sessions depending on -s.
-        '-t[choose a window]:windows:__tmux-windows'
-    )
-    _arguments : ${args} && return
+_tmux-move-window() {
+  [[ -n ${tmux_describe} ]] && print "move a window to another" && return
+  _arguments -s \
+    "-d[don't make the new window become the active one]" \
+    '-k[kill the target window if it exists]' \
+    '-s+[specify source window]:window:__tmux-windows' \
+    '-r[renumber windows in session in sequential order]' \
+    '-t+[specify destination window]:window:__tmux-windows'
 }
 
-function _tmux-list-sessions() {
-    [[ -n ${tmux_describe} ]] && print "List sessions managed by server" && return
-    local -a args
-    args=('-F[specify format of output]:format:__tmux-format')
-    _arguments : ${args} && return
+_tmux-new-session() {
+  [[ -n ${tmux_describe} ]] && print "create a new session" && return
+  _arguments -s -A "-*" -S \
+    '-A[attach to existing session if it already exists]' \
+    '-c+[specify working directory for the session]:directory:_directories' \
+    "-d[don't attach new session to current terminal]" \
+    "-D[in case of -A behave like attach-session's -d]" \
+    "-E[don't apply update-environment option]" \
+    '-F+[specify output format]:format:__tmux-format' \
+    '-n+[specify initial window name]:window name' \
+    '-P[print information about new session after it is created]' \
+    '-s+[name the session]:session name:__tmux-sessions' \
+    '-t+[specify target session]:session:__tmux-sessions' \
+    '-x[specify width]:width' \
+    '-y[specify height]:height' \
+    '*:: :_cmdstring'
 }
 
-function _tmux-list-windows() {
-    [[ -n ${tmux_describe} ]] && print "List windows of a session" && return
-    local -a args
-    args=(
-        '-a[list all windows the tmux server possesses]'
-        '-F[specify format of output]:format:__tmux-format'
-        '-t[choose a session]:sessions:__tmux-sessions'
-    )
-    _arguments : ${args} && return
+_tmux-new-window() {
+  [[ -n ${tmux_describe} ]] && print "create a new window" && return
+  _arguments -s -A "-*" -S \
+    '-a[insert new window at next free index from -t]' \
+    '-c+[specify working directory for the session]:directory:_directories' \
+    "-d[don't make the new window become the active one]" \
+    '-F+[specify output format]:format:__tmux-format' \
+    '-k[destroy it if the specified window exists]' \
+    '-n+[specify a window name]:window name' \
+    '-P[print information about new window after it is created]' \
+    '-t+[specify target window]:window:__tmux-windows' \
+    '*:: :_cmdstring'
 }
 
-function _tmux-load-buffer() {
-    [[ -n ${tmux_describe} ]] && print "Load a file into a paste buffer" && return
-    local -a args
-
-    args=(
-        '-b[choose a target buffer index]:panes:__tmux-buffers'
-        '1:file name:_files -g "*(-.)"'
-    )
-    _arguments : ${args} && return
+_tmux-next-layout() {
+  [[ -n ${tmux_describe} ]] && print "move a window to the next layout" && return
+  _arguments '-t+[specify target window]:window:__tmux-windows'
 }
 
-function _tmux-lock-client() {
-    [[ -n ${tmux_describe} ]] && print "Lock a client" && return
-    local -a args
-    args=('-t[choose a client]:clients:__tmux-clients')
-    _arguments : ${args} && return
+_tmux-next-window() {
+  [[ -n ${tmux_describe} ]] && print "move to the next window in a session" && return
+  _arguments -s \
+    '-a[move to the next window with an alert]' \
+    '-t+[specify target session]:session:__tmux-sessions'
 }
 
-function _tmux-lock-server() {
-    [[ -n ${tmux_describe} ]] && print "Lock all clients attached to the server" && return
-    __tmux-nothing-else
+_tmux-paste-buffer() {
+  [[ -n ${tmux_describe} ]] && print "insert a paste buffer into the window" && return
+  _arguments -s \
+    '-b+[specify buffer]:source buffer:__tmux-buffers' \
+    '-d[remove buffer from stack after pasting]' \
+    '-p[use bracketed paste mode if the application requested it]' \
+    "-r[don't replace LF with CR when pasting]" \
+    '-s+[specify separator]:separator' \
+    '-t+[specify target window]:window:__tmux-windows'
 }
 
-function _tmux-lock-session() {
-    [[ -n ${tmux_describe} ]] && print "Lock all clients attached to a session" && return
-    local -a args
-    args=('-t[choose a session]:sessions:__tmux-sessions')
-    _arguments : ${args} && return
+_tmux-pipe-pane() {
+  [[ -n ${tmux_describe} ]] && print "pipe output from a pane to a shell command" && return
+  _arguments -s -A "-*" -S \
+    '-o[only open a pipe if none is currently opened]' \
+    '-t+[specify target pane]:pane:__tmux-panes' \
+    ':shell command:_cmdstring'
 }
 
-function _tmux-move-pane() {
-    [[ -n ${tmux_describe} ]] && print "Move a pane into a new space" && return
-    local -a args
-    args=(
-        '-b[join source pane left of or above target pane]'
-        '-d[do not make the new window become the active one]'
-        '-h[split horizontally]'
-        '-v[split vertically]'
-        '-l[define new pane'\''s size]: :_guard "[0-9]#" "numeric value"'
-        '-p[define new pane'\''s size in percent]: :_guard "[0-9]#" "numeric value"'
-        '-s[choose source pane]:window:__tmux-panes'
-        '-t[choose target pane]:window:__tmux-panes'
-    )
-    _arguments : ${args} && return
+_tmux-previous-layout() {
+  [[ -n ${tmux_describe} ]] && print "move a window to the previous layout" && return
+  _arguments '-t+[specify target window]:window:__tmux-windows'
 }
 
-function _tmux-move-window() {
-    [[ -n ${tmux_describe} ]] && print "Move a window to another" && return
-    local -a args
-    args=(
-        '-d[do not make the new window become the active one]'
-        '-k[kill the target window if it exists]'
-        '-s[choose source window]:window:__tmux-windows'
-        '-r[renumber windows in session in sequential order]'
-        '-t[choose destination window]:window:__tmux-windows'
-    )
-    _arguments : ${args}
+_tmux-previous-window() {
+  [[ -n ${tmux_describe} ]] && print "move to the previous window in a session" && return
+  _arguments -s \
+    '-a[move to the previous window with an alert]' \
+    '-t+[specify target session]:session:__tmux-sessions'
 }
 
-function _tmux-new-session() {
-    [[ -n ${tmux_describe} ]] && print "Create a new session" && return
-    local -a args
-    args=(
-        '-A[attach to existing session if it already exists]'
-        '-c[specify working directory for the session]:directory:_path_files -g "*(-/)"'
-        '-d[do not attach new session to current terminal]'
-        '-D[in case of -A behave like attach-session'\''s -d]'
-        '-F[specify format of output]:format:__tmux-format'
-        '-n[name the initial window]:window name'
-        '-P[print information about new session after it is created]'
-        '-s[name the session]:session name:__tmux-sessions'
-        '-t[specify target session]:sessions:__tmux-sessions'
-        '-x[specify width]:width:_guard "[0-9]#" "numeric value"'
-        '-y[specify height]:height:_guard "[0-9]#" "numeric value"'
-        '*:: :_cmdstring'
-    )
-    _arguments -s : ${args}
+_tmux-refresh-client() {
+  [[ -n ${tmux_describe} ]] && print "refresh a client" && return
+  _arguments -s \
+    "-S[only update the client's status bar]" \
+    '-t+[specify target client]:client:__tmux-clients' \
+    '-C+:size'
 }
 
-function _tmux-new-window() {
-    [[ -n ${tmux_describe} ]] && print "Create a new window" && return
-    local -a args
-    args=(
-        '-a[insert new window at next free index from -t]'
-        '-c[specify working directory for the session]:directory:_path_files -g "*(-/)"'
-        '-d[do not make the new window become the active one]'
-        '-F[specify format of output]:format:__tmux-format'
-        '-k[destroy it if the specified window exists]'
-        '-n[specify a window name]:window name:'
-        '-P[print information about new window after it is created]'
-        '-t[specify target window]:windows:__tmux-windows'
-        '*:: :_cmdstring'
-    )
-    _arguments : ${args}
+_tmux-rename-session() {
+  [[ -n ${tmux_describe} ]] && print "rename a session" && return
+  _arguments -s -A "-*" -S \
+    '-t+[specify target session]:session:__tmux-sessions' \
+    ':new session name'
 }
 
-function _tmux-next-layout() {
-    [[ -n ${tmux_describe} ]] && print "Move a window to the next layout" && return
-    local -a args
-    args=('-t[choose target window]:window:__tmux-windows')
-    _arguments : ${args}
+_tmux-rename-window() {
+  [[ -n ${tmux_describe} ]] && print "rename a window" && return
+  _arguments -s -A "-*" -S \
+    '-t+[specify target window]:window:__tmux-windows' \
+    ':new window name'
 }
 
-function _tmux-next-window() {
-    [[ -n ${tmux_describe} ]] && print "Move to the next window in a session" && return
-    local -a args
-    args=(
-        '-a[move to the next window with an alert]'
-        '-t[choose target session]:session:__tmux-sessions'
-    )
-    _arguments : ${args}
+_tmux-resize-pane() {
+  [[ -n ${tmux_describe} ]] && print "resize a pane" && return
+  _arguments -s -A "-*" -S \
+    '-D[resize downward]' \
+    '-L[resize to the left]' \
+    '-M[begin mouse resizing]' \
+    '-R[resize to the right]' \
+    '-U[resize upward]' \
+    '-t+[specify target pane]:pane:__tmux-panes' \
+    '-x+[specify width]:width' \
+    '-y+[specify height]:height' \
+    '-Z[toggle zoom of pane]' \
+    ':adjustment'
 }
 
-function _tmux-paste-buffer() {
-    [[ -n ${tmux_describe} ]] && print "Insert a paste buffer into the window" && return
-    local -a args
-    args=(
-        '-b[choose buffer]:source buffer:__tmux-buffers'
-        '-d[remove buffer from stack after pasting]'
-        '-p[use bracketed paste mode if the application requested it]'
-        '-r[do not replace LF with CR when pasting]'
-        '-s[specify separator]:separator:'
-        '-t[choose target window]:window:__tmux-windows'
-    )
-    _arguments : ${args}
+_tmux-respawn-pane() {
+  [[ -n ${tmux_describe} ]] && print "reuse a pane in which a command has exited" && return
+  _arguments -s -A "-*" -S \
+    '-k[kill window if it is in use]' \
+    '-t+[specify target pane]:pane:__tmux-pane' \
+    ':command:_cmdstring'
 }
 
-function _tmux-pipe-pane() {
-    [[ -n ${tmux_describe} ]] && print "Pipe output from a pane to a shell command" && return
-    local state
-    args=(
-        '-o[only open a pipe if none is currently opened]'
-        '-t[choose target pane]:pane:__tmux-panes'
-        '*:: :->cmd'
-    )
-    _arguments : ${args} && return
-    __tmux-lastarg ${state} 'cmd' 1 "command string"
+_tmux-respawn-window() {
+  [[ -n ${tmux_describe} ]] && print "reuse a window in which a command has exited" && return
+  _arguments -s -A "-*" -S \
+    '-k[kill window if it is in use]' \
+    '-t+[specify target window]:window:__tmux-windows' \
+    ':command:_cmdstring'
 }
 
-function _tmux-previous-layout() {
-    [[ -n ${tmux_describe} ]] && print "Move a window to the previous layout" && return
-    local -a args
-    args=('-t[choose target window]:window:__tmux-windows')
-    _arguments : ${args}
+_tmux-rotate-window() {
+  [[ -n ${tmux_describe} ]] && print "rotate positions of panes in a window" && return
+  _arguments -s \
+    '-D[rotate downward]' \
+    '-U[rotate upward]' \
+    '-t+[specify target window]:window:__tmux-windows'
 }
 
-function _tmux-previous-window() {
-    [[ -n ${tmux_describe} ]] && print "Move to the previous window in a session" && return
-    local -a args
-    args=(
-        '-a[move to the previous window with an alert]'
-        '-t[choose target session]:session:__tmux-sessions'
-    )
-    _arguments : ${args}
+_tmux-run-shell() {
+  [[ -n ${tmux_describe} ]] && print "execute a command without creating a new window" && return
+  _arguments -s -A "-*" -S \
+    '-b[run shell command in background]' \
+    '-t+[specify target pane]:pane:__tmux-panes' \
+    ':command:_cmdstring'
 }
 
-function _tmux-refresh-client() {
-    [[ -n ${tmux_describe} ]] && print "Refresh a client" && return
-    local -a args
-    args=(
-        '-S[Only update the client'\''s status bar]'
-        '-t[choose target client]:client:__tmux-clients'
-    )
-    _arguments : ${args}
+_tmux-save-buffer() {
+  [[ -n ${tmux_describe} ]] && print "save a paste buffer to a file" && return
+  _arguments -s \
+    '-a[append to rather than overwriting file]' \
+    '-b+[specify a target buffer index]:buffer:__tmux-buffers'
 }
 
-function _tmux-rename-session() {
-    [[ -n ${tmux_describe} ]] && print "Rename a session" && return
-    local state
-    args=(
-        '-t[choose target session]:session:__tmux-sessions'
-        '*:: :->name'
-    )
-    _arguments : ${args} && return
-    __tmux-lastarg ${state} 'name' 1 "new session name"
+_tmux-select-layout() {
+  [[ -n ${tmux_describe} ]] && print "choose a layout for a window" && return
+  _arguments -s -A "-*" -S \
+    '-n[behave like next-layout]' \
+    '-o[revert to previous layout]' \
+    '-p[behave like previous-layout]' \
+    '-t+[specify a target window]:target window:__tmux-windows' \
+    ':layout:(even-horizontal even-vertical main-horizontal main-vertical)'
 }
 
-function _tmux-rename-window() {
-    [[ -n ${tmux_describe} ]] && print "Rename a window" && return
-    local state
-    args=(
-        '-t[choose target window]:window:__tmux-windows'
-        '*:: :->name'
-    )
-    _arguments : ${args} && return
-    __tmux-lastarg ${state} 'name' 1 "new window name"
+_tmux-select-pane() {
+  [[ -n ${tmux_describe} ]] && print "make a pane the active one in the window" && return
+  _arguments -s \
+    '-D[move to the pane below target]' \
+    '-d[disable input to the pane]' \
+    '-e[enable input to the pane]' \
+    '-g[show current pane style]' \
+    '-l[behave like last-pane]' \
+    '-L[move to the pane left of target]' \
+    '-M[clear marked pane]' \
+    '-m[set marked pane]' \
+    '-R[move to the pane right of target]' \
+    '-U[move to the pane above target]' \
+    '-P+[set pane style]:style:__tmux-style' \
+    '-t+[specify target pane]:pane:__tmux-panes'
 }
 
-function _tmux-resize-pane() {
-    [[ -n ${tmux_describe} ]] && print "Resize a pane" && return
-    args=(
-        '-D[resize downward]'
-        '-L[resize to the left]'
-        '-R[resize to the right]'
-        '-U[resize upward]'
-        '-t[choose target pane]:pane:__tmux-panes'
-        '-x[specify width]:width:_guard "[0-9]#" "numeric value"'
-        '-y[specify height]:height:_guard "[0-9]#" "numeric value"'
-        '-Z[toggle zoom of pane]'
-        '1::adjustment (defaults to one):_guard "[0-9]#" "numeric value"'
-    )
-    _arguments : ${args}
+_tmux-select-window() {
+  [[ -n ${tmux_describe} ]] && print "select a window" && return
+  _arguments -s \
+    '-l[behave like last-window]' \
+    '-n[behave like next-window]' \
+    '-p[behave like previous-window]' \
+    '-T[if selected window is the current behave like last-window]' \
+    '-t+[specify target window]:window:__tmux-windows'
 }
 
-function _tmux-respawn-pane() {
-    [[ -n ${tmux_describe} ]] && print "Reuse a pane in which a command has exited" && return
-    local -a args
-    args=(
-        '-k[kill window if it is in use]'
-        '-t[choose target pane]:window:__tmux-pane'
-        '*::command:_cmdstring'
-    )
-    _arguments : ${args}
+_tmux-send-keys() {
+  [[ -n ${tmux_describe} ]] && print "send key(s) to a window" && return
+  _arguments -s -A "-*" -S \
+    '-l[disable key name lookup and send data literally]' \
+    '-R[reset terminal state]' \
+    '-M[pass through a mouse event]' \
+    '-t+[specify target pane]:pane:__tmux-panes' \
+    '*:key'
 }
 
-function _tmux-respawn-window() {
-    [[ -n ${tmux_describe} ]] && print "Reuse a window in which a command has exited" && return
-    local -a args
-    args=(
-        '-k[kill window if it is in use]'
-        '-t[choose target window]:window:__tmux-windows'
-        '*::command:_cmdstring'
-    )
-    _arguments : ${args}
+_tmux-send-prefix() {
+  [[ -n ${tmux_describe} ]] && print "send the prefix key to a window" && return
+  _arguments -s \
+    '-2[send secondary prefix key]' \
+    '-t+[specify target pane]:pane:__tmux-panes'
 }
 
-function _tmux-rotate-window() {
-    [[ -n ${tmux_describe} ]] && print "Rotate positions of panes in a window" && return
-    local -a args
-    args=(
-        '-D[rotate downward]'
-        '-U[rotate upward]'
-        '-t[choose target window]:window:__tmux-windows'
-    )
-    _arguments : ${args}
+_tmux-server-info() {
+  [[ -n ${tmux_describe} ]] && print "show server information" && return
+  __tmux-nothing-else
 }
 
-function _tmux-run-shell() {
-    [[ -n ${tmux_describe} ]] && print "Execute a command without creating a new window" && return
-    local -a args
-    args=(
-        '-b[run shell command in background]'
-        '-t[choose target pane]:pane:__tmux-panes'
-        '*::command:_cmdstring'
-    )
-    _arguments : ${args}
+_tmux-set-buffer() {
+  [[ -n ${tmux_describe} ]] && print "set contents of a paster buffer" && return
+  _arguments -s -A "-*" -S \
+    '-a[append to rather than overwriting target buffer]' \
+    '-b+[specify target buffer index]:pane:__tmux-buffers' \
+    '-n+[specify new buffer name]:buffer-name' \
+    ':data'
 }
 
-function _tmux-save-buffer() {
-    [[ -n ${tmux_describe} ]] && print "Save a paste buffer to a file" && return
-    local -a args
-
-    args=(
-        '-a[append to rather than overwriting file]'
-        '-b[choose a target buffer index]:buffer:__tmux-buffers'
-    )
-    _arguments : ${args} && return
+_tmux-set-environment() {
+  [[ -n ${tmux_describe} ]] && print "(un)set an environment variable" && return
+  _arguments -s -A "-*" -S \
+    '-g[modify global environment]' \
+    '-r[remove variable before starting new processes]' \
+    '-u[unset a variable]' \
+    '-t[specify target session]:target session:__tmux-sessions' \
+    ':name' ':value'
 }
 
-function _tmux-select-layout() {
-    [[ -n ${tmux_describe} ]] && print "Choose a layout for a window" && return
-    args=(
-        '-n[behave like next-layout]'
-        '-p[behave like previous-layout]'
-        '-t[choose a target window]:target window:__tmux-windows'
-        '*::layout name:__tmux-layouts'
-    )
-    _arguments : ${args}
+_tmux-set-option() {
+  [[ -n ${tmux_describe} ]] && print "set a session option" && return
+  local mode=session
+  local curcontext="$curcontext" state line ret=1
+  typeset -A opt_args
+  _arguments -C -s \
+    '-a[append to string options]' \
+    '-g[set a global session option]' \
+    '-o[prevent setting of an option that is already set]' \
+    '-q[suppress errors about unknown or ambiguous options]' \
+    '-u[unset a non-global option]' \
+    '-w[change window (not session) options]' \
+    '-s[change server (not session) options]' \
+    '-t+[specify target session]:target session:__tmux-sessions' \
+    '*:: :->name_or_value' && ret=0
+
+  if (( ${+opt_args[-w]} )); then
+    mode=window
+  elif (( ${+opt_args[-s]} )); then
+    mode=server
+  fi
+  __tmux-options-complete ${mode} ${state} && ret=0
+  return ret
 }
 
-function _tmux-select-pane() {
-    [[ -n ${tmux_describe} ]] && print "Make a pane the active one in the window" && return
-    local -a args
-    args=(
-        '-D[Move to the pane down of this]'
-        '-d[disable input to the pane]'
-        '-e[enable input to the pane]'
-        '-l[behave like last-pane]'
-        '-L[Move to the pane left of this]'
-        '-R[Move to the pane right of this]'
-        '-U[Move to the pane above this]'
-        '-t[choose a target pane]:panes:__tmux-panes'
-    )
-    _arguments : ${args} && return
+_tmux-set-window-option() {
+  [[ -n ${tmux_describe} ]] && print "set a window option" && return
+  local curcontext="$curcontext" state line ret=1
+  typeset -A opt_args
+  _arguments -C -s \
+    '-a[append to string options]' \
+    '-g[set a global window option]' \
+    '-o[prevent setting of an option that is already set]' \
+    '-q[suppress errors about unknown or ambiguous options]' \
+    '-u[unset a non-global option]' \
+    '-t+[specify target window]:target window:__tmux-windows' \
+    '*:: :->name_or_value' && ret=0
+  __tmux-options-complete window ${state} && ret=0
+  return ret
 }
 
-function _tmux-select-window() {
-    [[ -n ${tmux_describe} ]] && print "Select a window" && return
-    local -a args
-    args=(
-        '-l[behave like last-window]'
-        '-n[behave like next-window]'
-        '-p[behave like previous-window]'
-        '-T[if selected window is the current behave like last-window]'
-        '-t[choose a target window]:windows:__tmux-windows'
-    )
-    _arguments : ${args} && return
+_tmux-set-hook() {
+  [[ -n ${tmux_describe} ]] && print "set a hook to a command" && return
+  _arguments -s \
+    '-g[add hook to global list]' \
+    '-t+[specify target session]:session:__tmux-sessions'
+    ':command'
 }
 
-function _tmux-send-keys() {
-    [[ -n ${tmux_describe} ]] && print "Send key(s) to a window" && return
-    local curcontext="${curcontext}" state
-    local -a args
-    args=(
-        '-l[disable key name lookup and send data literally]'
-        '-R[reset terminal state]'
-        '-t[choose a target pane]:panes:__tmux-panes'
-        '*:: :->key'
-    )
-    _arguments : ${args} && return
-    __tmux-lastarg ${state} 'key' 1 "key"
+_tmux-show-hooks() {
+  [[ -n ${tmux_describe} ]] && print "show the global list of hooks" && return
+  _arguments -s -S -A "-*" \
+    '-g[show global list of hooks]' \
+    '-t+[specify target session]:session:__tmux-sessions' \
+    ':hook name:(alert-activity alert-bell alert-silence client-attached client-detached client-resized pane-died pane-exited)' \
 }
 
-function _tmux-send-prefix() {
-    [[ -n ${tmux_describe} ]] && print "Send the prefix key to a window" && return
-    local -a args
-    args=(
-        '-2[send secondary prefix key]'
-        '-t[choose a target pane]:panes:__tmux-panes'
-    )
-    _arguments : ${args}
+_tmux-show-buffer() {
+  [[ -n ${tmux_describe} ]] && print "display the contents of a paste buffer" && return
+  _arguments '-b[specify target buffer index]:pane:->buffer'
 }
 
-function _tmux-server-info() {
-    [[ -n ${tmux_describe} ]] && print "Show server information" && return
-    __tmux-nothing-else
+_tmux-show-environment() {
+  [[ -n ${tmux_describe} ]] && print "display the environment" && return
+  _arguments -s \
+    '-g[show global environment]' \
+    '-s[format output as Bourne shell commands]' \
+    '-t+[specify target session]:target session:__tmux-sessions'
 }
 
-function _tmux-set-buffer() {
-    [[ -n ${tmux_describe} ]] && print "Set contents of a paster buffer" && return
-    local state
-    local -a args
-    args=(
-        '-a[append to rather than overwriting target buffer]'
-        '-b[choose a target buffer index]:panes:__tmux-buffer'
-        '-n[specify new buffer name]:buffer-name:'
-        '*:: :->data'
-    )
-    _arguments : ${args} && return
-    __tmux-lastarg ${state} 'data' 1 "data"
+_tmux-show-messages() {
+  [[ -n ${tmux_describe} ]] && print "show client's message log" && return
+  _arguments -s \
+    '-J[show debugging information about running jobs]' \
+    '-T[show debugging information about involved terminals]' \
+    '-t+[specify target client]:client:__tmux-clients'
 }
 
-function _tmux-set-environment() {
-    [[ -n ${tmux_describe} ]] && print "(Un)Set an environment variable" && return
-    local state
-    local -a args
-    args=(
-        '-g[modify global environment]'
-        '-r[remove variable before starting new processes]'
-        '-u[unset a variable]'
-        '-t[choose a target session]:target session:__tmux-sessions'
-        '*:: :->name_or_value'
-    )
-    _arguments -C : ${args}
-
-    case ${state} in
-        name_or_value)
-            if (( CURRENT == 1 )); then
-                _message 'name'
-            elif (( CURRENT == 2 )); then
-                _message 'value'
-            else
-                __tmux-nothing-else
-            fi
-            ;;
-    esac
+_tmux-show-options() {
+  [[ -n ${tmux_describe} ]] && print "show session options" && return
+  _arguments -s \
+    '-g[show global options]' \
+    '-q[suppress errors about unknown or ambiguous options]' \
+    '-s[show server options]' \
+    '-v[show only the option value, not the name]' \
+    '-w[show window options]' \
+    '-t+[specify target session]:target session:__tmux-sessions'
 }
 
-function _tmux-set-option() {
-    [[ -n ${tmux_describe} ]] && print "Set a session option" && return
-    local mode
-    local -a args
-    args=(
-        '-a[append to string options]'
-        '-g[set a global session option]'
-        '-u[unset a non-global option]'
-        '-w[change window (not session) options]'
-        '-s[change server (not session) options]'
-        '-t[choose a target session]:target session:__tmux-sessions'
-        '*:: :->name_or_value'
-    )
-    if __tmux-got-option-already -w; then
-        mode=window
-    elif __tmux-got-option-already -s; then
-        mode=server
-    else
-        mode=session
-    fi
-    _arguments -C : ${args}
-    __tmux-options-complete ${mode} ${state}
+_tmux-show-window-options() {
+  [[ -n ${tmux_describe} ]] && print "show window options" && return
+  _arguments -s \
+    '-g[show global options]' \
+    '-v[show only the option value, not the name]' \
+    '-t+[specify target window]:target window:__tmux-windows'
 }
 
-function _tmux-set-window-option() {
-    [[ -n ${tmux_describe} ]] && print "Set a window option" && return
-    local -a args
-    args=(
-        '-a[append to string options]'
-        '-g[set a global window option]'
-        '-u[unset a non-global option]'
-        '-t[choose a target window]:target window:__tmux-windows'
-        '*:: :->name_or_value'
-    )
-    _arguments -C : ${args}
-    __tmux-options-complete window ${state}
+_tmux-source-file() {
+    [[ -n ${tmux_describe} ]] && print "execute tmux commands from a file" && return
+    _files
 }
 
-function _tmux-show-buffer() {
-    [[ -n ${tmux_describe} ]] && print "Display the contents of a paste buffer" && return
-    local -a args
-    args=('-b[choose a target buffer index]:panes:->buffer')
-    _arguments : ${args} && return
+_tmux-split-window() {
+  [[ -n ${tmux_describe} ]] && print "splits a pane into two" && return
+  _arguments -s \
+    '-b[create new pane left of or above target pane]' \
+    "-d[don't make the new window become the active one]" \
+    '-F+[specify output format]:format:__tmux-format' \
+    '-h[split horizontally]' \
+    '-v[split vertically]' \
+    "-l[define new pane's size]:size" \
+    "-p[define new pane's size in percent]:size (percentage)" \
+    '-t+[specify target pane]:pane:__tmux-panes' \
+    ':command:_cmdstring'
+  # Yes, __tmux-panes is correct here. The behaviour was changed
+  # in recent tmux versions and makes more sense. Except that
+  # changing the command's name might annoy users. So it stays like
+  # this.
 }
 
-function _tmux-show-environment() {
-    [[ -n ${tmux_describe} ]] && print "Display the environment" && return
-    local -a args
-    args=(
-        '-g[show global environment]'
-        '-t[choose a target session]:target session:__tmux-sessions'
-    )
-    _arguments : ${args}
+_tmux-start-server() {
+  [[ -n ${tmux_describe} ]] && print "start a tmux server" && return
+  __tmux-nothing-else
 }
 
-function _tmux-show-messages() {
-    [[ -n ${tmux_describe} ]] && print "Show client"\'"s message log" && return
-    local -a args
-    args=(
-        '-I[show debugging information about the tmux server]'
-        '-J[show debugging information about running jobs]'
-        '-T[show debugging information about involved terminals]'
-        '-t[choose target client]:client:__tmux-clients'
-    )
-    _arguments : ${args}
+_tmux-suspend-client() {
+  [[ -n ${tmux_describe} ]] && print "suspend a client" && return
+  _arguments '-t+[specify destination client]:client:__tmux-clients'
 }
 
-function _tmux-show-options() {
-    [[ -n ${tmux_describe} ]] && print "Show session options" && return
-    local -a args
-    args=(
-        '-g[show global options]'
-        '-t[choose a target session]:target session:__tmux-sessions'
-    )
-    _arguments : ${args}
+_tmux-swap-pane() {
+  [[ -n ${tmux_describe} ]] && print "swap two panes" && return
+  _arguments -s \
+    '-D[move pane down]' \
+    '-U[move pane up]' \
+    "-d[don't change the active pane]" \
+    '-s+[specify source pane]:pane:__tmux-panes' \
+    '-t+[specify destination pane]:pane:__tmux-panes'
 }
 
-function _tmux-show-window-options() {
-    [[ -n ${tmux_describe} ]] && print "Show window options" && return
-    local -a args
-    args=(
-        '-g[show global options]'
-        '-t[choose a target window]:target window:__tmux-windows'
-    )
-    _arguments : ${args}
+_tmux-swap-window() {
+  [[ -n ${tmux_describe} ]] && print "swap two windows" && return
+  _arguments -s \
+    "-d[don't make the new window become the active one]" \
+    '-s+[specify source window]:window:__tmux-windows' \
+    '-t+[specify destination window]:window:__tmux-windows'
 }
 
-function _tmux-source-file() {
-    [[ -n ${tmux_describe} ]] && print "Execute tmux commands from a file" && return
-    _files -g "*(-.)"
+_tmux-switch-client() {
+  [[ -n ${tmux_describe} ]] && print "switch the client to another session" && return
+  _arguments -s \
+    '-c+[specify a target client]:client:__tmux-clients' \
+    "-E[don't apply update-environment option]" \
+    '-l[move client to last session]' \
+    '-n[move client to next session]' \
+    '-p[move client to previous session]' \
+    '-r[toggle read-only flag of client]' \
+    '-t+[specify target window]:window:__tmux-windows'
 }
 
-function _tmux-split-window() {
-    [[ -n ${tmux_describe} ]] && print "Splits a pane into two" && return
-    local -a args
-    args=(
-        '-b[create new pane left of or above target pane]'
-        '-d[do not make the new window become the active one]'
-        '-F[specify format of output]:format:__tmux-format'
-        '-h[split horizontally]'
-        '-v[split vertically]'
-        '-l[define new pane'\''s size]: :_guard "[0-9]#" "numeric value"'
-        '-p[define new pane'\''s size in percent]: :_guard "[0-9]#" "numeric value"'
-        # Yes, __tmux-panes is correct here. The behaviour was changed
-        # in recent tmux versions and makes more sense. Except that
-        # changing the command's name might annoy users. So it stays like
-        # this.
-        '-t[choose target pane]:window:__tmux-panes'
-        '*:: :_cmdstring'
-    )
-    _arguments : ${args} && return
-}
+_tmux-unbind-key() {
+  [[ -n ${tmux_describe} ]] && print "unbind a key" && return
+  local curcontext="$curcontext" state line keytable
+  local -a ow
 
-function _tmux-start-server() {
-    [[ -n ${tmux_describe} ]] && print "Start a tmux server" && return
-    __tmux-nothing-else
-}
+  ow=( "${words[@]}" )
+  _arguments -C -s \
+    '-a[remove all key bindings]' \
+    '-c[kill the window if it is only in one session]' \
+    '-n[remove a non-prefix binding]' \
+    '-t+[specify mode table]:mode table:__tmux-mode-tables' \
+    '-T[specify key table]:key table' \
+    '*:: :->boundkeys'
 
-function _tmux-suspend-client() {
-    [[ -n ${tmux_describe} ]] && print "Suspend a client" && return
-    local -a args
-    args=('-t[choose destination client]:client:__tmux-clients')
-    _arguments : ${args}
-}
-
-function _tmux-swap-pane() {
-    [[ -n ${tmux_describe} ]] && print "Swap two panes" && return
-    local -a args
-    args=(
-        '-D[move pane down]'
-        '-U[move pane up]'
-        '-d[do not change the active pane]'
-        '-s[choose source pane]:pane:__tmux-panes'
-        '-t[choose destination pane]:pane:__tmux-panes'
-    )
-    _arguments : ${args}
-}
-
-function _tmux-swap-window() {
-    [[ -n ${tmux_describe} ]] && print "Swap two windows" && return
-    local -a args
-    args=(
-        '-d[do not make the new window become the active one]'
-        '-s[choose source window]:window:__tmux-windows'
-        '-t[choose destination window]:window:__tmux-windows'
-    )
-    _arguments : ${args}
-}
-
-function _tmux-switch-client() {
-    [[ -n ${tmux_describe} ]] && print "Switch the client to another session" && return
-    local -a args
-    args=(
-        '-c[choose a target client]:client:__tmux-clients'
-        '-l[move client to last session]'
-        '-n[move client to next session]'
-        '-p[move client to previous session]'
-        '-r[toggle read-only flag of client]'
-        '-t[choose a target window]:window:__tmux-windows'
-    )
-    _arguments : ${args}
-}
-
-function _tmux-unbind-key() {
-    [[ -n ${tmux_describe} ]] && print "Unbind a key" && return
-    local state keytable
-    local -a args ow
-
-    ow=( "${words[@]}" )
-    args=(
-        '-a[Remove all key bindings]'
-        '-c[kill the window if it is only in one session]'
-        '-n[remove a non-prefix binding]'
-        '-t[choose a key table]:key table:__tmux-key-tables'
-        '*:: :->boundkeys'
-    )
-    _arguments : ${args} && return
     [[ ${state} != 'boundkeys' ]] && return
     keytable="$(__tmux-get-optarg -t "${ow[@]}")"
     if [[ -n ${keytable} ]]; then
@@ -1120,28 +922,20 @@ function _tmux-unbind-key() {
     __tmux-bound-keys
 }
 
-function _tmux-unlink-window() {
-    [[ -n ${tmux_describe} ]] && print "Unlink a window" && return
-    local -a args
-    args=(
-        '-k[kill the window if it is only in one session]'
-        '-t[choose a target window]:target window:__tmux-windows'
-    )
-    _arguments : ${args}
+_tmux-unlink-window() {
+  [[ -n ${tmux_describe} ]] && print "unlink a window" && return
+  _arguments -s \
+    '-k[kill the window if it is only in one session]' \
+    '-t+[specify target window]:target window:__tmux-windows'
 }
 
-function _tmux-wait-for() {
-    [[ -n ${tmux_describe} ]] && print "Wait for an event or trigger it" && return
-    local state
-    local -a args
-    args=(
-        '-L[lock the named channel]'
-        '-S[send signal to channel]'
-        '-U[unlock the named channel]'
-        '*:: :->channel'
-    )
-    _arguments : ${args} && return
-    __tmux-lastarg ${state} 'channel' 1 "event channel"
+_tmux-wait-for() {
+  [[ -n ${tmux_describe} ]] && print "wait for an event or trigger it" && return
+  _arguments -s \
+    '-L[lock the named channel]' \
+    '-S[send signal to channel]' \
+    '-U[unlock the named channel]' \
+    ':event channel'
 }
 
 # --- Utility functions ---
@@ -1152,7 +946,7 @@ function __tmux-attributes() {
     local -a attr already
     attr=( default bright bold dim underscore blink reverse hidden italics )
     compset -P '*,'
-    already=(${(s<,>)IPREFIX})
+    already=( ${(s<,>)IPREFIX} )
     _describe -t tmux-attribute 'tmux attribute' attr -S, -F already -q
 }
 
@@ -1213,37 +1007,14 @@ function __tmux-get-optarg() {
     done
 }
 
-function __tmux-got-option-already() {
-    [[ -n ${(M)words:#$1} ]] && return 0
-    return 1
+__tmux-mode-tables() {
+  local expl
+  _description mode-tables expl 'mode table'
+  compadd "$@" "$expl[@]" vi-edit emacs-edit vi-choice emacs-choice vi-copy emacs-copy
 }
 
-function __tmux-key-tables() {
-    local expl
-    local -a tables
-    tables=( vi-edit emacs-edit vi-choice emacs-choice vi-copy emacs-copy )
-    _wanted keytable expl 'key tables' compadd ${expl} -- ${tables}
-}
-
-function __tmux-lastarg() {
-    local got_state="$1" want_state="$2" pos="$3" msg="$4"
-
-    if [[ ${want_state} == ${got_state} ]] && (( CURRENT == ${pos} )); then
-        _message ${msg}
-    else
-        __tmux-nothing-else
-    fi
-}
-
-function __tmux-layouts() {
-    local expl
-    local -a layouts
-    layouts=( even-horizontal even-vertical main-horizontal main-vertical )
-    _wanted layout expl 'layouts' compadd ${expl} -- ${layouts}
-}
-
-function __tmux-nothing-else() {
-    _message "no further arguments"
+__tmux-nothing-else() {
+  _message "no further arguments"
 }
 
 function __tmux-option-guard() {
@@ -1417,7 +1188,7 @@ function __tmux-session-options() {
         'status-right-style:style of right part of status line'
         'status-style:style status line'
         'status-utf8:assume UTF-8 sequences to appear in status bar'
-        'update-environment:list of variables to be copied to a session'\''s environment'
+        "update-environment:list of variables to be copied to a session's environment"
         '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'
@@ -1485,7 +1256,6 @@ function __tmux-server-options() {
 }
 
 function __tmux-sessions() {
-    local expl
     local -a sessions
     sessions=( ${${(f)"$(command tmux 2> /dev/null list-sessions)"}/:[ $'\t']##/:} )
     _describe -t sessions 'sessions' sessions "$@"
@@ -1495,7 +1265,7 @@ function __tmux-socket-name() {
     local expl sdir
     local curcontext="${curcontext}"
     local -a socks
-    zstyle -s ":completion:${curcontext}:sockets" socketdir sdir || sdir="/tmp/tmux-${UID}"
+    zstyle -s ":completion:${curcontext}:sockets" socketdir sdir || sdir="${TMUX_TMPDIR:-/tmp}/tmux-${UID}"
     socks=(${sdir}/*(=:t))
     _wanted socket expl 'socket name' compadd ${expl} -- ${socks}
 }
@@ -1527,7 +1297,7 @@ 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-style:style of border pane'
-        'remain-on-exit:do not destroy windows after the program exits'
+        "remain-on-exit:don't destroy windows after the program exits"
         'synchronize-panes:send input to all panes of a window'
         'utf8:assume UTF-8 sequences to appear in a window'
         'window-active-style:style of active window'
@@ -1564,65 +1334,58 @@ function __tmux-windows() {
 }
 
 # And here is the actual _tmux(), that puts it all together:
-function _tmux() {
-    local curcontext="${curcontext}"
-    local mode state ret=1
-    local -a args
-    local tmuxcommand
-    local tmux_describe=
+_tmux() {
+  local curcontext="${curcontext}" state line ret=1
+  local mode
+  local tmuxcommand
+  local tmux_describe
 
-    args=(
-        '-2[force using 256 colours]'
-        '-8[force using 88 colours]'
-        '-c[execute a shell command]:command name:_command_names'
-        '-C[start tmux in control mode. -CC disables echo]'
-        '-f[specify configuration file]:tmux config file:_files -g "*(-.)"'
-        '-l[behave like a login shell]'
-        '-L[specify socket name]:socket name:__tmux-socket-name'
-        '-S[specify socket path]:server socket:_path_files -g "*(=,/)"'
-        '-u[force using UTF-8]'
-        '-v[request verbose logging]'
-        '-V[report tmux version]'
-        '*:: :->subcommand_or_options'
-    )
-    _arguments -C -s -w : ${args} && ret=0
+  _arguments -C -s -w \
+    '-2[force using 256 colours]' \
+    '-c[execute a shell command]:command name:_command_names' \
+    '-C[start tmux in control mode. -CC disables echo]' \
+    '-f[specify configuration file]:tmux config file:_files -g "*(-.)"' \
+    '-l[behave like a login shell]' \
+    '-L[specify socket name]:socket name:__tmux-socket-name' \
+    '-S[specify socket path]:server socket:_path_files -g "*(=,/)"' \
+    '-u[force using UTF-8]' \
+    '-v[request verbose logging]' \
+    '-V[report tmux version]' \
+    '*:: :->subcommand_or_options' && ret=0
 
-    if [[ ${state} == "subcommand_or_options" ]]; then
-        if (( CURRENT == 1 )) ; then
-            zstyle -s ":completion:${curcontext}:subcommands" mode mode || mode='both'
-            if [[ ${mode} == 'commands' ]]; then
-                _describe -t subcommands 'tmux commands' _tmux_commands && ret=0
-            elif [[ ${mode} == 'aliases' ]]; then
-                _describe -t subcommands 'tmux aliases' _tmux_aliases && ret=0
-            else
-                _describe -t subcommands 'tmux commands and aliases' _tmux_commands -- _tmux_aliases && ret=0
-            fi
-        else
-            if (( ${+commands[tmux]} == 0 )); then
-                _message '`tmux'\'' not found in $path; sub-cmd completions disabled.'
-                return
-            fi
-            tmuxcommand="${words[1]}"
-            if [[ -n ${_tmux_aliasmap[$tmuxcommand]} ]] ; then
-                tmuxcommand="${_tmux_aliasmap[$tmuxcommand]}"
-            fi
-            if ! (( ${+functions[_tmux-$tmuxcommand]} )); then
-              local low high
-              low=$_tmux_commands[(i)$tmuxcommand*]
-              high=$_tmux_commands[(I)$tmuxcommand*]
-              if (( low == high )); then
-                tmuxcommand=${_tmux_commands[low]%%:*}
-              elif (( low < high )); then
-                _message -e "Ambiguous command $tmuxcommand"
-              else
-                _message -e "Subcommand $tmuxcommand not known"
-              fi
-            fi
-            curcontext="${curcontext%:*:*}:tmux-${tmuxcommand}:"
-            _call_function ret _tmux-${tmuxcommand}
-        fi
+  [[ -z $state ]] && return ret
+
+  if (( CURRENT == 1 )); then
+    zstyle -s ":completion:${curcontext}:subcommands" mode mode || mode='both'
+    if [[ ${mode} == 'commands' ]]; then
+      _describe -t subcommands 'tmux commands' _tmux_commands && ret=0
+    elif [[ ${mode} == 'aliases' ]]; then
+      _describe -t subcommands 'tmux aliases' _tmux_aliases && ret=0
+    else
+      _describe -t subcommands 'tmux commands and aliases' _tmux_commands -- _tmux_aliases && ret=0
     fi
-    return ret
+  else
+    tmuxcommand="${words[1]}"
+    if [[ -n ${_tmux_aliasmap[$tmuxcommand]} ]] ; then
+      tmuxcommand="${_tmux_aliasmap[$tmuxcommand]}"
+    fi
+    if ! (( ${+functions[_tmux-$tmuxcommand]} )); then
+      local low high
+      low=$_tmux_commands[(i)$tmuxcommand*]
+      high=$_tmux_commands[(I)$tmuxcommand*]
+      if (( low == high )); then
+	tmuxcommand=${_tmux_commands[low]%%:*}
+      elif (( low < high )); then
+	_message "ambiguous command $tmuxcommand"
+      else
+	_message "subcommand $tmuxcommand not known"
+	_normal && ret=0
+      fi
+    fi
+    curcontext="${curcontext%:*}-${tmuxcommand}:"
+    _call_function ret _tmux-${tmuxcommand}
+  fi
+  return ret
 }
 
 # description generation follows; only done on 1st _tmux call.
@@ -1631,12 +1394,12 @@ local -A rev
 local tmux_describe
 tmux_describe='yes, please'
 for f in ${(k)_tmux_aliasmap} ; do
-    rev+=( ${_tmux_aliasmap[$f]} $f )
+  rev+=( ${_tmux_aliasmap[$f]} $f )
 done
 for f in ${(M)${(k)functions}:#_tmux-*} ; do
-    desc="$($f)"
-    _tmux_commands+=( "${f#_tmux-}${desc:+:$desc}" )
-    [[ -n ${rev[${f#_tmux-}]} ]] && _tmux_aliases+=( "${rev[${f#_tmux-}]}${desc:+:$desc}" )
+  desc="$($f)"
+  _tmux_commands+=( "${f#_tmux-}${desc:+:$desc}" )
+  [[ -n ${rev[${f#_tmux-}]} ]] && _tmux_aliases+=( "${rev[${f#_tmux-}]}${desc:+:$desc}" )
 done
 
 _tmux "$@"
diff --git a/Completion/Unix/Command/_tree b/Completion/Unix/Command/_tree
index d759409..4fd9aed 100644
--- a/Completion/Unix/Command/_tree
+++ b/Completion/Unix/Command/_tree
@@ -1,51 +1,54 @@
 #compdef tree
 
-# Completions for tree, version 1.5.3
-# Tree is available at
-# http://mama.indstate.edu/users/ice/tree/
-
-typeset -a opts
-
-opts=(
-'--help[verbose usage listing]'
-'--version[version of tree]'
-'-a[show all files, including hidden ones]'
-'-d[list directories only]'
-'-f[print full path prefix for each file]'
-'-i[do not print indentation lines]'
-'-l[follow symlinks that point to directories]'
-'-x[stay on current filesystem]'
-'-P[list only files matching a pattern]:pattern:'
-'-I[do not list files matching a pattern]:pattern:'
-'--noreport[do not print file and directory report at end]'
-'-p[print file type and permissions, like ls -l]'
-'-s[print size of each file in bytes]'
-'-h[print human readable file size]'
-'-u[print username]'
-'-g[print group name]'
-'-D[print date of last modification]'
-'--inodes[print inode numbers]'
-'--device[print device number to which file or directory belongs]'
-'-F[append descriptive character to end, like ls -F]'
-'-q[print non-printable characters as question mark, not caret]'
-'-N[print non-printable characters as is, not as caret]'
-'-v[sort the output as version]'
-'-r[sort output in reverse alphabetic order]'
-'-t[sort output by last modification time instead of alphabetically]'
-'--dirsfirst[list directories before files]'
-'-n[turn colorization off always, over-ridden by the -C option]'
-'-C[turn colorization on always]'
-'-A[turn on ANSI line graphics hack when printing indentation lines]'
-'-S[turn on ASCII line graphics]'
-'-L[max display depth of tree]:level:'
-'--filelimit[do not descend directories with more than number of entries]:number:'
-'-R[recursively cross down the tree and execute tree again]'
-'-H[turn on HTML output]'
-'-T[title for HTML output]'
-'--charset[character set for HTML and for line drawing]:charset:'
-'--nolinks[turn off hyperlinks in HTML output]'
-'-o[send output to file]:filename:_files'
-'*:directory:_files -/'
-)
-
-_arguments $opts
+_arguments -s -S \
+  '-a[show all files, including hidden ones]' \
+  '-d[list directories only]' \
+  '-l[follow symlinks that point to directories]' \
+  '-f[print full path prefix for each file]' \
+  '-x[stay on current filesystem]' \
+  '-L[specify max tree depth to descend]:level' \
+  '-R[recursively cross down the tree and execute tree again]' \
+  '-P[only list files matching a pattern]:pattern:_files' \
+  "-I[don't list files matching a pattern]:pattern:_files" \
+  '--ignore-case[ignore case when pattern matching]' \
+  '--matchdirs[include directory names in -P pattern matching]' \
+  '--noreport[omit file and directory report at end]' \
+  '--charset=[character set for HTML and for line drawing]:charset' \
+  "--filelimit=[don't descend directories with more than specified number of entries]:entries" \
+  '--timefmt=[use specified time format]:format:_date_formats' \
+  '-o[output to specified file]:file:_files' \
+  '--du[print directory sizes]' \
+  '--prune[exclude empty directories from the output]' \
+  '(-N)-q[print non-printable characters as question mark, not caret]' \
+  '(-q)-N[print non-printable characters as is, not as caret]' \
+  '-Q[quote filenames with double quotes]' \
+  '-p[print file type and permissions, like ls -l]' \
+  '-u[print file owner]' \
+  '-g[print file group]' \
+  '(-h --si)-s[print size of each file in bytes]' \
+  '(-s --si)-h[print human readable file size]' \
+  '(-s -h)--si[print human readable file size in SI units (powers of 1000)]' \
+  '-D[print last modification date or change time (with -c)]' \
+  '-F[append descriptive character to end, like ls -F]' \
+  '--inodes[print inode numbers]' \
+  '--device[print device number to which file or directory belongs]' \
+  '(--sort -t -c -U)-v[sort the output as version]' \
+  '(-v --sort -c -U)-t[sort output by modification time]' \
+  '(-v --sort -t -U)-c[sort output by change time]' \
+  '(-v --sort -t -c -r --dirsfirst)-U[leave files unsorted]' \
+  '(-U)-r[sort in reversed order]' \
+  '(-v -t -c -U)--sort[sort in specified order]:order:(name version size mtime ctime)' \
+  '(-U)--dirsfirst[list directories before files]' \
+  "-i[don't print indentation lines]" \
+  '(-S -X)-A[use ANSI line graphics hack when printing indentation lines]' \
+  '(-A -X)-S[use console (CP437) line graphics]' \
+  '(-C)-n[turn colorization off always, over-ridden by the -C option]' \
+  '(-n)-C[turn colorization on always]' \
+  '(-A -S -n -C -J -H -T --nolinks)-X[XML output]' \
+  '(-A -S -n -C -X -H -T --nolinks)-J[JSON output]' \
+  '(-n -C -X)-H[turn on HTML output]:base HREF' \
+  '(-n -C -X)-T[title for HTML output]:title' \
+  '(-n -C -X)--nolinks[turn off hyperlinks in HTML output]' \
+  '(-)--version[version of tree]' \
+  '(-)--help[verbose usage listing]' \
+  '*:directory:_files -/'
diff --git a/Completion/Unix/Command/_uniq b/Completion/Unix/Command/_uniq
index 1cf1235..6973cb3 100644
--- a/Completion/Unix/Command/_uniq
+++ b/Completion/Unix/Command/_uniq
@@ -5,8 +5,10 @@ local args
 args=(
   '(-c --count)'{-c,--count}'[prefix lines by the number of occurrences]'
   '(-d --repeated)'{-d,--repeated}'[only print duplicate lines]'
-  '(-D --all-repeated)'{-D,--all-repeated=}'[print all duplicate lines]:delimit method:(none prepend separate)'
+  '(--all-repeated)-D-[print all duplicate lines]'
+  '(-D)--all-repeated=-[print all duplicate lines]::delimit method [none]:(none prepend separate)'
   '(-f --skip-fields)'{-f,--skip-fields=}'[avoid comparing initial fields]:number of fields'
+  '--group=-[show all items]::group separation [separate]:(separate prepend append both)'
   '(-i --ignore-case)'{-i,--ignore-case}'[ignore differences in case when comparing]'
   '(-s --skip-chars)'{-s,--skip-chars=}'[avoid comparing initial characters]:number of characters'
   '(-t --separator)'{-t,--separator=}'[specify field delimiter]:separator'
diff --git a/Completion/Unix/Command/_user_admin b/Completion/Unix/Command/_user_admin
index 3653308..f077772 100644
--- a/Completion/Unix/Command/_user_admin
+++ b/Completion/Unix/Command/_user_admin
@@ -1,69 +1,171 @@
 #compdef useradd usermod groupadd groupmod
 
-local args shells home=${${words[(r)-D]:+b}:-d} sun redhat
+local -a args shells logindefs
+local defex
 
-[[ -e /etc/redhat-release || -e /etc/mandrake-release ]]
-redhat=$?
-
-if [[ $service = user* ]]; then
-  if [[ -r /etc/shells ]]; then
-    shells=( ${${(f)"$(</etc/shells)"}:#\#*} )
-  else
-    shells=( ${(M)commands:#*/(|[abckz]|tc|ba)sh} )
-  fi
-
-  args=(
-    '(-D)-c+[comment]:comment'
-    "(-D)-${home}+[home directory]:home directory:_directories -W /"
-    '(-D)-e+[specify expiration date]:expiration date (YYYY-MM-DD)'
-    '(-D)-f+[specify inactive days]:inactive days'
-    '(-D)-g+[initial group]:initial group:_groups'
-    '(-D)-G+[supplementary groups]:supplementary group:_groups -S,'
-    "(-D)-s+[shell]:shell:( $shells /bin/false )"
-    '(-D -M)-m[create home directory]'
-    '(-D)-u[uid]:uid'
-    '(-D)-o[allow non unique uid]'
-  )
-  [[ $OSTYPE = linux* ]] && args+=(
-      '(-D -U -L)-p+[specify encrypted password]:encrypted password' )
-
-  if [[ $service = useradd ]]; then
-    (( redhat )) || args+=(
-      "(-D -k -m)-M[don't create home]"
-      '(-D)-r[create system account]'
-      "(-D)-n[don't create mirrored user]"
-    )
-    [[ $OSTYPE = linux* ]] || sun=" -s"
+# this handles solaris, netbsd, openbsd and linux
+case ${service%???}:${(M)service%???}:$OSTYPE in
+  user:*)
+    if [[ -r /etc/shells ]]; then
+      shells=( ${${(f)"$(</etc/shells)"}:#\#*} )
+    else
+      shells=( ${(M)commands:#*/(|[abckz]|tc|ba)sh} )
+    fi
     args+=(
-      "(-c -G -m -k -M -p -u -o -n -r$sun)-D[modify or display defaults]"
-      '(-D -M)-k[skeleton home directory]:skeleton directory:_directories -W /'
+      '(-D -c --commend)'{-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'
+      '(-D -g --gid)'{-g+,--gid=}'[specify primary group]:initial group:_groups'
+      '(-D -G --groups)'{-G+,--groups=}'[specify supplementary groups]:supplementary group:_sequence _groups'
+      '(-D -s --shell)'{-s+,--shell=}"[shell]:shell:( $shells /bin/false )"
+      '(-D -u --uid)'{-u+,--uid=}'[specify uid]:uid'
+      '(-D -o --non-unique)'{-o,--non-unique}'[allow non unique uid]'
+    )
+  ;|
+  user:add:*)
+    [[ $OSTYPE = linux* ]] && defex=" -k -K -M -p -r -R -Z"
+    [[ $OSTYPE = (net|open)bsd* ]] && defex=" -p -v"
+    args+=(
+      "(-c -d -G -m -l -N -u -U -o -n -S$defex)"{-D,--defaults}'[show or modify defaults]'
+      '(-D -M -k --skel)'{-k,--skel}'[skeleton home directory]:skeleton directory:_directories -W /'
+      '(-D -M -m --create-home)'{-m,--create-home}'[create home directory]'
       ':username'
     )
-  else
-    (( redhat )) || args=( $args[@]
-	"(-U -p)-L[lock user's password]"
-	"(-L -p)-U[unlock user's password]"
+  ;|
+  user:add:linux*)
+    logindefs=( # see login.defs(5)
+      CREATE_HOME GID_MAX GID_MIN MAIL_DIR MAX_MEMBERS_PER_GROUP
+      PASS_MAX_DAYS PASS_MIN_DAYS PASS_WARN_AGE SUB_GID_COUNT SUB_GID_MAX
+      SUB_GID_MIN SUB_UID_COUNT SUB_UID_MAX SUB_UID_MIN SYS_GID_MAX
+      SYS_GID_MIN SYS_UID_MAX SYS_UID_MIN UID_MAX UID_MIN UMASK
     )
-    [[ $OSTYPE = openbsd* ]] || args+=('-a[append groups]')
     args+=(
-      '-l[specify new user name]:new username'
+      '(-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]"
+      '(-N --no-user-group -U --user-group)'{-U,--user-group}"[create a group with the same name as the user]"
+    )
+  ;|
+  user:add:(^solaris2.<-10>))
+    args+=(
+      '(-b --base-dir -d --home-dir)'{-b,--base-dir=}'[specify base directory for new home directory]:directory:_directories'
+    )
+  ;|
+  user:*:(net|open)bsd*)
+    args+=(
+      '-L[specify login class]:login class'
+      '-p+[specify encrypted password]:encrypted password'
+    )
+  ;|
+  user:add:(net|open)bsd*)
+    args+=( '-r[specify UID range]:low.high' )
+  ;|
+  user:add:netbsd*)
+    args+=( '-M[specify home directory permissions]:permissions (octal)' )
+  ;|
+  user:mod:netbsd*)
+    args+=( '-C[lock or unlock account]:locked:(yes no)' )
+  ;|
+  user:*:netbsd*)
+    args+=(
+      '-F[force password change on first login]'
+      '-S[allow samba usernames with a trailing dollar]'
+    )
+  ;|
+  user:mod:openbsd*)
+    args+=(
+      '(-G)-S+[set supplementary groups]:supplementary group:_sequence _groups'
+      "(-U)-Z[lock the account by adding \'-\' to password and shell]"
+      '(-Z)-U[unlock the account]'
+    )
+  ;|
+  *:*:(net|open)bsd*)
+    args+=( '-v[verbose mode - explain commands as they are executed]' )
+  ;|
+  *:*:solaris2.<11->)
+    args+=( '-S[specify repository]:repository:(files ldap)' )
+  ;|
+  user:*:solaris2.<11->)
+    args+=(
+      '-A[specify authorizations]:authorization'
+      \*{-K,--key=}'[set user attributes]:user attribute'
+      '-P[specify execution profiles]:profile'
+      '-R[specify roles]:role'
+      '-p[specify projects]:project'
+    )
+  ;|
+  user:mod:solaris2.<11->)
+    args+=(
+      '-q[specify host or netgroup to qualify extended attributes]:host or netgroup:_hosts'
+    )
+  ;|
+  user:mod:linux*)
+    args+=(
+      '(-a --append)'{-a,--append}'[add user to supplementary groups without removing from other groups]'
+      \*{-v,--add-sub-uids}'[add a range of subordinate uids]:uids (first-last)'
+      \*{-V,--del-sub-uids}'[remove a range of subordinate uids]:uids (first-last)'
+      \*{-w,--add-sub-gids}'[add a range of subordinate gids]:gids (first-last)'
+      \*{-W,--del-sub-gids}'[remove a range of subordinate gids]:gids (first-last)'
+    )
+  ;|
+  user:mod:*)
+    args+=(
+      '(-l --no-log-init)'{-l,--no-log-init}'[specify new user name]:new username'
+      '(-m --move-home)'{-m,--move-home}'[move home directory contents to new location]'
       ':username:_users'
     )
-  fi
-else
-  args=( '-g+[gid]:gid' '-o[allow non unique gid]' )
-  if [[ $service = groupadd ]]; then
-    args+=( ':group name' )
-    (( redhat )) || args=( $args[@]
-      '-r[create system group]'
-      '-f[force]'
-    )
-  else
+  ;|
+  user:*:linux*)
     args+=(
-      '-n[specify new group name]:new group name'
+      '(-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"
+    )
+  ;|
+  group:*)
+    args+=(
+      '(-g,--gid)'{-g+,--gid=}'[specify gid]:gid'
+      '(-o --non-unique)'{-o,--non-unique}'[allow non unique gid]'
+    )
+  ;|
+  group:add:linux*)
+    logindefs=( GID_MAX GID_MIN MAX_MEMBERS_PER_GROUP SYS_GID_MAX SYS_GID_MIN )
+    args+=(
+      '(-r --system)'{-r,--system}'[create a system account]'
+      '(-f --force)'{-f,--force}'[exit successfully if group already exists; cancel -g if GID in use]'
+    )
+  ;|
+  group:*:solaris2.<11->)
+    args+=( '-U[add users to the group]:user:_sequence _users' )
+  ;|
+  *:add:linux*)
+    args+=(
+      \*{-K,--key=}'[override /etc/login.defs defaults]:key: _values 'key' ${^logindefs}\:value'
+    )
+  ;|
+  group:add:netbsd*)
+    args+=( '-r[specify GID range]:low.high' )
+  ;|
+  *:*:linux*)
+    args+=(
+      '(-R --root)'{-R,--root=}'[specify directory to chroot into]:directory:_directories'
+      '(-D -U -L -p --password)'{-p+,--password=}'[specify encrypted password]:encrypted password'
+      '(-)'{-h,--help}'[display help information]'
+    )
+  ;|
+  group:add:*)
+    args+=( ':group name' )
+  ;|
+  group:mod:*)
+    args+=(
+      '(-n --new-name)'{-n,--new-name}'[specify new group name]:new group name'
       ':group:_groups'
     )
-  fi
-fi
+  ;|
+  ^*:linux*)
+    args=( ${(R)args:#(|\*)(|\(*\))--*} )    # remove long options
+  ;|
+esac
 
 _arguments -A "-*" -s $args[@]
diff --git a/Completion/Unix/Command/_wget b/Completion/Unix/Command/_wget
index b6feab5..b89f123 100644
--- a/Completion/Unix/Command/_wget
+++ b/Completion/Unix/Command/_wget
@@ -127,7 +127,6 @@ _arguments -C -s \
   '--trust-server-names' \
   '(--exclude-directories -X)'{--exclude-directories=,-X+}'[exclude directories]:excluded directories' \
   '(-np --no-parent)'{-np,--no-parent}"[don't ascend to parent directory]" \
-  '--no-host-lookup' \
   '--no-verbose' \
   '--no-clobber' \
   '--no-directories' \
diff --git a/Completion/Unix/Command/_xargs b/Completion/Unix/Command/_xargs
index d8c0a0e..8b54334 100644
--- a/Completion/Unix/Command/_xargs
+++ b/Completion/Unix/Command/_xargs
@@ -47,6 +47,7 @@ case $variant in
       '(-0 --null -d --delimiter)'{-0,--null}'[expect NUL characters as input separators]'
       '(-d --delimiter -0 --null)'{-d+,--delimiter=}'[specify delimiter of input items]:delimiter'
       '(-l -L --max-lines -n --max-args -s --max-chars)--max-lines=-[call program for every number of lines]::number of input lines'
+      '--process-slot-var=[set environment variable to unique value in child processes]:variable:_parameters -g "*export*"'
       '(-r --no-run-if-empty)'{-r,--no-run-if-empty}"[don't run command in absence of input]"
       '(- *)--help[show help information]'
       '(- *)--version[show version information]'
diff --git a/Completion/Unix/Command/_zip b/Completion/Unix/Command/_zip
index 1040fa9..1b1b6c3 100644
--- a/Completion/Unix/Command/_zip
+++ b/Completion/Unix/Command/_zip
@@ -6,38 +6,28 @@ typeset -A opt_args
 
 case $service in
   zip)
-    _arguments -C -s \
-      '-f[freshen: only changed files]' \
-      '-d[delete entries in zipfile]' \
+    _arguments -C -s -S \
+      '(-u --update)'{-u,--update}'[update: only changed or new files]' \
+      '(-f --freshen)'{-f,--freshen}'[freshen: update existing files only (no files added)]' \
+      '(-FS --filesync)'{-FS,--filesync}'[filesync: update if date or size changed]' \
+      '(-d --delete)'{-d,--delete}'[delete: delete files from archive]' \
+      '(-U --copy)'{-U,--copy}'[copy: select files in archive to copy]' \
       '-r[recurse into directories]' \
-      '-R[PKZIP recursion]' \
+      '(-m --move)'{-m,--move}'[after archive created, delete original files]' \
+      '(-j --junk-paths)'{-j,--junk-paths}'[junk directory names (store just file names)]' \
       '-q[quiet operation]' \
-      '-c[add one-line comments]' \
-      '-b[use "path" for temp file]:path for temporary archive:_files -/' \
-      '-@[read names from stdin]' \
-      '-F[fix zipfile]' \
-      '-FF[try harder to fix zipfile]' \
-      '-A[adjust self-extracting exe]' \
-      '-T[test zipfile integrity]' \
-      '-y[store symbolic links as the link instead of the referenced file]' \
-      '-e[encrypt]' \
-      '-h[show help]' \
-      '-u[update: only changed or new files]' \
-      '-m[move into zipfile (delete files)]' \
-      '-g[allow growing existing zipfile]' \
-      '-j[junk: do not record directory names]' \
+      '-v[verbose operation/print version info]' \
+      '(-c --entry-comments)'{-c,--entry-comments}'[prompt for one-line comment for each entry]' \
+      '(-z --archive-comment)'{-z,--archive-comment}'[prompt for comment for archive]' \
+      '(-@ --names-stdin)'{-@,--names-stdin}'[read names to zip from stdin]' \
+      '-o[make zipfile as old as latest entry]' \
+      '(-i --include)'{-i,--include}'[include files that match a pattern]:*(-*|@):pattern:_files' \
+      '(-x --exclude)'{-x,--exclude}'[exclude files that match a pattern]:*(-*|@):pattern:_files' \
       '-l[convert LF to CR LF]' \
       '-ll[convert CR LF to LF]' \
-      '-L[display license]' \
-      '-v[verbose operation/print version info]' \
-      '-z[add zipfile comment]' \
-      '-t[only do files after or at "mmddyyyy"]:mmddyyyy' \
-      '-tt[only do files before "mmddyyyy"]:mmddyyyy' \
-      '-o[make zipfile as old as latest entry]' \
-      '-D[do not add directory entries]' \
-      '-J[junk zip file prefix (unzipsfx)]' \
-      '-X[eXclude eXtra file attributes]' \
-      '-n[specify suffixes of files not to be compressed]:suffixes:->suffixes' \
+      '-R[recurse current dir and match patterns]' \
+      '-t+[exclude files modified before specified date]:date (mmddyyyy)' \
+      '-tt+[exclude files modified on or after specified date]:date (mmddyyyy)' \
       '(   -1 -2 -3 -4 -5 -6 -7 -8 -9)-0[store only]' \
       '(-0    -2 -3 -4 -5 -6 -7 -8 -9)-1[compress faster]' \
       '(-0 -1    -3 -4 -5 -6 -7 -8 -9)-2' \
@@ -48,18 +38,60 @@ case $service in
       '(-0 -1 -2 -3 -4 -5 -6    -8 -9)-7' \
       '(-0 -1 -2 -3 -4 -5 -6 -7    -9)-8' \
       '(-0 -1 -2 -3 -4 -5 -6 -7 -8   )-9[compress better]' \
-      '-x[exclude the following names]' \
-      '-i[include only the following names]' \
+      '(-Z --compression-method)'{-Z+,--compression-method=}'[specify compression method]:method:(store deflate bzip2)' \
+      '(-e --encrypt)'{-e,--encrypt}'[encrypt using (weak) PKZip 2.0 encryption, prompt for password]' \
+      '-P+[specify password for standard encryption]:password' \
+      '-s+[create split archive with splits of specified size]:size (MB)' \
+      '-sp[pause after each split to allow changing disks]' \
+      '-sb[ring bell when pausing between splits]' \
+      '-sv[be verbose about creating splits]' \
+      '(-O --out)'{-O,--out=}'[output to new archive]:archive' \
+      '(-FI --fifo)'{-FI,--fifo}'[support reading from a pipe]' \
+      '(-db --display-bytes)'{-db,--display-bytes}'[display running count of bytes processed and bytes to go]' \
+      '(-dc --display-counts)'{-dc,--display-counts}'[display running count of entries done and entries to go]' \
+      '(-dd --display-dots)'{-dd,--display-dots}'[display dots while each entry is zipped]' \
+      '(-dg --display-globaldots)'{-dg,--display-globaldots}'[display dots for the archive instead of each file]' \
+      '(-ds --dot-size)'{-ds,--dot-size=}'[specify size at which a dot is output while processing files]:size [10MB]' \
+      '(-du --display-usize)'{-du,--display-usize}'[display original uncompressed size for each entry as added]' \
+      '(-dv --display-volume)'{-dv,--display-volume}'[display volume (disk) number in format in_disk>out_disk]' \
+      '(-lf --logfile-path)'{-lf,--logfile-path=}'[specify log file]:file:_files' \
+      '(-la --log-append)'{-la,--log-append}'[append to existing log file]' \
+      '(-li --log-info)'{-li,--log-info}'[include info messages in log]' \
+      '(-T --test)'{-T,--test}'[test zipfile integrity]' \
+      '(-TT --unzip-command)'{-TT,--unzip-command=}'[specify command for testing archive]:command [unzip -tqq]:_cmdstring' \
+      '(-F --fix)'{-F,--fix}'[fix zipfile]' \
+      '(-F --fix -FF --fixfix)'{-FF,--fixfix}'[try harder to fix zipfile]' \
+      '(-DF --dif)'{-DF,--dif}'[only include files that have changed or are new as compared to the input archive]' \
+      '-sf[show files to operate on and exit]' \
+      '-su[as -sf but show escaped UTF-8 Unicode names also]' \
+      '-su[as -sf but show escaped UTF-8 Unicode names instead]' \
+      '-UN=[specify Unicode path mismatch handling]:mismatch handling:(Quit Warn Ignore No Escape UTF8)' \
+      '(-A --adjust-sfx)'{-A,--adjust-sfx}'[adjust self-extracting exe]' \
+      '(-J --junk-sfx)'{-J,--junk-sfx}'[junk zip file prefix (unzipsfx)]' \
+      '(-b --temp-path)'{-b,--temp-path}'[specify location for temporary archive]:path for temporary archive:_directories' \
+      '-nw[no wildcards]' \
+      '(-X --no-extra)'{-X,--no-extra}'[eXclude eXtra file attributes]' \
+      '(-y --symlinks)'{-y,--symlinks}'[store symbolic links as the link instead of the referenced file]' \
+      '(-)'{-h,--help}'[display help information]' \
+      '(-)'{-h2,--more-help}'[display extended help information]' \
+      '(-g --grow)'{-g,--grow}'[allow growing existing zipfile]' \
+      '(-L --license)'{-L,--license}'[display license]' \
+      '(-D --no-dir-entries)'{-D,--no-dir-entries}"[don't add directory entries]" \
+      '-n[specify suffixes of files not to be compressed]:suffixes:->suffixes' \
       "(-f -d -R -q -c -b -@ -F -FF -A -T -y -e -h -u -m -g -j -l -ll -L -v -z -t -tt -o -D -J -X -n -0 -1 -2 -3 -4 -5 -6 -7 -8 -9):zip file:_files -g '(#i)*.(zip|xpi|[ejw]ar)(-.)'" \
       '*:file:->files' && ret=0
   ;;
   unzip)
     _arguments -C -s \
-      '(-f -u -l -t -z -d)-p[extract files to pipe]' \
+      '(-Z)-M[page output]' \
+      - unzip \
+      '(-f -u -l -t -z -d -p)-c[extract files to stdout including file names]' \
       '(-p -u -l -t -z)-f[freshen existing files; create none]' \
+      '(-f -u -l -t -z -c -d)-p[extract files to stdout]' \
       '(-p -f -l -t -z)-u[update files; create if necessary]' \
       '(-p -f -u -t -z -d)-l[list files]' \
       '(-p -f -u -l -z -d)-t[test compressed archive data]' \
+      '-T[timestamp archive to latest]' \
       '(-p -f -u -l -t -d)-z[display archive comment]' \
       '(-p -l -t -z)-d+[specify directory to extract files to]:directory:_files -/' \
       '(-p -l -t -z -o)-n[never overwrite existing files]' \
@@ -70,13 +102,28 @@ case $service in
       '-q[quiet]' '-qq[quieter]' \
       '(-l -t -z)-a[auto-convert any text files]' \
       '(-l -t -z)-aa[treat all files as text]' \
+      '(-l -t -z)-b[treat all files as binary]' \
+      '(-l -t -z)-B[save backup copy of each overwritten file]' \
+      '(-DD)-D[skip restoration of timestamps for extracted directories]' \
+      '(-D)-DD[skip restoration of timestamps for all entries]' \
       '-v[verbose/display version info]' \
-      '(-p -z)-L[lowercase (some) filenames]' \
-      '-M[page output]' \
-      '-x[exclude the following names]' \
-      '-Z[zipinfo mode]:zipinfomode:->zipinfo' \
+      '(-c -p -z -LL)-L[lowercase filenames from case-insensitive file systems]' \
+      '(-c -p -z -L)-LL[lowercase all filenames]' \
+      '-K[keep setuid/setgid/sticky permissions]' \
+      '-P[specify password for decryption]:password' \
+      '(-UU)-U[use escapes for all non-ASCII Unicode]' \
+      '(-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]' \
+      '-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)(-.)'" \
-      '*:file:->files' && ret=0
+      '*:file:->files' \
+      - help \
+      '-hh[display detailed help information]' \
+      - zipinfo \
+      '-Z[zipinfo mode]:zipinfomode:->zipinfo' && ret=0
   ;;
 esac
 
diff --git a/Completion/Unix/Type/_diff_options b/Completion/Unix/Type/_diff_options
index 6af392a..55ddecd 100644
--- a/Completion/Unix/Type/_diff_options
+++ b/Completion/Unix/Type/_diff_options
@@ -6,6 +6,25 @@ local -a args
 cmd="$1"
 shift
 
+_diff_palette() {
+  local context state line ret=1
+  local -a suf
+  _values -s : attribute \
+    "ad[added text]:attribute [32]:->attrs" \
+    "de[deleted text]:attribute [31]:->attrs" \
+    "hd[header]:attribute [1]:->attrs" \
+    "ln[line numbers]:attribute [36]:->attrs" \
+    "rs[rest - other text]:attribute [0]:->attrs" && ret=0
+  if [[ -n $state ]]; then
+    compset -P '*;'
+    compset -S '[;=]*' || suf=( -S: -r ": ;\\\t\n\=" )
+    _alternative -C context -O suf \
+      'attributes:attributes:((0:reset 1:bold 3:italics 4:underline 5:blink))' \
+      'colors:color:((30:default 31:red 32:green 33:yellow 34:blue 35:magenta 36:cyan 37:white))' && ret=0
+  fi
+  return ret
+}
+
 if _pick_variant -c $cmd gnu=GNU unix -v; then
   # output formats
   of="-y --side-by-side -n --rcs -e -f --ed -q --brief -c -C --context -u -U \
@@ -46,6 +65,7 @@ if _pick_variant -c $cmd gnu=GNU unix -v; then
     '(--no-ignore-file-name-case)--ignore-file-name-case[ignore case when comparing file names]' \
     '(--ignore-file-name-case)--no-ignore-file-name-case[consider case when comparing file names]' \
     '(-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]' \
     '(-b --ignore-space-change)'{-b,--ignore-space-change}'[ignore changes in the amount of white space]' \
     '(--ignore-all-space -w)'{--ignore-all-space,-w}'[ignore all white space]' \
     '(-B --ignore-blank-lines)'{-B,--ignore-blank-lines}'[ignore lines that are all blank]' \
@@ -56,7 +76,7 @@ if _pick_variant -c $cmd gnu=GNU unix -v; then
     "($of $oss)-c[output a context diff]" \
     "($of $oss)"{-U+,--unified=-}'[output a unified diff]:number of lines of unified context' \
     "($of $oss)-u[output a unified diff]" \
-    "($ofwuc $oss)*"{-L+,--label=}'[set label to use instead of file name]:label' \
+    "($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)--brief[output only whether files differ]" \
@@ -84,8 +104,9 @@ if _pick_variant -c $cmd gnu=GNU unix -v; then
     '(-l --paginate)'{-l,--paginate}'[output through pr]' \
     '(-t --expand-tabs)'{-t,--expand-tabs}'[expand tabs to spaces]' \
     '(-T --initial-tab)'{-T,--initial-tab}'[prepend a tab]' \
-    '--tabsize=[specify width of tab]:width' \
+    '--tabsize=[specify width of tab]:width [8]' \
     '(-r --recursive)'{-r,--recursive}'[recursively compare subdirectories]' \
+    "--no-dereference[don't follow symbolic links]" \
     '(-N --new-file)'{-N,--new-file}'[treat absent files as empty]' \
     '(-P --unidirectional-new-file)'{-P,--unidirectional-new-file}'[treat absent first files as empty]' \
     '(-s --report-identical-files)'{-s,--report-identical-files}'[report when two files are the same]' \
@@ -97,6 +118,8 @@ if _pick_variant -c $cmd gnu=GNU unix -v; then
     '--horizon-lines=[set number of lines to keep in prefix and suffix]:number of horizon lines' \
     '(-d --minimal)'{-d,--minimal}'[try to find a smaller set of changes]' \
     '(-H --speed-large-files)'{-H,--speed-large-files}'[assume large files and many small changes]' \
+    '--color=-[use colors in output]::when [auto]:(never always auto)' \
+    '--palette=[specify colors to use]:color:_diff_palette' \
     '(-v --version)'{-v,--version}'[display version info]' \
     '--help[display help info]' \
     "$@"