about summary refs log tree commit diff
path: root/Completion/User
diff options
context:
space:
mode:
Diffstat (limited to 'Completion/User')
-rw-r--r--Completion/User/.distfiles17
-rw-r--r--Completion/User/_dir_list5
-rw-r--r--Completion/User/_fetchmail11
-rw-r--r--Completion/User/_hosts2
-rw-r--r--Completion/User/_iconv54
-rw-r--r--Completion/User/_mutt47
-rw-r--r--Completion/User/_ncftp8
-rw-r--r--Completion/User/_tar153
-rw-r--r--Completion/User/_urls14
-rw-r--r--Completion/User/_webbrowser2
-rw-r--r--Completion/User/_wget19
-rw-r--r--Completion/User/_xargs8
-rw-r--r--Completion/User/_zip121
13 files changed, 406 insertions, 55 deletions
diff --git a/Completion/User/.distfiles b/Completion/User/.distfiles
index f9bf07035..4411fb28e 100644
--- a/Completion/User/.distfiles
+++ b/Completion/User/.distfiles
@@ -1,13 +1,14 @@
 DISTFILES_SRC='
     .distfiles
-    _a2ps _apachectl _archie _arp _bison _bzip2 _chown _compress
-    _configure _cvs _dd _dict _diff _diff_options _dir_list _dirs
-    _domains _dvi _enscript
-    _find _finger _fakeroot _flex _gcc _gdb  _getconf _gprof _grep _groups
-    _gs _gv _gzip _hosts _imagemagick _init_d _ispell
-    _java _joe _killall _lp _look _ls _lynx _lzop
+    _a2ps _apachectl _archie _arp _bison _bzip2
+    _chown _compress _configure _cvs
+    _dd _dict _diff _diff_options _dir_list _dirs _domains _dvi
+    _enscript _find _finger _fakeroot _fetchmail _flex
+    _gcc _gdb  _getconf _gprof _grep _groups _gs _gv _gzip
+    _hosts _imagemagick _iconv _init_d _ispell
+    _java _joe _killall _look _lp _ls _lynx _lzop
     _mailboxes _make _man _mere _mh _mount _mutt _my_accounts _mysql_utils
-    _nedit _netscape _newsgroups _nslookup _other_accounts
+    _ncftp _nedit _netscape _newsgroups _nslookup _other_accounts
     _pack _patch _pbm _pdf _perl _perl_basepods _perl_builtin_funcs
     _perl_modules _perldoc _ports _prcs _printers _prompt _ps _pspdf
     _psutils _rcs _rlogin
@@ -15,5 +16,5 @@ DISTFILES_SRC='
     _tar _tar_archive _telnet _tex _texi _tiff _tilde_files _tin
     _urls _use_lo _user_at_host _users _users_on
     _w3m _webbrowser _wget _whereis _whois _xargs _yodl _yp
-    _zcat _zdump
+    _zcat _zdump _zip
 '
diff --git a/Completion/User/_dir_list b/Completion/User/_dir_list
index 8e3615dac..122d7ad94 100644
--- a/Completion/User/_dir_list
+++ b/Completion/User/_dir_list
@@ -1,4 +1,7 @@
 #autoload
 
+local suf
+
 compset -P '*:'
-_files -S: -r ': \t\t\-' -/
+compset -S ':*' || suf=":"
+_files -S "$suf" -r ': \t\t\-' -/
diff --git a/Completion/User/_fetchmail b/Completion/User/_fetchmail
new file mode 100644
index 000000000..0f9095107
--- /dev/null
+++ b/Completion/User/_fetchmail
@@ -0,0 +1,11 @@
+#compdef fetchmail
+
+_arguments \
+  {--bsmtp,'(--logfile)-L','(-L)--logfile','(--fetchmailrc)-f','(-f)--fetchmailrc','(--idfile)-i','(-i)--idfile'}':file:_files' \
+  {--plugin,--plugout,'(--mda)-m','(-m)--mda'}':command:_command_names -e' \
+  {'(--username)-u','(-u)--username'}:user:_users \
+  '--auth:authentication types:(password kerberos kerberos_v5)' \
+  {'(--protocol)-p','(-p)--protocol'}:protocol:'(auto pop2 pop3 apop rpop kpop sdps imap imap-k4 imap-gss etrn)' \
+  {'(--port)-P','(-P)--port'}':port number' \
+  '*:mail server:_hosts' \
+  --
diff --git a/Completion/User/_hosts b/Completion/User/_hosts
index 30c3b2357..f41097f96 100644
--- a/Completion/User/_hosts
+++ b/Completion/User/_hosts
@@ -1,4 +1,4 @@
-#compdef ftp ncftp ping rwho rup xping traceroute host
+#compdef ftp ping rwho rup xping traceroute host lftp
 
 local expl hosts
 
