summary refs log tree commit diff
path: root/Completion/Unix/Command
diff options
context:
space:
mode:
Diffstat (limited to 'Completion/Unix/Command')
-rw-r--r--Completion/Unix/Command/_perforce246
1 files changed, 172 insertions, 74 deletions
diff --git a/Completion/Unix/Command/_perforce b/Completion/Unix/Command/_perforce
index c9e20ca32..555bd9e51 100644
--- a/Completion/Unix/Command/_perforce
+++ b/Completion/Unix/Command/_perforce
@@ -1,4 +1,4 @@
-#compdef p4 -value-,P4CLIENT,-default- -value-,P4PORT,-default-
+#compdef p4 -value-,P4CLIENT,-default- -value-,P4PORT,-default- -value-,P4MERGE,-default- -value-,P4USER,-default-
 
 # Increasingly loosely based on _cvs version 1.17.
 
@@ -7,13 +7,13 @@
 #
 # If the `verbose' style is set (it is assumed by default), verbose
 # descriptions are provided for many completed quantities derived
-# dynamically such as subcommand names, labels, changelists -- in fact,
+# dynamically such as subcommand names, labels, changes -- in fact,
 # just about anything for which Perforce itself produces a verbose,
 # one-line description.  It may be turned off in the context of each
 # subcommand e.g.
 #   zstyle ':completion:*:p4-labelsync:*' verbose false
-# or for a particular tag, e.g. changelists,
-#   zstyle ':completeion:*:changelists' verbose false
+# or for a particular tag, e.g. changes,
+#   zstyle ':completeion:*:changes' verbose false
 # or just for top-level completion (i.e. up to and including completion
 # of the subcommand):
 #   zstyle ':completion:*:p4:*' verbose false
@@ -23,12 +23,13 @@
 # Perforce completion system; it's mentioned here as verbosity adds
 # significantly to a lot of the Perforce completions.
 #
-# Note that completing changelists (which are just numbers) is not very
-# useful if `verbose' is turned off.  There is no speed advantage for
-# turning it off, either.
+# Note that completing change numbers is not very useful if `verbose' is
+# turned off.  There is no speed advantage for turning it off, either.
+# (Changes are also known as changelists or changesets.  The functions
+# and tags here all consistently use `changes'.)
 #
 # The style `max' can be set to a number which limits how many
-# possibilities can be shown when selecting changelists or jobs.  This is
+# possibilities can be shown when selecting changes or jobs.  This is
 # handled within Perforce, so the completion code may limit the number even
 # further.  If not set explicitly, the value is taken to be 20 to avoid a
 # huge database being output.  Set it to a larger number if necessary.
@@ -60,6 +61,12 @@
 #
 # File completion handles @ and # suffixes.  If the filename is completed,
 # typing @ or # removes the space which was automatically added.
+# The context used has `at-suffix' or `hash-suffix' in the position
+# before the tag to indicate suffix completion (as always, ^Xh will
+# show you all possible contexts).  This should make it possible
+# to select changes, dates, labels and clients using the tag-order
+# style, but unfortunately there is a bug which stops any tags afer
+# the first group from being displayed.
 #
 # A # is automatically quoted when handled in this way; if the file is
 # typed by hand or the completion didn't finish (e.g. you typed a character
@@ -69,8 +76,8 @@
 # (since e# matches any number of e's including one).  Hence this can look
 # like an expansion which expands to `filename'.
 #
-# After @, you can complete changelists (note the use of the style `max'
-# above), labels or clients (but not dates), while after `#' you can
+# After @, you can complete changes (note the use of the style `max'
+# above), labels, clients or even dates, while after `#' you can
 # complete numeric revisions or the special revision names head, none,
 # have.  These are available whether or not you completed the filename; if
 # the file doesn't exist, numeric revisions won't work, but the rest will
@@ -90,7 +97,8 @@
 # automatically if the documentation suggests the command accepts ranges at
 # that point.  This is an auto-removable suffix, so it will disappear if
 # you hit space or return.  Typing a `#' at this point will insert a
