summary refs log tree commit diff
diff options
context:
space:
mode:
authorPeter Stephenson <pws@zsh.org>2016-11-29 17:08:56 +0000
committerPeter Stephenson <pws@zsh.org>2016-11-29 17:08:56 +0000
commit32daf2a0aa3c72e8b43cf28e880f1aeffde937da (patch)
treeba76935c5e45f70291a84d447d63c20018295e26
parent3a83e481ab6d9a250978ba0103c96f167407733a (diff)
downloadzsh-32daf2a0aa3c72e8b43cf28e880f1aeffde937da.tar.gz
zsh-32daf2a0aa3c72e8b43cf28e880f1aeffde937da.tar.xz
zsh-32daf2a0aa3c72e8b43cf28e880f1aeffde937da.zip
40026: Fix for completion after redirection.
This could get confused about where we were in the command
line word array e.g. after the > of "!> .".  Also take more care
if does confused, with debug output. Also neaten up one
obscure test.
-rw-r--r--ChangeLog6
-rw-r--r--Src/Zle/zle_tricky.c24
2 files changed, 25 insertions, 5 deletions
diff --git a/ChangeLog b/ChangeLog
index 655516d04..a016ce0e6 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2016-11-29  Peter Stephenson  <p.stephenson@samsung.com>
+
+	* 40026: Src/Zle/zle_tricky.c: More care with redirection
+	completion.  Fixes for completion after > in "!> ." that
+	should add to sanity.
+
 2016-11-29  Daniel Shahaf  <d.s@daniel.shahaf.name>
 
 	* unposted: Completion/Zsh/Context/_subscript: Complete the
diff --git a/Src/Zle/zle_tricky.c b/Src/Zle/zle_tricky.c
index c8d3bb35b..3d8679119 100644
--- a/Src/Zle/zle_tricky.c
+++ b/Src/Zle/zle_tricky.c
@@ -1305,8 +1305,12 @@ get_comp_string(void)
 	    zsfree(cmdstr);
 	    cmdstr = ztrdup(tokstr);
 	    cmdtok = tok;
-	    /* If everything before is a redirection, don't reset the index */
-	    if (wordpos != redirpos)
+	    /*
+	     * If everything before is a redirection, or anything
+	     * complicated enough that we've seen the word the
+	     * cursor is on, don't reset the index.
+	     */
+	    if (wordpos != redirpos && clwpos == -1)
 		wordpos = redirpos = 0;
 	} else if (tok == SEPER) {
 	    /*
@@ -1414,9 +1418,17 @@ get_comp_string(void)
 	/* If this is the word the cursor is in and we added a `x', *
 	 * remove it.                                               */
 	if (clwpos == wordpos++ && addedx) {
+	    int chuck_at, word_diff;
 	    zlemetacs_qsub = zlemetacs - qsub;
-	    chuck(&clwords[wordpos - 1][((zlemetacs_qsub - wb) >= sl) ?
-				 (sl - 1) : (zlemetacs_qsub - wb)]);
+	    word_diff = zlemetacs_qsub - wb;
+	    /* Ensure we chuck within the word... */
+	    if (word_diff >= sl)
+		chuck_at = sl -1;
+	    else if (word_diff < 0)
+		chuck_at = 0;
+	    else
+		chuck_at = word_diff;
+	    chuck(&clwords[wordpos - 1][chuck_at]);
 	}
     } while (tok != LEXERR && tok != ENDINPUT &&
 	     (tok != SEPER || (lexflags && tt0 == NULLTOK)));
@@ -1464,7 +1476,9 @@ get_comp_string(void)
 	t0 = STRING;
     } else if (t0 == STRING || t0 == TYPESET) {
 	/* We found a simple string. */
-	s = ztrdup(clwords[clwpos]);
+	s = clwords[clwpos];
+	DPUTS(!s, "Completion word has disappeared!");
+	s = ztrdup(s ? s : "");
     } else if (t0 == ENVSTRING) {
 	char sav;
 	/* The cursor was inside a parameter assignment. */