From 5d34f171a046fb181f5d44a4c9a6659a75967364 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Sun, 15 May 2022 21:17:27 -0700 Subject: [PATCH] insertLines with scroll region support --- src/terminal/Terminal.zig | 65 +++++++++++++++++++++++++++------------ 1 file changed, 45 insertions(+), 20 deletions(-) diff --git a/src/terminal/Terminal.zig b/src/terminal/Terminal.zig index 2f6395da8..5b1bcc0e6 100644 --- a/src/terminal/Terminal.zig +++ b/src/terminal/Terminal.zig @@ -438,40 +438,32 @@ pub fn linefeed(self: *Terminal, alloc: Allocator) void { /// /// Moves the cursor to the left margin. pub fn insertLines(self: *Terminal, alloc: Allocator, count: usize) !void { - // TODO: scroll region bounds - if (self.scrolling_region.bottom != self.rows - 1 or - self.scrolling_region.top != 0) @panic("unimplemented"); - // Move the cursor to the left margin self.cursor.x = 0; // Remaining rows from our cursor - const rem = self.rows - (self.cursor.y + 1); + const rem = self.scrolling_region.bottom - self.cursor.y + 1; - // If we're trying to insert more than the remaining number of rows, we just - // erase below and we're done. - if (count >= rem) { - try self.eraseDisplay(alloc, .below); - return; - } + // If count is greater than the amount of rows, adjust down. + const adjusted_count = @minimum(count, rem); // The the top `scroll_amount` lines need to move to the bottom - // scroll area. - const scroll_amount = rem - count; - var y: usize = self.rows - 1; - const top = y - scroll_amount - 1; + // scroll area. We may have nothing to scroll if we're clearing. + const scroll_amount = rem - adjusted_count; + var y: usize = self.scrolling_region.bottom; + const top = y - scroll_amount; // Ensure we have the lines populated to the end _ = try self.getOrPutCell(alloc, 0, y); while (y > top) : (y -= 1) { self.screen.items[y].deinit(alloc); - self.screen.items[y] = self.screen.items[y - count]; - self.screen.items[y - count] = .{}; + self.screen.items[y] = self.screen.items[y - adjusted_count]; + self.screen.items[y - adjusted_count] = .{}; } // Insert count blank lines y = self.cursor.y; - while (y < self.cursor.y + count) : (y += 1) { + while (y < self.cursor.y + adjusted_count) : (y += 1) { var x: usize = 0; while (x < self.cols) : (x += 1) { const cell = try self.getOrPutCell(alloc, x, y); @@ -825,6 +817,39 @@ test "Terminal: insertLines" { } } +test "Terminal: insertLines with scroll region" { + const alloc = testing.allocator; + var t = try init(alloc, 2, 6); + defer t.deinit(alloc); + + // Initial value + try t.print(alloc, 'A'); + t.carriageReturn(); + t.linefeed(alloc); + try t.print(alloc, 'B'); + t.carriageReturn(); + t.linefeed(alloc); + try t.print(alloc, 'C'); + t.carriageReturn(); + t.linefeed(alloc); + try t.print(alloc, 'D'); + t.carriageReturn(); + t.linefeed(alloc); + try t.print(alloc, 'E'); + + t.setScrollingRegion(1, 2); + t.setCursorPos(1, 1); + try t.insertLines(alloc, 1); + + try t.print(alloc, 'X'); + + { + var str = try t.plainString(testing.allocator); + defer testing.allocator.free(str); + try testing.expectEqualStrings("X\nA\nC\nD\nE", str); + } +} + test "Terminal: insertLines more than remaining" { const alloc = testing.allocator; var t = try init(alloc, 2, 5); @@ -848,8 +873,8 @@ test "Terminal: insertLines more than remaining" { // Move to row 2 t.setCursorPos(2, 1); - // Insert two lines - try t.insertLines(alloc, 10); + // Insert a bunch of lines + try t.insertLines(alloc, 20); { var str = try t.plainString(testing.allocator);