about summary refs log tree commit diff
path: root/Src/Zle
diff options
context:
space:
mode:
Diffstat (limited to 'Src/Zle')
-rw-r--r--Src/Zle/compcore.c15
-rw-r--r--Src/Zle/compmatch.c8
-rw-r--r--Src/Zle/compresult.c3
3 files changed, 22 insertions, 4 deletions
diff --git a/Src/Zle/compcore.c b/Src/Zle/compcore.c
index 38cbe03a2..4fdfaa159 100644
--- a/Src/Zle/compcore.c
+++ b/Src/Zle/compcore.c
@@ -49,6 +49,11 @@ mod_export int dolastprompt;
 /**/
 mod_export int oldlist, oldins;
 
+/* Original prefix/suffix lengths. Flag saying if they changed. */
+
+/**/
+int origlpre, origlsuf, lenchanged;
+
 /* This is used to decide when the cursor should be moved to the end of    *
  * the inserted word: 0 - never, 1 - only when a single match is inserted, *
  * 2 - when a full match is inserted (single or menu), 3 - always.         */
@@ -691,6 +696,11 @@ callcompfunc(char *s, char *fn)
 	compqiprefix = ztrdup(qipre ? qipre : "");
 	zsfree(compqisuffix);
 	compqisuffix = ztrdup(qisuf ? qisuf : "");
+	origlpre = (strlen(compqiprefix) + strlen(compiprefix) +
+		    strlen(compprefix));
+	origlsuf = (strlen(compqisuffix) + strlen(compisuffix) +
+		    strlen(compsuffix));
+	lenchanged = 0;
 	compcurrent = (usea ? (clwpos + 1 - aadd) : 0);
 
 	zsfree(complist);
@@ -1700,6 +1710,11 @@ addmatches(Cadata dat, char **argv)
 	    lsuf = dupstring(compsuffix);
 	    llpl = strlen(lpre);
 	    llsl = strlen(lsuf);
+
+	    if (llpl + strlen(compqiprefix) + strlen(lipre) != origlpre ||
+		llsl + strlen(compqisuffix) + strlen(lisuf) != origlsuf)
+		lenchanged = 1;
+
 	    /* Test if there is an existing -P prefix. */
 	    if (dat->pre && *dat->pre) {
 		pl = pfxlen(dat->pre, lpre);
diff --git a/Src/Zle/compmatch.c b/Src/Zle/compmatch.c
index 33b5b8a40..60a2fe7b9 100644
--- a/Src/Zle/compmatch.c
+++ b/Src/Zle/compmatch.c
@@ -473,7 +473,7 @@ match_str(char *l, char *w, Brinfo *bpp, int bc, int *rwlp,
 	bp = bp->next;
     }
     /*** This once was: `while (ll && lw)', but then ignored characters at
-     *   the end or not, well, ignored. */
+     *   the end were not, well, ignored. */
     while (ll) {
 
 	/* Hm, we unconditionally first tried the matchers for the cases
@@ -1859,8 +1859,10 @@ join_clines(Cline o, Cline n)
 	    if (!(o->flags & CLF_NEW) && (n->flags & CLF_NEW)) {
 		Cline t, tn;
 
-		for (t = n; (tn = t->next) && (tn->flags & CLF_NEW); t = tn);
-		if (tn && cmp_anchors(o, tn, 0)) {
+		for (t = n; (tn = t->next) &&
+			 ((tn->flags & CLF_NEW) || !cmp_anchors(o, tn, 0));
+		     t = tn);
+		if (tn) {
 		    diff = sub_join(o, n, tn, 0);
 
 #if 0
diff --git a/Src/Zle/compresult.c b/Src/Zle/compresult.c
index 531017afb..c55b65b0a 100644
--- a/Src/Zle/compresult.c
+++ b/Src/Zle/compresult.c
@@ -656,7 +656,8 @@ do_ambiguous(void)
 	/* Sometimes the different match specs used may result in a cline
 	 * that gives an empty string. If that happened, we re-insert the
          * old string. Unless there were matches added with -U, that is. */
-	if (!(lastend - wb) && !hasunmatched) {
+
+	if (lastend < we && !lenchanged && !hasunmatched) {
 	    cs = wb;
 	    foredel(lastend - wb);
 	    inststrlen(old, 0, we - wb);