From 1c57bbabdaf309678b9fd535709649219e22876f Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Tue, 19 Mar 2024 09:25:01 -0700 Subject: [PATCH] termio/exec: clear screen should erase rows and shift up --- src/terminal/PageList.zig | 8 +++----- src/terminal/Screen.zig | 29 +++++++++++++++++++++++++++++ src/termio/Exec.zig | 3 +-- 3 files changed, 33 insertions(+), 7 deletions(-) diff --git a/src/terminal/PageList.zig b/src/terminal/PageList.zig index a2918f604..19f2512d5 100644 --- a/src/terminal/PageList.zig +++ b/src/terminal/PageList.zig @@ -1871,12 +1871,10 @@ pub fn eraseRows( const old_dst = dst.*; dst.* = src.*; src.* = old_dst; - } - // We don't even bother deleting the data in the swapped rows - // because erasing in this way yields a page that likely will never - // be written to again (its in the past) or it will grow and the - // terminal erase will automatically erase the data. + // Clear the old data in case we reuse these cells. + chunk.page.data.clearCells(src, 0, chunk.page.data.size.cols); + } // Update any tracked pins to shift their y. If it was in the erased // row then we move it to the top of this page. diff --git a/src/terminal/Screen.zig b/src/terminal/Screen.zig index ca77ae177..59748a14c 100644 --- a/src/terminal/Screen.zig +++ b/src/terminal/Screen.zig @@ -2395,6 +2395,35 @@ test "Screen eraseRows history with more lines" { } } +test "Screen eraseRows active partial" { + const testing = std.testing; + const alloc = testing.allocator; + + var s = try Screen.init(alloc, 5, 5, 0); + defer s.deinit(); + + try s.testWriteString("1\n2\n3"); + + { + const str = try s.dumpStringAlloc(alloc, .{ .active = .{} }); + defer alloc.free(str); + try testing.expectEqualStrings("1\n2\n3", str); + } + + s.eraseRows(.{ .active = .{} }, .{ .active = .{ .y = 1 } }); + + { + const str = try s.dumpStringAlloc(alloc, .{ .active = .{} }); + defer alloc.free(str); + try testing.expectEqualStrings("3", str); + } + { + const str = try s.dumpStringAlloc(alloc, .{ .screen = .{} }); + defer alloc.free(str); + try testing.expectEqualStrings("3", str); + } +} + test "Screen: clearPrompt" { const testing = std.testing; const alloc = testing.allocator; diff --git a/src/termio/Exec.zig b/src/termio/Exec.zig index e3d08f2b3..43708ed2b 100644 --- a/src/termio/Exec.zig +++ b/src/termio/Exec.zig @@ -479,10 +479,9 @@ pub fn clearScreen(self: *Exec, history: bool) !void { // If we're not at a prompt, we just delete above the cursor. if (!self.terminal.cursorIsAtPrompt()) { if (self.terminal.screen.cursor.y > 0) { - self.terminal.screen.clearRows( + self.terminal.screen.eraseRows( .{ .active = .{ .y = 0 } }, .{ .active = .{ .y = self.terminal.screen.cursor.y - 1 } }, - false, ); }