- commit
- af0e1f3
- parent
- 3971f2d
- author
- Eric Bower
- date
- 2026-04-08 23:05:34 -0400 EDT
chore: cleanup util formatting
1 files changed,
+32,
-52
+32,
-52
1@@ -339,11 +339,13 @@ pub fn serializeTerminalState(alloc: std.mem.Allocator, term: *ghostty_vt.Termin
2 sb_bottom.x = @intCast(pages.cols - 1);
3
4 var scroll_fmt = ghostty_vt.formatter.TerminalFormatter.init(term, .vt);
5- scroll_fmt.content = .{ .selection = ghostty_vt.Selection.init(
6- screen_top,
7- sb_bottom,
8- false,
9- ) };
10+ scroll_fmt.content = .{
11+ .selection = ghostty_vt.Selection.init(
12+ screen_top,
13+ sb_bottom,
14+ false,
15+ ),
16+ };
17 scroll_fmt.extra = .none; // no modes, cursor, keyboard — just content
18 scroll_fmt.format(&builder.writer) catch |err| {
19 std.log.warn("failed to format scrollback err={s}", .{@errorName(err)});
20@@ -361,17 +363,21 @@ pub fn serializeTerminalState(alloc: std.mem.Allocator, term: *ghostty_vt.Termin
21
22 // Restrict content to the active viewport only
23 const active_tl = pages.pin(.{ .active = .{ .x = 0, .y = 0 } });
24- const active_br = pages.pin(.{ .active = .{
25- .x = @intCast(pages.cols - 1),
26- .y = @intCast(pages.rows - 1),
27- } });
28+ const active_br = pages.pin(.{
29+ .active = .{
30+ .x = @intCast(pages.cols - 1),
31+ .y = @intCast(pages.rows - 1),
32+ },
33+ });
34
35 if (active_tl != null and active_br != null) {
36- vis_fmt.content = .{ .selection = ghostty_vt.Selection.init(
37- active_tl.?,
38- active_br.?,
39- false,
40- ) };
41+ vis_fmt.content = .{
42+ .selection = ghostty_vt.Selection.init(
43+ active_tl.?,
44+ active_br.?,
45+ false,
46+ ),
47+ };
48 }
49 // Fallback: if pins are somehow invalid, use null selection (all content)
50
51@@ -815,20 +821,6 @@ test "serializeTerminalState excludes synchronized output replay" {
52 try std.testing.expect(std.mem.indexOf(u8, output, "\x1b[?2026h") == null);
53 }
54
55-// ---------------------------------------------------------------------------
56-// Integration tests: serializeTerminalState roundtrip verification
57-//
58-// These tests exercise the ghostty-vt roundtrip pattern:
59-// 1. Create Terminal A, feed VT sequences (scrollback, markers, cursor)
60-// 2. Serialize A via serializeTerminalState()
61-// 3. Create Terminal B (same dimensions), feed serialized bytes
62-// 4. Compare B's screen content and cursor with A's
63-//
64-// This verifies that what the user sees after re-attach matches what the
65-// daemon's terminal state actually contains — including in nested sessions
66-// (zmx→SSH→zmx) where serialized state flows through multiple layers.
67-// ---------------------------------------------------------------------------
68-
69 fn testCreateTerminal(alloc: std.mem.Allocator, cols: u16, rows: u16, vt_data: []const u8) !ghostty_vt.Terminal {
70 var term = try ghostty_vt.Terminal.init(alloc, .{
71 .cols = cols,
72@@ -892,8 +884,7 @@ fn expectMarkerAtRow(alloc: std.mem.Allocator, term: *ghostty_vt.Terminal, marke
73 test "serializeTerminalState roundtrip preserves cursor position" {
74 const alloc = std.testing.allocator;
75
76- var term = try testCreateTerminal(alloc, 80, 24,
77- "\x1b[2J" ++ // clear
78+ var term = try testCreateTerminal(alloc, 80, 24, "\x1b[2J" ++ // clear
79 "\x1b[10;20H" // cursor at row 10, col 20 (1-indexed)
80 );
81 defer term.deinit(alloc);
82@@ -909,14 +900,12 @@ test "serializeTerminalState roundtrip preserves cursor position" {
83 test "serializeTerminalState roundtrip preserves CUP-positioned markers" {
84 const alloc = std.testing.allocator;
85
86- var term = try testCreateTerminal(alloc, 80, 24,
87- "\x1b[2J" ++
88+ var term = try testCreateTerminal(alloc, 80, 24, "\x1b[2J" ++
89 "\x1b[2;5HMARK_A" ++
90 "\x1b[6;15HMARK_B" ++
91 "\x1b[10;30HMARK_C" ++
92 "\x1b[14;50HMARK_D" ++
93- "\x1b[16;20H"
94- );
95+ "\x1b[16;20H");
96 defer term.deinit(alloc);
97
98 var client = try serializeRoundtrip(alloc, &term);
99@@ -947,13 +936,11 @@ test "serializeTerminalState with scrollback preserves visible content" {
100 }
101
102 // Clear screen and place markers at specific positions
103- try stream.nextSlice(
104- "\x1b[2J" ++
105+ try stream.nextSlice("\x1b[2J" ++
106 "\x1b[2;5HMARK_A" ++
107 "\x1b[6;15HMARK_B" ++
108 "\x1b[10;30HMARK_C" ++
109- "\x1b[16;20H"
110- );
111+ "\x1b[16;20H");
112
113 // Verify source terminal has scrollback
114 const pages = &term.screens.active.pages;
115@@ -989,12 +976,10 @@ test "serializeTerminalState nested roundtrip preserves content" {
116 const line = std.fmt.bufPrint(&buf, "SCROLL_{d}\r\n", .{i}) catch unreachable;
117 try inner_stream.nextSlice(line);
118 }
119- try inner_stream.nextSlice(
120- "\x1b[2J" ++
121+ try inner_stream.nextSlice("\x1b[2J" ++
122 "\x1b[3;10HINNER_A" ++
123 "\x1b[12;25HINNER_B" ++
124- "\x1b[20;5H"
125- );
126+ "\x1b[20;5H");
127 }
128
129 // Record inner's ground truth
130@@ -1030,8 +1015,7 @@ test "serializeTerminalState nested roundtrip preserves content" {
131 test "serializeTerminalState alternate screen not leaked" {
132 const alloc = std.testing.allocator;
133
134- var term = try testCreateTerminal(alloc, 80, 24,
135- "\x1b[?1049h" ++ // enter alt screen
136+ var term = try testCreateTerminal(alloc, 80, 24, "\x1b[?1049h" ++ // enter alt screen
137 "\x1b[2J\x1b[3;10HALT_MARK" ++ // write on alt screen
138 "\x1b[?1049l" ++ // exit alt screen
139 "\x1b[2J\x1b[2;5HMAIN_MARK\x1b[8;20H" // write on main screen
140@@ -1052,13 +1036,11 @@ test "serializeTerminalState alternate screen not leaked" {
141 test "serializeTerminalState size mismatch roundtrip" {
142 const alloc = std.testing.allocator;
143
144- var term = try testCreateTerminal(alloc, 80, 30,
145- "\x1b[2J" ++
146+ var term = try testCreateTerminal(alloc, 80, 30, "\x1b[2J" ++
147 "\x1b[3;10HSIZE_A" ++
148 "\x1b[12;20HSIZE_B" ++
149 "\x1b[20;40HSIZE_C" ++
150- "\x1b[15;15H"
151- );
152+ "\x1b[15;15H");
153 defer term.deinit(alloc);
154
155 // Resize to 24 rows (simulates outer terminal being smaller)
156@@ -1085,12 +1067,10 @@ test "serializeTerminalState scrollback + size mismatch nested roundtrip" {
157 const line = std.fmt.bufPrint(&buf, "LINE_{d}\r\n", .{i}) catch unreachable;
158 try inner_stream.nextSlice(line);
159 }
160- try inner_stream.nextSlice(
161- "\x1b[2J" ++
162+ try inner_stream.nextSlice("\x1b[2J" ++
163 "\x1b[3;10HSTRESS_A" ++
164 "\x1b[12;25HSTRESS_B" ++
165- "\x1b[16;20H"
166- );
167+ "\x1b[16;20H");
168 }
169
170 // Resize inner to 24 rows (outer terminal is smaller)