Fix terminal snapshots reflowing after resize
Terminal snapshots now carry soft-wrap row metadata only to clients that advertise support, so restored output can resize like live output without breaking older clients.
This commit is contained in:
@@ -0,0 +1,49 @@
|
||||
import { describe, it, expect } from "vitest";
|
||||
import { renderTerminalSnapshotToAnsi } from "./terminal-snapshot";
|
||||
import type { TerminalState } from "./messages";
|
||||
|
||||
function cells(text: string): TerminalState["grid"][number] {
|
||||
return [...text].map((char) => ({ char }));
|
||||
}
|
||||
|
||||
describe("renderTerminalSnapshotToAnsi", () => {
|
||||
it("renders soft-wrapped rows as one contiguous logical line when wrap flags are present", () => {
|
||||
// The server soft-wrapped one logical line "ABCDEFGHIJKLMNOP" at 10 cols into
|
||||
// two grid rows. gridWrapped[0] = true marks row 0 as continuing into row 1.
|
||||
const state: TerminalState = {
|
||||
rows: 2,
|
||||
cols: 10,
|
||||
scrollback: [],
|
||||
scrollbackWrapped: [],
|
||||
grid: [cells("ABCDEFGHIJ"), cells("KLMNOP")],
|
||||
gridWrapped: [true, false],
|
||||
cursor: { row: 1, col: 6 },
|
||||
};
|
||||
|
||||
const ansi = renderTerminalSnapshotToAnsi(state);
|
||||
|
||||
// The rows must arrive unbroken so xterm re-wraps them itself (and can later
|
||||
// reflow them) — no hard newline injected between "...IJ" and "KL...".
|
||||
expect(ansi).toContain("ABCDEFGHIJKLMNOP");
|
||||
// Auto-wrap must stay enabled; disabling it (ESC[?7l) is what makes xterm mark
|
||||
// the rows non-wrapped and refuse to reflow them on resize.
|
||||
expect(ansi).not.toContain("[?7l");
|
||||
});
|
||||
|
||||
it("falls back to verbatim per-row replay when wrap flags are absent (old daemon)", () => {
|
||||
// No gridWrapped/scrollbackWrapped: the client cannot tell soft-wraps from hard
|
||||
// newlines, so it must keep today's exact behaviour rather than guess.
|
||||
const state: TerminalState = {
|
||||
rows: 2,
|
||||
cols: 10,
|
||||
scrollback: [],
|
||||
grid: [cells("ABCDEFGHIJ"), cells("KLMNOP")],
|
||||
cursor: { row: 1, col: 6 },
|
||||
};
|
||||
|
||||
const ansi = renderTerminalSnapshotToAnsi(state);
|
||||
|
||||
expect(ansi).toContain("[?7l");
|
||||
expect(ansi).toContain("ABCDEFGHIJ\r\nKLMNOP");
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user