Subject: PATCH: a few completion function updates
From: Oliver Kiddle <[email-masked]>
To: Zsh workers <[email-masked]>
Date: Fri, 08 Jul 2016 22:59:22 +0200
List-Id: Zsh Workers List <zsh-workers.zsh.org>

This updates options to a few completions. There's also new functions
for some common Unix commands - dmesg, touch and script. Changes are:
  chflags - a few more FreeBSD flags
  env - FreeBSD options and allow for more than one variable
  ln - new GNU --relative option
  ls - new GNU ls options
  service - update BSD options
  xsltproc/xmllint - update options
  _x_utils - add xlsclients
  vared - -i and -f options (by the way, -i vi-cmd-mode is useful).

Oliver

diff --git a/Completion/BSD/Command/_chflags b/Completion/BSD/Command/_chflags
index c9f2624..bfbaa01 100644
--- a/Completion/BSD/Command/_chflags
+++ b/Completion/BSD/Command/_chflags
@@ -1,6 +1,6 @@
 #compdef chflags
 
-local flags own='-g *(-u$EUID)'
+local flags args own='-g *(-u$EUID)'
 
 flags=(
   '(noopaque)opaque[set the opaque flag]'
@@ -14,7 +14,7 @@ flags=(
 )
 
 if (( ! EUID )); then
-  flags=( $flags[@]
+  flags+=(
     '(noarch)arch[set the archived flag]'
     '(arch)noarch[unset the archived flag]'
     '(nosappnd)sappnd[set the system append-only flag]'
@@ -26,19 +26,39 @@ if (( ! EUID )); then
 fi
 
 if [[ $OSTYPE = (freebsd|dragonfly|darwin)* ]]; then
-  flags=( $flags[@]
+  flags+=(
     '(nouunlnk)uunlnk[set the user undeletable flag]'
     '(uunlnk)nouunlnk[unset the user undeletable flag]'
     '(nohidden)hidden[set the hidden flag]'
     '(hidden)nohidden[unset the hidden flag]'
   )
-  (( EUID )) || flags=( $flags[@]
+  [[ $OSTYPE = freebsd* ]] && flags+=(
+    '(uoffline)offline[set the offline attribute]'
+    '(offline)uoffline[unset the offline attribute]'
+    '(urdonly)rdonly[set readonly flag]'
+    '(rdonly)urdonly[unset readonly flag]'
+    '(usparse)sparse[set the sparse attribute]'
+    '(sparse)usparse[unset the sparse attribute]'
+    '(usystem)system[set system flag]'
+    '(system)usystem[unset system flag]'
+    '(ureparse)reparse[set the Windows reparse point attribute]'
+    '(reparse)ureparse[unset the Windows reparse point attribute]'
+    '(uunlnk)unlnk[set undeletable flag]'
+    '(unlnk)uunlnk[unset undeletable flag]'
+  )
+
+  (( EUID )) || flags+=(
     '(nosunlnk)sunlnk[set the system undeletable flag]'
     '(sunlnk)nosunlnk[unset the system undeletable flag]'
   )
+  args=(
+    "-f[don't display diagnostic messages]"
+    '-h[act on symlinks]'
+    '-v[verbose output]'
+  )
 fi
 
-_arguments -s -A "-*" \
+_arguments -s -A "-*" $args \
   '(-L -P)-H[follow symlinks on the command line (specify with -R)]' \
   '(-H -P)-L[follow all symlinks (specify with -R)]' \
   '(-L -H)-P[do not follow symlinks (specify with -R)]' \
diff --git a/Completion/Unix/Command/_dmesg b/Completion/Unix/Command/_dmesg
new file mode 100644
index 0000000..3dd0592
--- /dev/null
+++ b/Completion/Unix/Command/_dmesg
@@ -0,0 +1,32 @@
+#compdef dmesg
+
+local args
+
+case $OSTYPE in
+  linux*) args=( -S --  ) ;;
+  darwin*|dragonfly*|*bsd*)
+    args=(
+      '-M[extract values from core]:core file:_files'
+      '-N[extract name list from kernel image]:system:_files'
+    )
+  ;|
+  dragonfly*|freebsd*)
+    args=(
+      '-a[show all data, including syslog and console]'
+      '-c[clear the buffer after printing]'
+    )
+  ;|
+  openbsd*)
+    args+=(
+      '-s[show console message buffer instead]'
+    )
+  ;;
+  dragonfly*)
+    args+=(
+      '\*-f[follow buffer, displaying new data as it arrives]'
+      '-n[use specified kernel core]:number'
+    )
+  ;;
+esac
+
+_arguments -s $args
diff --git a/Completion/Unix/Command/_env b/Completion/Unix/Command/_env
index 96261bb..9b2a1e0 100644
--- a/Completion/Unix/Command/_env
+++ b/Completion/Unix/Command/_env
@@ -1,13 +1,46 @@
 #compdef env
 
