Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: PATCH: completion of glob qualifiers



On Fri, 07 Nov 2008 13:38:56 +0100
Oliver Kiddle <okiddle@xxxxxxxxxxx> wrote:
> I've only just noticed this change back in message 24585. Is there any
> reason why globbing flags were not completed. This patch adds them.

Fine, the patch was simply incomplete.  The patch below will mess
yours up, however.

> Note that inside [[ ... ]] conditions, a bracket that is not preceded by
> some other character is assumed to be used for grouping of conditions so
> this won't work with glob flags at the beginning of a pattern.

We shouldn't complete glob flags right at the start of a word,
presumably---I don't think that's ever going to be useful.  I've
added a test that we're skipping over at least one character before the
parenthesis for a bare glob.

It seems the completion options always add BARE_GLOB_QUAL, in fact; it
would probably make more sense to rely on the use of (#q...) inside the
completion system, but I'm too lazy to fix this.

> One problem possibly due to your original patch is the following;
> : */( <tab>
> results in the /( being removed. I haven't worked out why but this
> doesn't occur with the old zsh that comes with Debian stable.

I'm not sure why I thought it was a good idea to match glob qualifiers
at a complicated point in the middle of path matching.  Even if the
qualifiers aren't after a glob expression, which they typically are, you
don't want to do completion on the earlier path if you're already
completing a qualifier.  I've therefore simply moved the chunk to the
start of _path_files.

Index: Completion/Unix/Type/_path_files
===================================================================
RCS file: /cvsroot/zsh/zsh/Completion/Unix/Type/_path_files,v
retrieving revision 1.39
diff -u -r1.39 _path_files
--- Completion/Unix/Type/_path_files	29 Oct 2008 21:59:32 -0000	1.39
+++ Completion/Unix/Type/_path_files	8 Nov 2008 23:13:30 -0000
@@ -1,5 +1,30 @@
 #autoload
 
+local -a match mbegin mend
+
+# Look for glob qualifiers.  Do this first:  if we're really
+# in a glob qualifier, we don't actually want to expand
+# the earlier part of the path.  We can't expand inside
+# parentheses otherwise, so as we test that successfully
+# we should be able to commit to glob qualifiers here.
+#
+# Extra nastiness to be careful about a quoted parenthesis.
+# The initial tests look for parentheses with zero or an
+# even number of backslashes in front.  We also require that
+# there was at least one character before the parenthesis for
+# a bare glob qualifier.
+# The later test looks for an outstanding quote.
+if [[ ( -o bareglobqual && \
+           $PREFIX = (#b)((*[^\\]|)(\\\\)#\()([^\)]#) && \
+           ${#match[1]} -gt 1 || \
+        -o extendedglob && \
+	   $PREFIX = (#b)((*[^\\]|)(\\\\)#"(#q")([^\)]#) \
+      ) && -z $compstate[quote] ]]; then
+   compset -p ${#match[1]}
+   _globquals
+   return
+fi
+
 # Utility function for in-path completion. This allows `/u/l/b<TAB>'
 # to complete to `/usr/local/bin'.
 
@@ -9,7 +34,7 @@
 local nm=$compstate[nmatches] menu matcher mopts sort mid accex fake
 local listfiles listopts tmpdisp origtmp1 Uopt
 integer npathcheck
-local -a match mbegin mend Mopts
+local -a Mopts
 
 typeset -U prepaths exppaths
 
@@ -383,19 +408,7 @@
 
     tmp2=( "$tmp1[@]" )
 
-    # Look for glob qualifiers.
-    # Extra nastiness to be careful about a quoted parenthesis.
-    # The initial tests look for parentheses with zero or an
-    # even number of backslashes in front.
-    # The later test looks for an outstanding quote.
-    if [[ ( -o bareglobqual && \
-	      "$tpre/$tsuf" = (#b)((*[^\\]|)(\\\\)#\()([^\)]#) || \
-            -o extendedglob && \
-		"$tpre/$tsuf" = (#b)((*[^\\]|)(\\\\)#"(#q")([^\)]#) \
-	  ) && -z $compstate[quote] ]]; then
-       compset -p ${#match[1]}
-       _globquals
-    elif [[ "$tpre$tsuf" = */* ]]; then
+    if [[ "$tpre$tsuf" = */* ]]; then
       compfiles -P$cfopt tmp1 accex "$skipped" "$_matcher $matcher[2]" "$sdirs" fake
     elif [[ "$sopt" = *[/f]* ]]; then
       compfiles -p$cfopt tmp1 accex "$skipped" "$_matcher $matcher[2]" "$sdirs" fake "$pats[@]"

-- 
Peter Stephenson <p.w.stephenson@xxxxxxxxxxxx>
Web page now at http://homepage.ntlworld.com/p.w.stephenson/



Messages sorted by: Reverse Date, Date, Thread, Author