ref: 3bbcc63e427b491a51e5f1cab929b9a9c16404e9
parent: dbdc9ace1a38beeb1e745330ed78be268e129688
author: Ori Bernstein <ori@eigenstate.org>
date: Tue Nov 4 15:19:17 EST 2025
vt: handle line wrapping correctly when we move past the end of a line, we should not wrap immediately, but we should also treat clear, backspace, etc as though we were still on the last character of the line, and not past it. this fixes the vttest wrapping tests.
--- a/sys/src/cmd/vt/main.c
+++ b/sys/src/cmd/vt/main.c
@@ -429,7 +429,8 @@
ap = onscreena(x, y);
cp = onscreenc(x, y);
c = fgcol(*ap, *cp, selected(x, y));
- for(n = 1; x+n <= xmax && rp[n] != 0 && fgcol(ap[n], cp[n], selected(x + n, y)) == c
+ for(n = 1; x+n <= xmax && rp[n] != 0
+ && fgcol(ap[n], cp[n], selected(x + n, y)) == c
&& ((ap[n] ^ *ap) & TUnderline) == 0; n++)
;
p = pt(x, y);
@@ -474,7 +475,13 @@
{int c = (attr & 0x0F00)>>8; /* bgcolor */
- if(y1 < 0 || y1 > ymax || x1 < 0 || x1 > xmax || y2 <= y1 || x2 <= x1)
+ /*
+ * We allow x to go above xmax to flag a pending wrap, however,
+ * the cursor itself should act as though we're on the last col.
+ */
+ if(x1 > xmax)
+ x1 = xmax;
+ if(y1 < 0 || y1 > ymax || x1 < 0 || y2 <= y1 || x2 <= x1)
return;
while(y1 < y2){--- a/sys/src/cmd/vt/vt.c
+++ b/sys/src/cmd/vt/vt.c
@@ -200,6 +200,7 @@
buf[0] = get_next_char();
buf[1] = '\0';
switch(buf[0]) {+ Escapeesc:
case '\000':
case '\001':
case '\002':
@@ -214,7 +215,9 @@
break;
case '\010': /* backspace */
- if (x > 0)
+ if(x > xmax)
+ x = xmax;
+ if(x > 0)
--x;
break;
@@ -221,7 +224,7 @@
case '\011': /* tab to next tab stop; if none, to right margin */
for(c=x+1; c<nelem(tabcol) && !tabcol[c]; c++)
;
- if(c < nelem(tabcol))
+ if(c < xmax && c < nelem(tabcol))
x = c;
else
x = xmax;
@@ -585,6 +588,8 @@
sendnchars(4, "\033[0n"); /* terminal ok */
break;
case 6: /* cursor position */
+ if(x > xmax)
+ x = xmax;
sendnchars(sprint((char*)buf, "\033[%d;%dR",
originrelative ? y+1 - yscrmin : y+1, x+1), (char*)buf);
break;
--
⑨