summaryrefslogtreecommitdiff
path: root/Completion/Unix/Command/_perforce
diff options
context:
space:
mode:
authorPeter Stephenson <pws@users.sourceforge.net>2003-09-22 13:04:37 +0000
committerPeter Stephenson <pws@users.sourceforge.net>2003-09-22 13:04:37 +0000
commitf27036858ae1b2e61b40d0467ba88566dc8863f6 (patch)
treec58b0a7014b992fbb955680271b60046474c7c54 /Completion/Unix/Command/_perforce
parentb598aba3687a07f554ad146771d4338aaa489f2f (diff)
downloadzsh-f27036858ae1b2e61b40d0467ba88566dc8863f6.tar.gz
zsh-f27036858ae1b2e61b40d0467ba88566dc8863f6.zip
19112: several improvements and fixes for Perforce completion
Diffstat (limited to 'Completion/Unix/Command/_perforce')
-rw-r--r--Completion/Unix/Command/_perforce2098
1 files changed, 1109 insertions, 989 deletions
diff --git a/Completion/Unix/Command/_perforce b/Completion/Unix/Command/_perforce
index 6891d6ba6..a76b64f52 100644
--- a/Completion/Unix/Command/_perforce
+++ b/Completion/Unix/Command/_perforce
@@ -33,6 +33,19 @@
# 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.
+# Setting it explicitly to zero removes the maximum. Because you see only
+# the most recent, changes and jobs are shown in the order given by
+# Perforce without further sorting.
+#
+# Completion of jobs can also be controlled by the `jobview' style.
+# This uses the standard Perforce JobView syntax, and is applied
+# in connection with the `max' style. In other words,
+# if you set
+# zstyle ':completion:*:p4-*:jobs' max 0
+# zstyle ':completion:*:p4-*:jobs' jobview 'user=pws'
+# then jobs to be completed will be those from the output of
+# p4 jobs -e 'user=pws'
+# i.e. those assigned to Perforce user `pws'.
#
# The style `all-files' is used to tell the completion system to
# complete any file in a given context. This is for use in places
@@ -69,7 +82,9 @@
# zstyle ':completion:*:p4-*:at-suffix:*' tag-order changes '*'
# will force all completion after `@' to show changes first. Executing
# _next_tags (usually ^x^n) will cycle between that and the remaining
-# tags (dates, labels, clients).
+# tags (dates, labels, clients). I recommend, at least, keeping labels
+# later than changes since the former are less useful and can take a long
+# time to complete.
#
# 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
@@ -197,7 +212,10 @@
# says that the command `p4cvsmap' takes arguments like `p4 files'.
# Often the options will be different; if this is a problem, you
# will need to write your own completer which loads _perforce and
-# calls its functions directly.
+# calls its functions directly. You can add -global to the end
+# of the service to say that the command also handles global
+# Perforce options, comme ca:
+# compdef _perforce p4reopen=p4-job-global
#
# TODO
# ====
@@ -209,106 +227,109 @@
# context `:completion:*:p4[-:]*' should work.
_perforce() {
- # rely on localoptions
- setopt nonomatch
- local p4cmd==p4 match mbegin mend
- integer i
-
- if [[ $service = -value-* ]]; then
- # Completing parameter value.
- # Some of these --- in particular P4PORT --- don't need
- # the perforce server.
- case $compstate[parameter] in
- (P4PORT) _perforce_hosts_ports
- ;;
- (P4CLIENT) _perforce_clients
- ;;
- (P4MERGE) _command_names -e
- ;;
- (P4USER) _users
- ;;
- esac
- # We do not handle values anywhere else.
- return
- fi
-
- if [[ $p4cmd = '=p4' ]]; then
- _message "p4 executable not found: completion not available"
- return
- fi
+ # rely on localoptions
+ setopt nonomatch
+ local p4cmd==p4 match mbegin mend
+ integer _perforce_cmd_ind
+
+ if [[ $service = -value-* ]]; then
+ # Completing parameter value.
+ # Some of these --- in particular P4PORT --- don't need
+ # the perforce server.
+ case $compstate[parameter] in
+ (P4PORT)
+ _perforce_hosts_ports
+ ;;
+
+ (P4CLIENT)
+ _perforce_clients
+ ;;
+
+ (P4MERGE)
+ _command_names -e
+ ;;
+
+ (P4USER)
+ _perforce_users
+ ;;
+ esac
+ # We do not handle values anywhere else.
+ return
+ fi
+
+ if [[ $p4cmd = '=p4' ]]; then
+ _message "p4 executable not found: completion not available"
+ return
+ fi
+
+ # If we are at or after the command word, remember the
+ # global arguments to p4 as we will need to pass these down
+ # when generating completion lists.
+ # This is both an array and a function, but luckily I never
+ # get confused...
+ local -a _perforce_global_options
+ local -a _perforce_option_dispatch
+ _perforce_option_dispatch=(
+ '-c+[client]:client:_perforce_clients' \
+ '-C+[charset]:charset:_perforce_charsets' \
+ '-d+[current directory]:directory:_path_files -g "*(/)"' \
+ '-H+[hostname]:host:_hosts' \
+ '-G[python output]' \
+ '-L+[message language]:language: ' \
+ '-p+[server port]:port:_perforce_hosts_ports' \
+ '-P+[password on server]:password: ' \
+ '-s[output script tags]' \
+ '-u+[user]:user name:_perforce_users' \
+ '-x+[filename or -]:file:_perforce_files_or_minus' \
+ )
+
+ # 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"
+ local p4cmd=$words[1] cmd=$match[1] gbl
- # 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
+ if [[ $cmd = (#b)(*)-global ]]; then
+ # Handles global options.
+ cmd=$match[1]
+ _perforce_global_options && gbl=1
fi
-
- # Options with arguments we need to pass down when calling
- # p4 from completers. There are no options without arguments
- # we need to pass. (Don't pass down -L language since we
- # parse based on English output.)
- local argopts_pass="cCdHpPu"
- # Other options which have arguments but we shouldn't pass down.
- # There are some debugging options, but they tend to get used
- # with the argument in the same word as the option, in which
- # case they will be handled OK anyway.
- local argopts_ignore="Lx"
-
- # If we are at or after the command word, remember the
- # global arguments to p4 as we will need to pass these down
- # when generating completion lists.
- local -a _perforce_global_options
-
- # 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
- # end of the arguments list, anyway.
- for (( i = 2; i < CURRENT; i++ )); do
- if [[ $words[i] = -[$argopts_pass$argopts_ignore] ]]; then
- # word with following argument --- check this
- # is less than the current word, else we are completing
- # this and shouldn't pass it down
- if [[ $(( i + 1 )) -lt $CURRENT && \
- $words[i] = -[$argopts_pass] ]]; then
- _perforce_global_options+=(${words[i,i+1]})
- fi
- (( i++ ))
- elif [[ $words[i] = -[$argopts_pass]* ]]; then
- # word including argument which we want to keep
- _perforce_global_options+=(${words[i]})
- elif [[ $words[i] != -* ]]; then
- break
- fi
- done
-
- if (( i >= CURRENT )); then
- _arguments -s : \
- '-c+[client]:client:_perforce_clients' \
- '-C+[charset]:charset:_perforce_charsets' \
- '-d+[current directory]:directory:_path_files -g "*(/)"' \
- '-H+[hostname]:host:_hosts' \
- '-G[python output]' \
- '-L+[message language]:language: ' \
- '-p+[server port]:port:_perforce_hosts_ports' \
- '-P+[password on server]:password: ' \
- '-s[output script tags]' \
- '-u+[user]:user name:_users' \
- '-x+[filename or -]:file:_perforce_files_or_minus' \
- '1:perforce command:_perforce_commands'
+ if (( $+functions[_perforce_cmd_$cmd] )); then
+ curcontext="${curcontext%:*:*}:p4-${cmd}:"
+ if [[ -n $gbl ]]; then
+ # We are handling global Perforce options as well as the
+ # arguments to the specific command.
+ # To handle the latter, we need the command name, plus
+ # all the arguments for the command with the global options
+ # removed. The function _perforce_service_dispatch handles
+ # this by unshifting the command ($p4cmd) into words,
+ # then dispatching for the Perforce subcommand $cmd.
+ #
+ # Has anyone noticed this is getting rather complicated?
+ _arguments -s : $_perforce_option_dispatch \
+ "*::p4-$cmd arguments: _perforce_service_dispatch $p4cmd $cmd"
+ else
+ _perforce_cmd_$cmd
+ fi
+ # Don't try to do full command handling.
+ return
else
- (( i-- ))
- (( CURRENT -= i ))
- shift $i words
- _perforce_command_args
+ _message "unhandled _perforce service: $service"
+ return 1
fi
+ fi
+
+ if _perforce_global_options; then
+ _arguments -s : $_perforce_option_dispatch \
+ '1:perforce command:_perforce_commands'
+ else
+ (( _perforce_cmd_ind-- ))
+ (( CURRENT -= _perforce_cmd_ind ))
+ shift $_perforce_cmd_ind words
+ _perforce_command_args
+ fi
}
@@ -320,12 +341,12 @@ _perforce() {
# passed to p4.
(( $+functions[_perforce_call_p4] )) ||
_perforce_call_p4() {
- local cp_tag=$1
- shift
- # This is for our own use for parsing, and we need English output,
- # so...
- local +x P4LANGUAGE
- _call_program $cp_tag p4 "${_perforce_global_options[@]}" "$@"
+ local cp_tag=$1
+ shift
+ # This is for our own use for parsing, and we need English output,
+ # so...
+ local +x P4LANGUAGE
+ _call_program $cp_tag p4 "${_perforce_global_options[@]}" "$@"
}
@@ -333,36 +354,46 @@ _perforce_call_p4() {
# only generate it via this function when we need it.
(( $+functions[_perforce_gen_cmd_list] )) ||
_perforce_gen_cmd_list() {
- (( ${+_perforce_cmd_list} )) || typeset -ga _perforce_cmd_list
- local hline
- # Output looks like <tab>command-name<space>description in words...
- # Ignore blank lines and the heading line beginning `Perforce...'
- # Just gets run once, then cached, so don't bother optimising
- # this to a grossly unreadable parameter substitution.
- _perforce_call_p4 help-commands help commands | while read -A hline; do
- (( ${#hline} < 2 )) && continue
- [[ $hline[1] = (#i)perforce ]] && continue
- _perforce_cmd_list+=("${hline[1]}:${hline[2,-1]}")
- done
+ (( ${+_perforce_cmd_list} )) || typeset -ga _perforce_cmd_list
+ local hline
+ # Output looks like <tab>command-name<space>description in words...
+ # Ignore blank lines and the heading line beginning `Perforce...'
+ # Just gets run once, then cached, so don't bother optimising
+ # this to a grossly unreadable parameter substitution.
+ _perforce_call_p4 help-commands help commands | while read -A hline; do
+ (( ${#hline} < 2 )) && continue
+ [[ $hline[1] = (#i)perforce ]] && continue
+ _perforce_cmd_list+=("${hline[1]}:${hline[2,-1]}")
+ done
}
(( $+functions[_perforce_commands] )) ||
_perforce_commands() {
- (( ${#_perforce_cmd_list} )) || _perforce_gen_cmd_list
- _describe -t p4-commands 'Perforce command' _perforce_cmd_list
+ (( ${#_perforce_cmd_list} )) || _perforce_gen_cmd_list
+ _describe -t p4-commands 'Perforce command' _perforce_cmd_list
}
(( $+functions[_perforce_command_args] )) ||
_perforce_command_args() {
- local curcontext="$curcontext" cmd=${words[1]}
- if (( $+functions[_perforce_cmd_$cmd] )); then
- curcontext="${curcontext%:*:*}:p4-${cmd}:"
- _perforce_cmd_$cmd
- else
- _message "unhandled perforce command: $cmd"
- fi
+ local curcontext="$curcontext" cmd=${words[1]}
+ if (( $+functions[_perforce_cmd_$cmd] )); then
+ curcontext="${curcontext%:*:*}:p4-${cmd}:"
+ _perforce_cmd_$cmd
+ else
+ _message "unhandled perforce command: $cmd"
+ fi
+}
+
+
+(( $+functions[_perforce_service_dispatch] )) ||
+_perforce_service_dispatch() {
+ # Put the original command name back, then dispatch for
+ # our Perforce handler.
+ words=($1 "$words[@]")
+ (( CURRENT++ ))
+ _perforce_cmd_$2
}
@@ -370,202 +401,250 @@ _perforce_command_args() {
# Helper functions
#
+(( $+functions[_perforce_global_options] )) ||
+_perforce_global_options() {
+ # Options with arguments we need to pass down when calling
+ # p4 from completers. There are no options without arguments
+ # we need to pass. (Don't pass down -L language since we
+ # parse based on English output.)
+ local argopts_pass="cCdHpPu"
+ # Other options which have arguments but we shouldn't pass down.
+ # There are some debugging options, but they tend to get used
+ # with the argument in the same word as the option, in which
+ # case they will be handled OK anyway.
+ local argopts_ignore="Lx"
+
+ integer i
+
+ # 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
+ # end of the arguments list, anyway.
+ for (( i = 2; i < CURRENT; i++ )); do
+ if [[ $words[i] = -[$argopts_pass$argopts_ignore] ]]; then
+ # word with following argument --- check this
+ # is less than the current word, else we are completing
+ # this and shouldn't pass it down
+ if [[ $(( i + 1 )) -lt $CURRENT && \
+ $words[i] = -[$argopts_pass] ]]; then
+ _perforce_global_options+=(${words[i,i+1]})
+ fi
+ (( i++ ))
+ elif [[ $words[i] = -[$argopts_pass]* ]]; then
+ # word including argument which we want to keep
+ _perforce_global_options+=(${words[i]})
+ elif [[ $words[i] != -* ]]; then
+ break
+ fi
+ done
+
+ (( _perforce_cmd_ind = i ))
+ (( _perforce_cmd_ind >= CURRENT ))
+}
+
(( $+functions[_perforce_branches] )) ||
_perforce_branches() {
- local bline match mbegin mend
- local -a bl
- bl=(${${${(f)"$(_perforce_call_p4 branches branches 2>/dev/null)"}##Branch }/ /:})
- [[ $#bl -eq 1 && $bl[1] = '' ]] && bl=()
- (( $#bl )) && _describe -t branches 'Perforce branch' bl
+ local bline match mbegin mend
+ local -a bl
+ bl=(${${${(f)"$(_perforce_call_p4 branches branches 2>/dev/null)"}##Branch }/ /:})
+ [[ $#bl -eq 1 && $bl[1] = '' ]] && bl=()
+ (( $#bl )) && _describe -t branches 'Perforce branch' bl
}
(( $+functions[_perforce_changes] )) ||
_perforce_changes() {
- local cline match mbegin mend max ctype num comma file
- local -a cl cstatus
-
- zstyle -s ":completion:${curcontext}:" max max
- if [[ ${NUMERIC:-0} -lt 0 && -z $compstate[insert] ]]; then
- # Not inserting (i.e. just listing) and given a negative
- # prefix argument. Instead of listing possible completions,
- # show the full description for the change number on the line at
- # the moment.
- [[ $PREFIX = (|*[^[:digit:]])(#b)(<->) ]] && num+=$match[1]
- [[ $SUFFIX = (#b)(<->)* ]] && num+=$match[1]
- if [[ -n $num ]]; then
- _message -r "$(_perforce_call_p4 describe describe $num)"
- return 0
- fi
- elif [[ ${NUMERIC:-0} -gt 0 ]]; then
- max=$NUMERIC
+ local cline match mbegin mend max ctype num comma file
+ local -a cl cstatus amax
+
+ zstyle -s ":completion:${curcontext}:changes" max max || max=20
+ if [[ ${NUMERIC:-0} -lt 0 && -z $compstate[insert] ]]; then
+ # Not inserting (i.e. just listing) and given a negative
+ # prefix argument. Instead of listing possible completions,
+ # show the full description for the change number on the line at
+ # the moment.
+ [[ $PREFIX = (|*[^[:digit:]])(#b)(<->) ]] && num+=$match[1]
+ [[ $SUFFIX = (#b)(<->)* ]] && num+=$match[1]
+ if [[ -n $num ]]; then
+ _message -r "$(_perforce_call_p4 describe describe $num)"
+ return 0
fi
-
- # Hack: assume the arguments we want are at the end.
- while [[ $argv[-1] = -t? ]]; do
- case $argv[-1] in
- # Change embedded in filename; extract that and remove
- # the corresponding prefix. Remove possible `#'s, too,
- # in case we are looking at a range.
- (-tf) file=${${(Q)PREFIX}%%[\#@]*}
- compset -P '*@'
- ;;
- # Changes already submitted
- (-ts) cstatus=(-s submitted)
- ctype="submitted "
- ;;
- # Changes still pending
- (-tp)
- cstatus=(-s pending)
- ctype="pending "
- ;;
- # Range allowed: append comma and supply rules for
- # removing and handling subsequent `#'.
- (-tR) comma=(-S, -R _perforce_file_suffix)
- esac
- argv=($argv[1,-2])
- done
- # Limit to the 20 most recent changes by default to avoid huge
- # output.
- cl=(
-${${${${(f)"$(_perforce_call_p4 changes changes -m ${max:-20} $cstatus \$file)"}##Change\ }//\ on\ /:}/\ by\ /\ }
+ elif [[ ${NUMERIC:-0} -gt 0 ]]; then
+ max=$NUMERIC
+ fi
+
+ (( max )) && amax=(-m $max)
+
+ # Hack: assume the arguments we want are at the end.
+ while [[ $argv[-1] = -t? ]]; do
+ case $argv[-1] in
+ # Change embedded in filename; extract that and remove
+ # the corresponding prefix. Remove possible `#'s, too,
+ # in case we are looking at a range.
+ (-tf)
+ file=${${(Q)PREFIX}%%[\#@]*}
+ compset -P '*@'
+ ;;
+
+ # Changes already submitted
+ (-ts)
+ cstatus=(-s submitted)
+ ctype="submitted "
+ ;;
+
+ # Changes still pending
+ (-tp)
+ cstatus=(-s pending)
+ ctype="pending "
+ ;;
+
+ # Range allowed: append comma and supply rules for
+ # removing and handling subsequent `#'.
+ (-tR)
+ comma=(-S, -R _perforce_file_suffix)
+ esac
+ argv=($argv[1,-2])
+ done
+ # Limit to the 20 most recent changes by default to avoid huge
+ # output.
+ cl=(
+${${${${(f)"$(_perforce_call_p4 changes changes $amax $cstatus \$file)"}##Change\ }//\ on\ /:}/\ by\ /\ }
"default:change not yet numbered")
- [[ $#cl -eq 1 && $cl[1] = '' ]] && cl=()
- _describe -t changes "${ctype}change" cl $comma
+ [[ $#cl -eq 1 && $cl[1] = '' ]] && cl=()
+ _describe -t changes "${ctype}change" cl -V changes-unsorted $comma
}
(( $+functions[_perforce_charsets] )) ||
_perforce_charsets() {
- local expl
- _wanted charset expl 'character set' \
- compadd eucjp iso8859-1 shiftjis utf8 winansi
+ local expl
+ _wanted charset expl 'character set' \
+ compadd eucjp iso8859-1 shiftjis utf8 winansi
}
(( $+functions[_perforce_clients] )) ||
_perforce_clients() {
- local cline match mbegin mend
- local -a slash cl
+ local -a slash cl
- # Are we completing after an @, or a client view in a filespec?
- if ! compset -P '*@'; then
- compset -P '//' && slash=(-S/ -q)
- fi
+ # Are we completing after an @, or a client view in a filespec?
+ if ! compset -P '*@'; then
+ compset -P '//' && slash=(-S/ -q)
+ fi
- cl=(${${${(f)"$(_perforce_call_p4 clients clients)"}##Client\ }/\ /:})
- [[ $#cl -eq 1 && $cl[1] = '' ]] && cl=()
- _describe -t clients 'Perforce client' cl $slash
+ cl=(${${${(f)"$(_perforce_call_p4 clients clients)"}##Client\ }/\ /:})
+ [[ $#cl -eq 1 && $cl[1] = '' ]] && cl=()
+ _describe -t clients 'Perforce client' cl $slash
}
(( $+functions[_perforce_counters] )) ||
_perforce_counters() {
- local cline match mbegin mend
- local -a cl
+ local cline match mbegin mend
+ local -a cl
- cl=(${${${(f)"$(_perforce_call_p4 counters counters)"}/\ /:}/\=/current value})
- [[ $#cl -eq 1 && $cl[1] = '' ]] && cl=()
- _describe -t counters 'Perforce counter' cl
+ cl=(${${${(f)"$(_perforce_call_p4 counters counters)"}/\ /:}/\=/current value})
+ [[ $#cl -eq 1 && $cl[1] = '' ]] && cl=()
+ _describe -t counters 'Perforce counter' cl
}
(( $+functions[_perforce_counter_values] )) ||
_perforce_counter_values() {
- if [[ -n $words[CURRENT-1] ]]; then
- local value="$(_perforce_call_p4 counter counter $words[CURRENT-1] 2>/dev/null)"
- if [[ -n $value ]]; then
- # No space. This allows stuff like incarg and decarg.
- compstate[insert]=1
- _wanted value expl 'counter value' compadd $value
- fi
+ if [[ -n $words[CURRENT-1] ]]; then
+ local value="$(_perforce_call_p4 counter counter $words[CURRENT-1] 2>/dev/null)"
+ if [[ -n $value ]]; then
+ # No space. This allows stuff like incarg and decarg.
+ compstate[insert]=1
+ _wanted value expl 'counter value' compadd $value
fi
+ fi
}
(( $+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
+ # 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
+ _describe -t dates $name offer $opts
}
(( $+functions[_perforce_depots] )) ||
_perforce_depots() {
- local dline match mbegin mend max
- local -a dl
+ local dline match mbegin mend
+ local -a dl
- dl=(${${${(f)"$(_perforce_call_p4 depots depots)"}##Depot\ }/\ /:})
- [[ $#dl -eq 1 && $dl[1] = '' ]] && dl=()
- _describe -t depots 'depot name' dl
+ dl=(${${${(f)"$(_perforce_call_p4 depots depots)"}##Depot\ }/\ /:})
+ [[ $#dl -eq 1 && $dl[1] = '' ]] && dl=()
+ _describe -t depots 'depot name' dl
}
(( $+functions[_perforce_files_or_minus] )) ||
_perforce_files_or_minus() {
- _alternative 'minus:minus sign:(-)' 'files:file name:_files'
+ _alternative 'minus:minus sign:(-)' 'files:file name:_files'
}
(( $+functions[_perforce_file_suffix] )) ||
_perforce_file_suffix() {
- # Used with compadd -R to handle @ or # after a file name.
- # Differs from compadd -r '...' in that it quotes `#' if typed.
- [[ $1 = 1 ]] || return
-
- if [[ $LBUFFER[-1] = [\ ,] ]]; then
- if [[ $KEYS = '#' ]]; then
- if [[ $LBUFFER[-1] = , ]]; then
- # Range: no suffix removal but add a backslash
- LBUFFER+=\\
- else
- # Suffix removal with an added backslash
- LBUFFER="$LBUFFER[1,-2]\\"
- fi
- elif [[ $KEYS = (*[^[:print:]]*|[[:blank:]\;\&\|]) || \
- ( $KEYS = @ && $LBUFFER[-1] = ' ' ) ]] ; then
- # Normal suffix removal
- LBUFFER="$LBUFFER[1,-2]"
- fi
- elif [[ $LBUFFER[-1] = / ]]; then
- # Normal suffix removal for directories.
- if [[ $KEYS = (*[^[:print:]]*|[[:blank:]\;\&\|/]) ]]; then
- LBUFFER="$LBUFFER[1,-2]"
- fi
+ # Used with compadd -R to handle @ or # after a file name.
+ # Differs from compadd -r '...' in that it quotes `#' if typed.
+ [[ $1 = 1 ]] || return
+
+ if [[ $LBUFFER[-1] = [\ ,] ]]; then
+ if [[ $KEYS = '#' ]]; then
+ if [[ $LBUFFER[-1] = , ]]; then
+ # Range: no suffix removal but add a backslash
+ LBUFFER+=\\
+ else
+ # Suffix removal with an added backslash
+ LBUFFER="$LBUFFER[1,-2]\\"
+ fi
+ elif [[ $KEYS = (*[^[:print:]]*|[[:blank:]\;\&\|]) || \
+ ( $KEYS = @ && $LBUFFER[-1] = ' ' ) ]] ; then
+ # Normal suffix removal
+ LBUFFER="$LBUFFER[1,-2]"
+ fi
+ elif [[ $LBUFFER[-1] = / ]]; then
+ # Normal suffix removal for directories.
+ if [[ $KEYS = (*[^[:print:]]*|[[:blank:]\;\&\|/]) ]]; then
+ LBUFFER="$LBUFFER[1,-2]"
fi
+ fi
}
@@ -577,297 +656,315 @@ _perforce_file_suffix() {
(( $+functions[_perforce_integrated_files] )) ||
_perforce_integrated_files() {
- local pfx=${(Q)PREFIX} type
- local -a files
+ local pfx=${(Q)PREFIX} type
+ local -a files
- compset -P '*/'
- files=(${${${(f)"$(_perforce_call_p4 integrated integrated \"\$pfx\*\$\{\(Q\)SUFFIX\}\" 2>/dev/null)"}%\#*}##*/})
- [[ $#files -eq 1 && $files[1] = '' ]] && files=()
- compadd "$@" -a files
+ compset -P '*/'
+ files=(${${${(f)"$(_perforce_call_p4 integrated integrated \"\$pfx\*\$\{\(Q\)SUFFIX\}\" 2>/dev/null)"}%\#*}##*/})
+ [[ $#files -eq 1 && $files[1] = '' ]] && files=()
+ compadd "$@" -a files
}
(( $+functions[_perforce_opened_files] )) ||
_perforce_opened_files() {
- local pfx=${(Q)PREFIX} type
- local -a files
+ local pfx=${(Q)PREFIX} type
+ local -a files
- compset -P '*/'
- files=(${${${(f)"$(_perforce_call_p4 opened opened \"\$pfx\*\$\{\(Q\)SUFFIX\}\" 2>/dev/null)"}%\#*}##*/})
- [[ $#files -eq 1 && $files[1] = '' ]] && files=()
- compadd "$@" -a files
+ compset -P '*/'
+ files=(${${${(f)"$(_perforce_call_p4 opened opened \"\$pfx\*\$\{\(Q\)SUFFIX\}\" 2>/dev/null)"}%\#*}##*/})
+ [[ $#files -eq 1 && $files[1] = '' ]] && files=()
+ compadd "$@" -a files
}
(( $+functions[_perforce_resolved_files] )) ||
_perforce_resolved_files() {
- local pfx=${(Q)PREFIX} type
- local -a files
+ local pfx=${(Q)PREFIX} type
+ local -a files
- compset -P '*/'
- files=(${${${(f)"$(_perfroce_call_p4 resolved resolved \"\$pfx\*\$\{\(Q\)SUFFIX\}\" 2>/dev/null)"}%\#*}##*/})
- [[ $#files -eq 1 && $files[1] = '' ]] && files=()
- compadd "$@" -a files
+ compset -P '*/'
+ files=(${${${(f)"$(_perfroce_call_p4 resolved resolved \"\$pfx\*\$\{\(Q\)SUFFIX\}\" 2>/dev/null)"}%\#*}##*/})
+ [[ $#files -eq 1 && $files[1] = '' ]] && files=()
+ compadd "$@" -a files
}
(( $+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.
- compset -P '*/'
- compadd "$@" '...'
+ # This has no other function than to offer to add the `...' used
+ # by Perforce to indicate a recursive search of directories.
+ # Bit pathetic, really.
+ compset -P '*/'
+ compadd "$@" '...'
}
(( $+functions[_perforce_depot_dirs] )) ||
_perforce_depot_dirs() {
- # Normal completion of directories in depots
- local pfx=${(Q)PREFIX} expl
- local -a files
+ # Normal completion of directories in depots
+ local pfx=${(Q)PREFIX} expl
+ local -a files
- compset -P '*/'
- files=(${"${(f)$(_perforce_call_p4 dirs dirs \"\$pfx\*\$\{\(Q\)SUFFIX\}\" 2>/dev/null)}"##*/})
- [[ $#files -eq 1 && $files[1] = '' ]] && files=()
- compadd "$@" -S / -q -a files
+ compset -P '*/'
+ files=(${"${(f)$(_perforce_call_p4 dirs dirs \"\$pfx\*\$\{\(Q\)SUFFIX\}\" 2>/dev/null)}"##*/})
+ [[ $#files -eq 1 && $files[1] = '' ]] && files=()
+ compadd "$@" -S / -q -a files
}
(( $+functions[_perforce_depot_files] )) ||
_perforce_depot_files() {
- # Normal completion of files in depots
- local pfx=${(Q)PREFIX} expl
- local -a files
+ # Normal completion of files in depots
+ local pfx=${(Q)PREFIX} expl
+ local -a files
- compset -P '*/'
- files=(${${${(f)"$(_perforce_call_p4 files files \"\$pfx\*\$\{\(Q\)SUFFIX\}\" 2>/dev/null)"}%\#*}##*/})
- [[ $#files -eq 1 && $files[1] = '' ]] && files=()
- compadd "$@" -R _perforce_file_suffix -a files
+ compset -P '*/'
+ files=(${${${(f)"$(_perforce_call_p4 files files \"\$pfx\*\$\{\(Q\)SUFFIX\}\" 2>/dev/null)"}%\#*}##*/})
+ [[ $#files -eq 1 && $files[1] = '' ]] && files=()
+ compadd "$@" -R _perforce_file_suffix -a files
}
(( $+functions[_perforce_client_dirs] )) ||
_perforce_client_dirs() {
- # This is a slightly odd addition which isn't often necessary.
- # When completing directories in a client specification, Perforce
- # doesn't tell you about intermediate directories which are in
- # the client, but not in the depot. (Well... sometimes. I've
- # had some odd results with this. I suspect there may be a bug
- # but I don't really know enough to be sure.)
- #
- # For example, if my view contains
- # //depot/branches/rev1.2/... //pws_client/branches/rev1.2/...
- # then `p4 dirs "//pws_client/*"' won't mention the `branches'
- # directory because the view actually starts lower down. So
- # we add it by hand when necessary.
- #
- # We don't want to waste time on this, since it's not the usual
- # case, so we cache the results where necessary. This means
- # recording all the clients that we can later ask about if necessary.
- # To flush the cache, `unset _perforce_client_list _perforce_client_dirs'.
- if (( ! ${+_perforce_client_list} )); then
- # Retrieve the list of clients.
- typeset -gA _perforce_client_list
- local -a tmplist
- local tmpelt
- tmplist=(${${${(f)"$(_perforce_call_p4 clients clients)"}##Client\ }%%\ *})
- [[ $#tmplist -eq 1 && $tmplist[1] = '' ]] && tmplist=()
- for tmpelt in $tmplist; do
- _perforce_client_list[$tmpelt]=1
- done
- fi
-
- # See if the first path element is a client. Very often it
- # will actually be a depot, so we test this as quickly as possible.
- local client=${${PREFIX##//}%%/*}
- [[ -z ${_perforce_client_list[$client]} ]] && return 1
-
- local oldifs=$IFS IFS= type dir line dirs
-
- (( ${+_perforce_client_dirs} )) || typeset -gA _perforce_client_dirs
-
- if (( ${+_perforce_client_dirs[$client]} )); then
- # Already cached, although may be empty.
- dirs=${_perforce_client_dirs[$client]}
- else
- # We need to look at the View stanza of the client record
- # to see what directories exist in the client view.
- _perforce_call_p4 client "client -o $client" 2>/dev/null | while read line; do
- case $line in
- ([[:blank:]]##) type=
- ;;
- ((#b)([[:alpha:]]##):*) type=${match[1]}
- ;;
- (*) if [[ $type = View ]]; then
- dir=${${line##[[:blank:]]##//*[[:blank:]]//$client}%%/...(/*|)}
- if [[ $#dir -gt 1 ]]; then
- dirs+="${dirs:+ }${(q)dir##/}"
- fi
- fi
- ;;
- esac
- done
- fi
-
- (( ${#dirs} )) || return 1
-
- # Turn our string of space-separated backquoted elements into an array.
- dirs=(${(z)dirs})
- # Get the current prefix also as an array of elements
- compset -P '//[^/]##/'
- pfx=(${(s./.)${(Q)PREFIX}})
-
- local -a ndirs
- local match mbegin mend
- # Check matching path segments
- while (( ${#pfx} > 1 )); do
- ndirs=()
- for dir in $dirs; do
- if [[ $dir = $pfx/(#b)(*) ]]; then
- ndirs+=($match[1])
- fi
- done
- (( ${#ndirs} )) || return 1
- dirs=($ndirs)
- shift pfx
- compset -P '[^/]'
+ # This is a slightly odd addition which isn't often necessary.
+ # When completing directories in a client specification, Perforce
+ # doesn't tell you about intermediate directories which are in
+ # the client, but not in the depot. (Well... sometimes. I've
+ # had some odd results with this. I suspect there may be a bug
+ # but I don't really know enough to be sure.)
+ #
+ # For example, if my view contains
+ # //depot/branches/rev1.2/... //pws_client/branches/rev1.2/...
+ # then `p4 dirs "//pws_client/*"' won't mention the `branches'
+ # directory because the view actually starts lower down. So
+ # we add it by hand when necessary.
+ #
+ # We don't want to waste time on this, since it's not the usual
+ # case, so we cache the results where necessary. This means
+ # recording all the clients that we can later ask about if necessary.
+ # To flush the cache, `unset _perforce_client_list _perforce_client_dirs'.
+ if (( ! ${+_perforce_client_list} )); then
+ # Retrieve the list of clients.
+ typeset -gA _perforce_client_list
+ local -a tmplist
+ local tmpelt
+ tmplist=(${${${(f)"$(_perforce_call_p4 clients clients)"}##Client\ }%%\ *})
+ [[ $#tmplist -eq 1 && $tmplist[1] = '' ]] && tmplist=()
+ for tmpelt in $tmplist; do
+ _perforce_client_list[$tmpelt]=1
+ done
+ fi
+
+ # See if the first path element is a client. Very often it
+ # will actually be a depot, so we test this as quickly as possible.
+ local client=${${PREFIX##//}%%/*}
+ [[ -z ${_perforce_client_list[$client]} ]] && return 1
+
+ local oldifs=$IFS IFS= type dir line dirs
+
+ (( ${+_perforce_client_dirs} )) || typeset -gA _perforce_client_dirs
+
+ if (( ${+_perforce_client_dirs[$client]} )); then
+ # Already cached, although may be empty.
+ dirs=${_perforce_client_dirs[$client]}
+ else
+ # We need to look at the View stanza of the client record
+ # to see what directories exist in the client view.
+ _perforce_call_p4 client "client -o $client" 2>/dev/null | while read line
+ do
+ case $line in
+ ([[:blank:]]##)
+ type=
+ ;;
+
+ ((#b)([[:alpha:]]##):*)
+ type=${match[1]}
+ ;;
+
+ (*)
+ if [[ $type = View ]]; then
+ dir=${${line##[[:blank:]]##//*[[:blank:]]//$client}%%/...(/*|)}
+ if [[ $#dir -gt 1 ]]; then
+ dirs+="${dirs:+ }${(q)dir##/}"
+ fi
+ fi
+ ;;
+ esac
done
- compadd -S / -q "$@" -- ${dirs%%/*}
+ fi
+
+ (( ${#dirs} )) || return 1
+
+ # Turn our string of space-separated backquoted elements into an array.
+ dirs=(${(z)dirs})
+ # Get the current prefix also as an array of elements
+ compset -P '//[^/]##/'
+ pfx=(${(s./.)${(Q)PREFIX}})
+
+ local -a ndirs
+ local match mbegin mend
+ # Check matching path segments
+ while (( ${#pfx} > 1 )); do
+ ndirs=()
+ for dir in $dirs; do
+ if [[ $dir = $pfx/(#b)(*) ]]; then
+ ndirs+=($match[1])
+ fi
+ done
+ (( ${#ndirs} )) || return 1
+ dirs=($ndirs)
+ shift pfx
+ compset -P '[^/]'
+ done
+ compadd -S / -q "$@" -- ${dirs%%/*}
}
(( $+functions[_perforce_files] )) ||
_perforce_files() {
- local pfx fline expl opt match mbegin mend range type
- local -a files types
-
- local dodirs unmaintained
- # Suffix operations can modify context
- local curcontext="$curcontext"
-
- while (( $# )); do
- if [[ $1 = -t(#b)(?) ]]; then
- case $match[1] in
- (d) dodirs=-/
- ;;
- (u) unmaintained=1
- ;;
- (i) types+=(integrated)
- ;;
- (o) types+=(opened)
- ;;
- (r) types+=(resolved)
- ;;
- (R) range="-tR"
- ;;
- esac
- fi
- shift
- done
-
- # Remove the quotes present in the word on the command line,
- # since we will treat this as a literal string from now on.
- # We might get into problems with characters recognised as
- # 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 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 \
- "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 suffix.
- curcontext="${curcontext%:*}:hash-suffix"
- # Check for existing range syntax
- [[ $PREFIX = *[@\#]*,* ]] && range=
- # Remove longest possible tail match to get name --- this
- # automatically handles filenames in ranges e.g. `foo#1,#3'.
- # (Note the compset removes the maximum possible head match,
- # so we only complete the second part of the range in that case.)
- _perforce_revisions $range
- elif [[ $PREFIX = //* ]]; then
- # This specifies files already handled by Perforce, so there's
- # no point trying to look for unmaintained files. Assume
- # the user knows what they're doing.
- local -a altfiles
-
- if [[ $PREFIX = //[^/]# ]]; then
- # Complete //clientname spec. Don't complete non-directories...
- # I don't actually know if they are valid here.
- altfiles+=("clients:Perforce client:_perforce_clients")
+ local pfx fline expl opt match mbegin mend range type
+ local -a files types
+
+ local dodirs unmaintained
+ # Suffix operations can modify context
+ local curcontext="$curcontext"
+
+ while (( $# )); do
+ if [[ $1 = -t(#b)(?) ]]; then
+ case $match[1] in
+ (d)
+ dodirs=-/
+ ;;
+
+ (u)
+ unmaintained=1
+ ;;
+
+ (i)
+ types+=(integrated)
+ ;;
+
+ (o)
+ types+=(opened)
+ ;;
+
+ (r)
+ types+=(resolved)
+ ;;
+
+ (R)
+ range="-tR"
+ ;;
+ esac
+ fi
+ shift
+ done
+
+ # Remove the quotes present in the word on the command line,
+ # since we will treat this as a literal string from now on.
+ # We might get into problems with characters recognised as
+ # 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 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 \
+ "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 suffix.
+ curcontext="${curcontext%:*}:hash-suffix"
+ # Check for existing range syntax
+ [[ $PREFIX = *[@\#]*,* ]] && range=
+ # Remove longest possible tail match to get name --- this
+ # automatically handles filenames in ranges e.g. `foo#1,#3'.
+ # (Note the compset removes the maximum possible head match,
+ # so we only complete the second part of the range in that case.)
+ _perforce_revisions $range
+ elif [[ $PREFIX = //* ]]; then
+ # This specifies files already handled by Perforce, so there's
+ # no point trying to look for unmaintained files. Assume
+ # the user knows what they're doing.
+ local -a altfiles
+
+ if [[ $PREFIX = //[^/]# ]]; then
+ # Complete //clientname spec. Don't complete non-directories...
+ # I don't actually know if they are valid here.
+ altfiles+=("clients:Perforce client:_perforce_clients")
+ else
+ local donefiles=1
+ if [[ -z $dodirs ]]; then
+ if [[ ${#types} -gt 0 ]] &&
+ ! zstyle -t ":completion:${curcontext}:" all-files; then
+ for type in $types; do
+ altfiles+=("$type-files:$type file:_perforce_${type}_files")
+ done
else
- local donefiles=1
- if [[ -z $dodirs ]]; then
- if [[ ${#types} -gt 0 ]] &&
- ! zstyle -t ":completion:${curcontext}:" all-files; then
- for type in $types; do
- altfiles+=("$type-files:$type file:_perforce_${type}_files")
- done
- else
- altfiles+=("depot-files:file in depot:_perforce_depot_files")
- fi
- fi
- # Intermediate directories in a client view.
- # See function for notes.
- altfiles+=("client-dirs:client directory:_perforce_client_dirs")
+ altfiles+=("depot-files:file in depot:_perforce_depot_files")
fi
- altfiles+=("depot-dirs:directory in depot:_perforce_depot_dirs"
- "subdirs:subdirectory search:_perforce_subdirs")
- _alternative $altfiles
- elif [[ -n $unmaintained && -z $dodirs ]]; then
- # a la _cvs_nonentried_files: directories are never maintained,
- # so skip 'em. Unmaintained files can't be integrated, opened
- # or resolved, so treat as exclusive (just as well, since
- # this bit's messy).
- local MATCH MBEGIN MEND
- local -a omitpats
-
- match=()
- : ${PREFIX:#(#b)(*/)(*)}
- pfx="$match[1]"
- pfx=${(e)~pfx}
- omitpats=(
- ${${${${(f)"$(_perforce_call_p4 files files \"\$pfx\*\$\{\(Q\)SUFFIX\}\" 2>/dev/null)"}%\#*}##*/}//(#m)[][*?()<|^~#\\]/\\$MATCH}
+ fi
+ # Intermediate directories in a client view.
+ # See function for notes.
+ altfiles+=("client-dirs:client directory:_perforce_client_dirs")
+ fi
+ altfiles+=("depot-dirs:directory in depot:_perforce_depot_dirs"
+ "subdirs:subdirectory search:_perforce_subdirs")
+ _alternative $altfiles
+ elif [[ -n $unmaintained && -z $dodirs ]]; then
+ # a la _cvs_nonentried_files: directories are never maintained,
+ # so skip 'em. Unmaintained files can't be integrated, opened
+ # or resolved, so treat as exclusive (just as well, since
+ # this bit's messy).
+ local MATCH MBEGIN MEND
+ local -a omitpats
+
+ match=()
+ : ${PREFIX:#(#b)(*/)(*)}
+ pfx="$match[1]"
+ pfx=${(e)~pfx}
+ omitpats=(
+ ${${${${(f)"$(_perforce_call_p4 files files \"\$pfx\*\$\{\(Q\)SUFFIX\}\" 2>/dev/null)"}%\#*}##*/}//(#m)[][*?()<|^~#\\]/\\$MATCH}
)
- [[ $#omitpats -eq 1 && $omitpats[1] = '' ]] && omitpats=()
- if (( ${#omitpats} )); then
- _path_files -g "*~(*/|)(${(j:|:)~omitpats})(D.)"
- else
- _path_files
- fi
- # Don't handle suffixes for non-entried files
- elif (( ${#types} )) && ! zstyle -t ":completion:${curcontext}:" all-files
+ [[ $#omitpats -eq 1 && $omitpats[1] = '' ]] && omitpats=()
+ if (( ${#omitpats} )); then
+ _path_files -g "*~(*/|)(${(j:|:)~omitpats})(D.)"
+ else
+ _path_files
+ fi
+ # Don't handle suffixes for non-entried files
+ elif (( ${#types} )) && ! zstyle -t ":completion:${curcontext}:" all-files
then
- local -a altfiles
+ local -a altfiles
- for type in $types; do
- altfiles+=("$type-files:$type file:_perforce_${type}_files")
- done
-
- altfiles+=("depot-dirs:directory in depot:_perforce_depot_dirs"
- "subdirs:subdirectory search:_perforce_subdirs")
- _alternative $altfiles
- elif zstyle -t ":completion:${curcontext}:" depot-files; then
- local -a altfiles
- if [[ -z $dodirs ]]; then
- altfiles+=("depot-files:file in depot:_perforce_depot_files")
- fi
- altfiles+=("depot-dirs:directory in depot:_perforce_depot_dirs"
- "subdirs:subdirectory search:_perforce_subdirs")
- _alternative $altfiles
- else
- # Look locally.
- _alternative \
- "files:file:_path_files -R _perforce_file_suffix $dodirs" \
- "subdirs:subdirectory search:_perforce_subdirs"
+ for type in $types; do
+ altfiles+=("$type-files:$type file:_perforce_${type}_files")
+ done
+
+ altfiles+=("depot-dirs:directory in depot:_perforce_depot_dirs"
+ "subdirs:subdirectory search:_perforce_subdirs"
+ "directories:directory:_path_files -/")
+ _alternative $altfiles
+ elif zstyle -t ":completion:${curcontext}:" depot-files; then
+ local -a altfiles
+ if [[ -z $dodirs ]]; then
+ altfiles+=("depot-files:file in depot:_perforce_depot_files")
fi
+ altfiles+=("depot-dirs:directory in depot:_perforce_depot_dirs"
+ "subdirs:subdirectory search:_perforce_subdirs")
+ _alternative $altfiles
+ else
+ # Look locally.
+ _alternative \
+ "files:file:_path_files -R _perforce_file_suffix $dodirs" \
+ "subdirs:subdirectory search:_perforce_subdirs"
+ fi
}
@@ -877,154 +974,166 @@ _perforce_files() {
(( $+functions[_perforce_filetypes] )) ||
_perforce_filetypes() {
- local -a values
- if compset -P '*+*'; then
- # That second `*' is deliberate --- only complete the last
- # letter since we can have a whole string of them.
- values=(
- "m:always set modtime on client"
- "w:always writeable on client"
- "x:set exec bit on client"
- "k:full RCS keyword expansion"
- "k:RCS expansion only for Id, Header"
- "l:exclusive open, disallow multiple opens"
- "C:server stores compress file per revision"
- "D:server stores deltas in RCS format"
- "F:server stores full file per revision"
- "S:server stores only head revision")
- _describe -t file-modifiers 'Perforce file modifier' values
- else
- values=(
- "text:text, translate newlines"
- "binary:raw bytes"
- "symlink:symbolic link"
- "apple:Mac resource + data"
- "unicode:text, translate newlines, store as UTF-8")
- _describe -t file-types 'Perforce file type' values -S+ -q
- fi
+ local -a values
+ if compset -P '*+*'; then
+ # That second `*' is deliberate --- only complete the last
+ # letter since we can have a whole string of them.
+ values=(
+ "m:always set modtime on client"
+ "w:always writeable on client"
+ "x:set exec bit on client"
+ "k:full RCS keyword expansion"
+ "k:RCS expansion only for Id, Header"
+ "l:exclusive open, disallow multiple opens"
+ "C:server stores compress file per revision"
+ "D:server stores deltas in RCS format"
+ "F:server stores full file per revision"
+ "S:server stores only head revision")
+ _describe -t file-modifiers 'Perforce file modifier' values
+ else
+ values=(
+ "text:text, translate newlines"
+ "binary:raw bytes"
+ "symlink:symbolic link"
+ "apple:Mac resource + data"
+ "unicode:text, translate newlines, store as UTF-8")
+ _describe -t file-types 'Perforce file type' values -S+ -q
+ fi
}
(( $+functions[_perforce_groups] )) ||
_perforce_groups() {
- _describe -t groups 'Perforce group' $(_perforce_call_p4 groups groups)
+ _describe -t groups 'Perforce group' $(_perforce_call_p4 groups groups)
}
(( $+functions[_perforce_hosts_ports] )) ||
_perforce_hosts_ports() {
- if compset -P '*:'; then
- _ports
- local expl
- _wanted ports expl port compadd "$@" 1666
- else
- # is this -q-able?
- _hosts -S :
- fi
+ if compset -P '*:'; then
+ _ports
+ local expl
+ _wanted ports expl port compadd "$@" 1666
+ else
+ # is this -q-able?
+ _hosts -S :
+ fi
}
(( $+functions[_perforce_jobs] )) ||
_perforce_jobs() {
- local jline match mbegin mend max
- local -a jl
-
- zstyle -s ":completion:${curcontext}:" max max
- if [[ ${NUMERIC:-0} -lt 0 && -z $compstate[insert] ]]; then
- # Not inserting (i.e. just listing) and given a negative
- # prefix argument. Instead of listing possible completions,
- # show the full description for the job which is on the line at
- # the moment.
- _message -r "$(_perforce_call_p4 jobs jobs -e \"Job=\$PREFIX\$SUFFIX\" -l 2>/dev/null)"
- return 0
- elif [[ ${NUMERIC:-0} -gt 0 ]]; then
- max=$NUMERIC
+ local jline match mbegin mend max jobview
+ local -a jl amax ajobview
+
+ zstyle -s ":completion:${curcontext}:jobs" max max || max=20
+ zstyle -s ":completion:${curcontext}:jobs" jobview jobview &&
+ ajobview=(-e $jobview)
+ if [[ ${NUMERIC:-0} -lt 0 && -z $compstate[insert] ]]; then
+ # Not inserting (i.e. just listing) and given a negative
+ # prefix argument. Instead of listing possible completions,
+ # show the full description for the job which is on the line at
+ # the moment.
+ _message -r "$(_perforce_call_p4 jobs jobs -e \"Job=\$PREFIX\$SUFFIX\" -l 2>/dev/null)"
+ return 0
+ elif [[ ${NUMERIC:-0} -gt 0 ]]; then
+ max=$NUMERIC
+ fi
+
+ (( max )) && amax=(-m $max)
+
+ _perforce_call_p4 jobs jobs $ajobview $amax | while read jline; do
+ if [[ $jline = (#b)([^[:blank:]]##)' '[^[:blank:]]##' '(*) ]]; then
+ jl+=("${match[1]}:${match[2]}")
fi
-
- _perforce_call_p4 jobs jobs -m ${max:-20} | while read jline; do
- if [[ $jline = (#b)([^[:blank:]]##)' '[^[:blank:]]##' '(*) ]]; then
- jl+=("${match[1]}:${match[2]}")
- fi
- done
- _describe -t jobs 'Perforce job' jl
+ done
+ _describe -t jobs 'Perforce job' jl -V jobs-unsorted
}
(( $+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
- # by various logical operators. The `=' could be a comparison,
- # but we don't currently bother with that here; it's a bit cumbersome
- # to complete.
- local line type oldifs=$IFS IFS= key value slash=/
- local match mbegin mend
- # This is simply to split out two space-delimited words a backreferences.
- local m2words
- m2words='(#b)[[:blank:]]##([[:alnum:]]##)[[:blank:]]##([^[:blank:]]##)'
-
- local -a valuespec
- local -A p4fields p4values
-
- # All the characters which can separate multiple match attempts.
- # Ignore up to the last one. We don't try to complete these.
- compset -P '*[[:blank:]\^\&\|\(\)]'
-
- # According to the manual, `p4 jobspec' requires admin privileges.
- # If this is true even of `p4 jobspec -o', we are a bit screwed.
- _perforce_call_p4 jobspec jobspec -o 2>/dev/null | while read line; do
- case $line in
- ([[:blank:]]##) type=
- ;;
- ((#b)([[:alpha:]]##):*) type=${match[1]}
- ;;
- (*) case $type in
- # This stanza tells us all the allowed fields.
- (Fields) if [[ $line = [[:blank:]]##<->${~m2words}* ]]
- then
- p4fields[${(L)match[1]}]=${match[2]}
- fi
- ;;
- # This stanza gives allowed values for the `select' types.
- (Values) if [[ $line = ${~m2words}* ]]; then
- p4values[${(L)match[1]}]=${match[2]}
- fi
- ;;
- esac
- ;;
- esac
- done
-
- IFS=$oldifs
+ # 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
+ # by various logical operators. The `=' could be a comparison,
+ # but we don't currently bother with that here; it's a bit cumbersome
+ # to complete.
+ local line type oldifs=$IFS IFS= key value slash=/
+ local match mbegin mend
+ # This is simply to split out two space-delimited words a backreferences.
+ local m2words
+ m2words='(#b)[[:blank:]]##([[:alnum:]]##)[[:blank:]]##([^[:blank:]]##)'
+
+ local -a valuespec
+ local -A p4fields p4values
+
+ # All the characters which can separate multiple match attempts.
+ # Ignore up to the last one. We don't try to complete these.
+ compset -P '*[[:blank:]\^\&\|\(\)]'
+
+ # According to the manual, `p4 jobspec' requires admin privileges.
+ # If this is true even of `p4 jobspec -o', we are a bit screwed.
+ _perforce_call_p4 jobspec jobspec -o 2>/dev/null | while read line; do
+ case $line in
+ ([[:blank:]]##)
+ type=
+ ;;
+
+ ((#b)([[:alpha:]]##):*)
+ type=${match[1]}
+ ;;
+
+ (*)
+ case $type in
+ # This stanza tells us all the allowed fields.
+ (Fields)
+ if [[ $line = [[:blank:]]##<->${~m2words}* ]]; then
+ p4fields[${(L)match[1]}]=${match[2]}
+ fi
+ ;;
- if (( ! ${#p4fields} )); then
- # We didn't get anything; add the defaults.
- p4fields=(
- date date
- description text
- job word
- status select
- user word
- )
- p4values=(
+ # This stanza gives allowed values for the `select' types.
+ (Values)
+ if [[ $line = ${~m2words}* ]]; then
+ p4values[${(L)match[1]}]=${match[2]}
+ fi
+ ;;
+ esac
+
+ ;;
+ esac
+ done
+
+ IFS=$oldifs
+
+ if (( ! ${#p4fields} )); then
+ # We didn't get anything; add the defaults.
+ p4fields=(
+ date date
+ description text
+ job word
+ status select
+ user word
+ )
+ p4values=(
status open/suspended/closed
)
+ fi
+
+ for key in ${(k)p4fields}; do
+ if [[ -n ${p4values[$key]} ]]; then
+ valuespec+=("${key}:${p4fields[$key]}:(${p4values[$key]//$slash/ })")
+ elif [[ $key = job ]]; then
+ # Nothing special for jobs; add our own completion.
+ valuespec+=("${key}:Perforce job:_perforce_jobs")
+ elif [[ $key = user ]]; then
+ # Nothing provided for user; add our own completion.
+ valuespec+=("${key}:user:_perforce_users")
+ else
+ valuespec+=("${key}:${p4fields[$key]}: ")
fi
+ done
- for key in ${(k)p4fields}; do
- if [[ -n ${p4values[$key]} ]]; then
- valuespec+=("${key}:${p4fields[$key]}:(${p4values[$key]//$slash/ })")
- elif [[ $key = job ]]; then
- # Nothing special for jobs; add our own completion.
- valuespec+=("${key}:Perforce job:_perforce_jobs")
- elif [[ $key = user ]]; then
- # Nothing provided for user; add our own completion.
- valuespec+=("${key}:user:_users")
- else
- valuespec+=("${key}:${p4fields[$key]}: ")
- fi
- done
-
- _values 'Job specification parameter' $valuespec
+ _values 'Job specification parameter' $valuespec
}
(( $+functions[_perforce_labels] )) ||
@@ -1046,75 +1155,86 @@ _perforce_labels() {
(( $+functions[_perforce_revisions] )) ||
_perforce_revisions() {
- # Doesn't handle standard completion options; requires space
- # in front if used as action in _arguments.
+ # Doesn't handle standard completion options; requires space
+ # in front if used as action in _arguments.
- local rline match mbegin mend comma expl pfx
- local -a rl
+ local rline match mbegin mend comma expl pfx
+ local -a rl
- if [[ $1 = -tR ]]; then
- # handle ranges
- comma=(-S, -R _perforce_file_suffix)
+ if [[ $1 = -tR ]]; then
+ # handle ranges
+ comma=(-S, -R _perforce_file_suffix)
shift
- fi
-
- # Beware of @foo,#bar; stupid but probably valid.
- pfx=${${(Q)PREFIX}%%[\#@]*}
- compset -P '*\#'
-
- # Numerical revision numbers, possibly with text.
- if [[ -z $PREFIX || $PREFIX = <-> ]]; then
- # always allowed (same as none)
- rl+=(0)
- _perforce_call_p4 filelog 'filelog $pfx' 2>/dev/null | while read rline; do
- if [[ $rline = (#b)'... #'(<->)' change '(*) ]]; then
- rl+=("${match[1]}:${match[2]}")
- fi
- done
- fi
- # Non-numerical (special) revision names.
- if [[ -z $PREFIX || $PREFIX != <-> ]]; then
- rl+=('head:head revision' 'none:empty revision'
- 'have:current synced revision')
- fi
- _describe -t revisions 'revision' rl $comma
+ fi
+
+ # Beware of @foo,#bar; stupid but probably valid.
+ pfx=${${(Q)PREFIX}%%[\#@]*}
+ compset -P '*\#'
+
+ # Numerical revision numbers, possibly with text.
+ if [[ -z $PREFIX || $PREFIX = <-> ]]; then
+ # always allowed (same as none)
+ rl+=(0)
+ _perforce_call_p4 filelog 'filelog $pfx' 2>/dev/null | while read rline; do
+ if [[ $rline = (#b)'... #'(<->)' change '(*) ]]; then
+ rl+=("${match[1]}:${match[2]}")
+ fi
+ done
+ fi
+ # Non-numerical (special) revision names.
+ if [[ -z $PREFIX || $PREFIX != <-> ]]; then
+ rl+=('head:head revision' 'none:empty revision'
+ 'have:current synced revision')
+ fi
+ _describe -t revisions 'revision' rl -V revisions-unsorted $comma
}
(( $+functions[_perforce_statuses] )) ||
_perforce_statuses() {
- # Perforce statuses are usually limited to a set of values
- # given by the jobspec.
- local jline match mbegin mend
- local -a statuses
-
- _perforce_call_p4 jobspec jobspec -o | while read jline; do
- if [[ $jline = (#b)Status[[:blank:]]##(*/*) ]]; then
- statuses=(${(s./.)match[1]})
- break
- fi
- done
- if (( !${#statuses} )); then
- # Couldn't find anything from the jobspec; add defaults.
- statuses=(closed open suspended)
+ # Perforce statuses are usually limited to a set of values
+ # given by the jobspec.
+ local jline match mbegin mend
+ local -a statuses
+
+ _perforce_call_p4 jobspec jobspec -o | while read jline; do
+ if [[ $jline = (#b)Status[[:blank:]]##(*/*) ]]; then
+ statuses=(${(s./.)match[1]})
+ break
fi
- _describe -t statuses 'job status' statuses
- return 1
+ done
+ if (( !${#statuses} )); then
+ # Couldn't find anything from the jobspec; add defaults.
+ statuses=(closed open suspended)
+ fi
+ _describe -t statuses 'job status' statuses
+}
+
+
+
+(( $+functions[_perforce_users] )) ||
+_perforce_users() {
+ local -a ul
+
+ ul=(${${(f)"$(_perforce_call_p4 users users)"}/\ /:})
+ [[ $#ul -eq 1 && $ul[1] = '' ]] && ul=()
+ _describe -t clients 'Perforce client' ul
}
(( $+functions[_perforce_variables] )) ||
_perforce_variables() {
- local line match mbegin mend expl
- local -a vars
+ local line match mbegin mend expl
+ local -a vars
- _perforce_call_p4 help-environment help environment | while IFS= read line; do
- if [[ $line = $'\t'(#b)([A-Z][A-Z0-9_]##)* ]]; then
- vars+=($match[1])
- fi
- done
+ _perforce_call_p4 help-environment help environment | while IFS= read line
+ do
+ if [[ $line = $'\t'(#b)([A-Z][A-Z0-9_]##)* ]]; then
+ vars+=($match[1])
+ fi
+ done
- _wanted variable expl 'environment variable' compadd -S= -q $vars
+ _wanted variable expl 'environment variable' compadd -S= -q $vars
}
#
@@ -1123,605 +1243,605 @@ _perforce_variables() {
(( $+functions[_perforce_cmd_add] )) ||
_perforce_cmd_add() {
- _arguments -s : \
- '-c+[select by change]:change:_perforce_changes -tp' \
- '-t+[set file type]:file type:_perforce_filetypes' \
- '*:file:_perforce_files -tu'
+ _arguments -s : \
+ '-c+[select by change]:change:_perforce_changes -tp' \
+ '-t+[set file type]:file type:_perforce_filetypes' \
+ '*:file:_perforce_files -tu'
}
(( $+functions[_perforce_cmd_admin] )) ||
_perforce_cmd_admin() {
- if (( CURRENT == 2 )); then
- local -a adcmds
- adcmds=(
- "checkpoint:checkpoint, save copy of journal file"
- "journal:save and truncate journal file"
- "stop:stop the server")
- _describe -t commands 'Perforce admin command' adcmds
- elif [[ $words[2] == (checkpoint|journal) ]]; then
- shift words
- (( CURRENT-- ))
- _arguments -s : \
- '-z[gzip journal file]' \
- '1::journal file prefix: '
- fi
+ if (( CURRENT == 2 )); then
+ local -a adcmds
+ adcmds=(
+ "checkpoint:checkpoint, save copy of journal file"
+ "journal:save and truncate journal file"
+ "stop:stop the server")
+ _describe -t commands 'Perforce admin command' adcmds
+ elif [[ $words[2] == (checkpoint|journal) ]]; then
+ shift words
+ (( CURRENT-- ))
+ _arguments -s : \
+ '-z[gzip journal file]' \
+ '1::journal file prefix: '
+ fi
}
(( $+functions[_perforce_cmd_annotate] )) ||
_perforce_cmd_annotate() {
- # If you don't have this, it's new in release 2002.2.
- _arguments -s : \
- '-a[all, show both added and deleted lines]' \
- '-q[quiet, suppress one-line file header]' \
- '*::file:_perforce_files -tR'
+ # If you don't have this, it's new in release 2002.2.
+ _arguments -s : \
+ '-a[all, show both added and deleted lines]' \
+ '-q[quiet, suppress one-line file header]' \
+ '*::file:_perforce_files -tR'
}
(( $+functions[_perforce_cmd_branch] )) ||
_perforce_cmd_branch() {
- _arguments -s : \
- '(-o)-f[force operation by superuser]' \
- '(-o -i)-d[delete branch]' \
- '(-d -i -f)-o[write specification to standard output]' \
- '(-d -o)-i[read specification from standard input]' \
- '(-i)*::branch name:_perforce_branches'
+ _arguments -s : \
+ '(-o)-f[force operation by superuser]' \
+ '(-o -i)-d[delete branch]' \
+ '(-d -i -f)-o[write specification to standard output]' \
+ '(-d -o)-i[read specification from standard input]' \
+ '(-i)*::branch name:_perforce_branches'
}
(( $+functions[_perforce_cmd_branches] )) ||
_perforce_cmd_branches() {
- # No arguments.
- _arguments -s :
+ # No arguments.
+ _arguments -s :
}
(( $+functions[_perforce_cmd_change] )) ||
_perforce_cmd_change() {
- local ctype
- # Unless forcing or outputting, we don't
- # complete committed changes since they can't be altered.
- [[ ${words[(I)-*(f|o)*]} -eq 0 ]] && ctype=" -tp"
- _arguments -s : \
- '(-o)-f[allow force by superuser]' \
- '-s[joblist includes the fix status]' \
- '(-o -i)-d[discard newly created pending change]' \
- '(-d -i -f)-o[output specification to standard output]' \
- '(-d -o)-i[read specification from standard input]' \
- "(-i)1::change:_perforce_changes$ctype"
+ local ctype
+ # Unless forcing or outputting, we don't
+ # complete committed changes since they can't be altered.
+ [[ ${words[(I)-*(f|o)*]} -eq 0 ]] && ctype=" -tp"
+ _arguments -s : \
+ '(-o)-f[allow force by superuser]' \
+ '-s[joblist includes the fix status]' \
+ '(-o -i)-d[discard newly created pending change]' \
+ '(-d -i -f)-o[output specification to standard output]' \
+ '(-d -o)-i[read specification from standard input]' \
+ "(-i)1::change:_perforce_changes$ctype"
}
(( $+functions[_perforce_cmd_changes] )) ||
_perforce_cmd_changes() {
- _arguments -s : \
- '-i[include integrated changes]' \
- '-l[long output]' \
- '-c[select by client]:client:_perforce_clients' \
- '-m[most recent N changes]:max changes: ' \
- '-s[select by status]:status:(pending submitted)' \
- '-u[select by user]:user:_users' \
- '*::file:_perforce_files -tR'
+ _arguments -s : \
+ '-i[include integrated changes]' \
+ '-l[long output]' \
+ '-c+[select by client]:client:_perforce_clients' \
+ '-m+[most recent N changes]:max changes: ' \
+ '-s+[select by status]:status:(pending submitted)' \
+ '-u+[select by user]:user:_perforce_users' \
+ '*::file:_perforce_files -tR'
}
(( $+functions[_perforce_cmd_client] )) ||
_perforce_cmd_client() {
- _arguments -s : \
- '-f[force modification by superuser]' \
- '-t[use template]:template client:_perforce_clients' \
- '(-o -i -t)-d[delete client]' \
- '(-d -i -f)-o[print to standard output]' \
- '(-d -o -t)-i[read from standard input]' \
- '1::file:_perforce_clients'
+ _arguments -s : \
+ '-f[force modification by superuser]' \
+ '-t[use template]:template client:_perforce_clients' \
+ '(-o -i -t)-d[delete client]' \
+ '(-d -i -f)-o[print to standard output]' \
+ '(-d -o -t)-i[read from standard input]' \
+ '1::file:_perforce_clients'
}
(( $+functions[_perforce_cmd_clients] )) ||
_perforce_cmd_clients() {
- # No arguments.
- _arguments -s :
+ # No arguments.
+ _arguments -s :
}
(( $+functions[_perforce_cmd_counter] )) ||
_perforce_cmd_counter() {
- _arguments -s : \
- '-d[delete counter]' \
- '-f[force setting of internal counter]' \
- '1:counter:_perforce_counters' \
- '(-d)2::numeric value:_perforce_counter_values'
+ _arguments -s : \
+ '-d[delete counter]' \
+ '-f[force setting of internal counter]' \
+ '1:counter:_perforce_counters' \
+ '(-d)2::numeric value:_perforce_counter_values'
}
(( $+functions[_perforce_cmd_counters] )) ||
_perforce_cmd_counters() {
- # No arguments
- _arguments -s :
+ # No arguments
+ _arguments -s :
}
(( $+functions[_perforce_cmd_delete] )) ||
_perforce_cmd_delete() {
- _arguments -s : \
- '-c[select change for deletion]:change:_perforce_changes -tp' \
- '*::file:_perforce_files'
+ _arguments -s : \
+ '-c[select change for deletion]:change:_perforce_changes -tp' \
+ '*::file:_perforce_files'
}
(( $+functions[_perforce_cmd_depot] )) ||
_perforce_cmd_depot() {
- _arguments -s : \
- '-d[delete depot]' \
- '-o[print to stdout]' \
- '-i[read name from stdin]' \
- '(-i)*::depot name:_perforce_depots'
+ _arguments -s : \
+ '-d[delete depot]' \
+ '-o[print to stdout]' \
+ '-i[read name from stdin]' \
+ '(-i)*::depot name:_perforce_depots'
}
(( $+functions[_perforce_cmd_depots] )) ||
_perforce_cmd_depots() {
- # No arguments
- _arguments -s :
+ # No arguments
+ _arguments -s :
}
(( $+functions[_perforce_cmd_describe] )) ||
_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]' \
- '*::change:_perforce_changes'
+ _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]' \
+ '*::change:_perforce_changes'
}
(( $+functions[_perforce_cmd_diff] )) ||
_perforce_cmd_diff() {
- local limit
- [[ ${words[(I)-(f|sd|se)]} -eq 0 ]] && limit=" -to"
- _arguments -s : \
- '-d-[select diff option]:diff option:((b\:ignore\ blanks c\:context n\:RCS s\:summary u\:unified w\:ignore\ all\ whitespace))' \
- '-f[diff every file]' \
- '(-sd -se -sr)-sa[opened files, different or missing]' \
- '(-sa -se -sr)-sd[unopened files, missing]' \
- '(-sa -sd -sr)-se[unopened files, different]' \
- '(-sa -sd -se)-sr[opened files, same as depot]' \
- '-t[include non-text files]' \
- "*::file:_perforce_files$limit"
+ local limit
+ [[ ${words[(I)-(f|sd|se)]} -eq 0 ]] && limit=" -to"
+ _arguments -s : \
+ '-d-[select diff option]:diff option:((b\:ignore\ blanks c\:context n\:RCS s\:summary u\:unified w\:ignore\ all\ whitespace))' \
+ '-f[diff every file]' \
+ '(-sd -se -sr)-sa[opened files, different or missing]' \
+ '(-sa -se -sr)-sd[unopened files, missing]' \
+ '(-sa -sd -sr)-se[unopened files, different]' \
+ '(-sa -sd -se)-sr[opened files, same as depot]' \
+ '-t[include non-text files]' \
+ "*::file:_perforce_files$limit"
}
(( $+functions[_perforce_cmd_diff2] )) ||
_perforce_cmd_diff2() {
- _arguments -s : \
- '-b[specify branch view]:branch name:_perforce_branches' \
- '-d-[select diff option]:diff option:((b\:ignore\ blanks c\:context n\:RCS s\:summary u\:unified w\:ignore\ all\ whitespace))' \
- '-q[only list different files]' \
- '-t[include non-text files]' \
- '-u[use patch-friendly output]' \
- '1::first file:_perforce_files' \
- '2::second file:_perforce_files'
+ _arguments -s : \
+ '-b[specify branch view]:branch name:_perforce_branches' \
+ '-d-[select diff option]:diff option:((b\:ignore\ blanks c\:context n\:RCS s\:summary u\:unified w\:ignore\ all\ whitespace))' \
+ '-q[only list different files]' \
+ '-t[include non-text files]' \
+ '-u[use patch-friendly output]' \
+ '1::first file:_perforce_files' \
+ '2::second file:_perforce_files'
}
(( $+functions[_perforce_cmd_dirs] )) ||
_perforce_cmd_dirs() {
- _arguments -s : \
- '-C[only dirs on current client]' \
- '-D[include dirs with deleted files]' \
- '-H[only dirs on the `have'\'' list]' \
- '*::directory:_perforce_files -td'
+ _arguments -s : \
+ '-C[only dirs on current client]' \
+ '-D[include dirs with deleted files]' \
+ '-H[only dirs on the `have'\'' list]' \
+ '*::directory:_perforce_files -td'
}
(( $+functions[_perforce_cmd_edit] )) ||
_perforce_cmd_edit() {
- _arguments -s : \
- '-c[set change for edit]:change:_perforce_changes -tp' \
- '-t[set filetype]:filetype:_perforce_filetypes' \
- '*::file:_perforce_files'
+ _arguments -s : \
+ '-c[set change for edit]:change:_perforce_changes -tp' \
+ '-t[set filetype]:filetype:_perforce_filetypes' \
+ '*::file:_perforce_files'
}
(( $+functions[_perforce_cmd_filelog] )) ||
_perforce_cmd_filelog() {
- _arguments -s : \
- '-i[follow branches]' \
- '-l[long output, full change text]' \
- '-m[set maximum number of revisions to show]:max revisions: ' \
- '-t[include time with date]' \
- '*::file:_perforce_files'
+ _arguments -s : \
+ '-i[follow branches]' \
+ '-l[long output, full change text]' \
+ '-m[set maximum number of revisions to show]:max revisions: ' \
+ '-t[include time with date]' \
+ '*::file:_perforce_files'
}
(( $+functions[_perforce_cmd_files] )) ||
_perforce_cmd_files() {
- _arguments -s : \
- '-a[display all revisions in given range]' \
- '*::file:_perforce_files -tR'
+ _arguments -s : \
+ '-a[display all revisions in given range]' \
+ '*::file:_perforce_files -tR'
}
(( $+functions[_perforce_cmd_fix] )) ||
_perforce_cmd_fix() {
- _arguments -s : \
- '-d[delete the fix]' \
- '-s[set job status]:status:_perforce_statuses' \
- '1::-c required:(-c)' \
- '2::change:_perforce_changes' \
- '3::job:_perforce_jobs'
+ _arguments -s : \
+ '-d[delete the fix]' \
+ '-s[set job status]:status:_perforce_statuses' \
+ '1::-c required:(-c)' \
+ '2::change:_perforce_changes' \
+ '3::job:_perforce_jobs'
}
(( $+functions[_perforce_cmd_fixes] )) ||
_perforce_cmd_fixes() {
- _arguments -s : \
- '-i[include integrated changes]' \
- '-j[select by job]:job:_perforce_jobs' \
- '-c[select by change]:change:_perforce_changes' \
- '*::fixed file:_perforce_files -tR'
+ _arguments -s : \
+ '-i[include integrated changes]' \
+ '-j[select by job]:job:_perforce_jobs' \
+ '-c[select by change]:change:_perforce_changes' \
+ '*::fixed file:_perforce_files -tR'
}
(( $+functions[_perforce_cmd_flush] )) ||
_perforce_cmd_flush() {
- _arguments -s : \
- '-f[force resynchronisation]' \
- '-n[show operations but don'\''t perform them]' \
- '*::file:_perforce_files -tR'
+ _arguments -s : \
+ '-f[force resynchronisation]' \
+ '-n[show operations but don'\''t perform them]' \
+ '*::file:_perforce_files -tR'
}
(( $+functions[_perforce_cmd_fstat] )) ||
_perforce_cmd_fstat() {
- _arguments -s : \
- '-c+[select by change]:change:_perforce_changes -ts' \
- '-C[select mapped files]' \
- '-H[select synced files]' \
- '-W[select opened files]' \
- '-l[include fileSize, possibly slow]' \
- '-P[output clientFile in full Perforce syntax]' \
- '-s[shorten, no client-related data]' \
- '*::file:_perforce_files'
+ _arguments -s : \
+ '-c+[select by change]:change:_perforce_changes -ts' \
+ '-C[select mapped files]' \
+ '-H[select synced files]' \
+ '-W[select opened files]' \
+ '-l[include fileSize, possibly slow]' \
+ '-P[output clientFile in full Perforce syntax]' \
+ '-s[shorten, no client-related data]' \
+ '*::file:_perforce_files'
}
(( $+functions[_perforce_cmd_group] )) ||
_perforce_cmd_group() {
- _arguments -s : \
- '-d[delete group]' \
- '-o[output to stdout]' \
- '-i[read from stdin]' \
- '1::perforce group:_perforce_groups'
+ _arguments -s : \
+ '-d[delete group]' \
+ '-o[output to stdout]' \
+ '-i[read from stdin]' \
+ '1::perforce group:_perforce_groups'
}
(( $+functions[_perforce_cmd_groups] )) ||
_perforce_cmd_groups() {
- _arguments -s : \
- '1::user name:_users'
+ _arguments -s : \
+ '1::user name:_perforce_users'
}
(( $+functions[_perforce_cmd_have] )) ||
_perforce_cmd_have() {
- _perforce_files
+ _perforce_files
}
(( $+functions[_perforce_cmd_help] )) ||
_perforce_cmd_help() {
- local hline
- if (( ! ${#_perforce_help_list} )); then
- (( ${+_perforce_help_list} )) || typeset -ga _perforce_help_list
- # All commands have help.
- (( ${#_perforce_cmd_list} )) || _perforce_gen_cmd_list
- _perforce_help_list=($_perforce_cmd_list)
- _perforce_call_p4 help help | while read -A hline; do
- if [[ $hline[1] = p4 && $hline[2] = help ]]; then
- _perforce_help_list+=("$hline[3]:${hline[4,-1]}")
- fi
- done
- fi
- _describe -t help-options 'Perforce help option' _perforce_help_list
+ local hline
+ if (( ! ${#_perforce_help_list} )); then
+ (( ${+_perforce_help_list} )) || typeset -ga _perforce_help_list
+ # All commands have help.
+ (( ${#_perforce_cmd_list} )) || _perforce_gen_cmd_list
+ _perforce_help_list=($_perforce_cmd_list)
+ _perforce_call_p4 help help | while read -A hline; do
+ if [[ $hline[1] = p4 && $hline[2] = help ]]; then
+ _perforce_help_list+=("$hline[3]:${hline[4,-1]}")
+ fi
+ done
+ fi
+ _describe -t help-options 'Perforce help option' _perforce_help_list
}
(( $+functions[_perforce_cmd_info] )) ||
_perforce_cmd_info() {
- # No arguments
- _arguments -s :
+ # No arguments
+ _arguments -s :
}
(( $+functions[_perforce_cmd_integrate] )) ||
_perforce_cmd_integrate() {
- local range
- # If -s is present, the first normal argument can't have revRange.
- [[ ${words[(I)-s]} -eq 0 ]] && range=" -tR"
- _arguments -s : \
- '-b[select branch]:branch:_perforce_branches' \
- '-c[select change for integration]:change:_perforce_changes -tp' \
- '-f[force reintegration]' \
- '-d[reintegrated deleted files]' \
- '-h[integrate to revision had on client]' \
- '-i[integrate if no common file base]' \
- '-n[no action, dummy run]' \
- '-r[reverse direction of integration with branch]' \
- '-s[select source]:source file:_perforce_files -tR' \
- '-t[propagate type changes]' \
- '-v[leave newly branched files uncopied till sync]' \
- "1:file:_perforce_files$range" \
- '*::file:_perforce_files'
+ local range
+ # If -s is present, the first normal argument can't have revRange.
+ [[ ${words[(I)-s]} -eq 0 ]] && range=" -tR"
+ _arguments -s : \
+ '-b[select branch]:branch:_perforce_branches' \
+ '-c[select change for integration]:change:_perforce_changes -tp' \
+ '-f[force reintegration]' \
+ '-d[reintegrated deleted files]' \
+ '-h[integrate to revision had on client]' \
+ '-i[integrate if no common file base]' \
+ '-n[no action, dummy run]' \
+ '-r[reverse direction of integration with branch]' \
+ '-s[select source]:source file:_perforce_files -tR' \
+ '-t[propagate type changes]' \
+ '-v[leave newly branched files uncopied till sync]' \
+ "1:file:_perforce_files$range" \
+ '*::file:_perforce_files'
}
(( $+functions[_perforce_cmd_integrated] )) ||
_perforce_cmd_integrated() {
- _perforce_files -ti
+ _perforce_files -ti
}
(( $+functions[_perforce_cmd_job] )) ||
_perforce_cmd_job() {
- _arguments -s : \
- '(-d -o -i)-f[force setting of readonly fields]' \
- '(-f -o -i)-d[delete job]' \
- '(-f -d -i)-o[print to stdout]' \
- '(-d -o)-i[read from stdin]' \
- '(-i)1::job:_perforce_jobs'
+ _arguments -s : \
+ '(-d -o -i)-f[force setting of readonly fields]' \
+ '(-f -o -i)-d[delete job]' \
+ '(-f -d -i)-o[print to stdout]' \
+ '(-d -o)-i[read from stdin]' \
+ '(-i)1::job:_perforce_jobs'
}
(( $+functions[_perforce_cmd_jobs] )) ||
_perforce_cmd_jobs() {
- _arguments -s : \
- '-e[select by jobview]:jobview:_perforce_jobviews' \
- '-i[included integrated changes]' \
- '-l[long output, full job descriptions]' \
- '-r[reverse order of job names]' \
- '-m[limit to most recent N jobs]:most recent jobs: ' \
- '(-e -i -l -m)-R[]' \
- '*::file:_perforce_files -tR'
+ _arguments -s : \
+ '-e[select by jobview]:jobview:_perforce_jobviews' \
+ '-i[included integrated changes]' \
+ '-l[long output, full job descriptions]' \
+ '-r[reverse order of job names]' \
+ '-m[limit to most recent N jobs]:most recent jobs: ' \
+ '(-e -i -l -m)-R[]' \
+ '*::file:_perforce_files -tR'
}
(( $+functions[_perforce_cmd_jobspec] )) ||
_perforce_cmd_jobspec() {
- _arguments -s : \
- '-i[read form from stdin]' \
- '-o[write form from to stdout]'
+ _arguments -s : \
+ '-i[read form from stdin]' \
+ '-o[write form from to stdout]'
}
(( $+functions[_perforce_cmd_label] )) ||
_perforce_cmd_label() {
- _arguments -s : \
- '-f[force operation]' \
- '-t+[copy template]:template: ' \
- '(-o -i -t)-d[delete label]' \
- '(-d -f -i)-o[write to standard output]' \
- '(-o -d -t)-i[read from standard input]' \
- '*::label:_perforce_labels'
+ _arguments -s : \
+ '-f[force operation]' \
+ '-t+[copy template]:template: ' \
+ '(-o -i -t)-d[delete label]' \
+ '(-d -f -i)-o[write to standard output]' \
+ '(-o -d -t)-i[read from standard input]' \
+ '*::label:_perforce_labels'
}
(( $+functions[_perforce_cmd_labels] )) ||
_perforce_cmd_labels() {
- _arguments -s : \
- '1::file or revisions which must contain label:_perforce_files -tR'
+ _arguments -s : \
+ '1::file or revisions which must contain label:_perforce_files -tR'
}
(( $+functions[_perforce_cmd_labelsync] )) ||
_perforce_cmd_labelsync() {
- _arguments -s : \
- '-a[add files to label]' \
- '-d[delete files from label]' \
- '-n[no effect, dummy run]' \
- '-l[specify label]:label:_perforce_labels' \
- '*::file:_perforce_files -tR'
+ _arguments -s : \
+ '-a[add files to label]' \
+ '-d[delete files from label]' \
+ '-n[no effect, dummy run]' \
+ '-l[specify label]:label:_perforce_labels' \
+ '*::file:_perforce_files -tR'
}
(( $+functions[_perforce_cmd_lock] )) ||
_perforce_cmd_lock() {
- _arguments -s : \
- '-c[select by change]:change:_perforce_changes -tp' \
- '*::file:_perforce_files -to'
+ _arguments -s : \
+ '-c[select by change]:change:_perforce_changes -tp' \
+ '*::file:_perforce_files -to'
}
(( $+functions[_perforce_cmd_logger] )) ||
_perforce_cmd_logger() {
- _arguments -s : \
- '-c[limit by counter no]:number: ' \
- '-t[use counter instead of logger]:counter:_perforce_counters'
+ _arguments -s : \
+ '-c[limit by counter no]:number: ' \
+ '-t[use counter instead of logger]:counter:_perforce_counters'
}
(( $+functions[_perforce_cmd_obliterate] )) ||
_perforce_cmd_obliterate() {
- _message "obliterate is dangerous: you're on your own here."
+ _message "obliterate is dangerous: you're on your own here."
}
(( $+functions[_perforce_cmd_opened] )) ||
_perforce_cmd_opened() {
- _arguments -s : \
- '-a[list for all clients]' \
- '-c+[select by change]:change:_perforce_changes -tp' \
- '*::file:_perforce_files -to'
+ _arguments -s : \
+ '-a[list for all clients]' \
+ '-c+[select by change]:change:_perforce_changes -tp' \
+ '*::file:_perforce_files -to'
}
(( $+functions[_perforce_cmd_passwd] )) ||
_perforce_cmd_passwd() {
- _arguments -s : : \
- '-O[explicit old password]:old password: ' \
- '-P[explicit new password]:new password: ' \
- '1::user name:_users'
+ _arguments -s : : \
+ '-O[explicit old password]:old password: ' \
+ '-P[explicit new password]:new password: ' \
+ '1::user name:_perforce_users'
}
(( $+functions[_perforce_cmd_print] )) ||
_perforce_cmd_print() {
- _arguments -s : \
- '-a[display all revisions in a range]' \
- '-o[select output file]:output file:_files' \
- '-q[suppress header]' \
- '*::file:_perforce_files -tR'
+ _arguments -s : \
+ '-a[display all revisions in a range]' \
+ '-o[select output file]:output file:_files' \
+ '-q[suppress header]' \
+ '*::file:_perforce_files -tR'
}
(( $+functions[_perforce_cmd_protect] )) ||
_perforce_cmd_protect() {
- _arguments -s : \
- '-o[write spec to stdout]' \
- '-i[read spec from stdin]'
+ _arguments -s : \
+ '-o[write spec to stdout]' \
+ '-i[read spec from stdin]'
}
(( $+functions[_perforce_cmd_reopen] )) ||
_perforce_cmd_reopen() {
- _arguments -s : \
- '-c+[select change to reopen on]:change:_perforce_changes -tp' \
- '-t+[set file type]:file type:_perforce_filetypes' \
- '*::file:_perforce_files -to'
+ _arguments -s : \
+ '-c+[select change to reopen on]:change:_perforce_changes -tp' \
+ '-t+[set file type]:file type:_perforce_filetypes' \
+ '*::file:_perforce_files -to'
}
(( $+functions[_perforce_cmd_resolve] )) ||
_perforce_cmd_resolve() {
- _arguments -s : \
- '-a-[select automatic merge type]:automation type:((f\:force\ acceptance m\:skip\ conflicts s\:safe t\:use\ theirs y\:use\ yours))' \
- '-d-[select diff option]:diff option:((b\:ignore\ blanks w\:ignore\ all\ whitespace))' \
- '-f[force re-resolution]' \
- '-n[no action, just list]' \
- '-t[force textual merge on binary files]' \
- '-v[verbose, mark all changes]' \
- '*::file:_perforce_files -to'
+ _arguments -s : \
+ '-a-[select automatic merge type]:automation type:((f\:force\ acceptance m\:skip\ conflicts s\:safe t\:use\ theirs y\:use\ yours))' \
+ '-d-[select diff option]:diff option:((b\:ignore\ blanks w\:ignore\ all\ whitespace))' \
+ '-f[force re-resolution]' \
+ '-n[no action, just list]' \
+ '-t[force textual merge on binary files]' \
+ '-v[verbose, mark all changes]' \
+ '*::file:_perforce_files -to'
}
(( $+functions[_perforce_cmd_resolved] )) ||
_perforce_cmd_resolved() {
- _perforce_files -tr
+ _perforce_files -tr
}
(( $+functions[_perforce_cmd_revert] )) ||
_perforce_cmd_revert() {
- _arguments -s : \
- '-a[revert unaltered files]' \
- '-c[limit reversions to change]:change:_perforce_changes -tp' \
- '-n[no action, show effect only]' \
- '*::file:_perforce_files -to'
+ _arguments -s : \
+ '-a[revert unaltered files]' \
+ '-c[limit reversions to change]:change:_perforce_changes -tp' \
+ '-n[no action, show effect only]' \
+ '*::file:_perforce_files -to'
}
(( $+functions[_perforce_cmd_review] )) ||
_perforce_cmd_review() {
- _arguments -s : \
- '-c[select change for counter]:change:_perforce_changes -ts' \
- '-t[limit change number by counter]:counter:_perforce_counters'
+ _arguments -s : \
+ '-c[select change for counter]:change:_perforce_changes -ts' \
+ '-t[limit change number by counter]:counter:_perforce_counters'
}
(( $+functions[_perforce_cmd_reviews] )) ||
_perforce_cmd_reviews() {
- _arguments -s : \
- '-c[show users by change]:change:_perforce_changes -ts' \
- '*::file:_perforce_files'
+ _arguments -s : \
+ '-c[show users by change]:change:_perforce_changes -ts' \
+ '*::file:_perforce_files'
}
(( $+functions[_perforce_cmd_set] )) ||
_perforce_cmd_set() {
- # Only works under Windoze but maybe we are on Cygwin.
- _arguments -s : \
- '-s[set for whole system]' \
- '-S[set for specified service]:service: ' \
- "*::environment variable:_perforce_variables"
+ # Only works under Windoze but maybe we are on Cygwin.
+ _arguments -s : \
+ '-s[set for whole system]' \
+ '-S[set for specified service]:service: ' \
+ "*::environment variable:_perforce_variables"
}
(( $+functions[_perforce_cmd_submit] )) ||
_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]:change:_perforce_changes -tp' \
- '(-c)-i[read change spec from stdin]' \
- '*::file:_perforce_files -to -tr' \
+ _arguments -s : \
+ '-r[files open for add or edit remain open]' \
+ '-s[include fix status in list]' \
+ '(-s -i)-c[submit specific change]:change:_perforce_changes -tp' \
+ '(-c)-i[read change spec from stdin]' \
+ '*::file:_perforce_files -to -tr'
}
(( $+functions[_perforce_cmd_sync] )) ||
_perforce_cmd_sync() {
- _arguments -s : \
- '-f[force resynchronisation]' \
- '-n[show operations but don'\''t perform them]' \
- '*::file:_perforce_files -tR'
+ _arguments -s : \
+ '-f[force resynchronisation]' \
+ '-n[show operations but don'\''t perform them]' \
+ '*::file:_perforce_files -tR'
}
(( $+functions[_perforce_cmd_triggers] )) ||
_perforce_cmd_triggers() {
- _arguments -s : \
- '-o[output form to stdout]' \
- '-i[read from from stdin]'
+ _arguments -s : \
+ '-o[output form to stdout]' \
+ '-i[read from from stdin]'
}
(( $+functions[_perforce_cmd_typemap] )) ||
_perforce_cmd_typemap() {
- _arguments -s : \
- '-o[output table to stdout]' \
- '-i[read table from stdin]'
+ _arguments -s : \
+ '-o[output table to stdout]' \
+ '-i[read table from stdin]'
}
(( $+functions[_perforce_cmd_unlock] )) ||
_perforce_cmd_unlock() {
- _arguments -s : \
- '-c[non-default change to unlock]:change:_perforce_changes -tp' \
- '-f[allow superuser to unlock any file]' \
- '*::file:_perforce_files'
+ _arguments -s : \
+ '-c[non-default change to unlock]:change:_perforce_changes -tp' \
+ '-f[allow superuser to unlock any file]' \
+ '*::file:_perforce_files'
}
(( $+functions[_perforce_cmd_user] )) ||
_perforce_cmd_user() {
- _arguments -s : \
- '(-o)-f[force edit by superuser]' \
- '(-o -i)-d[delete user]' \
- '(-o -d)-i[read form from stdin]' \
- '(-f -i -d)-o[write form to stdout]' \
- '(-i)1::username:_users'
+ _arguments -s : \
+ '(-o)-f[force edit by superuser]' \
+ '(-o -i)-d[delete user]' \
+ '(-o -d)-i[read form from stdin]' \
+ '(-f -i -d)-o[write form to stdout]' \
+ '(-i)1::username:_perforce_users'
}
(( $+functions[_perforce_cmd_users] )) ||
_perforce_cmd_users() {
- _arguments -s : \
- '*::username:_users'
+ _arguments -s : \
+ '*::username:_perforce_users'
}
(( $+functions[_perforce_cmd_verify] )) ||
_perforce_cmd_verify() {
- _arguments -s : \
- '-q[operate quietly]' \
- '-u[compute and save digest if missing]' \
- '-v[compute and save all digets]' \
- '*::file:_perforce_files -tR'
+ _arguments -s : \
+ '-q[operate quietly]' \
+ '-u[compute and save digest if missing]' \
+ '-v[compute and save all digets]' \
+ '*::file:_perforce_files -tR'
}
(( $+functions[_perforce_cmd_where] )) ||
_perforce_cmd_where() {
- _perforce_files
+ _perforce_files
}