Download raw body.
bin/ksh: series of patches which fixes wrong terminal width and UTF-8
bin/ksh: series of patches which fixes wrong terminal width and UTF-8
bin/ksh: series of patches which fixes wrong terminal width and UTF-8
bin/ksh: series of patches which fixes wrong terminal width and UTF-8
On Wed, 09 Sep 2026 13:23:01 +0200,
Stuart Henderson <stu@spacehopper.org> wrote:
>
> On 2026/09/09 12:55, Kirill A. Korinsky wrote:
> > On Wed, 08 Jul 2026 11:41:07 +0200,
> > Stuart Henderson <stu@spacehopper.org> wrote:
> > >
> > > On 2026/07/07 22:42, Kirill A. Korinsky wrote:
> > > > sorry to attached pathces, and not inlined, I think it makes it review
> > > > simpler.
> > > >
> > > > I use that pathces for last half year in emacs mode and happy with this, but
> > > > I think we should fix that bugs and commit it.
> > > >
> > > > It should be applied as sequence.
> > > >
> > > > Anyone willing to test it? Ok it?
> > >
> > > I'm running this on a few machines now. It's a big improvement so far.
> > >
> >
> > I still would like to go this series in.
>
> Me too.
>
> > Here it is as one diff with regression tests.
> >
> > I use it for months, and haven't discovered any issues.
> >
> > This patch fixes terminal resizes which leaves emacs and vi mode using a
> > stale width, causing premature scrolling and incorrect cursor placement;
> > UTF-8 input at the window edge also produces broken characters and misplaced
> > indicators; in vi mode, multibyte input can overrun the window buffers.
> >
> > Anyone willing to ok it?
>
> ok sthen, FWIW
>
shall it go in? shall I drop it?
Index: bin/ksh/edit.c
===================================================================
RCS file: /home/cvs/src/bin/ksh/edit.c,v
diff -u -p -r1.72 edit.c
--- bin/ksh/edit.c 22 May 2026 18:11:08 -0000 1.72
+++ bin/ksh/edit.c 9 Sep 2026 10:44:49 -0000
@@ -26,7 +26,8 @@ X_chars edchars;
static void x_sigwinch(int);
volatile sig_atomic_t got_sigwinch;
-static void check_sigwinch(void);
+void check_sigwinch(void);
+void (*x_resize_cb)(void); /* callback for resize during edit */
static int x_file_glob(int, const char *, int, char ***, int);
static char *x_tilde_expand(const char *);
@@ -64,7 +65,7 @@ x_sigwinch(int sig)
got_sigwinch = 1;
}
-static void
+void
check_sigwinch(void)
{
if (got_sigwinch) {
@@ -81,11 +82,16 @@ check_sigwinch(void)
* see the change cause the environ doesn't change.
*/
if (ws.ws_col) {
+ int old_cols = x_cols;
+
x_cols = ws.ws_col < MIN_COLS ? MIN_COLS :
ws.ws_col;
if ((vp = typeset("COLUMNS", 0, 0, 0, 0)))
setint(vp, (int64_t) ws.ws_col);
+
+ if (x_cols != old_cols && x_resize_cb)
+ (*x_resize_cb)();
}
if (ws.ws_row && (vp = typeset("LINES", 0, 0, 0, 0)))
setint(vp, (int64_t) ws.ws_row);
@@ -126,12 +132,14 @@ x_getc(void)
char c;
int n;
- while ((n = blocking_read(STDIN_FILENO, &c, 1)) < 0 && errno == EINTR)
+ while ((n = blocking_read(STDIN_FILENO, &c, 1)) < 0 && errno == EINTR) {
+ check_sigwinch();
if (trap) {
x_mode(false);
runtraps(0);
x_mode(true);
}
+ }
if (n != 1)
return -1;
return (int) (unsigned char) c;
Index: bin/ksh/edit.h
===================================================================
RCS file: /home/cvs/src/bin/ksh/edit.h,v
diff -u -p -r1.14 edit.h
--- bin/ksh/edit.h 22 May 2026 18:11:08 -0000 1.14
+++ bin/ksh/edit.h 9 Sep 2026 10:44:49 -0000
@@ -39,6 +39,8 @@ extern X_chars edchars;
#define XCF_COMMAND_FILE (XCF_COMMAND|XCF_FILE)
/* edit.c */
+void check_sigwinch(void);
+extern void (*x_resize_cb)(void);
int x_getc(void);
void x_flush(void);
int x_putc(int);
Index: bin/ksh/emacs.c
===================================================================
RCS file: /home/cvs/src/bin/ksh/emacs.c,v
diff -u -p -r1.92 emacs.c
--- bin/ksh/emacs.c 22 May 2026 18:11:08 -0000 1.92
+++ bin/ksh/emacs.c 9 Sep 2026 10:44:49 -0000
@@ -105,6 +105,7 @@ static int xlp_valid;
/* end from 4.9 edit.h } */
static int x_tty; /* are we on a tty? */
static int x_bind_quiet; /* be quiet when binding keys */
+static void x_emacs_resize(void);
static int (*x_last_command)(int);
static char **x_histp; /* history position */
@@ -129,6 +130,7 @@ static int x_size_str(char *);
static int x_size(int);
static void x_zots(char *);
static void x_zotc(int);
+static void x_zotcp(char *);
static void x_load_hist(char **);
static int x_search(char *, int, int);
static int x_match(char *, char *);
@@ -286,6 +288,9 @@ x_emacs(char *buf, size_t len)
xmp = NULL;
x_histp = histptr + 1;
+ x_resize_cb = NULL;
+ check_sigwinch();
+ x_resize_cb = x_emacs_resize;
xx_cols = x_cols;
x_col = promptlen(prompt, &p);
prompt_skip = p - prompt;
@@ -316,8 +321,11 @@ x_emacs(char *buf, size_t len)
x_last_command = NULL;
while (1) {
x_flush();
- if ((at = x_e_getu8(line, at)) < 0)
+ if ((at = x_e_getu8(line, at)) < 0) {
+ x_resize_cb = NULL;
return 0;
+ }
+
ntries++;
if (x_arg == -1) {
@@ -378,6 +386,7 @@ x_emacs(char *buf, size_t len)
x_last_command = NULL;
break;
case KEOL:
+ x_resize_cb = NULL;
ret = xep - xbuf;
return (ret);
break;
@@ -635,16 +644,17 @@ x_fword(void)
static void
x_goto(char *cp)
{
- if (cp < xbp || cp >= (xbp + x_displen)) {
+ x_lastcp();
+ if (cp < xbp || cp > xlp) {
/* we are heading off screen */
xcp = cp;
x_adjust();
} else if (cp < xcp) { /* move back */
while (cp < xcp)
- x_bs((unsigned char)*--xcp);
+ x_bs(*--xcp);
} else if (cp > xcp) { /* move forward */
while (cp > xcp)
- x_zotc((unsigned char)*xcp++);
+ x_zotcp(xcp++);
}
}
@@ -663,7 +673,7 @@ x_size_str(char *cp)
{
int size = 0;
while (*cp)
- size += x_size(*cp++);
+ size += x_size((unsigned char)*cp++);
return size;
}
@@ -691,7 +701,7 @@ x_zots(char *str)
}
x_lastcp();
while (*str && str < xlp && adj == x_adj_done)
- x_zotc(*str++);
+ x_zotcp(str++);
}
static void
@@ -707,6 +717,39 @@ x_zotc(int c)
x_e_putc(c);
}
+static void
+x_zotcp(char *p)
+{
+ unsigned char uc = (unsigned char)*p;
+
+ if (uc == '\t') {
+ /* Kludge, tabs are always four spaces. */
+ x_e_puts(" ");
+ return;
+ }
+ if (isu8cont(uc)) {
+ if (x_col <= xx_cols) {
+ x_putc(uc);
+ }
+ if (x_adj_ok && !isu8cont((unsigned char)p[1]) &&
+ (x_col < 0 || x_col >= (xx_cols - 2)))
+ x_adjust();
+ return;
+ }
+ if (iscntrl(uc)) {
+ x_e_putc('^');
+ x_e_putc(UNCTRL(uc));
+ } else {
+ if (x_col < xx_cols) {
+ x_putc(uc);
+ x_col++;
+ }
+ if (x_adj_ok && !isu8cont((unsigned char)p[1]) &&
+ (x_col < 0 || x_col >= (xx_cols - 2)))
+ x_adjust();
+ }
+}
+
static int
x_mv_back(int c)
{
@@ -1026,7 +1069,7 @@ x_clear_screen(int c)
static void
x_redraw(int limit)
{
- int i, j, truncate = 0;
+ int i, j, truncate = 0, dcols;
char *cp;
x_adj_ok = 0;
@@ -1068,10 +1111,12 @@ x_redraw(int limit)
if (xbp != xbuf || xep > xlp)
limit = xx_cols;
if (limit >= 0) {
- if (xep > xlp)
- i = 0; /* we fill the line */
- else
- i = limit - (xlp - xbp);
+ dcols = 0;
+ for (cp = xbp; cp < xlp; cp++)
+ dcols += x_size((unsigned char)*cp);
+ i = limit - dcols;
+ if (i < 0)
+ i = 0;
for (j = 0; j < i && x_col < (xx_cols - 2); j++)
x_e_putc(' ');
@@ -1128,8 +1173,8 @@ x_transpose(int c)
*/
x_bs(xcp[-1]);
x_bs(xcp[-2]);
- x_zotc(xcp[-1]);
- x_zotc(xcp[-2]);
+ x_zotcp(&xcp[-1]);
+ x_zotcp(&xcp[-2]);
tmp = xcp[-1];
xcp[-1] = xcp[-2];
xcp[-2] = tmp;
@@ -1138,8 +1183,8 @@ x_transpose(int c)
* cursor, move cursor position along one.
*/
x_bs(xcp[-1]);
- x_zotc(xcp[0]);
- x_zotc(xcp[-1]);
+ x_zotcp(&xcp[0]);
+ x_zotcp(&xcp[-1]);
tmp = xcp[-1];
xcp[-1] = xcp[0];
xcp[0] = tmp;
@@ -1802,12 +1847,22 @@ do_complete(int flags, /* XCF_{COMMAND,F
static void
x_adjust(void)
{
+ char *cp;
+ int col;
+
x_adj_done++; /* flag the fact that we were called. */
/*
* we had a problem if the prompt length > xx_cols / 2
*/
- if ((xbp = xcp - (x_displen / 2)) < xbuf)
- xbp = xbuf;
+ col = x_displen / 2;
+ cp = xcp;
+ while (cp > xbuf && col > 0) {
+ cp--;
+ while (cp > xbuf && isu8cont(*cp))
+ cp--;
+ col -= x_size((unsigned char)*cp);
+ }
+ xbp = cp;
xlp_valid = false;
x_redraw(xx_cols);
x_flush();
@@ -2161,9 +2216,58 @@ x_lastcp(void)
for (i = 0, rcp = xbp; rcp < xep && i < x_displen; rcp++)
i += x_size((unsigned char)*rcp);
xlp = rcp;
+ while (xlp < xep && isu8cont(*xlp))
+ xlp++;
}
xlp_valid = true;
return (xlp);
+}
+
+static void
+x_emacs_resize(void)
+{
+ int cr_done = 0, cleared = 0;
+
+#ifndef SMALL
+ if (cur_term != NULL) {
+ if (carriage_return != NULL &&
+ tputs(carriage_return, 1, x_putc) != ERR)
+ cr_done = 1;
+ if (clr_eos != NULL &&
+ tputs(clr_eos, 1, x_putc) != ERR)
+ cleared = 1;
+ }
+#endif
+ if (!cr_done)
+ x_putc('\r');
+ if (!cleared) {
+ x_putc('\033');
+ x_putc('[');
+ x_putc('J');
+ }
+
+ xx_cols = x_cols;
+ x_col = promptlen(prompt, NULL);
+ if (x_col > xx_cols)
+ x_col = x_col - (x_col / xx_cols) * xx_cols;
+ x_displen = xx_cols - 2 - x_col;
+ if (x_displen < 1) {
+ x_col = 0;
+ x_displen = xx_cols - 2;
+ prompt_redraw = 0;
+ } else {
+ xbp = xbuf;
+ xlp_valid = false;
+ if (xcp <= x_lastcp()) {
+ x_redraw(0);
+ x_flush();
+ return;
+ }
+ }
+
+ x_col = 0;
+ x_displen = xx_cols - 2;
+ x_adjust();
}
#endif /* EMACS */
Index: bin/ksh/vi.c
===================================================================
RCS file: /home/cvs/src/bin/ksh/vi.c,v
diff -u -p -r1.71 vi.c
--- bin/ksh/vi.c 15 Aug 2026 11:54:18 -0000 1.71
+++ bin/ksh/vi.c 9 Sep 2026 10:44:49 -0000
@@ -24,6 +24,7 @@
#undef CTRL
#define CTRL(x) ((x) & 0x1F) /* ASCII */
+#define UTF8_MAXBYTES 4
struct edstate {
char *cbuf; /* main buffer to build the command line */
@@ -75,6 +76,8 @@ static void vi_error(void);
static void vi_macro_reset(void);
static int x_vi_putbuf(const char *, size_t);
static int isu8cont(unsigned char);
+static void x_vi_resize(void);
+static void calc_winsize(void);
#define C_ 0x1 /* a valid command that isn't a M_, E_, U_ */
#define M_ 0x2 /* movement command (h, l, etc.) */
@@ -200,6 +203,9 @@ x_vi(char *buf, size_t len)
{
int c;
+ x_resize_cb = NULL;
+ check_sigwinch();
+ x_resize_cb = x_vi_resize;
vi_reset(buf, len > LINE ? LINE : len);
vi_pprompt(1);
x_flush();
@@ -242,6 +248,7 @@ x_vi(char *buf, size_t len)
x_flush();
}
+ x_resize_cb = NULL;
x_putc('\r'); x_putc('\n'); x_flush();
if (c == -1 || len <= (size_t)es->linelen)
@@ -1363,7 +1370,7 @@ static int prompt_trunc; /* how much of
static int prompt_skip; /* how much of prompt to skip */
static int winwidth; /* available column positions */
static char *wbuf[2]; /* current & previous window buffer */
-static int wbuf_len; /* length of window buffers (x_cols-3)*/
+static int wbuf_len; /* length of window buffers */
static int win; /* number of window buffer in use */
static char morec; /* more character at right of window */
static char holdbuf[LINE]; /* place to hold last edit buffer */
@@ -1423,8 +1430,6 @@ free_edstate(struct edstate *old)
static void
edit_reset(char *buf, size_t len)
{
- const char *p;
-
es = &ebuf;
es->cbuf = buf;
es->cbufsize = len;
@@ -1435,6 +1440,18 @@ edit_reset(char *buf, size_t len)
es->cursor = undo->cursor = 0;
es->winleft = undo->winleft = 0;
+ calc_winsize();
+ win = 0;
+ morec = ' ';
+ holdlen = 0;
+}
+
+static void
+calc_winsize(void)
+{
+ const char *p;
+ int newlen;
+
cur_col = pwidth = promptlen(prompt, &p);
prompt_skip = p - prompt;
if (pwidth > x_cols - 3 - MIN_EDIT_SPACE) {
@@ -1443,17 +1460,15 @@ edit_reset(char *buf, size_t len)
pwidth -= prompt_trunc;
} else
prompt_trunc = 0;
- if (!wbuf_len || wbuf_len != x_cols - 3) {
- wbuf_len = x_cols - 3;
+ newlen = (x_cols - 3) * UTF8_MAXBYTES;
+ if (!wbuf_len || wbuf_len != newlen) {
+ wbuf_len = newlen;
wbuf[0] = aresize(wbuf[0], wbuf_len, APERM);
wbuf[1] = aresize(wbuf[1], wbuf_len, APERM);
}
(void) memset(wbuf[0], ' ', wbuf_len);
(void) memset(wbuf[1], ' ', wbuf_len);
winwidth = x_cols - pwidth - 3;
- win = 0;
- morec = ' ';
- holdlen = 0;
}
/*
@@ -1870,6 +1885,7 @@ display(char *wb1, char *wb2, int leftsi
int ncol; /* display column of the cursor */
int cnt; /* remaining display columns to fill */
int moreright;
+ int trailu8;
char mc; /* new "more character" at the right of window */
unsigned char ch;
@@ -1881,8 +1897,11 @@ display(char *wb1, char *wb2, int leftsi
ncol = col = 0;
cur = es->winleft;
moreright = 0;
+ trailu8 = 0;
twb1 = wb1;
- while (col < winwidth && cur < es->linelen) {
+ while (cur < es->linelen &&
+ (col < winwidth ||
+ (col == winwidth && isu8cont(es->cbuf[cur])))) {
if (cur == es->cursor && leftside)
ncol = col + pwidth;
if ((ch = es->cbuf[cur]) == '\t') {
@@ -1898,7 +1917,8 @@ display(char *wb1, char *wb2, int leftsi
}
ch &= 0x7f;
}
- if (col < winwidth) {
+ if (col < winwidth ||
+ (col == winwidth && isu8cont(ch))) {
if (ch < ' ' || ch == 0x7f) {
*twb1++ = '^';
if (++col < winwidth) {
@@ -1906,6 +1926,8 @@ display(char *wb1, char *wb2, int leftsi
col++;
}
} else {
+ if (col == winwidth && isu8cont(ch))
+ trailu8 = 1;
*twb1++ = ch;
if (col == 0 || !isu8cont(ch))
col++;
@@ -1998,8 +2020,10 @@ display(char *wb1, char *wb2, int leftsi
mc = '>';
else
mc = ' ';
- if (mc != morec) {
- ed_mov_opt(pwidth + winwidth + 1, wb1);
+ if (mc != morec || trailu8) {
+ ed_mov_opt(pwidth + winwidth, wb1);
+ x_putc(' ');
+ cur_col++;
x_putc(mc);
cur_col++;
morec = mc;
@@ -2302,5 +2326,43 @@ static int
isu8cont(unsigned char c)
{
return !Flag(FVISHOW8) && (c & (0x80 | 0x40)) == 0x80;
+}
+
+static void
+x_vi_resize(void)
+{
+ int cur = 0, col = 0;
+ int cr_done = 0, cleared = 0;
+
+#ifndef SMALL
+ if (cur_term != NULL) {
+ if (carriage_return != NULL &&
+ tputs(carriage_return, 1, x_putc) != ERR)
+ cr_done = 1;
+ if (clr_eos != NULL &&
+ tputs(clr_eos, 1, x_putc) != ERR)
+ cleared = 1;
+ }
+#endif
+ if (!cr_done)
+ x_putc('\r');
+ if (!cleared) {
+ x_putc('\033');
+ x_putc('[');
+ x_putc('J');
+ }
+
+ calc_winsize();
+
+ while (cur < es->linelen)
+ col = newcol((unsigned char) es->cbuf[cur++], col);
+ if (col <= winwidth)
+ es->winleft = 0;
+ else if (outofwin())
+ rewindow();
+
+ redraw_line(0, 0);
+ refresh_line(insert != 0);
+ x_flush();
}
#endif /* VI */
Index: regress/bin/ksh/edit/edit.c
===================================================================
RCS file: /home/cvs/src/regress/bin/ksh/edit/edit.c,v
diff -u -p -r1.8 edit.c
--- regress/bin/ksh/edit/edit.c 10 Jul 2021 07:10:31 -0000 1.8
+++ regress/bin/ksh/edit/edit.c 9 Sep 2026 10:44:49 -0000
@@ -16,6 +16,7 @@
*/
#include <sys/wait.h>
+#include <sys/ioctl.h>
#include <err.h>
#include <errno.h>
@@ -49,6 +50,7 @@ main(int argc, char *argv[])
ssize_t n;
size_t nin, nprompt, nread, nwrite;
int c, nready, ptyfd, readprompt, ret, status, timeout;
+ int pending_resize, pending_cols, pending_quiet, pending_post;
while ((c = getopt(argc, argv, "p:")) != -1) {
switch (c) {
@@ -96,14 +98,20 @@ main(int argc, char *argv[])
}
nprompt = nread = nwrite = ret = 0;
+ pending_resize = pending_cols = pending_quiet = pending_post = 0;
readprompt = 1;
while (!gotsig) {
pfd.fd = ptyfd;
- if (!readprompt && nwrite < nin)
+ if (pending_resize || pending_post) {
+ pfd.events = POLLIN;
+ timeout = WRTIM;
+ } else if (!readprompt && nwrite < nin) {
pfd.events = POLLOUT;
- else
+ timeout = WRTIM;
+ } else {
pfd.events = POLLIN;
- timeout = readprompt ? PRTIM : WRTIM;
+ timeout = readprompt ? PRTIM : WRTIM;
+ }
nready = poll(&pfd, 1, timeout);
if (nready == -1) {
if (errno == EINTR)
@@ -111,6 +119,22 @@ main(int argc, char *argv[])
err(1, "poll");
}
if (nready == 0) {
+ if (pending_resize) {
+ if (++pending_quiet >= 2) {
+ ws.ws_col = pending_cols;
+ if (ioctl(ptyfd, TIOCSWINSZ, &ws) == -1)
+ err(1, "ioctl TIOCSWINSZ");
+ kill(pid, SIGWINCH);
+ pending_resize = pending_cols = 0;
+ pending_quiet = 0;
+ pending_post = 1;
+ }
+ continue;
+ }
+ if (pending_post) {
+ pending_post = 0;
+ continue;
+ }
if (timeout == PRTIM) {
warnx("timeout waiting from prompt");
ret = 1;
@@ -136,6 +160,28 @@ main(int argc, char *argv[])
readprompt = 0;
}
} else if (pfd.revents & POLLOUT) {
+ if (in[nwrite] == '\0' && nwrite + 3 < nin &&
+ in[nwrite + 1] == 'R' &&
+ in[nwrite + 2] == 'S' &&
+ in[nwrite + 3] >= '0' && in[nwrite + 3] <= '9') {
+ size_t i = nwrite + 3;
+ int cols = 0, nd = 0;
+
+ while (i < nin && nd < 3 &&
+ in[i] >= '0' && in[i] <= '9') {
+ cols = cols * 10 + (in[i] - '0');
+ i++;
+ nd++;
+ }
+ if (nd > 0 && (i == nin ||
+ in[i] < '0' || in[i] > '9') &&
+ cols > 0) {
+ pending_resize = 1;
+ pending_cols = cols;
+ nwrite = i;
+ continue;
+ }
+ }
if (strchr(linefeed, in[nwrite]) != NULL)
readprompt = 1;
@@ -143,6 +189,8 @@ main(int argc, char *argv[])
if (n == -1)
err(1, "write");
nwrite += n;
+ if (pending_resize)
+ pending_quiet = 0;
}
}
close(ptyfd);
Index: regress/bin/ksh/edit/emacs.sh
===================================================================
RCS file: /home/cvs/src/regress/bin/ksh/edit/emacs.sh,v
diff -u -p -r1.15 emacs.sh
--- regress/bin/ksh/edit/emacs.sh 2 Sep 2021 07:14:15 -0000 1.15
+++ regress/bin/ksh/edit/emacs.sh 9 Sep 2026 10:44:49 -0000
@@ -52,6 +52,62 @@ testseq "z\0002\0363\0277\0277\0277" " #
testseq "z\0002\0364\0200\0200\0200" " # z\b\0364\0200\0200\0200z\b"
testseq "z\0002\0364\0217\0277\0277" " # z\b\0364\0217\0277\0277z\b"
+# ASCII resize: cols=1/11/12
+testseq "aaaaaaaaaabbbbbbbbbb\0001\000RS1" \
+ " # aaaaaaaaaabbbbbbbbbb\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\r\033[J\r # aaaaaaa>\b\b\b\b\b\b\b\b"
+testseq "aaaaaaaaaabbbbbbbbbb\003310\0002\000RS11" \
+ " # aaaaaaaaaabbbbbbbbbb\b\b\b\b\b\b\b\b\b\b\r\033[J\raaaaabbbbb*\b\b\b\b\b\b"
+testseq "aaaaaaaaaabbbbbbbbbb\000RS12" \
+ " # aaaaaaaaaabbbbbbbbbb\r\033[J\rbbbbb <\b\b\b\b\b\b"
+
+# ASCII resize: cols=13, cursor -1/0/+1
+testseq "aaaaaaaaaabbbbbbbbbb\003313\0002\000RS13" \
+ " # aaaaaaaaaabbbbbbbbbb\b\b\b\b\b\b\b\b\b\b\b\b\b\r\033[J\r # aaaaaaaa>\b\b"
+testseq "aaaaaaaaaabbbbbbbbbb\003312\0002\000RS13" \
+ " # aaaaaaaaaabbbbbbbbbb\b\b\b\b\b\b\b\b\b\b\b\b\r\033[J\r # aaaaaaaa>\b"
+testseq "aaaaaaaaaabbbbbbbbbb\003311\0002\000RS13" \
+ " # aaaaaaaaaabbbbbbbbbb\b\b\b\b\b\b\b\b\b\b\b\r\033[J\raaaaaabbbbb*\b\b\b\b\b\b\b"
+
+# ASCII resize: cols=79/80/81
+testseq "aaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbccccccccccccccccccccccccc\0001\000RS79" \
+ " # aaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbccccccccccccccccccccccccc\rbbbbbbbbbbbbccccccccccccccccccccccccc <\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\r # aaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbccccccccccccccccccccccccc \b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\r\033[J\r # aaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbcccccccccccccccccccccccc>\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"
+testseq "aaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbccccccccccccccccccccccccc\0001\000RS80" \
+ " # aaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbccccccccccccccccccccccccc\rbbbbbbbbbbbbccccccccccccccccccccccccc <\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\r # aaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbccccccccccccccccccccccccc \b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"
+testseq "aaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbccccccccccccccccccccccccc\0001\000RS81" \
+ " # aaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbccccccccccccccccccccccccc\rbbbbbbbbbbbbccccccccccccccccccccccccc <\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\r # aaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbccccccccccccccccccccccccc \b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\r\033[J\r # aaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbccccccccccccccccccccccccc \b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"
+
+# ASCII window indicator at left edge
+testseq "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" \
+ " # aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\rbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb <\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"
+
+# UTF-8 window indicator at left edge
+testseq "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\0303\0266bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" \
+ " # aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\0303\0266bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\0303\0266bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb <\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"
+
+# ASCII redraw at right edge
+PS1='012345678901234567890123456789012345678901234567890123456789'
+testseq "#aaaaaaaaaaaaaaaaab\0033#" "012345678901234567890123456789012345678901234567890123456789#aaaaaaaaaaaaaaaaa\raaaaaaaaa <\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\bb\r012345678901234567890123456789012345678901234567890123456789aaaaaaaaaaaaaaaaab \b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"
+
+# UTF-8 redraw at right edge
+testseq "#aaaaaaaaaaaaaaaaa\0303\0266\0033#" "012345678901234567890123456789012345678901234567890123456789#aaaaaaaaaaaaaaaaa\raaaaaaaaa <\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\0303\0266\r012345678901234567890123456789012345678901234567890123456789aaaaaaaaaaaaaaaaa\0303\0266 \b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"
+PS1=' # '
+
+# ASCII window indicator at right edge
+testseq "\003342ab\003397b\0001" \
+ " # aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\raaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb <\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\rbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb <\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\bbbbbbbbbbbbbbbbbbbbbbbbb\r # aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb>\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"
+
+# UTF-8 window indicator at right edge
+testseq "\003342a\0303\0266\003397b\0001" \
+ " # aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\0303\0266bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\raaaa\0303\0266bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb <\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\rbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb <\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\bbbbbbbbbbbbbbbbbbbbbbbbb\r # aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\0303\0266bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb>\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"
+
+# ASCII window indicator on both sides
+testseq "\003342ab\003397b\0001\003379\0006" \
+ " # aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\raaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb <\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\rbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb <\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\bbbbbbbbbbbbbbbbbbbbbbbbb\r # aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb>\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\rbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb*\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"
+
+# UTF-8 window indicator on both sides
+testseq "\003342a\0303\0266\003397b\0001\003379\0006" \
+ " # aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\0303\0266bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\raaaa\0303\0266bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb <\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\rbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb <\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\bbbbbbbbbbbbbbbbbbbbbbbbb\r # aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\0303\0266bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb>\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\ra\0303\0266bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb*\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"
+
# insertion of incomplete UTF-8
testseq "z\0002\0302\0006" " # z\b\0302z\bz"
testseq "z\0002\0377\0006" " # z\b\0377z\bz"
Index: regress/bin/ksh/edit/vi.sh
===================================================================
RCS file: /home/cvs/src/regress/bin/ksh/edit/vi.sh,v
diff -u -p -r1.14 vi.sh
--- regress/bin/ksh/edit/vi.sh 4 Apr 2026 09:33:18 -0000 1.14
+++ regress/bin/ksh/edit/vi.sh 9 Sep 2026 10:44:49 -0000
@@ -233,3 +233,59 @@ testseq "(x)\00330%hrc" " # (x)\b\b\b(x\
# ^R: Redraw.
testseq "test\0033h\0022" " # test\b\b\r\r\n # test\b\b"
+
+# ASCII resize: cols=1/11/12
+testseq "aaaaaaaaaabbbbbbbbbb\0033hhhhhhhhhhhhhhhhhhh\000RS1" \
+ " # aaaaaaaaaabbbbbbbbbb\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\r\033[J# aaaaaaa >\r# "
+testseq "aaaaaaaaaabbbbbbbbbb\0033hhhhhhhhh\000RS11" \
+ " # aaaaaaaaaabbbbbbbbbb\b\b\b\b\b\b\b\b\b\b\r\033[J# aaabbbb +\b\b\b\b\b\b"
+testseq "aaaaaaaaaabbbbbbbbbb\0033\000RS12" \
+ " # aaaaaaaaaabbbbbbbbbb\b\r\033[J# bbbb <\b\b\b\b\b\b"
+
+# ASCII resize: cols=13, cursor -1/0/+1
+testseq "aaaaaaaaaabbbbbbbbbb\0033hhhhhhhhhhhhh\000RS13" \
+ " # aaaaaaaaaabbbbbbbbbb\b\b\b\b\b\b\b\b\b\b\b\b\b\b\r\033[J # aaaaaaa >\b\b\b"
+testseq "aaaaaaaaaabbbbbbbbbb\0033hhhhhhhhhhhh\000RS13" \
+ " # aaaaaaaaaabbbbbbbbbb\b\b\b\b\b\b\b\b\b\b\b\b\b\r\033[J # aaaaaab +\b\b\b\b\b\b"
+testseq "aaaaaaaaaabbbbbbbbbb\0033hhhhhhhhhhh\000RS13" \
+ " # aaaaaaaaaabbbbbbbbbb\b\b\b\b\b\b\b\b\b\b\b\b\r\033[J # aaaaabb +\b\b\b\b\b\b"
+
+# ASCII resize: cols=79/80/81
+testseq "aaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbccccccccccccccccccccccccc\0033hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh\000RS79" \
+ " # aaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbccccccccccccccccccccccc\r # bbbbbbbbbbbbbcccccccccccccccccccccccc <\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\bc\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\baaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbcccccccccccccccccccccccc >\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\r\033[J # aaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbccccccccccccccccccccccc >\r # "
+testseq "aaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbccccccccccccccccccccccccc\0033hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh\000RS80" \
+ " # aaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbccccccccccccccccccccccc\r # bbbbbbbbbbbbbcccccccccccccccccccccccc <\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\bc\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\baaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbcccccccccccccccccccccccc >\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"
+testseq "aaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbccccccccccccccccccccccccc\0033hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh\000RS81" \
+ " # aaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbccccccccccccccccccccccc\r # bbbbbbbbbbbbbcccccccccccccccccccccccc <\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\bc\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\baaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbcccccccccccccccccccccccc >\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\r\033[J # aaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbccccccccccccccccccccccccc >\r # "
+
+# ASCII window indicator at left edge
+testseq "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbb" \
+ " # aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbb\r # aaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbb <\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"
+
+# UTF-8 window indicator at left edge
+testseq "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\0303\0266bbbbbbbbb" \
+ " # aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\0303\0266bbbbbbbb\r # aaaaaaaaaaaaaaaaaaaaaaaaaaa\0303\0266bbbbbbbbb <\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"
+
+# ASCII window indicator at right edge
+testseq "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabb\00330" \
+ " # aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b <\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\bbb\b\baaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa >\r # "
+
+# UTF-8 window indicator at right edge
+testseq "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\0303\0266b\00330" \
+ " # aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b <\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\0303\0266b\b\baaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa >\r # "
+
+# ASCII window indicator on both sides
+testseq "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\003340h" \
+ " # aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b <\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\baaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r # aaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb \b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\r # aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbb +\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"
+
+# UTF-8 window indicator on both sides
+testseq "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\0303\0266bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\003340h" \
+ " # aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b <\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\baaaaaa\0303\0266bbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r # aaaaaa\0303\0266bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb \b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\r # aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\0303\0266bbbbbbbbbbbbbbbbbbbbbbbbbb +\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"
+
+# ASCII redraw at right edge
+testseq "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabb\00330\0022" \
+ " # aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b <\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\bbb\b\baaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa >\r # \r\r\n # aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa >\r # "
+
+# UTF-8 redraw at right edge
+testseq "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\0303\0266b\00330\0022" \
+ " # aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b <\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\0303\0266b\b\baaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa >\r # \r\r\n # aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa >\r # "
bin/ksh: series of patches which fixes wrong terminal width and UTF-8
bin/ksh: series of patches which fixes wrong terminal width and UTF-8
bin/ksh: series of patches which fixes wrong terminal width and UTF-8
bin/ksh: series of patches which fixes wrong terminal width and UTF-8