From ea33d78ae42e966775ca5b1f20fbcc83401ab47e Mon Sep 17 00:00:00 2001 From: 5brian Date: Tue, 8 Apr 2025 11:15:34 -0400 Subject: [PATCH] vim: Fix visual line yank on newline char (#28005) Problem: When yanking in visual line on the newline char, the next line gets yanked as well: https://github.com/user-attachments/assets/40f332dd-19f5-445f-a30f-39d50167c46f Changes: Similar to visual delete, exclude the newline char from the selection in line mode. Release Notes: - vim: Fixed visual line yank while on the newline character yanking following line --- crates/vim/src/visual.rs | 30 ++++++++++++++++++++++ crates/vim/test_data/test_visual_yank.json | 6 +++++ 2 files changed, 36 insertions(+) diff --git a/crates/vim/src/visual.rs b/crates/vim/src/visual.rs index adb288395e..de044575c5 100644 --- a/crates/vim/src/visual.rs +++ b/crates/vim/src/visual.rs @@ -598,6 +598,23 @@ impl Vim { self.store_visual_marks(window, cx); self.update_editor(window, cx, |vim, editor, window, cx| { let line_mode = line_mode || editor.selections.line_mode; + + // For visual line mode, adjust selections to avoid yanking the next line when on \n + if line_mode && vim.mode != Mode::VisualBlock { + editor.change_selections(None, window, cx, |s| { + s.move_with(|map, selection| { + let start = selection.start.to_point(map); + let end = selection.end.to_point(map); + if end.column == 0 && end > start { + let row = end.row.saturating_sub(1); + selection.end = + Point::new(row, map.buffer_snapshot.line_len(MultiBufferRow(row))) + .to_display_point(map); + } + }); + }); + } + editor.selections.line_mode = line_mode; let kind = if line_mode { MotionKind::Linewise @@ -1132,6 +1149,19 @@ mod test { cx.shared_clipboard() .await .assert_eq("fox jumps over\nthe lazy dog\n"); + + cx.set_shared_state(indoc! {" + The quick brown + fox ˇjumps over + the lazy dog"}) + .await; + cx.simulate_shared_keystrokes("shift-v shift-4 shift-y") + .await; + cx.shared_state().await.assert_eq(indoc! {" + The quick brown + ˇfox jumps over + the lazy dog"}); + cx.shared_clipboard().await.assert_eq("fox jumps over\n"); } #[gpui::test] diff --git a/crates/vim/test_data/test_visual_yank.json b/crates/vim/test_data/test_visual_yank.json index 6e48021dad..0b41f4cfd2 100644 --- a/crates/vim/test_data/test_visual_yank.json +++ b/crates/vim/test_data/test_visual_yank.json @@ -34,3 +34,9 @@ {"Key":"shift-y"} {"Get":{"state":"The quick brown\nˇfox jumps over\nthe lazy dog","mode":"Normal"}} {"ReadRegister":{"name":"\"","value":"fox jumps over\nthe lazy dog\n"}} +{"Put":{"state":"The quick brown\nfox ˇjumps over\nthe lazy dog"}} +{"Key":"shift-v"} +{"Key":"shift-4"} +{"Key":"shift-y"} +{"Get":{"state":"The quick brown\nˇfox jumps over\nthe lazy dog","mode":"Normal"}} +{"ReadRegister":{"name":"\"","value":"fox jumps over\n"}}