about summary refs log tree commit diff
path: root/Completion/User/_cvs
diff options
context:
space:
mode:
Diffstat (limited to 'Completion/User/_cvs')
-rw-r--r--Completion/User/_cvs943
1 files changed, 646 insertions, 297 deletions
diff --git a/Completion/User/_cvs b/Completion/User/_cvs
index 65fa87904..356c7a80a 100644
--- a/Completion/User/_cvs
+++ b/Completion/User/_cvs
@@ -1,315 +1,670 @@
 #compdef cvs
 
-_cvs () {
-  setopt localoptions extendedglob
-
-  typeset -A commands
-  commands=(add "ad new"            admin "adm rcs"         annotate ann
-	    checkout "co get"       commit "ci com"         diff "di dif"
-	    edit ""                 editors ""              export "exp ex"
-	    history "hi his"        import "im imp"         init ""
-	    log "lo rlog"           login "logon lgn"       logout ""
-	    rdiff patch             release "re rel"        remove "rm delete"
-	    status "st stat"        rtag "rt rfreeze"       tag "ta freeze"
-	    unedit ""               update "up upd"         watch ""
-	    watchers "")
-
-  local com="${words[(i)(${(j:|:)${(kv)=commands}})]}"
-
-  local showlist='compstate[list]=list; compstate[force_list]=yes'
-  local showhint="$showlist ; compstate[insert]=''"
-  local complete_D="compadd today yesterday week\\ ago month\\ ago"
-  local complete_k="compadd kv kvl k o b v"
-  local complete_r="_cvsrevisions"
-  local complete_m="compadd -UX 'Enter log message' -n ''; $showhint"
-
-  if (( com < CURRENT )); then
-    case "$words[$com]" in
-      add|ad|new) # "+k:m:"
-	_complete_opts k: "$complete_k" m: "$complete_m" || _cvsaddp
-	;;
-      admin|adm|rcs) # "+ib::c:a:A:e:l::u::LUn:N:m:o:s:t::IqxV:k:"
-	_complete_opts i '' b:: '' c: '' a: '' A: '' e: '' l:: '' u:: '' L '' \
-	  U '' n: '' N: '' m: "$complete_m" o: '' s: '' t:: '' I '' q '' x '' \
-	    V: '' k: "$complete_k" ||
-	_cvstargets
-	;;
-      annotate|ann) # "+lr:D:fR"
-	_complete_opts l '' r: "$complete_r" D: "$complete_D" f '' R '' ||
-	_cvstargets
-	;;
-      checkout|co|get) # "+ANnk:d:flRpQqcsr:D:j:P"
-	_complete_opts A '' N '' n '' k: "$complete_k" d: '_files -/' f '' \
-	  l '' R '' p '' Q '' q '' c '' s '' r: "$complete_r" D: "$complete_D" \
-	  j: "$complete_r" P '' ||
-	_cvsrepositories
-	;;
-      commit|ci|com) # "+nlRm:fF:r:"
-	_complete_opts n '' l '' R '' m: "$complete_m" f '' F: _files \
-	  r: "$complete_r" ||
-	_cvsmodified
-	;;
-      diff|di|dif) # "+abcdefhilnpstuw0123456789BHNRC:D:F:I:L:U:V:W:k:r:"
-	_complete_opts a '' b '' c '' d '' e '' f '' h '' i '' l '' n '' p '' \
-	  s '' t '' u '' w '' 0 '' 1 '' 2 '' 3 '' 4 '' 5 '' 6 '' 7 '' 8 '' \
-	  9 '' B '' H '' N '' R '' C: '' D: "$complete_D" F: '' I: '' L: '' \
-	  U: '' V: '' W: '' k: "$complete_k" r: "$complete_r" ||
-	_cvsmodified || _cvstargets
-	;;
-      edit) # "+lRa:"
-	_complete_opts l '' R '' a: 'compadd edit unedit commit all none' ||
-	_cvstargets
-	;;
-      editors) # "+lR"
-	_complete_opts l '' R '' || _cvstargets
-	;;
-      export|exp|ex) # "+Nnk:d:flRQqr:D:"
-	_complete_opts N '' n '' k: "$complete_k" d: '_files -/' f '' l '' \
-	  R '' Q '' q '' r: "$complete_r" D: "$complete_D" ||
-	_cvsrepositories
-	;;
-      history|hi|his) # "+Tacelow?D:b:f:m:n:p:r:t:u:x:X:z:"
-	_complete_opts T '' a '' c '' e '' l '' o '' w '' \? '' \
-	  D: "$complete_D" b: '' f: '' m: "$complete_m" n: '' p: '' r: '' \
-	  t: '' u: '' x: '' X: '' z: '' ||
-	_cvstargets
-	;;
-      import|im|imp) # "+Qqdb:m:I:k:W:"
-	_complete_opts Q '' q '' d '' b: '' m: "$complete_m" I: _files \
-	  k: "$complete_k" W: '' ||
-	case $[CURRENT-com] in
-	  1) _cvsrepositories;;
-	  2) compadd -UX "Enter vendor tag name" -n '' && eval "$showhint";;
-	  3) compadd -UX "Enter release tag name" -n '' && eval "$showhint";;
-	  *) compadd -UX "No futher arguments used" -n '' && eval "$showhint";;
-	  esac
-	;;
-      init)
-	break
-	;;
-      login|logon|lgn|logout)
-	_complete_opts || _files
-	;;
-      rdiff|patch|pa) # "+V:k:cuftsQqlRD:r:"
-	_complete_opts V: '' k: "$complete_k" c '' u '' f '' t '' s '' Q '' \
-	  q '' l '' R '' D: "$complete_D" r: "$complete_r" ||
-	_cvstargets
-	;;
-      release|re|rel) # "+Qdq"
-	_complete_opts Q '' d '' q '' || _files -/
-	;;
-      remove|rm|delete) # "+flR"
-	_complete_opts f '' l '' R '' || _cvsremovep
-	;;
-      status|st|stat) # "+vlR"
-	_complete_opts v '' l '' R '' || _cvstargets
-	;;
-      tag|ta|freeze) # "+FQqlRcdr:D:bf"
-	_complete_opts F '' Q '' q '' l '' R '' c '' d '' r: "$complete_r" \
-	  D: "$complete_D" b '' f '' ||
-	_cvstargets
-	;;
-      unedit) # "+lR"
-	_complete_opts l '' R '' || _cvstargets
-	;;
-      update|up|upd) # "+ApPflRQqduk:r:D:j:I:W:"
-	_complete_opts A '' p '' P '' f '' l '' R '' Q '' q '' d '' u '' \
-	  k: "$complete_k" r: "$complete_r" D: "$complete_D" j: "$complete_r" \
-	  I: '' W: '' ||
-	_cvstargets
-	;;
-      watch)
-	if (( CURRENT == com + 1 )); then
-	  compadd on off add remove
-	else
-	  case "$words[com+1]" in
-	    on|off) # "+lR"
-	      _complete_opts l '' R '' || _cvstargets
-	      ;;
-	    add|remove) # "+lRa:"
-	      _complete_opts l '' R '' \
-	        a: 'compadd edit unedit commit all none' || \
-	      _cvstargets
-	      ;;
-	  esac
-	fi
-	;;
-      watchers) # "+lR"
-	_complete_opts l '' R '' || _cvstargets
-	;;
-      *) _files;;
-    esac
-    return
-  fi
+# redefine _cvs.
 
