From 3ee30058ab8eeeefa9b6503693abd0f3e1328ae7 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Sun, 18 Jan 2026 14:43:19 -0800 Subject: [PATCH] terminal: increaseCapacity should preserve dirty flag This never caused any known issues, but it's a bug! `increaseCapacity` should produce a node with identical contents, just more capacity. We were forgetting to copy over the dirty flag. I looked back at `adjustCapacity` and it also didn't preserve the dirty flag so presumably downstream consumers have been handling this case manually. But, I think semantically it makes sense for `increaseCapacity` to preserve the dirty flag. This bug was found by AI (while I was doing another task). I fixed it and wrote the test by hand though. --- src/terminal/PageList.zig | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/src/terminal/PageList.zig b/src/terminal/PageList.zig index c5897b7e7..ea6168caa 100644 --- a/src/terminal/PageList.zig +++ b/src/terminal/PageList.zig @@ -3045,6 +3045,9 @@ pub fn increaseCapacity( @panic("unexpected clone failure"); }; + // Preserve page-level dirty flag (cloneFrom only copies row data) + new_page.dirty = page.dirty; + // Must not fail after this because the operations we do after this // can't be recovered. errdefer comptime unreachable; @@ -6942,6 +6945,37 @@ test "PageList increaseCapacity multi-page" { ); } +test "PageList increaseCapacity preserves dirty flag" { + const testing = std.testing; + const alloc = testing.allocator; + + var s = try init(alloc, 2, 4, 0); + defer s.deinit(); + + // Set page dirty flag and mark some rows as dirty + const page = &s.pages.first.?.data; + page.dirty = true; + + const rows = page.rows.ptr(page.memory); + rows[0].dirty = true; + rows[1].dirty = false; + rows[2].dirty = true; + rows[3].dirty = false; + + // Increase capacity + const new_node = try s.increaseCapacity(s.pages.first.?, .styles); + + // The page dirty flag should be preserved + try testing.expect(new_node.data.dirty); + + // Row dirty flags should be preserved + const new_rows = new_node.data.rows.ptr(new_node.data.memory); + try testing.expect(new_rows[0].dirty); + try testing.expect(!new_rows[1].dirty); + try testing.expect(new_rows[2].dirty); + try testing.expect(!new_rows[3].dirty); +} + test "PageList pageIterator single page" { const testing = std.testing; const alloc = testing.allocator;