zsh-workers
 help / color / mirror / code / Atom feed
From: Peter Stephenson <p.w.stephenson@ntlworld.com>
To: zsh workers <zsh-workers@zsh.org>
Subject: Re: Fun redraw issue with double-width characters
Date: Sun, 24 Oct 2010 19:12:29 +0100	[thread overview]
Message-ID: <20101024191229.0bc47b23@pws-pc.ntlworld.com> (raw)
In-Reply-To: <AANLkTinpzD04E3cm+myCUDVEXvhUhQc7VyyNzz2WxzvL@mail.gmail.com>

On Sun, 24 Oct 2010 14:11:08 +0200
Mikael Magnusson <mikachu@gmail.com> wrote:
> I got a random thought, "what if i enter five doublewidth characters,
> then go back to the start and enter a bunch of spaces". Turns out
> doing that causes the line to clear and cursor to move up one line.
> Doesn't happen with four or less.

I think that may depend on what you're inserting: if you're inserting
stuff such that the character you're inserting changes the line near
the start, it may happen early.   But this may be a wild goose chase.

> Long story short, it happens only if
> ich1 is defined in the terminfo for the current $TERM, which it
> happens to be for rxvt-unicode, but also for rxvt. It doesn't matter
> if you're using xterm or rxvt or urxvt, just set TERM=rxvt, enter five
> ま and go back to the start and hold down space. I don't really know
> where to begin debugging this.

Actually, there's only one use of insert in the entire source, which is
in a quite short chunk in zle_refresh.c, so localising it was the easy
bit.

After staring enough I think I've worked out what's going on, but you
might want to stare at it, too.  Much of this is reformatting for
clarity, the important bit is near the end where I've moved an extra
chunk inside an #ifdef MULTIBYTE_SUPPORT with a new comment.

Index: Src/Zle/zle_refresh.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/Zle/zle_refresh.c,v
retrieving revision 1.81
diff -p -u -r1.81 zle_refresh.c
--- Src/Zle/zle_refresh.c	17 Oct 2010 17:59:27 -0000	1.81
+++ Src/Zle/zle_refresh.c	24 Oct 2010 18:06:22 -0000
@@ -2000,7 +2000,7 @@ refreshline(int ln)
 		   newline: foobar	 / characters, then we have six matches */
 		if (tccan(TCDEL)) {
 		    int first = 1;
-		    for (i = 1; ol[i].chr; i++)
+		    for (i = 1; ol[i].chr; i++) {
 			if (tcdelcost(i) < wpfxlen(ol + i, nl)) {
 			    /*
 			     * Some terminals will output the current
@@ -2023,15 +2023,19 @@ refreshline(int ln)
 			    i = 0;
 			    break;
 			}
+		    }
 		    if (!i)
 			continue;
 		}
-		/* inserting characters - characters pushed off the right should be
-		   annihilated, but we don't do this if we're on the last line lest
-		   undesired scrolling occurs due to `illegal' characters on screen */
-
-		if (tccan(TCINS) && (vln != lines - 1)) {	/* not on last line */
-		    for (i = 1; nl[i].chr; i++)
+		/*
+		 * inserting characters - characters pushed off the right
+		 * should be annihilated, but we don't do this if we're on the
+		 * last line lest undesired scrolling occurs due to `illegal'
+		 * characters on screen
+		 */ 
+		if (tccan(TCINS) && (vln != lines - 1)) {
+		    /* not on last line */
+		    for (i = 1; nl[i].chr; i++) {
 			if (tcinscost(i) < wpfxlen(ol, nl + i)) {
 			    tc_inschars(i);
 			    zwrite(nl, i);
@@ -2044,19 +2048,37 @@ refreshline(int ln)
 #endif
 			    char_ins += i;
 			    ccs = (vcs += i);
-			    /* if we've pushed off the right, truncate oldline */
-			    for (i = 0; ol[i].chr && i < winw - ccs; i++);
+			    /*
+			     * if we've pushed off the right, truncate
+			     * oldline
+			     */
+			    for (i = 0; ol[i].chr && i < winw - ccs; i++)
+				;
 #ifdef MULTIBYTE_SUPPORT
 			    while (ol[i].chr == WEOF)
 				i++;
-#endif
 			    if (i >= winw - ccs) {
+				/*
+				 * Yes, we're over the right.
+				 * Make sure we truncate at the real
+				 * character, not a WEOF added to
+				 * make up the width.
+				 */
+				while (ol[i-1].chr == WEOF)
+				    i--;
 				ol[i] = zr_zr;
 				ins_last = 1;
 			    }
+#else
+			    if (i >= winw - ccs) {
+				ol[i] = zr_zr;
+				ins_last = 1;
+			    }
+#endif
 			    i = 0;
 			    break;
 			}
+		    }
 		    if (!i)
 			continue;
 		}

-- 
Peter Stephenson <p.w.stephenson@ntlworld.com>
Web page now at http://homepage.ntlworld.com/p.w.stephenson/


  reply	other threads:[~2010-10-24 19:19 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-10-24 12:11 Mikael Magnusson
2010-10-24 18:12 ` Peter Stephenson [this message]
2010-10-25  4:14   ` Mikael Magnusson
2010-10-25 14:31     ` Bart Schaefer
2011-05-27  1:28     ` Mikael Magnusson
2011-05-27  8:44       ` Peter Stephenson

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20101024191229.0bc47b23@pws-pc.ntlworld.com \
    --to=p.w.stephenson@ntlworld.com \
    --cc=zsh-workers@zsh.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/zsh/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).