-if _pick_variant gnu=Free\ Soft unix --version; then
-  _arguments \
-    '(--ignore-environment -i)'{-i,--ignore-environment}'[start with empty environment]' \
-    '*'{-u,--unset=}'[remove variable from the environment]:env var to remove:compadd ${(k)parameters[(R)*export*]}' \
-    '--help[help]' \
-    '--version[version]' \
-    '(-):command: _command_names -e' \
-    '*::arguments: _normal'
-else
-  _precommand
+local context state line variant args ret=1
+
+_pick_variant -r variant gnu=Free\ Soft $OSTYPE --version
+case $variant in
+  gnu)
+    args=(
+      '(-)'{-i,--ignore-environment}'[start with empty environment]'
+      '(--ignore-environment -i --help --version)*'{-u,--unset=}'[remove variable from the environment]:env var to remove:_parameters -g "*export*"'
+      '(- *)--help[display help information]'
+      '(- *)--version[display version information]'
+    )
+  ;;
+  freebsd*)
+    args=(
+      '(-i)*-u[remove variable from the environment]:env var to remove:_parameters -g "*export*"'
+      '-P[specify alternate executable search PATH]:path:_dir_list'
+      '-S[perform word splitting]'
+      '*-v[verbose output]'
+    )
+  ;&
+  *)
+    if (( $words[(i)-] < CURRENT )); then
+      words[(i)-]=()
+      (( CURRENT-- ))
+    else
+      args+=(
+	'(-i)'{-,-i}'[start with empty environment]'
+      )
+    fi
+  ;;
+esac
+
+_arguments $args \
+  '*::arguments:->normal' && ret=0
+
+if [[ -n $state ]]; then
+  while [[ $words[1] = *=* ]]; do
+    shift words
+    (( CURRENT-- ))
+  done
+  _normal && ret=0
 fi
+
+return ret
diff --git a/Completion/Unix/Command/_ln b/Completion/Unix/Command/_ln
index c903fee..efb982a 100644
--- a/Completion/Unix/Command/_ln
+++ b/Completion/Unix/Command/_ln
@@ -38,6 +38,7 @@ if [[ $variant == gnu ]]; then
     '(-L --logical)'{-L,--logical}'[create hard links to symbolic link references]'
     '(-n --no-dereference)'{-n,--no-dereference}'[treat destination symbolic link to a directory as if it were a normal file]'
     '(-P --physical)'{-P,--physical}'[create hard links directly to symbolic links]'
+    '(-r --relative)'{-r,--relative}'[create symbolic links relative to link location]'
     '(-s --symbolic)'{-s,--symbolic}'[create symbolic links instead of hard links]'
     '(-S --suffix)'{-S,--suffix=}'[override default backup suffix]:suffix'
     '(-t --target-directory)'{-t,--target-directory=}'[specify directory in which to create the links]: :_directories'
diff --git a/Completion/Unix/Command/_ls b/Completion/Unix/Command/_ls
index f2e1494..74f317a 100644
--- a/Completion/Unix/Command/_ls
+++ b/Completion/Unix/Command/_ls
@@ -1,6 +1,6 @@
 #compdef ls gls
 
-local arguments is_gnu
+local arguments is_gnu datef
 
 if ! _pick_variant gnu=gnu unix --help; then
   arguments=(
@@ -70,6 +70,7 @@ if ! _pick_variant gnu=gnu unix --help; then
     )
   fi
 else
