summaryrefslogtreecommitdiff
path: root/src/normal.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/normal.zig')
-rw-r--r--src/normal.zig28
1 files changed, 24 insertions, 4 deletions
diff --git a/src/normal.zig b/src/normal.zig
index 4459ab53..2aea2e54 100644
--- a/src/normal.zig
+++ b/src/normal.zig
@@ -686,10 +686,7 @@ fn executeNormalAction(p: *Pardes, t: *Text, semantic: modal.Normal.Action) void
.all => return t.setRange(text, 0, .{ .anchor = 0, .head = text.len }, false),
},
.multi => |multi| {
- if (multi.kind == .keep_primary) {
- t.nsel = 0;
- return;
- }
+ if (multi.kind == .keep_primary) return t.dropSels();
return t.multiSelAction(text, multi.kind, multi.count);
},
// s, S and | answer for the text they are pressed in; `/` searches
@@ -922,6 +919,7 @@ test "flat text movement and selection replay need no scratch rows" {
pane.body.cur_row = 1024;
pane.body.cur_col = 0;
pane.body.nsel = 1;
+ _ = pane.body.reserveSels();
pane.body.sels[0] = .{ .row = 3072, .col = 0, .arow = 3072, .acol = 0 };
handleNormal(p, &pane.body, .{ .cp = 'l' });
handleNormal(p, &pane.body, .{ .cp = 'j' });
@@ -1021,3 +1019,25 @@ test "tree-sitter selection keys do in a JSON file what hx 25.07.1 does" {
};
}
}
+
+test "one cursor holds no room for other ranges; a second range makes it and one again gives it back" {
+ const gpa = std.testing.allocator;
+ const p = try Pardes.init(gpa, .{ .tty_only = true, .cols = 60, .rows = 12 });
+ defer p.deinit();
+ const pane = try p.setTestFile("alpha beta\nalpha beta\n");
+ for ("wxe%;gg") |cp| handleNormal(p, &pane.body, .{ .cp = cp });
+ try std.testing.expectEqual(@as(usize, 0), pane.body.sels.len);
+ handleNormal(p, &pane.body, .{ .cp = 'C' });
+ try std.testing.expectEqual(@as(u16, 1), pane.body.nsel);
+ try std.testing.expect(pane.body.sels.len > 0);
+ handleNormal(p, &pane.body, .{ .cp = 'l' }); // replayed at both, still two
+ try std.testing.expectEqual(@as(u16, 1), pane.body.nsel);
+ handleNormal(p, &pane.body, .{ .cp = ',' });
+ try std.testing.expectEqual(@as(usize, 0), pane.body.sels.len);
+ handleNormal(p, &pane.body, .{ .cp = 'C' });
+ handleNormal(p, &pane.body, .{ .cp = ';' });
+ handleNormal(p, &pane.body, .{ .cp = 'x' }); // x at both: still two lines
+ handleNormal(p, &pane.body, .{ .cp = '_', .alt = true }); // merged to one
+ try std.testing.expectEqual(@as(u16, 0), pane.body.nsel);
+ try std.testing.expectEqual(@as(usize, 0), pane.body.sels.len);
+}