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

Re: PATCH: displaying wide characters



Peter Stephenson <pws@xxxxxxx> wrote:
> Mikael Magnusson wrote:
> > My terminal (rxvt-unicode) automatically breaks a wide character to
> > the next line if you try to print it in the last (singlewidth) column
> > of a line. Zsh does seem to get confused when you get to the second
> > line then.
> 
> Yes, I think this is fairly standard, hence adding spaces in front ought
> to be the right thing to do.

I think this fixes the end-of-line problem, which is the easier one.  If
the screen's just too narrow for the character it simply prints a '?';
that's a very unusual case where safety is probably best.  However, maybe
some other character might make the user more aware of what's going on, '>'
for example?

Index: Src/Zle/zle_refresh.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/Zle/zle_refresh.c,v
retrieving revision 1.31
diff -u -r1.31 zle_refresh.c
--- Src/Zle/zle_refresh.c	19 Oct 2005 23:45:06 -0000	1.31
+++ Src/Zle/zle_refresh.c	24 Oct 2005 16:50:20 -0000
@@ -612,7 +612,7 @@
     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 */
@@ -631,33 +631,33 @@
 	}
 #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 */
@@ -705,14 +705,20 @@
 #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


-- 
Peter Stephenson <pws@xxxxxxx>                  Software Engineer
CSR PLC, Churchill House, Cambridge Business Park, Cowley Road
Cambridge, CB4 0WZ, UK                          Tel: +44 (0)1223 692070


This message has been scanned for viruses by BlackSpider MailControl - www.blackspider.com



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