From 76bbb7c361166964de43422c749c67f56eb08e04 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Sun, 8 Oct 2023 20:51:00 -0700 Subject: [PATCH] terminal: insert lines (IL) handles left/right scroll regions --- src/terminal/Screen.zig | 21 ++++++++++++++++ src/terminal/Terminal.zig | 50 ++++++++++++++++++++------------------- 2 files changed, 47 insertions(+), 24 deletions(-) diff --git a/src/terminal/Screen.zig b/src/terminal/Screen.zig index 6fd50b54e..93194393b 100644 --- a/src/terminal/Screen.zig +++ b/src/terminal/Screen.zig @@ -498,6 +498,27 @@ pub const Row = struct { } } + /// Copy a single cell from column x in src to column x in this row. + pub fn copyCell(self: Row, src: Row, x: usize) !void { + const dst_cell = self.getCellPtr(x); + const src_cell = src.getCellPtr(x); + + // If our destination has graphemes, we have to clear them. + if (dst_cell.attrs.grapheme) self.clearGraphemes(x); + dst_cell.* = src_cell.*; + + // If the source doesn't have any graphemes, then we can just copy. + if (!src_cell.attrs.grapheme) return; + + // Source cell has graphemes. Copy them. + const src_key = src.getId() + x + 1; + const src_data = src.screen.graphemes.get(src_key) orelse return; + const dst_key = self.getId() + x + 1; + const dst_gop = try self.screen.graphemes.getOrPut(self.screen.alloc, dst_key); + dst_gop.value_ptr.* = try src_data.copy(self.screen.alloc); + self.storage[0].header.flags.grapheme = true; + } + /// Copy the row src into this row. The row can be from another screen. pub fn copyRow(self: Row, src: Row) !void { // If we have graphemes, clear first to unset them. diff --git a/src/terminal/Terminal.zig b/src/terminal/Terminal.zig index cdf044be4..b09ca943e 100644 --- a/src/terminal/Terminal.zig +++ b/src/terminal/Terminal.zig @@ -1590,7 +1590,9 @@ pub fn insertLines(self: *Terminal, count: usize) !void { while (y > top) : (y -= 1) { const src = self.screen.getRow(.{ .active = y - adjusted_count }); const dst = self.screen.getRow(.{ .active = y }); - try dst.copyRow(src); + for (self.scrolling_region.left..self.scrolling_region.right + 1) |x| { + try dst.copyCell(src, x); + } } // Insert count blank lines @@ -2730,29 +2732,29 @@ test "Terminal: insertLines top/bottom scroll region" { } } -// test "Terminal: insertLines left/right scroll region" { -// const alloc = testing.allocator; -// var t = try init(alloc, 10, 10); -// defer t.deinit(alloc); -// -// try t.printString("ABC123"); -// t.carriageReturn(); -// try t.linefeed(); -// try t.printString("DEF456"); -// t.carriageReturn(); -// try t.linefeed(); -// try t.printString("GHI789"); -// t.scrolling_region.left = 1; -// t.scrolling_region.right = 3; -// t.setCursorPos(2, 2); -// try t.insertLines(1); -// -// { -// var str = try t.plainString(testing.allocator); -// defer testing.allocator.free(str); -// try testing.expectEqualStrings("ABC123\nD 56\nGEF489\n HI7", str); -// } -// } +test "Terminal: insertLines left/right scroll region" { + const alloc = testing.allocator; + var t = try init(alloc, 10, 10); + defer t.deinit(alloc); + + try t.printString("ABC123"); + t.carriageReturn(); + try t.linefeed(); + try t.printString("DEF456"); + t.carriageReturn(); + try t.linefeed(); + try t.printString("GHI789"); + t.scrolling_region.left = 1; + t.scrolling_region.right = 3; + t.setCursorPos(2, 2); + try t.insertLines(1); + + { + var str = try t.plainString(testing.allocator); + defer testing.allocator.free(str); + try testing.expectEqualStrings("ABC123\nD 56\nGEF489\n HI7", str); + } +} test "Terminal: insertLines" { const alloc = testing.allocator;