From fa5646e762b4836526858ba3e2ea2cfdb8c43812 Mon Sep 17 00:00:00 2001 From: Qwerasd Date: Wed, 3 Apr 2024 19:28:02 -0400 Subject: [PATCH 1/2] test(terminal/Screen): selectionString across page boundaries --- src/terminal/Screen.zig | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/src/terminal/Screen.zig b/src/terminal/Screen.zig index a295f0ce5..f59a4549f 100644 --- a/src/terminal/Screen.zig +++ b/src/terminal/Screen.zig @@ -7073,6 +7073,37 @@ test "Screen: selectionString, rectangle, more complex w/breaks" { try testing.expectEqualStrings(expected, contents); } +test "Screen: selectionString multi-page" { + const testing = std.testing; + const alloc = testing.allocator; + + var s = try init(alloc, 130, 40, 512); + defer s.deinit(); + // 512 * "y\n" + var str: [1024]u8 = undefined; + var i: usize = 0; + while (i < str.len) : (i += 2) { + str[i] = 'y'; + str[i + 1] = '\n'; + } + try s.testWriteString(&str); + + { + const sel = Selection.init( + s.pages.pin(.{ .screen = .{ .x = 0, .y = 0 } }).?, + s.pages.pin(.{ .active = .{ .x = 1, .y = 39 } }).?, + false, + ); + const contents = try s.selectionString(alloc, .{ + .sel = sel, + .trim = true, + }); + defer alloc.free(contents); + const expected = str[0..1023]; + try testing.expectEqualStrings(expected, contents); + } +} + test "Screen: lineIterator" { const testing = std.testing; const alloc = testing.allocator; From 8be145ec1f8afa1f44f2f8a015869545b719c254 Mon Sep 17 00:00:00 2001 From: Qwerasd Date: Wed, 3 Apr 2024 20:03:25 -0400 Subject: [PATCH 2/2] fix(terminal/Sreen): selectionString across pages Newlines after rows should only be omitted on the final row of the entire SELECTION, not on the final row of each page/chunk. --- src/terminal/Screen.zig | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/terminal/Screen.zig b/src/terminal/Screen.zig index f59a4549f..9b7472531 100644 --- a/src/terminal/Screen.zig +++ b/src/terminal/Screen.zig @@ -1355,14 +1355,14 @@ pub fn selectionString(self: *Screen, alloc: Allocator, opts: SelectionString) ! defer if (mapbuilder) |*b| b.deinit(); const sel_ordered = opts.sel.ordered(self, .forward); - const sel_start = start: { - var start = sel_ordered.start(); + const sel_start: Pin = start: { + var start: Pin = sel_ordered.start(); const cell = start.rowAndCell().cell; if (cell.wide == .spacer_tail) start.x -= 1; break :start start; }; - const sel_end = end: { - var end = sel_ordered.end(); + const sel_end: Pin = end: { + var end: Pin = sel_ordered.end(); const cell = end.rowAndCell().cell; switch (cell.wide) { .narrow, .wide => {}, @@ -1433,7 +1433,9 @@ pub fn selectionString(self: *Screen, alloc: Allocator, opts: SelectionString) ! } } - if (row_count < rows.len - 1 and + const is_final_row = sel_end.page == chunk.page and sel_end.y == chunk.start + row_count; + + if (!is_final_row and (!row.wrap or sel_ordered.rectangle)) { try strbuilder.append('\n');