+  [[ $PREFIX = *+* ]] && datef='formats:format: _date_formats'
   arguments=(
     '(--all -a -A --almost-all)'{--all,-a}'[list entries starting with .]'
     '(--almost-all -A -a --all)'{--almost-all,-A}'[list all except . and ..]'
@@ -89,6 +90,7 @@ else
 
     '(--format -l -g -o -1 -C -m -x)-l[long listing]'
     '(--format -l -1 -C -m -x)-g[long listing but without owner information]'
+    --group-directories-first
     '(--format -l --no-group -G -1 -C -m -x)-o[no group, long]'
     '(--format -l -g -o -C -m -x)-1[single column output]'
     '(--format -l -g -o -1 -m -x)-C[list entries in columns sorted vertically]'
@@ -101,7 +103,7 @@ else
     '(--time -u)-c[status change time]'
     '(--time -c)-u[access time]'
     '(-c -u)--time=[specify time to show]:time:(ctime status use atime access)'
-    '--time-style=[show times using specified style]:time style:(full-iso long-iso iso locale)'
+    '--time-style=[show times using specified style]:style: _alternative "time-styles\:time style\:(full-iso long-iso iso locale)" $datef'
 
     '(-a --all -U -l --format -s --size -t --sort --full-time)-f[unsorted, all, short list]'
     '(--reverse)'{--reverse,-r}'[reverse sort order]'
@@ -114,10 +116,10 @@ else
     '(-S -t -U -v -X)--sort=:sort:(size time none version extension)'
 
     '--color=-[control use of color]:color:(never always auto)'
-
+    "--hide=[don't list entries matching pattern]:pattern"
     '(--classify -F --indicator-style -p --file-type)'{--classify,-F}'[append file type indicators]'
     '(--file-type -p --indicator-style -F --classify)'{--file-type,-p}'[append file type indicators except *]'
-    '(-F --classify -p --file-type)--indicator-style=:indicator style:(none file-type classify)'
+    '(-F --classify -p --file-type)--indicator-style=:indicator style:(none file-type classify slash)'
 
     '(-f)--full-time[list both full date and full time]'
 
@@ -139,6 +141,11 @@ else
     '(- :)--version[display version information]'
     '*:files:_files'
   )
+  if [[ $OSTYPE = linux* ]]; then
+    arguments+=(
+      '(-Z --context)'{-Z,--context}'[print any security context of each file]'
+    )
+  fi
 fi
 
 _arguments -s $arguments
diff --git a/Completion/Unix/Command/_script b/Completion/Unix/Command/_script
new file mode 100644
index 0000000..7f682ea
--- /dev/null
+++ b/Completion/Unix/Command/_script
@@ -0,0 +1,71 @@
+#compdef script scriptreplay
+
+local args hlp="-h --help -V --version"
+
+if [[ $service = scriptreplay ]]; then
+  _arguments -S -s \
+    "(1 -t --timing $hlp)"{-t+,--timing=}'[specify file containing timing output]:timing file:_files' \
+    "(2 -s --typescript $hlp)"{-s+,--typescript=}'[specify file containing terminal output]:typescript file:_files' \
+    "(3 -d --divisor $hlp)"{-d+,--divisor=}'[speed up replay]:factor' \
+    "(-m --maxdelay $hlp)"{-m+,--maxdelay=}'[set maximum delay between updates]:delay (seconds)' \
+    '(- *)'{-h,--help}'[display help information]' \
+    '(- *)'{-V,--version}'[display version information]' \
+    "(-t --timing $hlp):timing file:_files" \
+    "(-s --typescript $hlp):typescript file:_files" \
+    "(-d --divisor $hlp): :_guard '[0-9.]#' 'timing divisor'"
+  return
+fi
+
+case $OSTYPE in
+  linux*)
+    args=( -S
+      "(-a --append $hlp)"{-a,--append}'[append output]'
+      "(-c --command $hlp)"{-c,--command=}'[run specified command instead of a shell]:command:_cmdstring'
+      "(-e --return $hlp)"{-e,--return}'[return exit status of the child process]'
+      "(-f --flush $hlp)"{-f,--flush}'[flush output after each write]'
+      "($hlp)--force[use output file even when it is a link]"
+      "(-q --quiet $hlp)"{-q,--quiet}'[be quiet]'
+      "(-t --timing $hlp)"{-t-,--timing=-}'[output timing data]::timing file:_files'
+      '(- 1)'{-h,--help}'[display help information]'
+      '(- 1)'{-V,--version}'[display version information]'
+    )
+  ;;
+  darwin*|dragonfly*|netbsd*|freebsd*)
+    args=(
+      '-q[be quiet: suppress display of starting and ending lines]'
+    )
+  ;|
+  netbsd*|freebsd*)
+    args+=(
+      '(-a -r -k)-d[suppress sleeps when playing back a session]'
+      '(-a -r -k -t)-p[play back a recorded session]'
+      '(-d -p)-r[record a session with input, output and timing data]'
+    )
+  ;|
+  netbsd*)
+    args+=(
+      '-f[flush output after each write]'
+      '-c[run specified command instead of a shell]:command:_cmdstring'
+    )
+  ;|
+  freebsd*)
+    args+=(
+      '-f[use filemon(4)]'
+    )
+  ;|
+  darwin*|dragonfly*|freebsd*)
+    args+=(
+      '-t+[specify interval of data flushing]:interval (seconds)'
+      '-k[log keys sent to the program as well as output]'
+      '*:::arguments: _normal'
+    )
+  ;|
+  *)
+    args+=(
+      '(-p -d)-a[append output]'
+    )
+  ;;
+esac
+
+_arguments -s $args \
+  "($hlp):typescript file:_files"
diff --git a/Completion/Unix/Command/_service b/Completion/Unix/Command/_service
index e99ad55..50e8607 100644
--- a/Completion/Unix/Command/_service
+++ b/Completion/Unix/Command/_service
@@ -5,27 +5,34 @@
 # _sub_command happy
 
 # we are interested in init service only
