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

Re: Unexpected behavior from _match completer



On Mon, 16 Jul 2007 03:25:51 -0400
"Matt Wozniski" <godlygeek@xxxxxxxxx> wrote:
> I seem to be seeing some weird behavior from the _match completer.
> So, on zsh 4.3.4, after running zsh -f:
> 
> mastermind% autoload -U compinit; compinit
> mastermind% zstyle ':completion:*' completer _match
> mastermind% touch ' test ' '[test]' atesta btestb
> mastermind% ls ?test<TAB>
> # shows only atesta and btestb in menu completion
> mastermind% ls ?test*
> # lists all 4 files
> mastermind% ls *test<TAB>
> # shows all 4 files in menu completion
> mastermind% ls *test*
> # lists all 4 files
> 
> Why aren't all 4 of those files matched by "?test<TAB>"?  It seems as
> though the match completer is deciding that '\ ' and '\[' are each two
> characters rather than one and failing to match properly as a result.

Yes, that's exactly what's happening.  The file names are quoted in the
script _path_files, then compadd -Q is called to process them without
adding more quoting.  This means the matching is done on the quoted form.

The easiest thing to do is to unquote strings for matching when -Q is
passed.  There may be complicated cases where this isn't the right thing to
do, but it should catch cases like this.

Index: Src/Zle/compmatch.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/Zle/compmatch.c,v
retrieving revision 1.50
diff -u -r1.50 compmatch.c
--- Src/Zle/compmatch.c	30 Sep 2006 06:53:15 -0000	1.50
+++ Src/Zle/compmatch.c	23 Jul 2007 13:11:22 -0000
@@ -966,7 +966,8 @@
 /* Check if the word w is matched by the strings in pfx and sfx (the prefix
  * and the suffix from the line) or the pattern cp. In clp a cline list for
  * w is returned.
- * qu is non-zero if the words has to be quoted before processed any further.
+ * qu is non-zero if the words has to be quoted before processed any
+ * further: the value 2 indicates file quoting.
  * bpl and bsl are used to report the positions where the brace-strings in
  * the prefix and the suffix have to be re-inserted if this match is inserted
  * in the line.
@@ -983,9 +984,30 @@
     if (cp) {
 	/* We have a globcomplete-like pattern, just use that. */
 	int wl;
+	char *teststr;
 
 	r = w;
-	if (!pattry(cp, r))
+	if (!qu) {
+	    /*
+	     * If we're not quoting the strings, that means they're
+	     * already quoted (?) and so when we test them against
+	     * a pattern we have to remove the quotes else we will
+	     * end up trying to match against the quote characters.
+	     *
+	     * Almost certainly this fails in some complicated cases
+	     * but it should catch the basic ones.
+	     */
+	    teststr = dupstring(r);
+	    tokenize(teststr);
+	    if (parse_subst_string(teststr))
+		teststr = r;
+	    else {
+		remnulargs(teststr);
+		untokenize(teststr);
+	    }
+	} else
+	    teststr = r;
+	if (!pattry(cp, teststr))
 	    return NULL;
     
 	r = (qu == 2 ? tildequote(r, 0) : multiquote(r, !qu));


-- 
Peter Stephenson <pws@xxxxxxx>                  Software Engineer
CSR PLC, Churchill House, Cambridge Business Park, Cowley Road
Cambridge, CB4 0WZ, UK                          Tel: +44 (0)1223 692070


To access the latest news from CSR copy this link into a web browser:  http://www.csr.com/email_sig.php

To get further information regarding CSR, please visit our Investor Relations page at http://ir.csr.com/phoenix.zhtml?c=177117&p=irol-homeProfile



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