Zsh Mailing List Archive
Messages sorted by:
Reverse Date,
Date,
Thread,
Author
PATCH: more extra-wide character refreshing.
- X-seq: zsh-workers 21957
- From: Peter Stephenson <p.w.stephenson@xxxxxxxxxxxx>
- To: zsh-workers@xxxxxxxxxx (Zsh hackers list)
- Subject: PATCH: more extra-wide character refreshing.
- Date: Sun, 30 Oct 2005 20:35:55 +0000
- Mailing-list: contact zsh-workers-help@xxxxxxxxxx; run by ezmlm
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