diff --git a/Completion/User/_iconv b/Completion/User/_iconv
new file mode 100644
index 000000000..1e21b9655
--- /dev/null
+++ b/Completion/User/_iconv
@@ -0,0 +1,54 @@
+#compdef iconv
+
+local expl curcontext="$curcontext" state line codeset LOCPATH
+
+(( $+_is_gnu )) || typeset -gA _is_gnu
+if (( ! $+_is_gnu[$words[1]] )); then
+  if [[ $(_call version $words[1] --version </dev/null 2>/dev/null) = *GNU* ]]; 
+  then
+    _is_gnu[$words[1]]=yes
+  else
+    _is_gnu[$words[1]]=
+  fi
+fi
+
+if [[ -n "$_is_gnu[$words[1]]" ]]; then
+
+  _arguments -C \
+    {'(--from-code --list)-f','(-f --list)--from-code='}'[specify code set of input file]:code set:->codeset' \
+    {'(--to-code --list)-t','(-t --list)--to-code='}'[specify code set for output]:code set:->codeset' \
+    '--list[list all character code sets]' \
+    '--verbose[print progress information]' \
+    {'(--help)-\?','(-\?)--help'}'[display help information]' \
+    '--usage[display a short usage message]' \
+    {'(--version)-V','(-V)--version'}'[print program version]' \
+    '1:file:_files' && return 0
+    
+    if [[ $state = codeset ]]; then
+      _wanted codesets expl 'code set' \
+          compadd "$@" ${${(s:,:)$(iconv --list|sed -n '/^$/,$ p')}## #}
+    fi
+    
+else
+
+  _arguments -C \
+    '-f[specify code set of input file]:code set:->codeset' \
+    '-t[specify code set for output]:code set:->codeset' \
+    '1:file:_files' && return 0
+
+    if [[ $state = codeset ]]; then
+      if [[ -f /usr/lib/iconv/iconv_data ]]; then  # IRIX & Solaris
+	codeset=( ${${(f)"$(</usr/lib/iconv/iconv_data)"}%%[[:blank:]]*} )
+      elif [[ -d ${LOCPATH:=/usr/lib/nls/loc}/iconv ]]; then  # OSF
+	codeset=( $LOCPATH/iconv/*(N:t) )
+	codeset=( ${(j:_:s:_:)codeset} )
+      else
+	return 1
+      fi
+	
+      _wanted codesets expl 'code set' compadd "$@" -a codeset
+    fi
+
+fi    
+    
+    
diff --git a/Completion/User/_mutt b/Completion/User/_mutt
index 5e8e6cc42..7898a0527 100644
--- a/Completion/User/_mutt
+++ b/Completion/User/_mutt
@@ -1,38 +1,39 @@
 #compdef mutt
 
-local curcontext="$curcontext" state line ret=1
+local curcontext="$curcontext" state line suf
 typeset -A opt_args
 
-_arguments -C \
+_arguments -C -s \
     '::recipient:->userhost' \
-    '*-a:MIME attachment:_files' \
-    '*-b:BCC recipient:->userhost' \
-    '*-c:CC recipient:->userhost' \
-    '-e:post-init configuration:' \
-    '-f+:mailbox: _mailboxes' \
-    '-F+:init file:_files' \
-    '-h+:help:' \
-    '-H+:draft file:_files' \
-    '-i:include file:_files' \
-    '-m+:default mailbox type:(mbox MMDF MH Maildir)' \
-    '-n+:bypass system configuration:' \
-    '-p+:resume postponed message:' \
-    '-R+:open in read-only mode:' \
-    '-s+:subject:' \
-    '-v+:version:' \
-    '-x+:emulate mailx compose:' \
-    '-y+:start listing mailboxes:' \
-    '-z+:start only if new messages:' \
-    '-Z+:open first mailbox with new mail:' && ret=0
+    '*-a[attach file using MIME]:file attachment:_files' \
+    '*-b[specify a BCC recipient]:BCC recepient:->userhost' \
+    '*-c[specify a CC recipient]:CC recipient:->userhost' \
+    '-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+[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)' \
+    '-n[bypass system configuration]' \
+    '-p[resume postponed message]' \
+    '-R[open in read-only mode]' \
+    '-s+[specify a subject]:subject:' \
+    '-v[display mutt version]' \
+    '-x[emulate mailx compose]' \
+    '-y[start listing mailboxes]' \
+    '-z[start only if new messages]' \
+    '-Z[open first mailbox with new mail]' && return 0
 
 if [[ "$state" = userhost ]]; then
   if compset -P '*@'; then
     _description hosts expl 'remote host name'
     _hosts "$expl[@]" -q -S, && return 0
   else
+    compset -S '@*' || suf='@'
     _description users expl 'login name'
-    _users "$expl[@]" -q -S@ && return 0
+    _users "$expl[@]" -q -S "$suf" && return 0
   fi
 fi
 
-return ret
+return 1
diff --git a/Completion/User/_ncftp b/Completion/User/_ncftp
new file mode 100644
index 000000000..e760b3536
--- /dev/null
+++ b/Completion/User/_ncftp
@@ -0,0 +1,8 @@
+#compdef ncftp
+
+if [[ -f ~/.ncftp/bookmarks ]]; then
+  _wanted bookmarks expl bookmark \
+      compadd - $(awk -F, 'NR > 2 { print $1 }' ~/.ncftp/bookmarks) && return 0
+fi
+
+_hosts
diff --git a/Completion/User/_tar b/Completion/User/_tar
index 91767e44d..9a71d8cef 100644
--- a/Completion/User/_tar
+++ b/Completion/User/_tar
@@ -1,11 +1,148 @@
-#defcomp tar
+#compdef tar
 
-local nm=$NMATCHES tf="$2"
+# Tar completion.  Features:
+#  - Tries to collect tar commands from second position, single letter
+#    option, and long options.
+#  - `tar' can be called anything, will use the correct name
+#  - Uses the function `_tar_archive' to complete archive files.
+#  - Tries to find out if compressed archives should be used.
+#  - Completes files inside archive.  This is supposed to look pretty
+#    much as if the files are in an ordinary directory hierarchy.
+#    Handles extraction from compressed archives (GNU tar).
+#  - Anywhere -- appears, gets a list of long options to complete from
+#    tar itself (GNU tar)
+#  - Things like --directory=... are also completed correctly.
 
-if [[ ( -mword 1 *t*f* || -mword 1 *x*f* ) && -position 3 100000 ]]; then
-  complist -k "( $(tar tf $tf) )"
-elif [[ -mword 1 *c*f* && -position 3 100000 ]]; then
-  _files
-elif [[ -mcurrent -1 *f* && -position 2 ]]; then
-  _files -g '*.(tar|TAR)'
+local _tar_cmd tf tmp tmpb del
+
+# First we collect in `_tar_cmd' single letter options describing what
+# should be done with the archive and if it is compressed. This
+# collected from options arguments that start with only one hyphen,
+# from some of the possible long options, and from the second word if
+# that does not start with a hyphen.
+
+tmp=("${(@M)words:#-[^-]*}")
+_tar_cmd="${(j::)tmp#-}"
+
+(( $words[(I)--(un|)gzip] ))     && _tar_cmd="z$_tar_cmd"
+(( $words[(I)--(un|)compress] )) && _tar_cmd="Z$_tar_cmd"
+(( $words[(I)--list] ))          && _tar_cmd="t$_tar_cmd"
+(( $words[(I)--(extract|get)] )) && _tar_cmd="x$_tar_cmd"
+(( $words[(I)--create] ))        && _tar_cmd="c$_tar_cmd"
+
+# Other ways of finding out what we're doing:  first
+# look in the first argument if it's not an option
+if [[ "$words[2]" = *[txcdruA]*~-* ]]; then
+  _tar_cmd="$words[2]$_tar_cmd"
+elif [[ $_tar_cmd != *[txcdruA]* && CURRENT -gt 2 ]]; then
+  # look for more obscure long options: these aren't all handled.
+  (( $words[(I)--(diff|compare)] )) && _tar_cmd="d$_tar_cmd"
+  (( $words[(I)--append] ))         && _tar_cmd="r$_tar_cmd"
+  (( $words[(I)--update] ))         && _tar_cmd="u$_tar_cmd"
+  (( $words[(I)--(con|)catenate] )) && _tar_cmd="A$_tar_cmd"
+  (( $words[(I)--delete] ))         && del=1
+fi
+
+# Next, we try to find the archive name and store it in `tf'. The name 
+# is searched after a `--file=' long option, in the third word if the
+# second one didn't start with a hyphen but contained a `f', and after 
+# an option argument starting with only one hyphen and containing a `f'.
+# unless that option argument also contains a `C'.
+
+tmp="$words[(I)--file=*]"
+tmpb="$words[(I)-*Cf*~--*]"
+
+if (( tmp )); then
+  tf=${~words[tmp][8,-1]}
+  _tar_cmd="f$_tar_cmd"
+elif [[ "$words[2]" != -* && "$words[2]" = *f* ]]; then
+  tf=${~words[3]}
+  _tar_cmd="f$_tar_cmd"
+elif (( tmpb )); then
+  tf=${~words[tmpb+2]}
+  wdir=${~words[tmpb+1]}
+  _tar_cmd="Cf$_tar_cmd"
+else
+  tmp="${words[(I)-*f*~--*]}"
+  if (( tmp )); then
+    tf=${~words[tmp+1]}
+    _tar_cmd="f$_tar_cmd"
+  fi
+fi
+
+# See if we should use a path prefix.  We have to use eval as the dir can
+# be any unevaluated thing which appears on the command line, including a
+# parameter.
+
+# This isn't used right now.
+
+tmp=${words[(r)--dir[a-z]#=*]}
+
+if [[ -n $tmp ]]; then
+  eval "wdir=(${tmp#*=})"
+fi
+
+# Now we complete...
+
+if [[ "$PREFIX" = --* ]]; then
+
+  # ...long options after `--'.
+
+  _arguments -- '--owner*:user:_users' \
+                 '*=(PROG|COMMAND)*:program:_command_names -e' \
+		 '*=ARCHIVE*:archive: _tar_archive' \
+		 '*=NAME*:file:_files' \
+		 '*=DIR*:directory:_files -/' \
+		 '*=CONTROL*::version control:(t numbered nil existing never simple)'
+
+elif [[ ( CURRENT -gt 2 && "$words[CURRENT-1]" = -*f* &&
+          "$words[CURRENT-1]" != --* && "$words[CURRENT-1]" != -*Cf* ) ||
+        ( CURRENT -eq 3 && "$words[2]" = *f* && "$words[2]" != -* &&
+          "$words[2]" != *Cf* ) ||
+        ( CURRENT -gt 2 && "$words[CURRENT-2]" = -*Cf* &&
+          "$words[CURRENT-2]" != --* && "$words[CURRENT-1]" != --* ) ||
+        ( CURRENT -eq 4 && "$words[2]" = *Cf* && "$words[2]" != -* ) ]]; then
+
+  # ...archive files if we think they are wanted here.
+
+  _tar_archive
+
+elif [[ ( CURRENT -gt 2 && "$words[CURRENT-1]" = -*Cf*) ||
+        ( CURRENT -eq 3 && "$words[2]" = *Cf* ) ]]; then
+
+  # a directory for -C
+
+  _files -/
+
+elif [[ ( "$_tar_cmd" = *[xt]* || -n $del ) && -n "$tf" ]]; then
+
+  # ...and files from the archive if we found an archive name and tar
+  # commands. We run `tar t...' on the file, keeping the list of
+  # filenames cached, plus the name of the tarfile so we know if it
+  # changes.  We skip this test if the alleged archive is not a file.
+
+  local largs=-tf expl
+
+  if [[ $_tar_cmd = *z* ]]; then
+    largs=-tzf
+  elif [[ $_tar_cmd = *y* ]]; then
+    largs=-tyf
+  elif [[ $_tar_cmd = *Z* ]]; then
+    largs=-tZf
+  elif [[ $_tar_cmd = *I* ]]; then
+    largs=-tIf
+  else
+    # Some random compression program
+    tmp="${words[(r)--use-comp*]}"
+    [[ -n $tmp ]] && largs=($tmp -tf)
+  fi
+
+  if [[ $tf != $_tar_cache_name && -f $tf ]]; then
+    _tar_cache_list=("${(@f)$($words[1] $largs $tf)}")
+    _tar_cache_name=$tf
+  fi
+
+  _wanted files expl 'file from archive' _multi_parts / _tar_cache_list
+else
+    _files
 fi
diff --git a/Completion/User/_urls b/Completion/User/_urls
index 06df60c28..78a72f890 100644
--- a/Completion/User/_urls
+++ b/Completion/User/_urls
@@ -1,4 +1,4 @@
-#compdef curl
+#compdef curl galeon
 
 # Usage: _urls [-f]
 # Options:
@@ -38,7 +38,7 @@
 #    E.g.:
 #      zstyle ':completion:*:urls' local www /usr/local/apache/htdocs public_html
 
-local ipre scheme host user uhosts ret=1 expl match glob
+local ipre scheme host user uhosts ret=1 expl match glob suf
 local urls_path localhttp
 zstyle -s ":completion:${curcontext}:urls" path urls_path ||
     urls_path="${ZDOTDIR:-$HOME}/.zsh/urls"
@@ -118,16 +118,16 @@ case "$scheme" in
 esac
 
 # Complete hosts
-if ! compset -P '(#b)([^/]#)/'; then
+if ! compset -P '(#b)([^:/]#)([:/])'; then
   uhosts=($urls_path/$scheme/$PREFIX*$SUFFIX(/:t))
 
   _tags hosts
   while _tags; do
     while _next_label hosts expl host "$@"; do
-      compset -S '/*' || suf="/"
-      (( $#uhosts )) || _hosts -S "$suf" "$expl[@]" && ret=0
+      compset -S '[:/]*' || suf="/"
+      (( $#uhosts )) || _hosts -S "$suf" -r '/:' "$expl[@]" && ret=0
       [[ "$scheme" = http ]] && uhosts=($uhosts $localhttp_servername)
-      compadd -S "$suf" "$expl[@]" -a uhosts && ret=0
+      compadd -S "$suf" -r '/:' "$expl[@]" -a uhosts && ret=0
     done
     (( ret )) || return 0
   done
@@ -135,6 +135,8 @@ if ! compset -P '(#b)([^/]#)/'; then
 fi
 host="$match[1]"
 
+[[ $match[2] = ':' ]] && ! compset -P '<->/' && _message 'port number' && return 0
+
 # Complete part after hostname
 
 _tags -C local files || return 1
diff --git a/Completion/User/_webbrowser b/Completion/User/_webbrowser
index da8961ea8..6a82a4e9d 100644
--- a/Completion/User/_webbrowser
+++ b/Completion/User/_webbrowser
@@ -1,3 +1,3 @@
-#compdef amaya arena chimera express grail gzilla hotjava mmm mozilla www xmosaic Mosaic
+#compdef amaya arena chimera express grail gzilla hotjava mmm mozilla opera www xmosaic Mosaic
 
 _urls -f
diff --git a/Completion/User/_wget b/Completion/User/_wget
index fbacc5b27..515f73eda 100644
--- a/Completion/User/_wget
+++ b/Completion/User/_wget
@@ -18,6 +18,8 @@ _arguments -C -s \
   '*-n+[no]:flags:->noflags' \
   {'(--input-file)-i+[input file]','(-i)--input-file='}':file containing URLs:_files' \
   '(--force-html)-F[force html]' '(-F)--force-html' \
+  {'(--base)-B+[prepend URL to relative links]','(-B)--base='}':base URL:_urls' \
+  '--bind-address=:address to bind to (hostname or IP):_hosts' \
   {'(--tries)-t+[tries]','(-t)--tries='}':number of retries:(0)' \
   {'(--output-document)-O+[output document]','(-O)--output-document='}':output file:_files' \
   '(--continue)-c[continue]' '(-c)--continue' \
@@ -27,6 +29,7 @@ _arguments -C -s \
   '--spider' \
   {'(--timeout)-T+[timeout]','(-T)--timeout='}':read timeout(seconds):' \
   {'(--wait)-w+[wait]','(-w)--wait='}':wait between retrievals(seconds):' \
+  '--waitretry=:seconds to wait between retries of a retieval:' \
   {'(--proxy --use-proxy)-Y+[proxy]','(-Y --use-proxy)--proxy=','(-Y --proxy)--use-proxy='}':proxy:(on off)' \
   {'(--quota)-Q+[quota]','(-Q)--quota='}':number:' \
   '(--force-directories)-x[force directories]' '(-x)--force-directories' \
@@ -34,10 +37,13 @@ _arguments -C -s \
   '--cut-dirs=:number:' \
   '--http-user=:user:' \
   '--http-passwd=:password:' \
+  '(--html-extension)-E[save all text/html files with a .html extension]' \
+  '(-E)--html-extension' \
   '--ignore-length' \
   '--header=:string:' \
   '--proxy-user=:user:' \
   '--proxy-passwd=:password:' \
+  '--referer=:url:_urls' \
   '(--save-headers)-s[save headers]' '(-s)--save-headers' \
   {'(--user-agent)-U+[user agent]','(-U)--user-agent='}':user-agent:' \
   '--retr-symlinks' \
@@ -47,17 +53,22 @@ _arguments -C -s \
   {'(--level)-l+[level]','(-l)--level='}':level:(0)' \
   '--delete-after' \
   '(--convert-links)-k[convert links]' '(-k)--convert-links' \
+  '(--backup-converted)-K[backup files before conversion]' \
+  '(-K)--backup-converted' \
   '(--mirror)-m[mirror]' '(-m)--mirror' \
-  {'(--accept)-A+[accept]','(-A)--accept='}':accepted etensions:' \
-  {'(--reject)-R+[reject]','(-R)--reject='}':rejected etensions:' \
+  '(--page-requisites)-p[get all images needed to display page]' \
+  '(-p)--page-requisites' \
+  {'(--accept)-A+[accept]','(-A)--accept='}':accepted extensions:' \
+  {'(--reject)-R+[reject]','(-R)--reject='}':rejected extensions:' \
   {'(--domains)-D+[domains]','(-D)--domains='}':accepted domains:' \
   '--exclude-domains=:rejected domains:' \
-  '(--relative)-L[relative]' '(-L)--relative' \
   '--follow-ftp' \
+  '--follow-tags=:HTML tags:' \
+  {'(--ignore-tags)-G+[ignored HTML tags]','(-G)--ignore-tags='}':HTML tags:' \
   '(--span-hosts)-H[span hosts]' '(-H)--span-hosts' \
+  '(--relative)-L[follow relative links only]' '(-L)--relative' \
   {'(--include-directories)-I+[include directories]','(-I)--include-directories='}':allowed directories:' \
   {'(--exclude-directories)-X+[exclude directories]','(-X)--exclude-directories='}':excluded directories:' \
-  {'(--base)-B+[base]','(-B)--base='}':base:' \
   '--no-host-lookup' \
   '--no-parent' \
   '--non-verbose' \
diff --git a/Completion/User/_xargs b/Completion/User/_xargs
index 8b9291227..f727ed8b7 100644
--- a/Completion/User/_xargs
+++ b/Completion/User/_xargs
@@ -1,13 +1,15 @@
 #compdef xargs
 
 _arguments \
-  -{p,t,x} \
+  '(-t)-p[prompt user for each command]' \
+  '(-p)-t[verbose - echo each command]' \
+  '-x[exit if max size exceeded]' \
   -{e-,E}':end-of-file string:' \
   '(-x -I)-i-:replacement string for lines:' \
   '(-x -i)-I:replacement string for lines:' \
   '(-n -L -x)-l-:number of input lines:' \
   '(-n -l)-L:number of input lines:' \
-  '(-l -L)-n:maximum number of arguments:' \
-  '-s:maximum command line length:' \
+  '(-l -L)-n-:maximum number of arguments:' \
+  '-s-:maximum command line length:' \
   '(-):command: _command_names -e' \
   '*::args: _normal'
diff --git a/Completion/User/_zip b/Completion/User/_zip
new file mode 100644
index 000000000..d6bb2d835
--- /dev/null
+++ b/Completion/User/_zip
@@ -0,0 +1,121 @@
+#compdef zip unzip zipinfo
+
+local suffixes suf zipfile izip
+local expl curcontext="$curcontext" state line
+typeset -A opt_args
+
+case $service in
+  zip)
+    _arguments -C -s \
+      '-f[freshen: only changed files]' \
+      '-d[delete entries in zipfile]' \
+      '-R[recurse into directories]' \
+      '-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]' \
+      '-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' \
+      '(   -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' \
+      '(-0 -1 -2    -4 -5 -6 -7 -8 -9)-3' \
+      '(-0 -1 -2 -3    -5 -6 -7 -8 -9)-4' \
+      '(-0 -1 -2 -3 -4    -6 -7 -8 -9)-5' \
+      '(-0 -1 -2 -3 -4 -5    -7 -8 -9)-6' \
+      '(-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]' \
+      "(-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|[jw]ar)'" \
+      ':file:->files' && return 0
+  ;;
+  unzip)
+    _arguments -C -s \
+      '(-f -u -l -t -z -d)-p[extract files to pipe]' \
+      '(-p -u -l -t -z)-f[freshen existing files; create none]' \
+      '(-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]' \
+      '(-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]' \
+      '(-p -l -t -z -n)-o[overwrite files without prompting]' \
+      "(-p -l -t -z)-j[junk paths (don't make directories)]" \
+      '-C[match filenames case-insensitively]' \
+      '(-p -l -t -z)-X[restore UID/GID info]' \
+      '-q[quiet]' '-qq[quieter]' \
+      '(-l -t -z)-a[auto-convert any text files]' \
+      '(-l -t -z)-aa[treat all files as text]' \
+      '-v[verbose/display version info]' \
+      '(-p -z)-L[lowercase (some) filenames]' \
+      '-M[page output]' \
+      '-x[exclude the following names]' \
+      "(-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|[jw]ar)'" \
+      '*:file:->files' && return 0
+  ;;
+  zipinfo)
+    _arguments -C -s \
+      '(-2 -s -m -l -v -h -t -T -z)-1[filenames only]' \
+      '(-1 -s -m -l -v -T)-2[just filenames but allow -h/-t/-z]' \
+      '(-1 -2 -m -l -v -h -t)-s[short format]' \
+      '(-1 -2 -s -l -v -h -t)-m[medium format]' \
+      '(-1 -2 -s -m -v -h -t)-l[long format]' \
+      '(-1 -2 -s -m -l -h -z)-v[verbose, multi-page format]' \
+      '(-1 -s -m -l -v)-h[print header line]' \
+      '(-1 -v)-z[print zipfile comment]' \
+      '-C[match filenames case-insensitively]' \
+      '(-1 -s -m -l)-t[print totals]' \
+      '(-1 -2)-T[use sortable decimal format for file times]' \
+      '-M[page output]' \
+      '-x[exclude the following names]' \
+      "(-1 -2 -s -m -l -v -h -z -C -t -T -M)1:zip file:_files -g '(#i)*.(zip|[jw]ar)'" \
+      '*:file:->files' && return 0
+  ;;
+esac
+
+case $state in
+  suffixes)
+    compset -P '*:'
+    compset -S ':*' || suf=":"
+    suffixes=( *.*(N:e) )
+    _wanted suffixes expl suffixes compadd -S "$suf" -r " " .$^suffixes && return 0
+  ;;
+  files)
+    if [[ $service = zip ]] && (( ! ${+opt_args[-d]} )); then
+      _files -g '^(#i)*.(zip|[jw]ar)' && return 0
+    else
+      (( izip = 1 + words[(I)-[^xi]*] ))
+      (( izip == 1 )) && (( izip++ ))
+      zipfile=( $~words[izip](|.zip|.ZIP) )
+      [[ -z $zipfile[1] ]] && return 1
+      if [[ $zipfile[1] !=  $_zip_cache_list ]]; then
+	_zip_cache_name="$zipfile[1]"
+	_zip_cache_list=( $(zipinfo -1 $_zip_cache_name) )
+      fi
+     _wanted files expl 'file from archive' _multi_parts / _zip_cache_list
+    fi
+  ;;
+esac