-# backslash, as before.
+# backslash, as before.  The # and @ are never added automatically; you
+# have to select one by hand.
 #
 # File completion for some functions is restricted by the Perforce
 # status of the file; for example, `p4 opened' only completes opened
@@ -147,6 +155,22 @@
 # In this case, the entire text of the word being completed is assumed
 # to constitute the job name (which is almost certainly correct).
 #
+# Completion of dates
+# ===================
+#
+# In a file revision specification it is possible to give a date
+# in the form file@YYYY/MM/DD:hh:mm:ss, which may be completed.  This
+# is ever so slightly less silly than it sounds.  Any component entered
+# by hand with the appropriate suffix will be ignored; any component
+# completed will be set to the current value.  Hence you can easily
+# specify, say, one month ago by using the completed value for all
+# components except the month and setting that to one less.  The shell
+# will also happily append the appropriate suffix if you try to complete
+# after anything which is already the appropriate width.  (Perforce
+# supports two-digit years, but these are confusing and no longer
+# particularly useful as they refer to the twentieth century, so
+# the shell does not.)
+#
 # Calls to p4
 # ===========
 #
@@ -172,7 +196,7 @@
 _perforce() {
     # rely on localoptions
     setopt nonomatch
-    local p4cmd==p4
+    local p4cmd==p4 match mbegin mend
     integer i
 
     if [[ $service = -value-* ]]; then
@@ -180,10 +204,14 @@ _perforce() {
 	# Some of these --- in particular P4PORT --- don't need
 	# the perforce server.
 	case $compstate[parameter] in
-	    (P4PORT) _perforce_host_port
+	    (P4PORT) _perforce_hosts_ports
 		     ;;
 	    (P4CLIENT) _perforce_clients
 		       ;;
+	    (P4MERGE) _command_names -e
+		      ;;
+	    (P4USER) _users
+		     ;;
 	esac
 	# We do not handle values anywhere else.
 	return
@@ -208,6 +236,20 @@ _perforce() {
 	done
     fi
 
+    # If we are given a service of the form p4-cmd, treat this
+    # as if it was after `p4 cmd'.  This provides an easy way in
+    # for scripts and functions that emulate the behaviour of
+    # p4 subcommands.  Note we don't shorten the command line arguments.
+    if [[ $service = p4-(#b)(*) ]]; then
+        local curcontext="$curcontext"
+	if (( $+functions[_perforce_cmd_${match[1]}] )); then
+	    curcontext="${curcontext%:*:*}:p4-$match[1]:"
+	    _perforce_cmd_${match[1]}
+	else
+	    _message "unhandled _perforce service: $service"
+	fi
+    fi
+
     # We need to try and check if we are before or after the
     # subcommand, since some of the options with arguments, in particular -c,
     # work differently.  It didn't work if I just added '*::...' to the
@@ -224,7 +266,7 @@ _perforce() {
     if (( i >= CURRENT )); then
 	_arguments -s : \
 	    '-c+[client]:client:_perforce_clients' \
-	    '-C+[charset]:charset:_perforce_charset' \
+	    '-C+[charset]:charset:_perforce_charsets' \
 	    '-d+[current directory]:directory:_path_files -g "*(/)"' \
 	    '-H+[hostname]:host:_hosts' \
 	    '-G[python output]' \
@@ -233,13 +275,13 @@ _perforce() {
 	    '-P+[password on server]:password: ' \
 	    '-s[output script tags]' \
 	    '-u+[user]:user name:_users' \
-	    '-x+[filename or -]:file:_perforce_file_or_Minus' \
-	    '1:perforce command:_perforce_command'
+	    '-x+[filename or -]:file:_perforce_files_or_minus' \
+	    '1:perforce command:_perforce_commands'
     else
 	(( i-- ))
 	(( CURRENT -= i ))
 	shift $i words
-	_perforce_command_arg
+	_perforce_command_args
     fi
 }
 
@@ -248,14 +290,14 @@ _perforce() {
 # Command and argument dispatchers
 #
 
-(( $+functions[_perforce_command] )) ||
-_perforce_command() {
+(( $+functions[_perforce_commands] )) ||
+_perforce_commands() {
     _describe -t p4-commands 'Perforce command' _perforce_cmd_list
 }
 
 
-(( $+functions[_perforce_command_arg] )) ||
-_perforce_command_arg() {
+(( $+functions[_perforce_command_args] )) ||
+_perforce_command_args() {
     local curcontext="$curcontext" cmd=${words[1]}
     if (( $+functions[_perforce_cmd_$cmd] )); then
 	 curcontext="${curcontext%:*:*}:p4-${cmd}:"
@@ -280,8 +322,8 @@ _perforce_branches() {
 }
 
 
-(( $+functions[_perforce_changelist] )) ||
-_perforce_changelist() {
+(( $+functions[_perforce_changes] )) ||
+_perforce_changes() {
     local cline match mbegin mend max ctype num comma file
     local -a cl cstatus
 
@@ -329,14 +371,14 @@ _perforce_changelist() {
     # output.
     cl=(
 ${${${${(f)"$(_call_program changes p4 changes -m ${max:-20} $cstatus \$file)"}##Change\ }//\ on\ /:}/\ by\ /\ }
-"default:changelist not yet numbered")
+"default:change not yet numbered")
     [[ $#cl -eq 1 && $cl[1] = '' ]] && cl=()
-    _describe -t changelists "${ctype}changelist" cl $comma
+    _describe -t changes "${ctype}change" cl $comma
 }
 
 
-(( $+functions[_perforce_charset] )) ||
-_perforce_charset() {
+(( $+functions[_perforce_charsets] )) ||
+_perforce_charsets() {
     local expl
     _wanted charset expl 'character set' \
 	 compadd eucjp iso8859-1 shiftjis utf8 winansi
@@ -348,8 +390,10 @@ _perforce_clients() {
     local cline match mbegin mend 
     local -a slash cl
 
-    # Are we completing a client view in a filespec?
-    compset -P '//' && slash=(-S/ -q)
+    # Are we completing after an @, or a client view in a filespec?
+    if ! compset -P '*@'; then
+	compset -P '//' && slash=(-S/ -q)
+    fi
 
     cl=(${${${(f)"$(_call_program clients p4 clients)"}##Client\ }/\ /:})
     [[ $#cl -eq 1 && $cl[1] = '' ]] && cl=()
@@ -368,8 +412,8 @@ _perforce_counters() {
 }
 
 
-(( $+functions[_perforce_counter_value] )) ||
-_perforce_counter_value() {
+(( $+functions[_perforce_counter_values] )) ||
+_perforce_counter_values() {
     if [[ -n $words[CURRENT-1] ]]; then
 	 local value="$(_call_program counter p4 counter $words[CURRENT-1] 2>/dev/null)"
 	 if [[ -n $value ]]; then
@@ -381,6 +425,46 @@ _perforce_counter_value() {
 }
 
 
+(( $+functions[_perforce_dates] )) ||
+_perforce_dates() {
+    # Only useful in a file spec after `@'.
+    compset -P '*@'
+
+    # Date/time now in format required by Perforce.
+    local now="$(date +%Y:%m:%d:%T)" name prefix
+    local -a nowarray offer opts matchpats suffixes names
+    nowarray=(${(s.:.)now})
+
+    names=(   year month day\ of\ month hour minute second)
+    suffixes=(  /    /    :               :     :     ''  )
+
+    integer i
+    prefix=${(Q)PREFIX}
+    for (( i = 6; i >= 1; i-- )); do
+	# Match from the most specific back.
+	# The following is one of those occasions where zsh
+	# substitution skips to the right answer without ever
+	# passing through the real world on the way.
+	if [[ $prefix = *${(j.*.)~suffixes[1,i-1]}* ]]; then
+	    (( i > 1 )) && compset -P "*$suffixes[i-1]"
+	    # If what's there already is the right length,
+	    # just accept it and add the suffix.
+	    prefix=${(Q)PREFIX}
+	    if [[ ${#prefix} = ${#nowarray[i]} ]]; then
+		offer=($prefix)
+	    else
+		offer=($nowarray[i])
+	    fi
+	    [[ -n $suffixes[i] ]] && opts=(-S $suffixes[i] -q)
+	    name=$names[i]
+	    break
+	fi
+    done
+
+    _describe -t dates $name offer $opts
+}
+
+
 (( $+functions[_perforce_depots] )) ||
 _perforce_depots() {
     local dline match mbegin mend max
@@ -392,8 +476,8 @@ _perforce_depots() {
 }
 
 
-(( $+functions[_perforce_file_or_minus] )) ||
-_perforce_file_or_minus() {
+(( $+functions[_perforce_files_or_minus] )) ||
+_perforce_files_or_minus() {
     _alternative 'minus:minus sign:(-)' 'files:file name:_files'
 }
 
@@ -463,8 +547,8 @@ _perforce_resolved_files() {
     compadd "$@" -a files
 }
 
-(( $+functions[_perforce_subdir_search] )) ||
-_perforce_subdir_search() {
+(( $+functions[_perforce_subdirs] )) ||
+_perforce_subdirs() {
     # This has no other function than to offer to add the `...' used
     # by Perforce to indicate a recursive search of directories.
     # Bit pathetic, really.
@@ -591,6 +675,8 @@ _perforce_files() {
     local -a files types
 
     local dodirs unmaintained
+    # Suffix operations can modify context
+    local curcontext="$curcontext"
 
     while (( $# )); do
 	if [[ $1 = -t(#b)(?) ]]; then
@@ -618,15 +704,23 @@ _perforce_files() {
     # special by p4 files and p4 dirs, but worry about that later.
     pfx=${(Q)PREFIX}
     if [[ -prefix *@ ]]; then
+	# Modify context to indicate we are in a suffix.
+	curcontext="${curcontext%:*}:at-suffix"
 	# Check for existing range syntax
 	[[ $PREFIX = *[@\#]*,* ]] && range=
-	# After @ you can specify changelists, clients, labels or dates.
-	# Don't try to complete dates.
+	# After @ you can specify changes, clients, labels or dates.
+	# Note we don't remove the prefix here; we leave it to the
+	# subcommand.  This is in case it needs information from
+	# the prefix; _perforce_changes uses this to limit the
+	# output to relevant changes.
 	_alternative \
-	    "changelist:changelist:_perforce_changelist $range -tf" \
-	    client:client:_perforce_clients \
-	    label:label:_perforce_labels
+	    "changes:change:_perforce_changes $range -tf" \
+	    clients:client:_perforce_clients \
+	    labels:label:_perforce_labels \
+	    'dates:date (+ time):_perforce_dates'
     elif [[ -prefix *\# ]]; then
+	# Modify context to indicate we are in a suffx.
+	curcontext="${curcontext%:*}:hash-suffix"
 	# Check for existing range syntax
 	[[ $PREFIX = *[@\#]*,* ]] && range=
 	# Remove longest possible tail match to get name --- this
@@ -661,7 +755,7 @@ _perforce_files() {
 	    altfiles+=("client-dirs:client directory:_perforce_client_dirs")
 	fi
 	altfiles+=("depot-dirs:directory in depot:_perforce_depot_dirs"
-	    "subdirs:subdirectory search:_perforce_subdir_search")
+	    "subdirs:subdirectory search:_perforce_subdirs")
 	_alternative $altfiles
     elif [[ -n $unmaintained && -z $dodirs ]]; then
 	# a la _cvs_nonentried_files: directories are never maintained,
@@ -695,7 +789,7 @@ _perforce_files() {
 	done
 
 	altfiles+=("depot-dirs:directory in depot:_perforce_depot_dirs"
-	    "subdirs:subdirectory search:_perforce_subdir_search")
+	    "subdirs:subdirectory search:_perforce_subdirs")
 	_alternative $altfiles
     elif zstyle -t ":completion:${curcontext}:" depot-files; then
 	local -a altfiles
@@ -703,13 +797,13 @@ _perforce_files() {
 	    altfiles+=("depot-files:file in depot:_perforce_depot_files")
 	fi
 	altfiles+=("depot-dirs:directory in depot:_perforce_depot_dirs"
-	    "subdirs:subdirectory search:_perforce_subdir_search")
+	    "subdirs:subdirectory search:_perforce_subdirs")
 	_alternative $altfiles
     else
 	# Look locally.
 	_alternative \
 	    "files:file:_path_files -R _perforce_file_suffix $dodirs" \
-	    "subdirs:subdirectory search:_perforce_subdir_search"
+	    "subdirs:subdirectory search:_perforce_subdirs"
     fi
 }
 
@@ -754,8 +848,8 @@ _perforce_groups() {
 }
 
 
-(( $+functions[_perforce_host_port] )) ||
-_perforce_host_port() {
+(( $+functions[_perforce_hosts_ports] )) ||
+_perforce_hosts_ports() {
     if compset -P '*:'; then
 	_ports
     else
@@ -789,8 +883,8 @@ _perforce_jobs() {
     _describe -t jobs 'Perforce job' jl
 }
 
-(( $+functions[_perforce_jobview] )) ||
-_perforce_jobview() {
+(( $+functions[_perforce_jobviews] )) ||
+_perforce_jobviews() {
     # Jobviews (see `p4 help jobview') are ways of interrogating the
     # jobs/fixes database.  It's basically either a set of strings,
     # or a set of key=value pairs, or some combination, separated
@@ -872,6 +966,10 @@ _perforce_jobview() {
 _perforce_labels() {
     local lline match mbegin mend
     local -a ll
+
+    # May be completing after `@'.
+    compset -P '*@'
+
     _call_program labels p4 labels | while read lline; do
 	if [[ $lline = (#b)'Label '([^[:blank:]]##)' '(*) ]]; then
 	    ll+=("${match[1]}:${match[2]}")
@@ -918,8 +1016,8 @@ _perforce_revisions() {
 }
 
 
-(( $+functions[_perforce_status] )) ||
-_perforce_status() {
+(( $+functions[_perforce_statuses] )) ||
+_perforce_statuses() {
     # Perforce statuses are usually limited to a set of values
     # given by the jobspec.
     local jline match mbegin mend
@@ -935,7 +1033,7 @@ _perforce_status() {
 	# Couldn't find anything from the jobspec; add defaults.
 	statuses=(closed open suspended)
     fi
-    _describe -t status 'job status' statuses
+    _describe -t statuses 'job status' statuses
     return 1
 }
 
@@ -961,7 +1059,7 @@ _perforce_variables() {
 (( $+functions[_perforce_cmd_add] )) ||
 _perforce_cmd_add() {
     _arguments -s : \
-	'-c+[select by changelist]:changelist:_perforce_changelist -tp' \
+	'-c+[select by change]:change:_perforce_changes -tp' \
 	'-t+[set file type]:file type:_perforce_filetypes' \
 	'*:file:_perforce_files -tu'
 }
@@ -1021,7 +1119,7 @@ _perforce_cmd_change() {
 	'(-o -i)-d[describe newly created pending change]' \
 	'(-d -i -f)-o[output specification to standard output]' \
 	'(-d -o)-i[read specification from standard input]' \
-	'(-i)1::changelist:_perforce_changelist -tp'
+	'(-i)1::change:_perforce_changes -tp'
 }
 
 
@@ -1063,7 +1161,7 @@ _perforce_cmd_counter() {
 	'-d[delete counter]' \
 	'-f[force setting of internal counter]' \
 	'1:counter:_perforce_counters' \
-	'(-d)2::numeric value:_perforce_counter_value'
+	'(-d)2::numeric value:_perforce_counter_values'
 }
 
 
@@ -1077,7 +1175,7 @@ _perforce_cmd_counters() {
 (( $+functions[_perforce_cmd_delete] )) ||
 _perforce_cmd_delete() {
     _arguments -s : \
-	'-c[select changelist for deletion]:changelist:_perforce_changelist -tp' \
+	'-c[select change for deletion]:change:_perforce_changes -tp' \
 	'*::file:_perforce_files'
 }
 
@@ -1104,7 +1202,7 @@ _perforce_cmd_describe() {
     _arguments -s : \
 	'-d-[select diff option]:diff option:((b\:ignore\ blanks c\:context n\:RCS s\:summary u\:unified w\:ignore\ all\ whitespace))' \
 	'-s[short form]' \
-	'*::changelist:_perforce_changelist'
+	'*::change:_perforce_changes'
 }
 
 
@@ -1150,7 +1248,7 @@ _perforce_cmd_dirs() {
 (( $+functions[_perforce_cmd_edit] )) ||
 _perforce_cmd_edit() {
     _arguments -s : \
-	'-c[set changelist for edit]:changelist:_perforce_changelist -tp' \
+	'-c[set change for edit]:change:_perforce_changes -tp' \
 	'-t[set filetype]:filetype:_perforce_filetypes' \
 	'*::file:_perforce_files'
 }
@@ -1160,7 +1258,7 @@ _perforce_cmd_edit() {
 _perforce_cmd_filelog() {
     _arguments -s : \
 	'-i[follow branches]' \
-	'-l[long output, full changelist text]' \
+	'-l[long output, full change text]' \
 	'-m[set maximum number of revisions to show]:max revisions: ' \
 	'-t[include time with date]' \
 	'*::file:_perforce_files'
@@ -1179,9 +1277,9 @@ _perforce_cmd_files() {
 _perforce_cmd_fix() {
     _arguments -s : \
 	'-d[delete the fix]' \
-	'-s[set job status]:status:_perforce_status' \
+	'-s[set job status]:status:_perforce_statuses' \
 	'1::-c required:(-c)' \
-	'2::changelist:_perforce_changelist' \
+	'2::change:_perforce_changes' \
 	'3::job:_perforce_jobs'
 }
 
@@ -1189,9 +1287,9 @@ _perforce_cmd_fix() {
 (( $+functions[_perforce_cmd_fixes] )) ||
 _perforce_cmd_fixes() {
     _arguments -s : \
-	'-i[include integrated changelists]' \
+	'-i[include integrated changes]' \
 	'-j[select by job]:job:_perforce_jobs' \
-	'-c[select by changelist]:changelist:_perforce_changelist' \
+	'-c[select by change]:change:_perforce_changes' \
 	'*::fixed file:_perforce_files -tR'
 }
 
@@ -1208,7 +1306,7 @@ _perforce_cmd_flush() {
 (( $+functions[_perforce_cmd_fstat] )) ||
 _perforce_cmd_fstat() {
     _arguments -s : \
-	'-c+[select by changelist]:changelist:_perforce_changelist -ts' \
+	'-c+[select by change]:change:_perforce_changes -ts' \
 	'-C[select mapped files]' \
 	'-H[select synced files]' \
 	'-W[select opened files]' \
@@ -1273,7 +1371,7 @@ _perforce_cmd_integrate() {
     [[ ${words[(I)-s]} -eq 0 ]] && range=" -tR"
     _arguments -s : \
 	'-b[select branch]:branch:_perforce_branches' \
-	'-c[select changelist for integration]:changelist:_perforce_changelist -tp' \
+	'-c[select change for integration]:change:_perforce_changes -tp' \
 	'-f[force reintegration]' \
 	'-d[reintegrated deleted files]' \
 	'-h[integrate to revision had on client]' \
@@ -1308,7 +1406,7 @@ _perforce_cmd_job() {
 (( $+functions[_perforce_cmd_jobs] )) ||
 _perforce_cmd_jobs() {
     _arguments -s : \
-	'-e[select by jobview]:jobview:_perforce_jobview' \
+	'-e[select by jobview]:jobview:_perforce_jobviews' \
 	'-i[included integrated changes]' \
 	'-l[long output, full job descriptions]' \
 	'-r[reverse order of job names]' \
@@ -1359,7 +1457,7 @@ _perforce_cmd_labelsync() {
 (( $+functions[_perforce_cmd_lock] )) ||
 _perforce_cmd_lock() {
     _arguments -s : \
-	'-c[select by changelist]:changelist:_perforce_changelist -tp' \
+	'-c[select by change]:change:_perforce_changes -tp' \
 	'*::file:_perforce_files -to'
 }
 
@@ -1382,7 +1480,7 @@ _perforce_cmd_obliterate() {
 _perforce_cmd_opened() {
     _arguments -s : \
 	'-a[list for all clients]' \
-	'-c+[select by changelist]:changelist:_perforce_changelist -tp' \
+	'-c+[select by change]:change:_perforce_changes -tp' \
 	'*::file:_perforce_files -to'
 }
 
@@ -1417,7 +1515,7 @@ _perforce_cmd_protect() {
 (( $+functions[_perforce_cmd_reopen] )) ||
 _perforce_cmd_reopen() {
     _arguments -s : \
-	'-c+[select changelist to reopen on]:changelist:_perforce_changelist -tp' \
+	'-c+[select change to reopen on]:change:_perforce_changes -tp' \
 	'-t+[set file type]:file type:_perforce_filetypes' \
 	'*::file:_perforce_files -to'
 }
@@ -1446,7 +1544,7 @@ _perforce_cmd_resolved() {
 _perforce_cmd_revert() {
     _arguments -s : \
 	'-a[revert unaltered files]' \
-	'-c[limit reversions to changelist]:changelist:_perforce_changelist -tp' \
+	'-c[limit reversions to change]:change:_perforce_changes -tp' \
 	'-n[no action, show effect only]' \
 	'*::file:_perforce_files -to'
 }
@@ -1455,7 +1553,7 @@ _perforce_cmd_revert() {
 (( $+functions[_perforce_cmd_review] )) ||
 _perforce_cmd_review() {
     _arguments -s : \
-	'-c[select changelist for counter]:changelist:_perforce_changelist -ts' \
+	'-c[select change for counter]:change:_perforce_changes -ts' \
 	'-t[limit change number by counter]:counter:_perforce_counters'
 }
 
@@ -1463,7 +1561,7 @@ _perforce_cmd_review() {
 (( $+functions[_perforce_cmd_reviews] )) ||
 _perforce_cmd_reviews() {
     _arguments -s : \
-	'-c[show users by changelist]:changelist:_perforce_changelist -ts' \
+	'-c[show users by change]:change:_perforce_changes -ts' \
 	'*::file:_perforce_files'
 }
 
@@ -1483,8 +1581,8 @@ _perforce_cmd_submit() {
     _arguments -s : \
 	'-r[files open for add or edit remain open]' \
 	'-s[include fix status in list]' \
-	'(-s -i)-c[submit specific change]:changelist:_perforce_changelist -tp' \
-	'(-c)-i[read changelist spec from stdin]' \
+	'(-s -i)-c[submit specific change]:change:_perforce_changes -tp' \
+	'(-c)-i[read change spec from stdin]' \
 	'*::file:_perforce_files -to -tr' \
 }
 
@@ -1517,7 +1615,7 @@ _perforce_cmd_typemap() {
 (( $+functions[_perforce_cmd_unlock] )) ||
 _perforce_cmd_unlock() {
     _arguments -s : \
-	'-c[non-default changelist to unlock]:changelist:_perforce_changelist -tp' \
+	'-c[non-default change to unlock]:change:_perforce_changes -tp' \
 	'-f[allow superuser to unlock any file]' \
 	'*::file:_perforce_files'
 }