-  _complete_opts \
-    H '' Q '' q '' r '' w '' l '' n '' t '' v '' f '' a '' \
-    b: "compadd /usr/local/bin" \
-    T: "compadd $TMPPREFIX:h $TMPDIR /tmp" \
-    e: "compadd vi" \
-    d: "compadd $_cvs_roots || _files -/" \
-    z: "compadd 9'" \
-    s: "_cvs_user_variable" \
-   || 
-  compadd ${(k)commands} ||
-  compadd ${(kv)=commands}
+_cvs () {
+  # "+Qqrwtnlvb:T:e:d:Hfz:s:xa"
+  _arguments -s \
+    -{a,f,H,l,n,Q,q,r,t,v,w,x} \
+    '--version' '--help' '--help-commands' '--help-synonyms' '--help-options' \
+    '--allow-root=:rootdir:_files -/' \
+    '-b+:bindir:_cvs_bindir' \
+    '-T+:temporary directory:_cvs_tempdir' \
+    '-d+:cvsroot:_cvs_root' \
+    '-e+:editor:_cvs_editor' \
+    '-s+:user variable:_cvs_user_variable' \
+    '-z+:gzip level:_cvs_gzip_level' \
+    '*::cvs command:_cvs_command'
 }
 
-_cvsrevisions () {
-  compadd - ${${${(M)${(f)"$(cvs -q status -vl .)"}:#	*}##[ 	]##}%%[ 	]*}
-}
+# define cvs command dispatch function.
 
-_cvsrepositories () {
-  local root=$CVSROOT
-  [[ -f CVS/Root ]] && root=$(<CVS/Root)
+if ! builtin functions _cvs_command >&-; then
+  _cvs_command () {
+    typeset -A cmds
+    cmds=(add " ad new "          admin " adm rcs "       annotate " ann "
+	  checkout " co get "     commit " ci com "       diff " di dif "
+	  edit ""                 editors ""              export " exp ex "
+	  history " hi his "      import " im imp "       init ""
+	  log " lo rlog "         login " logon lgn "     logout ""
+	  rdiff " patch pa "      release " re rel "      remove " rm delete "
+	  status " st stat "      rtag " rt rfreeze "     tag " ta freeze "
+	  unedit ""               update " up upd "       watch ""
+	  watchers "")
 
-  if [[ $root = :* || ! -d $root ]]; then
-    compadd -UX "Enter repository name" -n '' &&
-    { compstate[list]=list; compstate[force_list]=yes; compstate[insert]='' }
-  else
-    compadd - \
-      $root/^CVSROOT(:t) \
-      ${${(M)${(f)"$(<$root/CVSROOT/modules)"}:#[^#]*}%%[ 	]*}
-  fi
-}
+    if (( CURRENT == 1 )); then
+      compadd "$@" ${(k)cmds} || compadd "$@" ${(kv)=cmds}
+    else
+      case "${${(k)cmds[(R)* $words[1] *]}:-$words[1]}" in
+	add) _cvs_add;;
+	admin) _cvs_admin;;
+	annotate) _cvs_annotate;;
+	checkout) _cvs_checkout;;
+	commit) _cvs_commit;;
+	diff) _cvs_diff;;
+	edit) _cvs_edit;;
+	editors) _cvs_editors;;
+	export) _cvs_export;;
+	history) _cvs_history;;
+	import) _cvs_import;;
+	init) _cvs_init;;
+	log) _cvs_log;;
+	login) _cvs_login;;
+	logout) _cvs_logout;;
+	rdiff) _cvs_rdiff;;
+	release) _cvs_release;;
+	remove) _cvs_remove;;
+	status) _cvs_status;;
+	rtag) _cvs_rtag;;
+	tag) _cvs_tag;;
+	unedit) _cvs_unedit;;
+	update) _cvs_update;;
+	watch) _cvs_watch;;
+	watchers) _cvs_watchers;;
+	*) _message "unknown cvs command: $words[1]";;
+      esac
+    fi
+  }
+fi
 
