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

PATCH: more extra-wide character refreshing.



This fixes problems I was having when inserting characters on a command
line that wrapped to the next screen line.  The main fix is the new test
that starts the for-loop; most of the change inside is reindentation,
though I put some possibly paranoid checks into the code for insertion.
I think the problem was it didn't well handle the case where the
change between the old and new lines finished in the middle of a wide
character.

I've tried to guard against an infinite loop, but it's complicated...

Index: Src/Zle/zle_refresh.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/Zle/zle_refresh.c,v
retrieving revision 1.37
diff -u -r1.37 zle_refresh.c
--- Src/Zle/zle_refresh.c	28 Oct 2005 22:13:44 -0000	1.37
+++ Src/Zle/zle_refresh.c	30 Oct 2005 20:35:18 -0000
@@ -1069,128 +1069,144 @@
 /* 3: main display loop - write out the buffer using whatever tricks we can */
 
     for (;;) {
-	if (*nl && *ol && nl[1] == ol[1]) {
-	    /* skip only if second chars match */
 #ifdef MULTIBYTE_SUPPORT
-	    int ccs_was = ccs;
+	if ((!*nl || *nl != WEOF) && (!*ol || *ol != WEOF)) {
 #endif
-	/* skip past all matching characters */
-	    for (; *nl && (*nl == *ol); nl++, ol++, ccs++) ;
+	    if (*nl && *ol && nl[1] == ol[1]) {
+		/* skip only if second chars match */
 #ifdef MULTIBYTE_SUPPORT
-	    /* Make sure ol and nl are pointing to real characters */
-	    while ((*nl == WEOF || *ol == WEOF) && ccs > ccs_was) {
-		nl--;
-		ol--;
-		ccs--;
-	    }
+		int ccs_was = ccs;
 #endif
-	}
+		/* skip past all matching characters */
+		for (; *nl && (*nl == *ol); nl++, ol++, ccs++) ;
+#ifdef MULTIBYTE_SUPPORT
+		/* Make sure ol and nl are pointing to real characters */
+		while ((*nl == WEOF || *ol == WEOF) && ccs > ccs_was) {
+		    nl--;
+		    ol--;
+		    ccs--;
+		}
+#endif
+	    }
 
-	if (!*nl) {
-	    if (ccs == winw && hasam && char_ins > 0 && ins_last
-		&& vcs != winw) {
-		nl--;           /* we can assume we can go back here */
-		moveto(ln, winw - 1);
-		zputc(*nl);
-		vcs++;
-		return;         /* write last character in line */
+	    if (!*nl) {
+		if (ccs == winw && hasam && char_ins > 0 && ins_last
+		    && vcs != winw) {
+		    nl--;           /* we can assume we can go back here */
+		    moveto(ln, winw - 1);
+		    zputc(*nl);
+		    vcs++;
+		    return;         /* write last character in line */
+		}
+		if ((char_ins <= 0) || (ccs >= winw))    /* written everything */
+		    return;
+		if (tccan(TCCLEAREOL) && (char_ins >= tclen[TCCLEAREOL])
+		    && col_cleareol != -2)
+		    /* we've got junk on the right yet to clear */
+		    col_cleareol = 0;	/* force a clear to end of line */
 	    }
-	    if ((char_ins <= 0) || (ccs >= winw))    /* written everything */
-		return;
-	    if (tccan(TCCLEAREOL) && (char_ins >= tclen[TCCLEAREOL])
-	    	&& col_cleareol != -2)
-	    /* we've got junk on the right yet to clear */
-		col_cleareol = 0;	/* force a clear to end of line */
-	}
 
-	moveto(ln, ccs);	/* move to where we do all output from */
+	    moveto(ln, ccs);	/* move to where we do all output from */
 
-    /* if we can finish quickly, do so */
-	if ((col_cleareol >= 0) && (ccs >= col_cleareol)) {
-	    tcout(TCCLEAREOL);
-	    return;
-	}
+	    /* if we can finish quickly, do so */
+	    if ((col_cleareol >= 0) && (ccs >= col_cleareol)) {
+		tcout(TCCLEAREOL);
+		return;
+	    }
 
-    /* we've written out the new but yet to clear rubbish due to inserts */
-	if (!*nl) {
-	    i = (winw - ccs < char_ins) ? (winw - ccs) : char_ins;
-	    if (tccan(TCDEL) && (tcdelcost(i) <= i + 1))
-		tc_delchars(i);
-	    else {
-		vcs += i;
-		while (i-- > 0)
-		    zputc(ZWC(' '));
+	    /* we've written out the new but yet to clear rubbish due to inserts */
+	    if (!*nl) {
+		i = (winw - ccs < char_ins) ? (winw - ccs) : char_ins;
+		if (tccan(TCDEL) && (tcdelcost(i) <= i + 1))
+		    tc_delchars(i);
+		else {
+		    vcs += i;
+		    while (i-- > 0)
+			zputc(ZWC(' '));
+		}
+		return;
 	    }
-	    return;
-	}
 
-    /* if we've reached the end of the old buffer, then there are few tricks
-       we can do, so we just dump out what we must and clear if we can */
-	if (!*ol) {
-	    i = (col_cleareol >= 0) ? col_cleareol : nllen;
-	    i -= vcs;
-	    zwrite(nl, i);
-	    vcs += i;
-	    if (col_cleareol >= 0)
-		tcout(TCCLEAREOL);
-	    return;
-	}
+	    /* if we've reached the end of the old buffer, then there are few tricks
+	       we can do, so we just dump out what we must and clear if we can */
+	    if (!*ol) {
+		i = (col_cleareol >= 0) ? col_cleareol : nllen;
+		i -= vcs;
+		zwrite(nl, i);
+		vcs += i;
+		if (col_cleareol >= 0)
+		    tcout(TCCLEAREOL);
+		return;
+	    }
 
-    /* inserting & deleting chars: we can if there's no right-prompt */
-	if ((ln || !put_rpmpt || !oput_rpmpt) 
+	    /* inserting & deleting chars: we can if there's no right-prompt */
+	    if ((ln || !put_rpmpt || !oput_rpmpt) 
 #ifdef MULTIBYTE_SUPPORT
-	    && *ol != WEOF && *nl != WEOF
+		&& *ol != WEOF && *nl != WEOF
 #endif
-	    && nl[1] && ol[1] && nl[1] != ol[1]) { 
+		&& nl[1] && ol[1] && nl[1] != ol[1]) { 
 
-	/* deleting characters - see if we can find a match series that
-	   makes it cheaper to delete intermediate characters
-	   eg. oldline: hifoobar \ hopefully cheaper here to delete two
-	       newline: foobar	 / characters, then we have six matches */
-	    /* TODO replace wpfxlen back with pfxlen when the latter is fixed */
-	    if (tccan(TCDEL)) {
-		for (i = 1; *(ol + i); i++)
-		    if (tcdelcost(i) < wpfxlen(ol + i, nl)) {
-			tc_delchars(i);
-			ol += i;
-			char_ins -= i;
-#ifdef MULTIBYTE_SUPPORT
-			while (*ol == WEOF) {
-			    ol++;
-			    char_ins--;
+		/* deleting characters - see if we can find a match series that
+		   makes it cheaper to delete intermediate characters
+		   eg. oldline: hifoobar \ hopefully cheaper here to delete two
+		   newline: foobar	 / characters, then we have six matches */
+		/* TODO replace wpfxlen back with pfxlen when the latter is fixed */
+		if (tccan(TCDEL)) {
+		    for (i = 1; *(ol + i); i++)
+			if (tcdelcost(i) < wpfxlen(ol + i, nl)) {
+			    tc_delchars(i);
+			    ol += i;
+			    char_ins -= i;
+#ifdef MULTIBYTE_SUPPORT
+			    while (*ol == WEOF) {
+				ol++;
+				char_ins--;
+			    }
+#endif
+			    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); i++)
+			if (tcinscost(i) < wpfxlen(nl + i, ol)) {
+			    tc_inschars(i);
+			    zwrite(nl, i);
+			    nl += i;
+#ifdef MULTIBYTE_SUPPORT
+			    while (*nl == WEOF) {
+				nl++;
+				i++;
+			    }
+#endif
+			    char_ins += i;
+			    ccs = (vcs += i);
+			    /* if we've pushed off the right, truncate oldline */
+			    for (i = 0; *(ol + i) && i < winw - ccs; i++);
+#ifdef MULTIBYTE_SUPPORT
+			    while (ol[i] == WEOF)
+				i++;
 #endif
-			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); i++)
-		    if (tcinscost(i) < wpfxlen(nl + i, ol)) {
-			tc_inschars(i);
-			zwrite(nl, i);
-			nl += i;
-			char_ins += i;
-			ccs = (vcs += i);
-		    /* if we've pushed off the right, truncate oldline */
-			for (i = 0; *(ol + i) && i < winw - ccs; i++);
-			if (i == winw - ccs) {
-			    *(ol + i) = ZWC('\0');
-			    ins_last = 1;
+			    if (i >= winw - ccs) {
+				*(ol + i) = ZWC('\0');
+				ins_last = 1;
+			    }
+			    i = 0;
+			    break;
 			}
-			i = 0;
-			break;
-		    }
-		if (!i)
-		    continue;
+		    if (!i)
+			continue;
+		}
 	    }
+#ifdef MULTIBYTE_SUPPORT
 	}
+#endif
     /* we can't do any fancy tricks, so just dump the single character
        and keep on trying */
 #ifdef MULTIBYTE_SUPPORT
@@ -1204,7 +1220,7 @@
 	     * Make sure we always overwrite the complete width of
 	     * a character that was there before.
 	     */
-	} while (*ol == WEOF && *nl);
+	} while ((*ol == WEOF && *nl) || (*nl == WEOF && *ol));
 #endif
     }
 }


-- 
Peter Stephenson <p.w.stephenson@xxxxxxxxxxxx>
Web page still at http://www.pwstephenson.fsnet.co.uk/



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