diff options
Diffstat (limited to 'Src')
-rw-r--r-- | Src/Zle/compcore.c | 15 | ||||
-rw-r--r-- | Src/Zle/compresult.c | 15 |
2 files changed, 24 insertions, 6 deletions
diff --git a/Src/Zle/compcore.c b/Src/Zle/compcore.c index 3e4d4c93c..b0ee2b1d0 100644 --- a/Src/Zle/compcore.c +++ b/Src/Zle/compcore.c @@ -163,10 +163,10 @@ mod_export struct cldata listdat; /**/ mod_export int ispattern, haspattern; -/* Non-zero if at least one match was added without -U. */ +/* Non-zero if at least one match was added without/with -U. */ /**/ -mod_export int hasmatched; +mod_export int hasmatched, hasunmatched; /* The current group of matches. */ @@ -304,7 +304,7 @@ do_completion(Hookdef dummy, Compldat dat) startauto = isset(AUTOMENU); movetoend = ((cs == we || isset(ALWAYSTOEND)) ? 2 : 1); showinglist = 0; - hasmatched = 0; + hasmatched = hasunmatched = 0; minmlen = 1000000; maxmlen = -1; @@ -1522,9 +1522,12 @@ addmatches(Cadata dat, char **argv) /* Switch back to the heap that was used when the completion widget * was invoked. */ SWITCHHEAPS(compheap) { - if ((doadd = (!dat->apar && !dat->opar && !dat->dpar)) && - (dat->aflags & CAF_MATCH)) - hasmatched = 1; + if ((doadd = (!dat->apar && !dat->opar && !dat->dpar))) { + if (dat->aflags & CAF_MATCH) + hasmatched = 1; + else + hasunmatched = 1; + } if (dat->apar) aparl = newlinklist(); if (dat->opar) diff --git a/Src/Zle/compresult.c b/Src/Zle/compresult.c index e5d0617ef..64de5c744 100644 --- a/Src/Zle/compresult.c +++ b/Src/Zle/compresult.c @@ -610,6 +610,7 @@ do_ambiguous(void) do_ambig_menu(); } else if (ainfo) { int atend = (cs == we), la, eq, tcs; + VARARR(char, old, we - wb); minfo.cur = NULL; minfo.asked = 0; @@ -617,11 +618,25 @@ do_ambiguous(void) fixsuffix(); /* First remove the old string from the line. */ + tcs = cs; cs = wb; + memcpy(old, (char *) line + wb, we - wb); foredel(we - wb); /* Now get the unambiguous string and insert it into the line. */ cline_str(ainfo->line, 1, NULL); + + /* Sometimes the different match specs used may result in a cline + * that is shorter than the original string. If that happened, we + * re-insert the old string. Unless there were matches added with + * -U, that is. */ + if (lastend - wb < we - wb && !hasunmatched) { + cs = wb; + foredel(lastend - wb); + inststrlen(old, 0, we - wb); + lastend = we; + cs = tcs; + } if (eparq) { tcs = cs; cs = lastend; |