commit efaab74
uint
·
2026-05-14 18:12:13 +0000 UTC
parent 500c495
add terminal delayed autowrapping
2 files changed,
+31,
-4
+1,
-0
1@@ -45,6 +45,7 @@ typedef struct {
2 pid_t ptypid;
3
4 enum TState state;
5+ bool wrapnext;
6 int csi_params[CSI_PARAMS_MAX];
7 int csi_idx;
8 char utf8[4];
+30,
-4
1@@ -72,6 +72,7 @@ static void csi_dispatch(Term* t, Caret* c, unsigned char ch)
2 switch (ch) {
3 case 'H': /* CUP - Cursor Position - ESC[row;colH */
4 case 'f': { /* HVP - Horizontal and Vertical Postion - ESC[row;colf */
5+ t->wrapnext = false;
6 int row = csi_arg(t, 0, 1) - 1;
7 int col = csi_arg(t, 1, 1) - 1;
8
9@@ -109,6 +110,7 @@ static void csi_dispatch(Term* t, Caret* c, unsigned char ch)
10 break;
11
12 case 'A': { /* CUU - cursor up */
13+ t->wrapnext = false;
14 int n = csi_arg(t, 0, 1);
15 c->y -= n;
16 if (c->y < 0)
17@@ -117,6 +119,7 @@ static void csi_dispatch(Term* t, Caret* c, unsigned char ch)
18 }
19
20 case 'B': { /* CUD - cursor down */
21+ t->wrapnext = false;
22 int n = csi_arg(t, 0, 1);
23 c->y += n;
24 if (c->y >= t->rows)
25@@ -125,6 +128,7 @@ static void csi_dispatch(Term* t, Caret* c, unsigned char ch)
26 }
27
28 case 'C': { /* CUF - cursor forward */
29+ t->wrapnext = false;
30 int n = csi_arg(t, 0, 1);
31 c->x += n;
32 if (c->x >= t->cols)
33@@ -133,6 +137,7 @@ static void csi_dispatch(Term* t, Caret* c, unsigned char ch)
34 }
35
36 case 'D': { /* CUB - cursor back */
37+ t->wrapnext = false;
38 int n = csi_arg(t, 0, 1);
39 c->x -= n;
40 if (c->x < 0)
41@@ -141,6 +146,7 @@ static void csi_dispatch(Term* t, Caret* c, unsigned char ch)
42 }
43
44 case 'G': { /* CHA - cursor horizontal absolute */
45+ t->wrapnext = false;
46 int col = csi_arg(t, 0, 1) - 1;
47
48 if (col < 0)
49@@ -153,6 +159,7 @@ static void csi_dispatch(Term* t, Caret* c, unsigned char ch)
50 }
51
52 case 'd': { /* VPA - vertical position absolute */
53+ t->wrapnext = false;
54 int row = csi_arg(t, 0, 1) - 1;
55
56 if (row < 0)
57@@ -165,20 +172,24 @@ static void csi_dispatch(Term* t, Caret* c, unsigned char ch)
58 }
59
60 case 'L': /* IL - Insert Line */
61+ t->wrapnext = false;
62 if (c->y >= t->scroll_top && c->y <= t->scroll_bot)
63 scroll_down(t, c->y, t->scroll_bot, csi_arg(t, 0, 1));
64 break;
65
66 case 'M': /* DL - Delete Line */
67+ t->wrapnext = false;
68 if (c->y >= t->scroll_top && c->y <= t->scroll_bot)
69 scroll_up(t, c->y, t->scroll_bot, csi_arg(t, 0, 1));
70 break;
71
72 case 'S': /* SU - Scroll Up */
73+ t->wrapnext = false;
74 scroll_up(t, t->scroll_top, t->scroll_bot, csi_arg(t, 0, 1));
75 break;
76
77 case 'T': /* SD - Scroll Down */
78+ t->wrapnext = false;
79 scroll_down(t, t->scroll_top, t->scroll_bot, csi_arg(t, 0, 1));
80 break;
81
82@@ -204,6 +215,7 @@ static void csi_dispatch(Term* t, Caret* c, unsigned char ch)
83 break;
84 }
85 case 'r': { /* DECSTBM - scrolling region */
86+ t->wrapnext = false;
87 int top = csi_arg(t, 0, 1) - 1;
88 int bot = csi_arg(t, 1, t->rows) - 1;
89 if (top < 0)
90@@ -219,7 +231,7 @@ static void csi_dispatch(Term* t, Caret* c, unsigned char ch)
91 break;
92 }
93 case 's': t->saved = *c; break; /* save cursor */
94- case 'u': *c = t->saved; break; /* restore cursor */
95+ case 'u': t->wrapnext = false; *c = t->saved; break; /* restore cursor */
96
97 default: /* Unsupported CSI */
98 break;
99@@ -433,6 +445,7 @@ void term_clear(Term* t, Caret* c)
100
101 c->x = 0;
102 c->y = 0;
103+ t->wrapnext = false;
104 }
105
106 void term_damage_all(Term* t)
107@@ -455,9 +468,11 @@ void term_putc(Term* t, Caret* c, uint32_t cp)
108 switch (cp) {
109 case '\r':
110 c->x = 0;
111+ t->wrapnext = false;
112 break;
113 case '\n':
114 c->x = 0;
115+ t->wrapnext = false;
116 if (c->y == t->scroll_bot) {
117 term_scroll(t);
118 }
119@@ -465,10 +480,12 @@ void term_putc(Term* t, Caret* c, uint32_t cp)
120 c->y++;
121 break;
122 case '\b':
123+ t->wrapnext = false;
124 if (c->x > 0)
125 c->x--;
126 break;
127 case '\t':
128+ t->wrapnext = false;
129 /* move cursor to next tabstop */
130 c->x = (c->x+8) & ~0x7;
131 if (c->x >= t->cols)
132@@ -478,6 +495,11 @@ void term_putc(Term* t, Caret* c, uint32_t cp)
133 if (cp < 32)
134 break;
135
136+ if (t->wrapnext) {
137+ term_putc(t, c, '\n');
138+ t->wrapnext = false;
139+ }
140+
141 Rune* r = &RUNE(t, c->x, c->y);
142 if (r->cp != cp || r->fg != t->fg || r->bg != t->bg) {
143 r->cp = cp;
144@@ -485,9 +507,10 @@ void term_putc(Term* t, Caret* c, uint32_t cp)
145 r->bg = t->bg;
146 r->dmg = true;
147 }
148- c->x++;
149- if (c->x >= t->cols)
150- term_putc(t, c, '\n');
151+ if (c->x == t->cols - 1)
152+ t->wrapnext = true;
153+ else
154+ c->x++;
155
156 break;
157 }
158@@ -560,6 +583,7 @@ int term_resize(Term* t, Caret* c, int cols, int rows)
159 c->x = 0;
160 if (c->y < 0)
161 c->y = 0;
162+ t->wrapnext = false;
163 if (t->saved.x >= cols)
164 t->saved.x = cols - 1;
165 if (t->saved.y >= rows)
166@@ -606,6 +630,7 @@ bool term_write(Term* t, Caret* c, const char* s, size_t n)
167 t->state = TSTATE_NORMAL;
168 }
169 else if (ch == 'M') {
170+ t->wrapnext = false;
171 if (c->y == t->scroll_top)
172 scroll_down(t, t->scroll_top, t->scroll_bot, 1);
173 else if (c->y > 0)
174@@ -613,6 +638,7 @@ bool term_write(Term* t, Caret* c, const char* s, size_t n)
175 t->state = TSTATE_NORMAL;
176 }
177 else if (ch == 'D' || ch == 'E') {
178+ t->wrapnext = false;
179 if (ch == 'E')
180 c->x = 0;
181 if (c->y == t->scroll_bot)