repos / zmx

session persistence for terminal processes
git clone https://github.com/neurosnap/zmx.git

commit
ac62850
parent
4b729ab
author
Eric Bower
date
2025-10-14 11:56:40 -0400 EDT
chore: reset
1 files changed,  +12, -84
M src/daemon.zig
+12, -84
  1@@ -733,91 +733,19 @@ fn renderTerminalSnapshot(session: *Session, allocator: std.mem.Allocator) ![]u8
  2     // Clear screen and move to home
  3     try output.appendSlice(allocator, "\x1b[2J\x1b[H");
  4 
  5-    // Get the active screen from the terminal
  6     const screen = &session.vt.screen;
  7-    var it = screen.pages.pageIterator(.right_down, .{ .screen = .{} }, null);
  8-
  9-    var blank_rows: usize = 0;
 10-    var blank_cells: usize = 0;
 11-
 12-    while (it.next()) |chunk| {
 13-        const page: *const ghostty.Page = &chunk.node.data;
 14-        const start_y = chunk.start;
 15-        const end_y = chunk.end;
 16-
 17-        for (start_y..end_y) |y_usize| {
 18-            const y: u16 = @intCast(y_usize);
 19-            const row = page.getRow(y);
 20-            const cells = page.getCells(row);
 21-
 22-            // Check if row has any text content
 23-            const has_text = blk: {
 24-                for (cells) |cell| {
 25-                    if (cell.hasText()) break :blk true;
 26-                }
 27-                break :blk false;
 28-            };
 29-
 30-            // If row is blank, accumulate blank rows
 31-            if (!has_text) {
 32-                blank_rows += 1;
 33-                continue;
 34-            }
 35-
 36-            // Dump accumulated blank rows as newlines
 37-            for (0..blank_rows) |_| {
 38-                try output.appendSlice(allocator, "\r\n");
 39-            }
 40-            blank_rows = 0;
 41-
 42-            // If row doesn't continue a wrap, reset blank cells
 43-            if (!row.wrap_continuation) blank_cells = 0;
 44-
 45-            // Write each cell in the row
 46-            for (cells) |*cell| {
 47-                // Skip spacer cells (wide character continuations)
 48-                switch (cell.wide) {
 49-                    .narrow, .wide => {},
 50-                    .spacer_head, .spacer_tail => continue,
 51-                }
 52-
 53-                // Accumulate blank cells
 54-                if (!cell.hasText()) {
 55-                    blank_cells += 1;
 56-                    continue;
 57-                }
 58-
 59-                // Dump accumulated blank cells as spaces
 60-                if (blank_cells > 0) {
 61-                    for (0..blank_cells) |_| {
 62-                        try output.append(allocator, ' ');
 63-                    }
 64-                    blank_cells = 0;
 65-                }
 66-
 67-                // Write the actual character
 68-                const cp = cell.content.codepoint;
 69-                var buf: [4]u8 = undefined;
 70-                const len = std.unicode.utf8Encode(cp, &buf) catch continue;
 71-                try output.appendSlice(allocator, buf[0..len]);
 72-
 73-                // Handle grapheme clusters (combining characters)
 74-                if (cell.content_tag == .codepoint_grapheme) {
 75-                    if (page.lookupGrapheme(cell)) |grapheme| {
 76-                        for (grapheme) |gcp| {
 77-                            const glen = std.unicode.utf8Encode(gcp, &buf) catch continue;
 78-                            try output.appendSlice(allocator, buf[0..glen]);
 79-                        }
 80-                    }
 81-                }
 82-            }
 83-
 84-            // Add newline after each row (unless it wraps to the next)
 85-            if (!row.wrap) {
 86-                try output.appendSlice(allocator, "\r\n");
 87-            }
 88-        }
 89-    }
 90+    const content = try session.vt.plainStringUnwrapped(allocator);
 91+    defer allocator.free(content);
 92+    try output.appendSlice(allocator, content);
 93+    // Get the active screen from the terminal
 94+    // var it = screen.pages.pageIterator(.right_down, .{ .screen = .{} }, null);
 95+    // var blank_rows: usize = 0;
 96+    // var blank_cells: usize = 0;
 97+    // while (it.next()) |chunk| {
 98+    //     const page: *const ghostty.Page = &chunk.node.data;
 99+    //     const start_y = chunk.start;
100+    //     const end_y = chunk.end;
101+    // }
102 
103     // Position cursor at correct location (ANSI is 1-based)
104     const cursor = screen.cursor;