diff options
| author | Gabriel Schneider <[email protected]> | 2026-09-15 12:29:41 -0300 |
|---|---|---|
| committer | Gabriel Schneider <[email protected]> | 2026-09-15 17:24:42 -0300 |
| commit | 8b0bed0427064794725f95cb7b020d7d96956975 (patch) | |
| tree | e44dad51729bafd8a46a386af4a20674fc36c9d8 /test | |
| parent | a624a56e289e4a02a411f83741f0f2c9fc0f0b2e (diff) | |
| download | pardes-8b0bed0427064794725f95cb7b020d7d96956975.tar.gz pardes-8b0bed0427064794725f95cb7b020d7d96956975.zip | |
Preserve selections when navigating jump history
Diffstat (limited to 'test')
| -rw-r--r-- | test/panes.zig | 65 | ||||
| -rw-r--r-- | test/pdf.zig | 12 |
2 files changed, 73 insertions, 4 deletions
diff --git a/test/panes.zig b/test/panes.zig index a324d74a..ab7726e1 100644 --- a/test/panes.zig +++ b/test/panes.zig @@ -12,6 +12,70 @@ const image = pardes.image; const syntax = pardes.syntax; const filesystem = pardes.filesystem; +const JumpSelectionTests = struct { + fn drag(p: *Pardes, col0: u16, row0: u16, col1: u16, row1: u16) void { + p.update(.{ .mouse = .{ .button = .left, .kind = .press, .col = col0, .row = row0 } }); + p.update(.{ .mouse = .{ .button = .left, .kind = .drag, .col = col1, .row = row1 } }); + p.update(.{ .mouse = .{ .button = .left, .kind = .release, .col = col1, .row = row1 } }); + } + + fn exercise(prefix: []const u8, wrap: bool, reverse: bool, first_col: u16, last_col: u16, expected: ?[]const u8) !void { + const p = try Pardes.init(std.testing.allocator, .{ .tty_only = true, .cols = 34, .rows = 10 }); + defer p.deinit(); + p.settings.wrap = wrap; + const text = try std.fmt.allocPrint(p.gpa, "{s}{s}", .{ prefix, "unrelated destination text\n" ** 80 }); + defer p.gpa.free(text); + const pane = try p.setTestFile(text); + var frame = std.heap.ArenaAllocator.init(p.gpa); + defer frame.deinit(); + _ = try p.render(frame.allocator()); + if (wrap) try std.testing.expectEqual(pane.wrap_line[0], pane.wrap_line[1]); + const rect = p.rects[0]; + const x = rect.x + config.GUTTER + panes.File.gutterWidth(pane); + const y = if (p.settings.tag_bottom) rect.y else rect.y + pardes.BOX_H; + if (reverse) + drag(p, x + last_col, y + 1, x + first_col, y) + else + drag(p, x + first_col, y, x + last_col, y + 1); + + const selected = try p.gpa.dupe(u8, pardes.test_api.heldSelection(p, 0) orelse return error.MissingMouseSelection); + defer p.gpa.free(selected); + if (expected) |want| try std.testing.expectEqualStrings(want, selected); + try std.testing.expect(std.mem.indexOfScalar(u8, selected, '\n') != null); + if (wrap) try std.testing.expect(std.mem.indexOf(u8, selected, "界") != null); + + // Seed two actual locations after the drag, so both history directions + // must scroll while retaining the rectangle's original source text. + p.njumps = 2; + p.jcur = 1; + p.jumps[0] = .{ .pane = 0, .serial = pane.serial, .line = 60, .col = 1 }; + p.jumps[1] = .{ .pane = 0, .serial = pane.serial, .line = 1, .col = 1 }; + p.update(.{ .key = .{ .cp = 'o', .ctrl = true } }); + _ = frame.reset(.retain_capacity); + _ = try p.render(frame.allocator()); + try std.testing.expectEqual(@as(usize, 0), p.jcur); + try std.testing.expect(pane.file.?.scroll > 20); + try std.testing.expectEqualStrings(selected, pardes.test_api.heldSelection(p, 0) orelse return error.LostMouseSelection); + + p.update(.{ .key = .{ .cp = 'i', .ctrl = true } }); + _ = frame.reset(.retain_capacity); + _ = try p.render(frame.allocator()); + try std.testing.expectEqual(@as(usize, 1), p.jcur); + try std.testing.expectEqual(@as(usize, 0), pane.file.?.scroll); + try std.testing.expectEqualStrings(selected, pardes.test_api.heldSelection(p, 0) orelse return error.LostMouseSelection); + } + + test "jump selection retains copied rectangle text after scrolling away and back" { + for ([_]bool{ false, true }) |reverse| + try exercise("alpha\nbravo\n", false, reverse, 1, 3, "lph\nrav"); + } + + test "jump selection retains wrapped Unicode and tab rectangle text" { + for ([_]bool{ false, true }) |reverse| + try exercise("界\tabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789\n", true, reverse, 0, 8, null); + } +}; + test "pane filename edits stage commit and cancel without changing body or command tail" { const p = try Pardes.init(std.testing.allocator, .{ .tty_only = true, .cols = 70, .rows = 12 }); defer p.deinit(); @@ -2627,6 +2691,7 @@ const TerminalTests = struct { }; test { + _ = JumpSelectionTests; _ = @import("output.zig"); _ = @import("pdf.zig"); _ = @import("fs_namespace.zig"); diff --git a/test/pdf.zig b/test/pdf.zig index a5720f3f..4c0daf34 100644 --- a/test/pdf.zig +++ b/test/pdf.zig @@ -1629,7 +1629,7 @@ test "PDF native mouse selection, Look, and highlights share page geometry" { p.scratch.allocator(), panes.Pdf.highlightInput(p, 0, pane), ); - const page_highlights = decorated.forPage(pv.page, pv.page); + const page_highlights = decorated.forPage(pv.page); try std.testing.expectEqual(pdf_impl.HighlightKind.custom, page_highlights[0].kind); try std.testing.expectEqual(pdf_impl.HighlightKind.selection, page_highlights[page_highlights.len - 1].kind); _ = frame.reset(.retain_capacity); @@ -1672,7 +1672,7 @@ test "PDF native mouse selection, Look, and highlights share page geometry" { pv, p.scratch.allocator(), panes.Pdf.highlightInput(p, 0, pane), - )).items; + )).forPage(pv.page); try std.testing.expect(highlights.len > 1); try std.testing.expectEqual(pdf_impl.HighlightKind.search, highlights[0].kind); try std.testing.expectEqual(pdf_impl.HighlightKind.selection, highlights[highlights.len - 1].kind); @@ -1814,9 +1814,13 @@ test "PDF native mouse selection, Look, and highlights share page geometry" { const saved_query = try gpa.dupe(u8, pv.search_query); defer gpa.free(saved_query); + const saved_selection = try gpa.dupe(u8, pv.selection_text); + defer gpa.free(saved_selection); + const selected_page = pv.selection_page; panes.Pdf.setPage(p, pane, 1); - try std.testing.expect(pv.selection == null); - try std.testing.expectEqual(@as(usize, 0), pv.selection_text.len); + try std.testing.expect(pv.selection != null); + try std.testing.expectEqual(selected_page, pv.selection_page); + try std.testing.expectEqualStrings(saved_selection, pv.selection_text); try std.testing.expectEqualStrings(saved_query, pv.search_query); } |