-local ctx="${curcontext}argument-1:"
+local args ctx="${curcontext}argument-1:"
 zstyle -T  ":completion:${ctx}" tag-order && \
   zstyle ":completion:${ctx}" tag-order init
 
-
-if [[ $OSTYPE = freebsd* ]]; then
-  _arguments -s \
-    '(-)-e[show services that are enabled]' \
-    '(-)-l[list all scripts in /etc/rc.d and the local startup directory]' \
-    '(-)-r[show the results of boot time rcorder]' \
-    '(-)-v[verbose]' \
-    ':service name:_services' \
-    '*::service argument:_init_d'
-else
-  _arguments -s \
-    '(-d --debug)'{-d,--debug}'[turn debugging on]' \
-    '(- :)'{-h,--help}'[print usage]' \
-    '(- :)'{-v,--version}'[print version]' \
-    '(-)'{-f,--full-restart}'[restart service]' \
-    '(- :)'{-R,--full-restart-all}'[restart all services]' \
-    '(- :)'{-s,--status-all}'[print status of all services]' \
-    ':service name:_services' \
-    '*::service argument: _init_d'
-fi
+case $OSTYPE in
+  freebsd*|dragonfly*)
+    args=(
+      '(-)-r[show the results of boot time rcorder]'
+      '(-)-R[restart all enabled local services]'
+    )
+  ;&
+  netbsd*)
+    _arguments -s $args \
+      '(-)-e[show services that are enabled]' \
+      '(-)-l[list all scripts in /etc/rc.d and the local startup directory]' \
+      '(-e -R)-v[verbose]' \
+      ':service name:_services' \
+      '*::service argument:_init_d'
+  ;;
+  *)
+    _arguments -s \
+      '(-d --debug)'{-d,--debug}'[turn debugging on]' \
+      '(- :)'{-h,--help}'[print help information]' \
+      '(- :)'{-v,--version}'[print version information]' \
+      '(-)'{-f,--full-restart}'[restart service]' \
+      '(- :)'{-R,--full-restart-all}'[restart all services]' \
+      '(- :)'{-s,--status-all}'[print status of all services]' \
+      ':service name:_services' \
+      '*::service argument: _init_d'
+  ;;
+esac
diff --git a/Completion/Unix/Command/_touch b/Completion/Unix/Command/_touch
new file mode 100644
index 0000000..9b91447
--- /dev/null
+++ b/Completion/Unix/Command/_touch
@@ -0,0 +1,45 @@
+#compdef touch gtouch
+
+local args variant
+_pick_variant -r variant gnu=GNU $OSTYPE --version
+
+args=(
+  '-a[change access time (atime)]'
+  '-m[change modification time (mtime)]'
+  '(-r -d --date --reference 1)-t+[use specified time]:time ([[CC]YY]MMDDhhmm[.SS])'
+)
+case $variant in
+  gnu)
+    args+=(
+      '(-c --no-create)'{-c,--no-create}"[don't create file if it doesn't exist]"
+      '(-h --no-dereference)'{-h,--no-dereference}'[act on symbolic links themselves]'
+      '(-t -d --date -r --reference)'{-r+,--reference=}'[use corresponding times from specified reference file]:file:_files'
+      '(-t -d --date -r --reference)'{-d+,--date=}'[use specified date/time]:date/time'
+      '*--time=[change specified time]:time:(atime access use mtime modify)'
+      '(-)--help[display help information]'
+      '(-)--version[display version information]'
+    )
+  ;;
+  darwin*|dragonfly*|freebsd*)
+    args+=(
+      '(-c 1)-A+[adjust time stamps by relative value]:time delta ([[-][hh]mm]SS)'
+    )
+  ;|
+  darwin*|dragonfly*|freebsd*|netbsd*)
+    args+=( '-h[act on symbolic links themselves]' )
+  ;|
+  dragonfly*|freebsd*|openbsd*|solaris*)
+    args+=( '(-r -t 1)-d+[use specified date/time]:date/time' )
+  ;|
+  darwin*|dragonfly*|freebsd*|netbsd*|solaris*)
+    args+=( '1:: :_guard "[0-9]#" "timespec (MMDDhhmm[YY])"' )
+  ;|
+  *) # not GNU
+    args=( -A "-*" $args
+      "(-A)-c[don't create file if it doesn't exist]"
+      '(-t -d 1)-r+[use corresponding times from specified reference file]:file:_files'
+    )
+  ;;
+esac
+
+_arguments -s -S $args '*:file:_files'
diff --git a/Completion/Unix/Command/_xmlsoft b/Completion/Unix/Command/_xmlsoft
index 67ba6c0..7b4b0b0 100644
--- a/Completion/Unix/Command/_xmlsoft
+++ b/Completion/Unix/Command/_xmlsoft
@@ -1,7 +1,7 @@
 #compdef xsltproc xmllint -value-,XML_CATALOG_FILES,-default-
 
