diff options
Diffstat (limited to 'src/terminal.zig')
| -rw-r--r-- | src/terminal.zig | 17 |
1 files changed, 16 insertions, 1 deletions
diff --git a/src/terminal.zig b/src/terminal.zig index 6bf46bef..1a3b6a21 100644 --- a/src/terminal.zig +++ b/src/terminal.zig @@ -1343,7 +1343,10 @@ pub fn shellRows(p: *Pardes, pane: *Pane) ![]const []const u8 { if (pane.terminal == null) return &empty_grid; const c = &p.shell_rows; if (!c.stale and c.pane == pane) return c.rows; - if (c.pane != null) { + // Another pane's rows, or a dropped pane's still waiting for the step's + // sweep (dropPane keeps them, as they may still be borrowed): this + // step's rows are scratch, and nothing in the slot is written over. + if (c.pane != null or c.text_alloc.len > 0 or c.rows.len > 0) { c.stale = true; return (try buildRows(p.scratch.allocator(), p, pane)).rows; } @@ -1357,6 +1360,18 @@ pub fn shellRows(p: *Pardes, pane: *Pane) ![]const []const u8 { return c.rows; } +test "rows asked for after a pane's cached rows were dropped, before the sweep, leak nothing" { + if (comptime !enabled) return error.SkipZigTest; + const p = try Pardes.init(std.testing.allocator, .{ .tty_only = true }); + defer p.deinit(); + const pane = p.panes[0].?; + try std.testing.expect(pane.terminal != null); + _ = try shellRows(p, pane); + // A pane's teardown drops its entry; the rows stay until the sweep. + p.shell_rows.dropPane(pane); + _ = try shellRows(p, pane); +} + /// The full modal motion surface: shell history with the live edit overlay /// spliced into the rows it covers. pub fn cursorLines(p: *Pardes, pane: *Pane) ![]const []const u8 { |
