summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog5
-rw-r--r--Src/Zle/zle_tricky.c26
2 files changed, 29 insertions, 2 deletions
diff --git a/ChangeLog b/ChangeLog
index 4b92ddcdd..e9e609c45 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2013-08-02  Peter Stephenson  <p.w.stephenson@ntlworld.com>
+
+	* 31611: Src/Zle/zle_tricky.c: attempt to fix crash in
+	"for in 1; do <[TAB] x".
+
 2013-08-01  Peter Stephenson  <p.stephenson@samsung.com>
 
 	* Thomas Klausner: 31625: Completion/X/Command/_mplayer: mplayer
diff --git a/Src/Zle/zle_tricky.c b/Src/Zle/zle_tricky.c
index 78a9fa490..610055c64 100644
--- a/Src/Zle/zle_tricky.c
+++ b/Src/Zle/zle_tricky.c
@@ -1095,6 +1095,7 @@ get_comp_string(void)
      * the command word is not at index zero in the array.
      */
     int redirpos;
+    int noword;
     char *s = NULL, *tmp, *p, *tt = NULL, rdop[20];
     char *linptr, *u;
 
@@ -1165,7 +1166,7 @@ get_comp_string(void)
     * and whatnot. */
 
     do {
-        qsub = 0;
+        qsub = noword = 0;
 
 	lincmd = ((incmdpos && !ins && !incond) ||
 		  (oins == 2 && wordpos == 2) ||
@@ -1239,6 +1240,19 @@ get_comp_string(void)
 	     * leave the loop.                                           */
 	    if (tt)
 		break;
+	    if (ins < 2) {
+		/*
+		 * Don't add this as a word, because we're about to start
+		 * a new command line: pretend there's no string here.
+		 * We don't dare do this if we're using one of the
+		 * *really* gross hacks with ins to get later words
+		 * to look like command words, because we don't
+		 * understand how they work.  Quite possibly we
+		 * should be using a mechanism like the one here rather
+		 * than the ins thing.
+		 */
+		noword = 1;
+	    }
 	    /* Otherwise reset the variables we are collecting data in. */
 	    wordpos = cp = rd = ins = redirpos = 0;
 	    tt0 = NULLTOK;
@@ -1253,6 +1267,14 @@ get_comp_string(void)
 	    /* If everything before is a redirection, don't reset the index */
 	    if (wordpos != redirpos)
 		wordpos = redirpos = 0;
+	} else if (tok == SEPER) {
+	    /*
+	     * A following DOLOOP should cause us to reset to the start
+	     * of the command line.  For some reason we only recognise
+	     * DOLOOP for this purpose (above) if ins is set.  Why?
+	     * Don't ask pointless questions.
+	     */
+	    ins = 1;
 	}
 	if (!lexflags && tt0 == NULLTOK) {
 	    /* This is done when the lexer reached the word the cursor is on. */
@@ -1322,7 +1344,7 @@ get_comp_string(void)
 	    else if (tok == DAMPER)
 		tokstr = "&&";
 	}
-	if (!tokstr)
+	if (!tokstr || noword)
 	    continue;
 	/* Hack to allow completion after `repeat n do'. */
 	if (oins == 2 && !wordpos && !strcmp(tokstr, "do"))