From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 16494 invoked from network); 30 Oct 2005 20:36:32 -0000 Received: from news.dotsrc.org (HELO a.mx.sunsite.dk) (130.225.247.88) by ns1.primenet.com.au with SMTP; 30 Oct 2005 20:36:32 -0000 Received: (qmail 42444 invoked from network); 30 Oct 2005 20:36:26 -0000 Received: from sunsite.dk (130.225.247.90) by a.mx.sunsite.dk with SMTP; 30 Oct 2005 20:36:26 -0000 Received: (qmail 26736 invoked by alias); 30 Oct 2005 20:36:23 -0000 Mailing-List: contact zsh-workers-help@sunsite.dk; run by ezmlm Precedence: bulk X-No-Archive: yes X-Seq: 21957 Received: (qmail 26726 invoked from network); 30 Oct 2005 20:36:23 -0000 Received: from news.dotsrc.org (HELO a.mx.sunsite.dk) (130.225.247.88) by sunsite.dk with SMTP; 30 Oct 2005 20:36:23 -0000 Received: (qmail 42103 invoked from network); 30 Oct 2005 20:36:23 -0000 Received: from mta09-winn.ispmail.ntl.com (81.103.221.49) by a.mx.sunsite.dk with SMTP; 30 Oct 2005 20:36:22 -0000 Received: from aamta11-winn.ispmail.ntl.com ([81.103.221.35]) by mta09-winn.ispmail.ntl.com with ESMTP id <20051030203621.EJTP8609.mta09-winn.ispmail.ntl.com@aamta11-winn.ispmail.ntl.com> for ; Sun, 30 Oct 2005 20:36:21 +0000 Received: from pwslaptop.csr.com ([81.105.238.64]) by aamta11-winn.ispmail.ntl.com with ESMTP id <20051030203621.JSLU8786.aamta11-winn.ispmail.ntl.com@pwslaptop.csr.com> for ; Sun, 30 Oct 2005 20:36:21 +0000 Received: from pwslaptop.csr.com (pwslaptop.csr.com [127.0.0.1]) by pwslaptop.csr.com (8.13.4/8.13.4) with ESMTP id j9UKZvlF007754 for ; Sun, 30 Oct 2005 20:35:57 GMT Received: from pwslaptop.csr.com (pws@localhost) by pwslaptop.csr.com (8.13.4/8.13.4/Submit) with ESMTP id j9UKZtaI007751 for ; Sun, 30 Oct 2005 20:35:56 GMT Message-Id: <200510302035.j9UKZtaI007751@pwslaptop.csr.com> X-Authentication-Warning: pwslaptop.csr.com: pws owned process doing -bs From: Peter Stephenson To: zsh-workers@sunsite.dk (Zsh hackers list) Subject: PATCH: more extra-wide character refreshing. Date: Sun, 30 Oct 2005 20:35:55 +0000 X-Spam-Checker-Version: SpamAssassin 3.0.4 (2005-06-05) on f.primenet.com.au X-Spam-Level: X-Spam-Status: No, score=-2.6 required=5.0 tests=AWL,BAYES_00 autolearn=ham version=3.0.4 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 Web page still at http://www.pwstephenson.fsnet.co.uk/