-_cvsprefix () {
-  if [[ -prefix */ ]]; then
-    qpref="${PREFIX%/*}/"
-    pref=$~qpref
-  else
-    qpref=
-    pref=./
-  fi
-}
+# define completion functions for each cvs command
 
-_cvsentries_dir () {
-  entries=($entries ${${${(M)rawentries:#D/*}#D/}%%/*})
-}
+if ! builtin functions _cvs_add >&-; then
+  _cvs_add () {
+    # "+k:m:"
+    _arguments -s \
+      '-k+:keyword substitution:_cvs_k' \
+      '-m+:message:_cvs_m' \
+      '*:file:_cvs_files_unmaintained' \
+  }
+fi
 
-_cvsentries_plain () {
-  entries=($entries ${${${(M)rawentries:#/*}#/}%%/*})
-}
+if ! builtin functions _cvs_admin >&-; then
+  _cvs_admin () {
+    # "+ib::c:a:A:e:l::u::LUn:N:m:o:s:t::IqxV:k:"
+    _arguments -s \
+      -{i,L,U,I,q,x} \
+      '-b-:default branch:(1.1.1)' \
+      '-c+:comment leader (not used):' \
+      '-a+:login names (not work with CVS):' \
+      '-A+:access list to append (not work with CVS):' \
+      '-e+:access list to erase (not work with CVS):' \
+      '-l-:revision to lock:' \
+      '-u-:revision to unlock:' \
+      '-n+:symbolic-name[\:revision]:' \
+      '-N+:symbolic-name[\:revision]:' \
+      '-m+:revision\:msg:' \
+      '-o+:range to delete:' \
+      '-s+:state[\:revision]:' \
+      '-t-:descriptive text:_cvs_admin_t' \
+      '-V+:version (obsolete):' \
+      '-k+:keyword substitution:_cvs_k' \
+      '*:file:_cvs_files'
+  }
+fi
 
-_cvsentries_modified () {
-  if (( $+_cvsentries_modified_disable_stat )) ||
-    ! { zmodload -e stat || zmodload stat }; then
-    _cvsentries_plain
-    return
-  fi
+if ! builtin functions _cvs_admin_t >&-; then
+  _cvs_admin_t () {
+    if compset -P -; then
+      _message 'descriptive text'
+    else
+      _files "$@"
+    fi
+  }
+fi
 
-  local ents pats
-  ents=(${${${${(M)rawentries:#/*}#/}/\\/[^\\/]#\\///}%/[^/]#/[^/]#})
-  pats=(${${${(f)"$(LANG=C builtin stat -gn +mtime -F '%a %b %e %T %Y' ${pref}*(D))"}##*/}/ //})
-  eval 'ents=(${ents:#('${(j:|:)pats:q}')})'
-  entries=($entries ${ents%%/*})
-}
+if ! builtin functions _cvs_annotate >&-; then
+  _cvs_annotate () {
+    # "+lr:D:fR"
+    _arguments -s \
+      -{l,f,R} \
+      '-r+:tag:_cvs_revisions' \
+      '-D+:date:_cvs_D' \
+      '*:file:_cvs_files'
+  }
+fi
 
-_cvsdirentries () {
-  entries=()
-  if [[ -f ${pref}CVS/Entries ]]; then
-    local rawentries
-    rawentries=(${(f)"$(<${pref}CVS/Entries)"})
-    _cvsentries_dir
-  fi
-}
+if ! builtin functions _cvs_checkout >&-; then
+  _cvs_checkout () {
+    # "+ANnk:d:flRpQqcsr:D:j:P"
+    _arguments -s \
+      -{A,N,n,f,l,R,q,c,s,P} \
+      '-k+:keyword substitution:_cvs_k' \
+      '-d+:directory:_files -/' \
+      '-r+:tag:_cvs_revisions' \
+      '-D+:date:_cvs_D' \
+      '-j+:tag:_cvs_revisions' \
+      '*:module:_cvs_modules'
+  }
+fi
 
-_cvsentries () {
-  entries=()
-  if [[ -f ${pref}CVS/Entries ]]; then
-    local rawentries
-    rawentries=(${(f)"$(<${pref}CVS/Entries)"})
-    _cvsentries_plain
-    _cvsentries_dir
-  fi
-}
+if ! builtin functions _cvs_commit >&-; then
+  _cvs_commit () {
+    # "+nlRm:fF:r:"
+    _arguments -s \
+      -{n,l,R,f} \
+      '-m+:message:_cvs_m' \
+      '-F+:log message file:_files' \
+      '-r+:tag:_cvs_revisions' \
+      '*:file:_cvs_files_modified'
+  }
+fi
 
-_cvsmodentries () {
-  entries=()
-  if [[ -f ${pref}CVS/Entries ]]; then
-    local rawentries
-    rawentries=(${(f)"$(<${pref}CVS/Entries)"})
-    _cvsentries_modified
-    _cvsentries_dir
-  fi
-}
+if ! builtin functions _cvs_diff >&-; then
+  _cvs_diff () {
+    # "+abcdefhilnpstuw0123456789BHNRC:D:F:I:L:U:V:W:k:r:"
+    _arguments -s \
+      -{l,R} \
+      '-D+:date:_cvs_D' \
+      '-k+:keyword substitution:_cvs_k' \
+      '-r+:tag:_cvs_revisions' \
+      -{h,p,0,1,2,3,4,5,6,7,8,9} \
+      '--binary' \
+      '--brief' \
+      '--changed-group-format=:format:' \
+      '-c' '-C+:lines:' '--context=-:lines:' \
+      '-e' '--ed' \
+      '-t' '--expand-tabs' \
+      '-f' '--forward-ed' \
+      '--horizon-lines=:lines:' \
+      '--ifdef=:name:' \
+      '-w' '--ignore-all-space' \
+      '-B' '--ignore-blank-lines' \
+      '-i' '--ignore-case' \
+      '-I+:regex:' '--ignore-matching-lines=:regex:' \
+      '-b' '--ignore-space-change' \
+      '--initial-tab' \
+      '*-L+:label:' '*--label=:label:' \
+      '--left-column' \
+      '--line-format=:format:' \
+      '-d' '--minimal' \
+      '-N' '--new-file' \
+      '--new-group-format=:format:' \
+      '--new-line-format=:format:' \
+      '--old-group-format=:format:' \
+      '--old-line-format=:format:' \
+      '--paginate' \
+      '-n' '--rcs' \
+      '-s' '--report-identical-files' \
+      '--show-c-function' \
+      '-F+:regex:' '--show-function-line=:regex:' \
+      '-y' '--side-by-side' \
+      '-H' '--speed-large-files' \
+      '--suppress-common-lines' \
+      '-a' '--text' \
+      '--unchanged-group-format=:format:' \
+      '--unchanged-line-format=:format:' \
+      '-u' '-U+:lines:' '--unified=-:lines:' \
+      '-W:columns:' '--width=:columns:' \
+      '*:file:_cvs_diff_arg'
+  }
+fi
 
-_cvsdirs () {
-  if [[ -d ${pref}CVS ]]; then
-    _cvsdirentries
-    case $#entries in
-      0) false;;
-      1) compgen "$@" -g "${entries:q}";;
-      *) compgen "$@" -g '('${(j:|:)entries:q}')';;
-    esac
-  else
-    _files
-  fi
-}
+if ! builtin functions _cvs_diff_arg >&-; then
+  _cvs_diff_arg () {
+    _cvs_files_modified || _cvs_files
+  }
+fi
 
-_cvstargets () {
-  local qpref pref entries
-  _cvsprefix
-  if [[ -d ${pref}CVS ]]; then
-    _cvsentries
-    case $#entries in
-      0) false;;
-      1) compgen -g "${entries:q}";;
-      *) compgen -g '('${(j:|:)entries:q}')';;
-    esac
-  else
-    _files
-  fi
-}
+if ! builtin functions _cvs_edit >&-; then
+  _cvs_edit () {
+    # "+lRa:"
+    _arguments -s \
+      -{l,R} \
+      '-a+:action:(edit unedit commit all none)'
+      '*:file:_cvs_files'
+  }
+fi
 
-_cvsmodified () {
-  local qpref pref entries
-  _cvsprefix
-  if [[ -d ${pref}CVS ]]; then
-    _cvsmodentries
-    case $#entries in
-      0) false;;
-      1) compgen -g "${entries:q}";;
-      *) compgen -g '('${(j:|:)entries:q}')';;
-    esac
-  else
-    _files 
-  fi
-}
+if ! builtin functions _cvs_editors >&-; then
+  _cvs_editors () {
+    # "+lR"
+    _arguments -s \
+      -{l,R} \
+      '*:file:_cvs_files'
+  }
+fi
 
-_cvsremovep () {
-  local qpref pref entries
-  _cvsprefix
-  if [[ -d ${pref}CVS ]]; then
-    _cvsentries
-    setopt localoptions unset
-    local omit
-    omit=(${pref}*(D:t))
-    eval 'entries=(${entries:#('${(j:|:)omit:q}')})'
-    compadd -P "$qpref" - ${entries:q} ||
-    _cvsdirs
-  else
-    _files
-  fi
-}
+if ! builtin functions _cvs_export >&-; then
+  _cvs_export () {
+    # "+Nnk:d:flRQqr:D:"
+    _arguments -s \
+      -{N,n,f,l,R,Q,q} \
+      '-k+:keyword substitution:_cvs_k' \
+      '-d+:directory:_files -/' \
+      '-r+:tag:_cvs_revisions' \
+      '-D+:date:_cvs_D' \
+      '*:module:_cvs_modules'
+  }
+fi
+
+if ! builtin functions _cvs_history >&-; then
+  _cvs_history () {
+    # "+Tacelow?D:b:f:m:n:p:r:t:u:x:X:z:"
+    _arguments -s \
+      -{T,a,c,e,l,o,w,\?} \
+      '-D+:date:_cvs_D' \
+      '-b+:string:' \
+      '-f+:arg:' \
+      '-m+:module:_cvs_modules' \
+      '-n+:arg:' \
+      '*-p+:repository:' \
+      '-r+:rev:' \
+      '-t+:tag:' \
+      '-u+:user name:' \
+      '-x+:type:_cvs_history_x' \
+      '-X+:arg:' \
+      '-z+:arg:' \
+      '*:file:_cvs_files'
+  }
+fi
+
+if ! builtin functions _cvs_history_x >&-; then
+  _cvs_history_x () {
+    compset -P '*'
+
+    compadd "$@" -y '(
+    F\ --\ release
+    O\ --\ checkout
+    E\ --\ export
+    T\ --\ rtag
+    C\ --\ merge\ collision-detected
+    G\ --\ merge\ succeed
+    U\ --\ working\ file\ was\ copied
+    W\ --\ working\ file\ was\ deleted
+    A\ --\ A\ file\ was\ added
+    M\ --\ A\ file\ was\ modified
+    R\ --\ A\ file\ was\ removed
+    )' F O E T C G U W A M R
+  }
+fi
+
+if ! builtin functions _cvs_import >&-; then
+  _cvs_import () {
+    # "+Qqdb:m:I:k:W:"
+    _arguments -s \
+      -{Q,q,d} \
+      '-b+:branch:' \
+      '-m+:message:_cvs_m' \
+      '*-I+:name:_files' \
+      '-k+:keyword substitution:_cvs_k' \
+      '*-W+:spec:' \
+      ':repository:_cvs_modules' \
+      ':vendor tag:' \
+      ':release tag:'
+  }
+fi
+
+if ! builtin functions _cvs_init >&-; then
+  _cvs_init () {
+    false
+  }
+fi
+
+if ! builtin functions _cvs_login >&-; then
+  _cvs_login () {
+    false
+  }
+fi
+
+if ! builtin functions _cvs_logout >&-; then
+  _cvs_logout () {
+    false
+  }
+fi
+
+if ! builtin functions _cvs_rdiff >&-; then
+  _cvs_rdiff () {
+    # "+V:k:cuftsQqlRD:r:"
+    _arguments -s \
+      -{c,u,f,t,s,Q,q,l,R} \
+      '-V+:version:' \
+      '-k+:keyword substitution:_cvs_k' \
+      '*-D+:date:_cvs_D' \
+      '*-r+:tag:_cvs_revisions' \
+      '*:module:_cvs_modules'
+  }
+fi
+
+if ! builtin functions _cvs_release >&-; then
+  _cvs_release () {
+    # "+Qdq"
+    _arguments -s \
+      -{Q,d,q} \
+      '*:directory:_files -/'
+  }
+fi
+
+if ! builtin functions _cvs_remove >&-; then
+  _cvs_remove () {
+    # "+flR"
+    _arguments -s \
+      -{f,l,R} \
+      '*:file:_cvs_files_removed'
+  }
+fi
+
+if ! builtin functions _cvs_status >&-; then
+  _cvs_status () {
+    # "+vlR"
+    _arguments -s \
+      -{v,l,R} \
+      '*:file:_cvs_files'
+  }
+fi
+
+if ! builtin functions _cvs_tag >&-; then
+  _cvs_tag () {
+    # "+FQqlRcdr:D:bf"
+    _arguments -s \
+      -{F,Q,q,l,R,c,d,b,f} \
+      '-r+:tag:_cvs_revisions' \
+      '-D+:date:_cvs_D' \
+      '*:file:_cvs_files'
+  }
+fi
+
+if ! builtin functions _cvs_unedit >&-; then
+  _cvs_unedit () {
+    # "+lR"
+    _arguments -s \
+      -{l,R} \
+      '*:file:_cvs_files'
+  }
+fi
+
+if ! builtin functions _cvs_update >&-; then
+  _cvs_update () {
+    # "+ApPflRQqduk:r:D:j:I:W:"
+    _arguments -s \
+      -{A,p,P,f,l,R,Q,q,d,u} \
+      '-k+:keyword substitution:_cvs_k' \
+      '-r+:tag:_cvs_revisions' \
+      '-D+:date:_cvs_D' \
+      '-j+:tag:_cvs_revisions' \
+      '*-I+:name:_files' \
+      '*-W+:spec:' \
+      '*:file:_cvs_files'
+  }
+fi
+
+if ! builtin functions _cvs_watch >&-; then
+  _cvs_watch () {
+    if (( CURRENT == 2 )); then
+      compadd on off add remove
+    else
+      case "$words[2]" in
+	on|off) # "+lR"
+	  _arguments -s \
+	  -{l,R} \
+	  ':watch command:' \
+	  ':*:file:_cvs_files'
+	  ;;
+	add|remove) # "+lRa:"
+	  _arguments -s \
+	  -{l,R} \
+	  '*-a+:action:(edit unedit commit all none)' \
+	  ':watch command:' \
+	  ':*:file:_cvs_files'
+	  ;;
+      esac
+    fi
+  }
+fi
+
+if ! builtin functions _cvs_watchers >&-; then
+  _cvs_watchers () {
+    # "+lR"
+    _arguments -s \
+      -{l,R} \
+      ':*:file:_cvs_files'
+  }
+fi
+
+if ! builtin functions _cvs_root >&-; then
+  _cvs_root () {
+    compadd "$@" $_cvs_roots || _files "$@" -/
+  }
+fi
+
+if ! builtin functions _cvs_tempdir >&-; then
+  _cvs_tempdir () {
+    compadd "$@" $TMPPREFIX:h $TMPDIR /tmp
+  }
+fi
+
+if ! builtin functions _cvs_user_variable >&-; then
+  _cvs_user_variable () {
+    if compset -P '*='; then
+      _default
+    else
+      _message "variable=value"
+    fi
+  }
+fi
+
+# define completion functions for cvs global options.
+
+if ! builtin functions _cvs_bindir >&-; then
+  _cvs_bindir () {
+    compadd "$@" /usr/local/bin || _files "$@" -/
+  }
+fi
+
+if ! builtin functions _cvs_editor >&-; then
+  _cvs_editor () {
+    compadd "$@" vi
+  }
+fi
+
+if ! builtin functions _cvs_gzip_level >&-; then
+  _cvs_gzip_level () {
+    compadd "$@" 9
+  }
+fi
+
+# define completion functions for cvs common options and arguments.
+
+if ! builtin functions _cvs_D >&-; then
+  _cvs_D () {
+    compadd "$@" today yesterday week\ ago month\ ago
+  }
+fi
+
+if ! builtin functions _cvs_k >&-; then
+  _cvs_k () {
+    compadd "$@" kv kvl k o b v
+  }
+fi
+
+if ! builtin functions _cvs_m >&-; then
+  _cvs_m () {
+    _message "log message"
+  }
+fi
+
+if ! builtin functions _cvs_modules >&-; then
+  _cvs_modules () {
+    local root=$CVSROOT
+    [[ -f CVS/Root ]] && root=$(<CVS/Root)
+
+    if [[ $root = :* || ! -d $root ]]; then
+      _message "module name"
+    else
+      compadd - \
+	$root/^CVSROOT(:t) \
+	${${(M)${(f)"$(<$root/CVSROOT/modules)"}:#[^#]*}%%[ 	]*}
+    fi
+  }
+fi
+
+if ! builtin functions _cvs_revisions >&-; then
+  _cvs_revisions () {
+    compadd - ${${${(M)${(f)"$(cvs -q status -vl .)"}:#	*}##[ 	]##}%%[ 	]*}
+  }
+fi
+
+# define completion functions for files maintained by cvs.
+
+if ! builtin functions _cvs_setup_prefix >&-; then
+  _cvs_setup_prefix () {
+    if [[ -prefix */ ]]; then
+      qpref="${PREFIX%/*}/"
+      pref=$~qpref
+    else
+      qpref=
+      pref=./
+    fi
+  }
+fi
+
+if ! builtin functions _cvs_extract_directory_entries >&-; then
+  _cvs_extract_directory_entries () {
+    entries=($entries ${${${(M)rawentries:#D/*}#D/}%%/*})
+  }
+fi
 
-_cvsaddp () {
-  local qpref pref entries
-  _cvsprefix
-  if [[ -d ${pref}CVS ]]; then
-    _cvsentries
-    setopt localoptions unset
-    local omit
-    omit=($_cvs_ignore_default ${entries:q} ${=cvsignore})
-    [[ -r ~/.cvsignore ]] && omit=($omit $(<~/.cvsignore))
-    [[ -r ${pref}.cvsignore ]] && omit=($omit $(<${pref}.cvsignore))
-    compgen -g '*~(*/|)('${(j:|:)omit}')(D)' ||
-    compgen -g '*~(*/|)('${(j:|:)entries:q}')(D)' ||
-    _cvsdirs
+if ! builtin functions _cvs_extract_file_entries >&-; then
+  _cvs_extract_file_entries () {
+    entries=($entries ${${${(M)rawentries:#/*}#/}%%/*})
+  }
+fi
+
+if ! builtin functions _cvs_extract_modifiedfile_entries >&-; then
+  _cvs_extract_modifiedfile_entries () {
+    if [[ -n "$compconfig[_cvs_disable_stat]" ]] ||
+      ! { zmodload -e stat || zmodload stat }; then
+      _cvs_extract_file_entries
+      return
+    fi
+
+    local ents pats
+    ents=(${${${${(M)rawentries:#/*}#/}/\\/[^\\/]#\\///}%/[^/]#/[^/]#})
+    pats=(${${${(f)"$(LANG=C builtin stat -gn +mtime -F '%a %b %e %T %Y' ${pref}*(D))"}##*/}/ //})
+    eval 'ents=(${ents:#('${(j:|:)${(@)pats:q}}')})'
+    entries=($entries ${ents%%/*})
+  }
+fi
+
+if ! builtin functions _cvs_setup_allentries >&-; then
+  _cvs_setup_allentries () {
+    entries=()
+    if [[ -f ${pref}CVS/Entries ]]; then
+      local rawentries
+      rawentries=(${(f)"$(<${pref}CVS/Entries)"})
+      _cvs_extract_file_entries
+      _cvs_extract_directory_entries
+    fi
+  }
+fi
+
+if ! builtin functions _cvs_setup_direntries >&-; then
+  _cvs_setup_direntries () {
+    entries=()
+    if [[ -f ${pref}CVS/Entries ]]; then
+      local rawentries
+      rawentries=(${(f)"$(<${pref}CVS/Entries)"})
+      _cvs_extract_directory_entries
+    fi
+  }
+fi
+
+if ! builtin functions _cvs_setup_modentries >&-; then
+  _cvs_setup_modentries () {
+    entries=()
+    if [[ -f ${pref}CVS/Entries ]]; then
+      local rawentries
+      rawentries=(${(f)"$(<${pref}CVS/Entries)"})
+      _cvs_extract_modifiedfile_entries
+      _cvs_extract_directory_entries
+    fi
+  }
+fi
+
+if ! builtin functions _cvs_directories >&-; then
+  _cvs_directories () {
+    if [[ -d ${pref}CVS ]]; then
+      _cvs_setup_direntries
+      (( $#entries )) && compgen "$@" -g "${(j:|:)${(@)entries:q}}"
+    else
+      _files "$@"
+    fi
+  }
+fi
+
+if ! builtin functions _cvs_files >&-; then
+  _cvs_files () {
+    local qpref pref entries
+    _cvs_setup_prefix
+    if [[ -d ${pref}CVS ]]; then
+      _cvs_setup_allentries
+      (( $#entries )) && compgen "$@" -g "${(j:|:)${(@)entries:q}}"
+    else
+      _files "$@"
+    fi
+  }
+fi
+
+if ! builtin functions _cvs_files_modified >&-; then
+  _cvs_files_modified () {
+    local qpref pref entries
+    _cvs_setup_prefix
+    if [[ -d ${pref}CVS ]]; then
+      _cvs_setup_modentries
+      (( $#entries )) && compgen "$@" -g "${(j:|:)${(@)entries:q}}"
+    else
+      _files "$@"
+    fi
+  }
+fi
+
+if ! builtin functions _cvs_files_removed >&-; then
+  _cvs_files_removed () {
+    local qpref pref entries
+    _cvs_setup_prefix
+    if [[ -d ${pref}CVS ]]; then
+      _cvs_setup_allentries
+      setopt localoptions unset
+      local omit
+      omit=(${pref}*(D:t))
+      eval 'entries=(${entries:#('${(j:|:)${(@)omit:q}}')})'
+      compadd "$@" -P "$qpref" - ${entries:q} ||
+      _cvs_directories "$@"
+    else
+      _files "$@"
+    fi
+  }
+fi
+
+if ! builtin functions _cvs_files_unmaintained >&-; then
+  _cvs_files_unmaintained () {
+    local qpref pref entries
+    _cvs_setup_prefix
+    if [[ -d ${pref}CVS ]]; then
+      _cvs_setup_allentries
+      setopt localoptions unset
+      local omit
+      omit=($_cvs_ignore_default ${entries:q} ${=cvsignore})
+      [[ -r ~/.cvsignore ]] && omit=($omit $(<~/.cvsignore))
+      [[ -r ${pref}.cvsignore ]] && omit=($omit $(<${pref}.cvsignore))
+      compgen "$@" -g '*~(*/|)('${(j:|:)omit}')(D)' ||
+      compgen "$@" -g '*~(*/|)('${(j:|:)${(@)entries:q}}')(D)' ||
+      _cvs_directories "$@"
+    else
+      _files "$@"
+    fi
+  }
+fi
+
+# define configuration variables.
+
+if (( ! $+_cvs_roots )); then
+  if [[ -f ~/.cvspass ]]; then
+    _cvs_roots=(${${(f)"$(<~/.cvspass)"}%% *})
   else
-    _files
+    _cvs_roots=()
   fi
-}
+fi
 
 if (( ! $+_cvs_ignore_default )); then
   _cvs_ignore_default=(
@@ -320,12 +675,6 @@ if (( ! $+_cvs_ignore_default )); then
   )
 fi
 
-if (( ! $+_cvs_roots )); then
-  if [[ -f ~/.cvspass ]]; then
-    _cvs_roots=(${${(f)"$(<~/.cvspass)"}%% *})
-  else
-    _cvs_roots=()
-  fi
-fi
+# call real _cvs.
 
 _cvs "$@"