mirror of
git://git.code.sf.net/p/zsh/code
synced 2025-09-11 13:01:28 +02:00
21957: more wide-character refresh stuff
This commit is contained in:
parent
4dae429ba3
commit
4f683c2eea
2 changed files with 134 additions and 110 deletions
|
@ -1,3 +1,11 @@
|
|||
2005-10-30 Peter Stephenson <p.w.stephenson@ntlworld.com>
|
||||
|
||||
* 21957: Src/Zle/zle_refresh.c: more wide character stuff.
|
||||
|
||||
* 21954 (plus comment): configure.ac: use /dev/fd/3 to check
|
||||
for availability of feature (works around FreeBSD 5
|
||||
configuration).
|
||||
|
||||
2005-10-28 Wayne Davison <wayned@users.sourceforge.net>
|
||||
|
||||
* 21948: Src/zsh.h, Src/Zle/zle_refresh.c: fixed a couple
|
||||
|
|
|
@ -1069,128 +1069,144 @@ refreshline(int ln)
|
|||
/* 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 ((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 */
|
||||
|
||||
/* 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(' '));
|
||||
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 */
|
||||
}
|
||||
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)
|
||||
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;
|
||||
}
|
||||
|
||||
/* inserting & deleting chars: we can if there's no right-prompt */
|
||||
if ((ln || !put_rpmpt || !oput_rpmpt)
|
||||
#ifdef MULTIBYTE_SUPPORT
|
||||
&& *ol != WEOF && *nl != WEOF
|
||||
#endif
|
||||
&& 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--;
|
||||
}
|
||||
#endif
|
||||
i = 0;
|
||||
break;
|
||||
}
|
||||
if (!i)
|
||||
continue;
|
||||
return;
|
||||
}
|
||||
/* 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;
|
||||
}
|
||||
i = 0;
|
||||
break;
|
||||
}
|
||||
if (!i)
|
||||
continue;
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/* 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)
|
||||
#ifdef MULTIBYTE_SUPPORT
|
||||
&& *ol != WEOF && *nl != WEOF
|
||||
#endif
|
||||
&& 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--;
|
||||
}
|
||||
#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
|
||||
if (i >= winw - ccs) {
|
||||
*(ol + i) = ZWC('\0');
|
||||
ins_last = 1;
|
||||
}
|
||||
i = 0;
|
||||
break;
|
||||
}
|
||||
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 @@ refreshline(int ln)
|
|||
* 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
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue