vim: Handle paste in visual line mode when cursor is at newline (#30791)
Dino
created
This Pull Request fixes the current paste behavior in vim mode, when in
visual mode, and the cursor is at a newline character. Currently this
joins the pasted contents with the line right below it, but in vim this
does not happen, so these changes make it so that Zed's vim mode behaves
the same as vim for this specific case.
Closes #29270
Release Notes:
- Fixed pasting in vim's visual line mode when cursor is on a newline
character
@@ -124,7 +124,20 @@ impl Vim {
}
let display_range = if !selection.is_empty() {
- selection.start..selection.end
+ // If vim is in VISUAL LINE mode and the column for the
+ // selection's end point is 0, that means that the
+ // cursor is at the newline character (\n) at the end of
+ // the line. In this situation we'll want to move one
+ // position to the left, ensuring we don't join the last
+ // line of the selection with the line directly below.
+ let end_point =
+ if vim.mode == Mode::VisualLine && selection.end.column() == 0 {
+ movement::left(&display_map, selection.end)
+ } else {
+ selection.end
+ };
+
+ selection.start..end_point
} else if line_mode {
let point = if before {
movement::line_beginning(&display_map, selection.start, false)
@@ -553,6 +566,17 @@ mod test {
ˇfox jumps over
the lazy dog"});
cx.shared_clipboard().await.assert_eq("The quick brown\n");
+
+ // Copy line and paste in visual mode, with cursor on newline character.
+ cx.set_shared_state(indoc! {"
+ ˇThe quick brown
+ fox jumps over
+ the lazy dog"})
+ .await;
+ cx.simulate_shared_keystrokes("y y shift-v j $ p").await;
+ cx.shared_state().await.assert_eq(indoc! {"
+ ˇThe quick brown
+ the lazy dog"});
}
#[gpui::test]