authorgravatar for git@paperclover.netclover caruso <git@paperclover.net> 2026-03-17 23:48:29-07:00
committergravatar for git@paperclover.netclover caruso <git@paperclover.net> 2026-03-21 18:03:28-07:00
log5b403d91b350d337f743d3a99ac0637fd3c12953
treea010799cfbc394934da44161341b1abc71368834
parent2f082aadf24befd5d4005e5734216bd23f5af84c
signature Signed by SSH key SHA256:xbd+BjjhyBfwk7GVoURf9Yx0gzDerHbvYv7SddNWmAs

fix: bug in `trimForTerminal` with ansi escapes


4 files changed, 10 insertions(+), 8 deletions(-)

lib/log.ts+1-1
......@@ -404,7 +404,7 @@ export function createWidgetHost(env: WidgetHostOptions): WidgetHost {
404404 if (rowsLeft === 1) break;
405405 const lines = outText.split("\n").slice(0, rowsLeft);
406406 newWidgetLines.push(
407 ...lines.map((line) => ansi.trimToWidth(line, columns - 1)),
407 ...lines.map((line) => ansi.trimForTerminal(line, columns - 1)),
408408 );
409409
410410 next = Math.min(next, UNWRAP(internals[w]).frameTime);
lib/readme.changes.md+4-1
......@@ -22,7 +22,9 @@
2222 you to give some information about where the cursor was moved to.
2323 - messages now do not imply a newline
2424- `render` is now deprecated with no replacement. in the downstream `sitegen`
25 project, the entire codebase is moving to Marko after depending on both renderers.
25 project, the codebase is moving to Marko after depending on both renderers.
26- `string/ansi`
27 - rename `trimToWidth` to `trimForTerminal`
2628
2729### features
2830
......@@ -36,6 +38,7 @@
3638 a newline.
3739- `async.delay` handles timers longer than 23 days.
3840- `Lru.revive` recieves bug fixes. this function previously didn't really work.
41- `ansi` gets more cursor control constants
3942
4043## v3
4144
lib/string/ansi.test.ts+3-3
......@@ -8,13 +8,13 @@ test("widthInTerminal", () => {
88 9,
99 );
1010});
11test("trimToWidth", () => {
11test("trimForTerminal", () => {
1212 assert.equal(
13 ansi.trimToWidth("snowmobile", 6),
13 ansi.trimForTerminal("snowmobile", 6),
1414 "snowmo",
1515 );
1616 assert.equal(
17 ansi.trimToWidth("🏳️‍⚧️ " + ansi.style(ansi.bold, "rights"), 5),
17 ansi.trimForTerminal("🏳️‍⚧️ " + ansi.style(ansi.bold, "rights"), 5),
1818 "🏳️‍⚧️ " + ansi.bold + "ri" + ansi.reset,
1919 );
2020});
lib/string/ansi.ts+2-3
......@@ -277,8 +277,7 @@ export function widthInTerminal(str: string): number {
277277 * Like `str.slice(0, columns)`, but respecting width in a terminal.
278278 * preserves ansi escape sequences.
279279 */
280// TODO: rename to trimForTerminal
281export function trimToWidth(str: string, columns: number): string {
280export function trimForTerminal(str: string, columns: number): string {
282281 segmenter ??= new Intl.Segmenter();
283282 let width = 0;
284283 let ansi = false;
......@@ -286,7 +285,7 @@ export function trimToWidth(str: string, columns: number): string {
286285 const code = str.charCodeAt(i);
287286 if (code < 32) {
288287 if (code === 0x1b) {
289 const esc = str.slice().match(ansiEscapes);
288 const esc = str.slice(i).match(ansiEscapes);
290289 if (esc) i += esc[0].length - 1, ansi = true;
291290 }
292291 continue;