about summary refs log tree commit diff
diff options
context:
space:
mode:
authorBarton E. Schaefer <schaefer@zsh.org>2013-10-03 15:59:52 -0700
committerBarton E. Schaefer <schaefer@zsh.org>2013-10-03 15:59:52 -0700
commit75fdec17b1ed7e4b3ede4b995003175b885d5f6d (patch)
treefb38e95b3346406477c604ff92ff43a3634fb6fe
parentea30fdaf25ad11ca727d3708bdd47b0f90d9ff68 (diff)
downloadzsh-75fdec17b1ed7e4b3ede4b995003175b885d5f6d.tar.gz
zsh-75fdec17b1ed7e4b3ede4b995003175b885d5f6d.tar.xz
zsh-75fdec17b1ed7e4b3ede4b995003175b885d5f6d.zip
31784: better line width calculation for completion listings
When deciding whether there is enough horizontal space to show completion
descriptions for each match in a listing, treat the separator as part of
the description rather than as part of the match, and account for lines
that have already wrapped due to very long matches.
-rw-r--r--ChangeLog6
-rw-r--r--Src/Zle/computil.c58
2 files changed, 39 insertions, 25 deletions
diff --git a/ChangeLog b/ChangeLog
index 9ec3bc581..bd37e0a2d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,11 @@
 2013-10-03  Barton E. Schaefer  <schaefer@zsh.org>
 
+	* 31784: Src/Zle/computil.c: when deciding whether there is enough
+	horizontal space to show completion descriptions for each match in
+	a listing, treat the separator as part of the description rather
+	than as part of the match, and account for lines that have already
+	wrapped due to very long matches.
+	
 	* 31781: Src/Zle/computil.c: "compdescribe -i" must clear the
 	completion list column padding width along with the rest of the
 	description state.  Cf. 31782.
diff --git a/Src/Zle/computil.c b/Src/Zle/computil.c
index ee3918566..f5e6ba195 100644
--- a/Src/Zle/computil.c
+++ b/Src/Zle/computil.c
@@ -644,35 +644,43 @@ cd_get(char **params)
 		    p += str->len;
                     memset(p, ' ', (l = (cd_state.premaxw - str->width + CM_SPACE)));
 		    p += l;
-		    strcpy(p, cd_state.sep);
-		    p += cd_state.slen;
 
-		    /*
-		     * copy a character at once until no more screen width
-		     * is available. Leave 1 character at the end of screen
-		     * as safety margin
-		     */
 		    remw = zterm_columns - cd_state.premaxw -
 			cd_state.swidth - 3;
-		    d = str->desc;
-		    w = MB_METASTRWIDTH(d);
-		    if (w <= remw)
-			strcpy(p, d);
-		    else {
-			pp = p;
-			while (remw > 0 && *d) {
-			    l = MB_METACHARLEN(d);
-			    memcpy(pp, d, l);
-			    pp[l] = '\0';
-			    w = MB_METASTRWIDTH(pp);
-			    if (w > remw) {
-				*pp = '\0';
-				break;
-			    }
+		    while (remw < 0 && zterm_columns) {
+			/* line wrapped, use remainder of the extra line */
+			remw += zterm_columns;
+		    }
+		    if (cd_state.slen < remw) {
+			strcpy(p, cd_state.sep);
+			p += cd_state.slen;
+			remw -= cd_state.slen;
 
-			    pp += l;
-			    d += l;
-			    remw -= w;
+			/*
+			 * copy a character at once until no more screen
+			 * width is available. Leave 1 character at the
+			 * end of screen as safety margin
+			 */
+			d = str->desc;
+			w = MB_METASTRWIDTH(d);
+			if (w <= remw)
+			    strcpy(p, d);
+			else {
+			    pp = p;
+			    while (remw > 0 && *d) {
+				l = MB_METACHARLEN(d);
+				memcpy(pp, d, l);
+				pp[l] = '\0';
+				w = MB_METASTRWIDTH(pp);
+				if (w > remw) {
+				    *pp = '\0';
+				    break;
+				}
+
+				pp += l;
+				d += l;
+				remw -= w;
+			    }
 			}
 		    }