fix: replace selected ranges instead of ignoring visual paste

This commit is contained in:
Valdemar Lorenzen
2026-10-14 12:26:01 +02:00
parent 5580d6fbd4
commit c5f80f27a6
6 changed files with 159 additions and 11 deletions
+56
View File
@@ -42,6 +42,62 @@ fn keys(editor: &mut Editor, text: &str) {
}
}
#[test]
fn visual_paste_replaces_selection_and_preserves_clipboard_and_undo() {
for paste in ['p', 'P'] {
for (yank, select, expected) in [
("vly", "j0vl", "XY\nXYc\nend"),
("vly", "j0lvh", "XY\nXYc\nend"),
("yy", "j0vl", "XY\nXY\nc\nend"),
("yy", "jV", "XY\nXY\nend"),
("vly", "jV", "XY\nXYend"),
] {
let fixture = Fixture::new();
let source = "XY\nabc\nend";
let mut editor = fixture.editor(source);
keys(&mut editor, yank);
keys(&mut editor, select);
editor.handle(Input::Char(paste));
assert_eq!(editor.context().text, expected, "{yank} {select} {paste}");
assert_eq!(editor.mode(), Mode::Normal);
keys(&mut editor, "u");
assert_eq!(editor.context().text, source);
keys(&mut editor, "U");
assert_eq!(editor.context().text, expected);
keys(
&mut editor,
if select.ends_with("vh") {
"u0l."
} else {
"u0."
},
);
assert_eq!(
editor.context().text,
expected,
"repeat: {yank} {select} {paste}"
);
keys(&mut editor, "u");
keys(&mut editor, select.trim_start_matches('j'));
editor.handle(Input::Char(paste));
assert_eq!(editor.context().text, expected, "clipboard stays unchanged");
}
}
}
#[test]
fn visual_paste_replaces_every_selected_range_in_one_undo_group() {
let fixture = Fixture::new();
let source = "XY\n界e\u{301}\n👩‍🚀z";
let mut editor = fixture.editor(source);
keys(&mut editor, "vlyj0vl");
editor.handle(Input::Ctrl('e'));
keys(&mut editor, "p");
assert_eq!(editor.context().text, "XY\nXY\nXY");
keys(&mut editor, "u");
assert_eq!(editor.context().text, source);
}
#[test]
fn whole_line_yank_pastes_above_or_below_the_target_and_keeps_indentation() {
let source = " \t界e\u{301}👩‍🚀\nother\nlast\n";