Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

[PATCH] use clear-to-end to reduce trailing whitespace



zsh leaves trailing whitespace in the terminal in some circumstances,
e.g. when moving from a long history line to a short history line.  (The
short line gets padded with spaces to the length of the longer one.)

The cause seems to be excessively conservative conditions applied to use
of the clear-to-end terminal control code.  The patch below seems to
address the problem.  It also gets rid of the "is the control sequence
longer than the spaces" cost check, because zsh should be using
clear-to-end even when it could send fewer characters by padding with
spaces because padding with spaces produces display and copy-and-paste
artifacts in terminals.

diff --git a/Src/Zle/zle_refresh.c b/Src/Zle/zle_refresh.c
index f076bdd61..7f4fb1362 100644
--- a/Src/Zle/zle_refresh.c
+++ b/Src/Zle/zle_refresh.c
@@ -1772,17 +1772,12 @@ refreshline(int ln)
 	p1 = zhalloc((winw + 2) * sizeof(*p1));
 	if (nllen)
 	    ZR_memcpy(p1, nl, nllen);
-	ZR_memset(p1 + nllen, zr_sp, winw - nllen);
-	p1[winw] = zr_zr;
-	if (nllen < winw)
-	    p1[winw + 1] = zr_zr;
-	else
-	    p1[winw + 1] = nl[winw + 1];
+	p1[nllen] = zr_zr;
+	p1[nllen + 1] = nl ? nl[nllen + 1] : zr_zr;
 	if (ln && nbuf[ln])
 	    ZR_memcpy(nl, p1, winw + 2);	/* next time obuf will be up-to-date */
 	else
 	    nl = p1;		/* don't keep the padding for prompt line */
-	nllen = winw;
     } else if (ollen > nllen) { /* make new line at least as long as old */
 	p1 = zhalloc((ollen + 1) * sizeof(*p1));
 	ZR_memcpy(p1, nl, nllen);
@@ -1797,19 +1792,15 @@ refreshline(int ln)
    With automatic margins, we shouldn't do it if there is another line, in
    case it messes up cut and paste. */
 
-    if (hasam && ln < nlnct - 1 && rnllen == winw)
-	col_cleareol = -2;	/* clearing eol would be evil so don't */
-    else {
-	col_cleareol = -1;
-	if (tccan(TCCLEAREOL) && (nllen == winw || put_rpmpt != oput_rpmpt)) {
-	    for (i = nllen; i && ZR_equal(zr_sp, nl[i - 1]); i--)
-		;
-	    for (j = ollen; j && ZR_equal(ol[j - 1], zr_sp); j--)
-		;
-	    if ((j > i + tclen[TCCLEAREOL])	/* new buf has enough spaces */
-		|| (nllen == winw && ZR_equal(zr_sp, nl[winw - 1])))
-		col_cleareol = i;
-	}
+/* 2: see if we can clear to end-of-line. Always use TCCLEAREOL when available
+   to avoid leaving trailing spaces when moving between lines of different lengths. */
+
+    col_cleareol = -1;
+    if (tccan(TCCLEAREOL)) {
+        /* Find first trailing space in new line */
+        for (i = nllen; i && ZR_equal(zr_sp, nl[i - 1]); i--)
+            ;
+        col_cleareol = i;
     }
 
 /* 2b: first a new trick for automargin niceness - good for cut and paste */




Messages sorted by: Reverse Date, Date, Thread, Author