summary refs log tree commit diff
path: root/Src
diff options
context:
space:
mode:
authorPeter Stephenson <pws@users.sourceforge.net>2005-10-24 16:58:41 +0000
committerPeter Stephenson <pws@users.sourceforge.net>2005-10-24 16:58:41 +0000
commit7c442d2e060df88eba4ae20b462424d644eb9e02 (patch)
treebc22db40f96e5e1d9150484dcf9fe70e15db3289 /Src
parent6f8d328a53bc2c4965b36e36400d1c5e7b4635dd (diff)
downloadzsh-7c442d2e060df88eba4ae20b462424d644eb9e02.tar.gz
zsh-7c442d2e060df88eba4ae20b462424d644eb9e02.tar.xz
zsh-7c442d2e060df88eba4ae20b462424d644eb9e02.zip
21930: handle extra-wide characters at end of line
Diffstat (limited to 'Src')
-rw-r--r--Src/Zle/zle_refresh.c70
1 files changed, 38 insertions, 32 deletions
diff --git a/Src/Zle/zle_refresh.c b/Src/Zle/zle_refresh.c
index 1323d9666..4fbcd1e71 100644
--- a/Src/Zle/zle_refresh.c
+++ b/Src/Zle/zle_refresh.c
@@ -608,7 +608,7 @@ zrefresh(void)
     rpms.sen = *nbuf + winw;
     for (; t < tmpline+tmpll; t++) {
 	if (t == scs)			/* if cursor is here, remember it */
-	    rpms.nvcs = rpms.s - (nbuf[rpms.nvln = rpms.ln]);
+	    rpms.nvcs = rpms.s - nbuf[rpms.nvln = rpms.ln];
 
 	if (*t == ZWC('\n')){		/* newline */
 	    /* text not wrapped */
@@ -627,33 +627,33 @@ zrefresh(void)
 	}
 #ifdef ZLE_UNICODE_SUPPORT
 	else if (iswprint(*t)) {
-	    int width = wcwidth(*t), break2 = 0;
-	    *rpms.s++ = *t;
-	    while (--width > 0) {
+	    int width = wcwidth(*t);
+	    if (width > rpms.sen - rpms.s) {
 		/*
-		 * Character is wider than a single position.
-		 * Put WEOF into the positions above 1 as placeholders.
-		 * This keeps the indexing into the video buffer correct.
+		 * Too wide to fit.  Insert spaces to end of current line.
 		 */
-		if (rpms.s == rpms.sen) {
-		    /*
-		     * Text wrapped.
-		     *
-		     * TODO: hmm, what is the terminal emulator going to
-		     * do?  Let's assume some kind of automatic margin
-		     * behaviour, implying we continue the procedure on the
-		     * next line.  Wrapping behaviour has always been
-		     * problematic.  I foresee interesting times...
-		     */
-		    if (nextline(&rpms, 1)) {
-			break2 = 1;
-			break;
-		    }
+		do {
+		    *rpms.s++ = ZWC(' ');
+		} while (rpms.s < rpms.sen);
+		if (nextline(&rpms, 1))
+		    break;
+		if (t == scs) {
+		    /* Update cursor to this point */
+		    rpms.nvcs = rpms.s - nbuf[rpms.nvln = rpms.ln];
 		}
-		*rpms.s++ = WEOF;
 	    }
-	    if (break2)
-		break;
+	    if (width > rpms.sen - rpms.s) {
+		/*
+		 * The screen width is too small to fit even one
+		 * occurrence.
+		 */
+		*rpms.s++ = ZWC('?');
+	    } else {
+		/* We can fit it without reaching the end of the line. */
+		*rpms.s++ = *t;
+		while (--width > 0)
+		    *rpms.s++ = WEOF;
+	    }
 	}
 #endif
 	else if (ZC_icntrl(*t)) {	/* other control character */
@@ -701,14 +701,20 @@ zrefresh(void)
 #ifdef ZLE_UNICODE_SUPPORT
 	    if (iswprint(*u)) {
 		int width = wcwidth(*u);
-		*rpms.s++ = *u;
-		while (--width > 0) {
-		    /* Wide character, handled as above */
-		    if (rpms.s == rpms.sen) {
-			nbuf[rpms.ln][winw + 1] = ZWC('\n');
-			snextline(&rpms);
-		    }
-		    *rpms.s++ = WEOF;
+		/* Handle wide characters as above */
+		if (width > rpms.sen - rpms.s) {
+		    do {
+			*rpms.s++ = ZWC(' ');
+		    } while (rpms.s < rpms.sen);
+		    nbuf[rpms.ln][winw + 1] = ZWC('\n');
+		    snextline(&rpms);
+		}
+		if (width > rpms.sen - rpms.s) {
+		    *rpms.s++ = ZWC('?');
+		} else {
+		    *rpms.s++ = *u;
+		    while (--width > 0)
+			*rpms.s++ = WEOF;
 		}
 	    }
 	    else