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

Re: completion after < at the start of the line



Peter Stephenson <pws@xxxxxxx> wrote:
> Stephane Chazelas <Stephane_Chazelas@xxxxxxxx> wrote:
>> $ mkdir 1
>> $ cd 1
>> $ touch foo bar
>> $ zsh -f
>> sc% < b<TAB> foo
>> 
>> (That is type "< b foo" move the cursor back to 4rd character,
>> then type <Tab>)
>> 
>> Then zsh completes that to:
>> 
>> sc% < foo foo
>> 
>> (instead of expected < bar foo).
>
> An alternative strategy is to record redirections before the command word,
> but I'd rather understand what's there at present than bolt something new
> on regardless.

I've gone for this strategy.  I thought about it in the bath:  the
number of cases where you might need to reset the index because you've
got a new command word is quite large and it would be nastier to try
to detect them all than to work around the problem.  The fix using a
special index for initial redirections isn't particularly horrible by
the standards of this code.

I've been seeing something screwy to do with the complist module when
trying this.  It doesn't seem to be related; it happens with or without
an initial redirection, but I happened to fall over it when testing
this.  I've been getting it with "ls --<TAB>" with menu selection turned
on.

Index: Src/Zle/zle_tricky.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/Zle/zle_tricky.c,v
retrieving revision 1.84
diff -u -r1.84 zle_tricky.c
--- Src/Zle/zle_tricky.c	13 Feb 2007 21:54:41 -0000	1.84
+++ Src/Zle/zle_tricky.c	28 Mar 2007 21:17:34 -0000
@@ -1072,6 +1072,12 @@
      * still use zlemetacs.
      */
     int qsub, zlemetacs_qsub = 0;
+    /*
+     * redirpos is used to record string arguments for redirection
+     * when they occur at the start of the line.  In this case
+     * the command word is not at index zero in the array.
+     */
+    int redirpos;
     char *s = NULL, *tmp, *p, *tt = NULL, rdop[20];
     char *linptr, *u;
 
@@ -1130,7 +1136,7 @@
     lexsave();
     inpush(dupstrspace(linptr), 0, NULL);
     strinbeg(0);
-    i = tt0 = cp = rd = ins = oins = linarr = parct = ia = 0;
+    i = tt0 = cp = rd = ins = oins = linarr = parct = ia = redirpos = 0;
 
     /* This loop is possibly the wrong way to do this.  It goes through *
      * the previously massaged command line using the lexer.  It stores *
@@ -1186,6 +1192,9 @@
             else
                 strcpy(rdop, tokstrings[tok]);
             strcpy(rdstr, rdop);
+	    /* Record if we haven't had the command word yet */
+	    if (i == redirpos)
+		redirpos++;
         }
 	if (tok == DINPAR)
 	    tokstr = NULL;
@@ -1204,7 +1213,7 @@
 	    if (tt)
 		break;
 	    /* Otherwise reset the variables we are collecting data in. */
-	    i = tt0 = cp = rd = ins = 0;
+	    i = tt0 = cp = rd = ins = redirpos = 0;
 	}
 	if (lincmd && (tok == STRING || tok == FOR || tok == FOREACH ||
 		       tok == SELECT || tok == REPEAT || tok == CASE)) {
@@ -1213,7 +1222,9 @@
 	    ins = (tok == REPEAT ? 2 : (tok != STRING));
 	    zsfree(cmdstr);
 	    cmdstr = ztrdup(tokstr);
-	    i = 0;
+	    /* If everything before is a redirection, don't reset the index */
+	    if (i != redirpos)
+		i = redirpos = 0;
 	}
 	if (!zleparse && !tt0) {
 	    /* This is done when the lexer reached the word the cursor is on. */
@@ -1399,9 +1410,9 @@
      * foo[_ wrong (note no $).  If we are in a subscript, treat it   *
      * as being in math.                                              */
     if (inwhat != IN_MATH) {
-	int i = 0;
 	char *nnb, *nb = NULL, *ne = NULL;
 
+	i = 0;
 	MB_METACHARINIT();
 	if (itype_end(s, IIDENT, 1) == s)
 	    nnb = s + MB_METACHARLEN(s);


-- 
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