-# xmllint: using libxml version 20707
-# xsltproc: using libxml 20707, libxslt 10126 and libexslt 815
+# xmllint: using libxml version 20904
+# xsltproc: using libxml 20904, libxslt 10129 and libexslt 817
 
 local -a encoding
 
@@ -38,7 +38,9 @@ case $service in
       '--nodtdattr[do not default attributes from the DTD]' \
       '--noout[do not dump the result]' \
       '--maxdepth[increase the maximum depth]:depth' \
+      '--maxvars[increase the maximum variables]:variables' \
       '--maxparserdepth[increase the maximum parser depth]:depth' \
+      '--seed-rand[initialise random number generator]:seed' \
       '--html[input document is an HTML file]' \
       '--encoding[the input document character encoding]:encoding:(${encoding[@]})' \
       '*--param[pass a parameter,value pair]:name::value (xpath expression)' \
@@ -87,6 +89,7 @@ case $service in
       '--xmlout[use the XML serializer when using --html]' \
       '--nodefdtd[do not default HTML doctype]' \
       '--push[use the push mode of the parser]' \
+      '--pushsmall[use the push mode of the parser using tiny increments]' \
       '--memory[parse from memory]' \
       '--maxmem[limit memory allocation]:bytes' \
       '--nowarning[do not emit warnings from parser/validator]' \
diff --git a/Completion/X/Command/_x_utils b/Completion/X/Command/_x_utils
index 05a899b..9364235 100644
--- a/Completion/X/Command/_x_utils
+++ b/Completion/X/Command/_x_utils
@@ -1,4 +1,4 @@
-#compdef xdpyinfo xwininfo xkill xfontsel xfd xev xhost xon xsetroot xwd xwud xrdb xprop xlsatoms
+#compdef xdpyinfo xwininfo xkill xfontsel xfd xev xhost xon xsetroot xwd xwud xrdb xprop xlsatoms xlsclients
 
 local curcontext="$curcontext" state line expl ret=1
 
@@ -37,6 +37,12 @@ xlsatoms)
     '*-range[atom values to list]:[num]-[num]' \
     '*-name[name of single atom to print]:atom:->atoms'
   ;;
+xlsclients)
+  _x_arguments -C \
+    '-a[list all clients on all screens]' \
+    '-l[long format adding window/icon names and class hints]' \
+    '-m[maximum characters of command to include]:characters'
+ ;;
 xkill)
   _x_arguments \
     -version \
diff --git a/Completion/Zsh/Command/_vared b/Completion/Zsh/Command/_vared
index bb31cc1..2bcc87b 100644
--- a/Completion/Zsh/Command/_vared
+++ b/Completion/Zsh/Command/_vared
@@ -6,6 +6,8 @@ _arguments -s -A "-*" \
   "-c[create parameter or change type]" \
   '-p+[specify left prompt]:prompt' \
   '-r+[specify right prompt]:right prompt' \
+  '-i+[specify initialisation widget]:widget:compadd -M "r\:|-=* r\:|=*" -k widgets' \
+  '-f+[specify finish widget]:widget:compadd -M "r\:|-=* r\:|=*" -k widgets' \
   '-h[allow access to history]' \
   '-e[exit on EOF (^D)]' \
   '1:parameter spec:_vars'