about summary refs log tree commit diff
diff options
context:
space:
mode:
authorPeter Stephenson <pws@users.sourceforge.net>2006-02-15 10:53:46 +0000
committerPeter Stephenson <pws@users.sourceforge.net>2006-02-15 10:53:46 +0000
commite7da56976239deba85d513990851c532834f4fc3 (patch)
tree93805f0705ed26ec6354e844a5cca790d5f68694
parente89840f0cc9df7ae7f8cb740153c72f00b2e3b13 (diff)
downloadzsh-e7da56976239deba85d513990851c532834f4fc3.tar.gz
zsh-e7da56976239deba85d513990851c532834f4fc3.tar.xz
zsh-e7da56976239deba85d513990851c532834f4fc3.zip
unposted: fix _perforce to allow matching control on files from p4 output
-rw-r--r--ChangeLog7
-rw-r--r--Completion/Unix/Command/_perforce99
2 files changed, 78 insertions, 28 deletions
diff --git a/ChangeLog b/ChangeLog
index 589a6f0a7..40be4e20e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2006-02-15  Peter Stephenson  <pws@csr.com>
+
+	* unposted: Completion/Unix/Command/_perforce: use zsh to
+	match files within directories generated from p4 output, so
+	as to get matching control working; style "glob" provides
+	backward compatibility.
+
 2006-02-15  Wayne Davison  <wayned@users.sourceforge.net>
 
 	* 22268: Src/subst.c, Test/D04parameter.ztst, Doc/Zsh/expn.yo,
diff --git a/Completion/Unix/Command/_perforce b/Completion/Unix/Command/_perforce
index 03765e94a..254e7f6e1 100644
--- a/Completion/Unix/Command/_perforce
+++ b/Completion/Unix/Command/_perforce
@@ -1,5 +1,7 @@
 #compdef p4 -value-,P4CLIENT,-default- -value-,P4PORT,-default- -value-,P4MERGE,-default- -value-,P4USER,-default-
 
+# Maintainer: Peter Stephenson <pws@csr.com>.
+
 # Increasingly loosely based on _cvs version 1.17.
 # Completions currently based on Perforce release 2004.2.
 
@@ -76,6 +78,28 @@
 # Perforce to search all subdirectories.  Hence you can turn this
 # feature off by suitably manipulating your tags.
 #
+# The function will usually try to limit the files it lists by
+# context; for example, to just opened files.  By default it does
+# this by retrieving the complete list from Perforce and then
+# relying on the completion system to do the matching.  If this is
+# slow, it is possible to set the style "glob", in which case the
+# matching is done within Perforce, potentially reducing the amount of
+# searching of Perforce's internal database.  The tag used for
+# this is the same as the command used to retrieve the file name:
+# integrated, opened, resolved, dirs, files.  The disadvantage
+# of doing the matching within Perforce is that no matcher specification
+# is applied; for example, it's not possible to match a_u.c against
+# admin_utils.c.
+#
+# Actually, a hybrid strategy is used when the glob style is not set: the
+# directory is passed literally to Perforce, but the file or directory
+# being matched is passed as "*", so that matching on the contents of the
+# directory is performed by the completion system.
+#
+# Experiment suggests that the glob style isn't usually needed: only
+# "p4 integrated" is likely to be significantly slowed if no limiting
+# pattern is applied, and completing only integrated files is uncommon.
+#
 # Completion of files and their revisions
 # =======================================
 #
@@ -735,6 +759,43 @@ _perforce_file_suffix() {
 
 
 #
+# Helper function for the helper functions for the helper function
+# _perforce_files.  This is common code to retrieve a list of files
+# from Perforce.
+#
+# First argument is the p4 subcommand used to list the files.
+# This is also used as a tag for the style to decide whether
+# to limit the list within Perforce.
+# Remaining arguments are additional arguments to compadd.
+#
+(( $+functions[_perforce_retrieve_files] )) ||
+_perforce_retrieve_files() {
+  local pfx
+  local -a files
+
+  if zstyle -t ":completion:${curcontext}:$1" glob; then
+    # Limit the list by using Perforce to glob the pattern.
+    # This may be faster, but won't use matcher specs etc.
+    pfx=${(Q)PREFIX}
+    compset -P '*/'
+    files=(${${${(f)"$(_perforce_call_p4 $1 $1 \"\$pfx\*\$\{\(Q\)SUFFIX\}\" 2>/dev/null)"}%\#*}##*/})
+  else
+    # We need to limit the list to a directory.
+    if [[ $PREFIX = */* ]]; then
+      pfx="${(Q)${PREFIX%/*}}/*"
+    else
+      pfx="*"
+    fi
+    compset -P '*/'
+    files=(${${${(f)"$(_perforce_call_p4 $1 $1 \$pfx 2>/dev/null)"}%\#*}##*/})
+  fi
+  [[ $#files -eq 1 && $files[1] = '' ]] && files=()
+  shift
+  compadd "$@" -a files
+}
+
+
+#
 # Helper functions for the helper function _perforce_files.  These files
 # are low-level enough that they don't handle tags; this is done
 # by the _alternative handler in _perforce_files.
@@ -745,36 +806,25 @@ _perforce_integrated_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
+  _perforce_retrieve_files integrated "$@"
 }
 
 
 (( $+functions[_perforce_opened_files] )) ||
 _perforce_opened_files() {
-  local pfx=${(Q)PREFIX} type
+  local 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
+  _perforce_retrieve_files opened "$@"
 }
 
 
 (( $+functions[_perforce_resolved_files] )) ||
 _perforce_resolved_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
+  _perforce_retrieve_files resolved "$@"
 }
 
+
 (( $+functions[_perforce_subdirs] )) ||
 _perforce_subdirs() {
   # This has no other function than to offer to add the `...' used
@@ -784,30 +834,23 @@ _perforce_subdirs() {
   compadd "$@" '...'
 }
 
+
 (( $+functions[_perforce_depot_dirs] )) ||
 _perforce_depot_dirs() {
   # 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
+  _perforce_retrieve_files dirs "$@" -S / -q
 }
 
+
 (( $+functions[_perforce_depot_files] )) ||
 _perforce_depot_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
+  _perforce_retrieve_files files "$@" -R _perforce_file_suffix
 }
 
+
 (( $+functions[_perforce_client_dirs] )) ||
 _perforce_client_dirs() {
   # This is a slightly odd addition which isn't often necessary.