From b02bd9bce1db3a68dcd606718fa02709020860af Mon Sep 17 00:00:00 2001 From: Conrad Irwin Date: Fri, 15 Sep 2023 11:14:04 -0600 Subject: [PATCH] Fix Y on last line with no trailing new line For zed-industries/community#2044 --- assets/keymaps/vim.json | 1 + crates/vim/src/utils.rs | 3 ++- crates/vim/src/visual.rs | 22 ++++++++++++++++++++-- crates/vim/test_data/test_visual_yank.json | 6 ++++++ 4 files changed, 29 insertions(+), 3 deletions(-) diff --git a/assets/keymaps/vim.json b/assets/keymaps/vim.json index 4dffb07dfc..8d32d0bccd 100644 --- a/assets/keymaps/vim.json +++ b/assets/keymaps/vim.json @@ -453,6 +453,7 @@ "d": "vim::VisualDelete", "x": "vim::VisualDelete", "y": "vim::VisualYank", + "shift-y": "vim::VisualYank", "p": "vim::Paste", "shift-p": [ "vim::Paste", diff --git a/crates/vim/src/utils.rs b/crates/vim/src/utils.rs index 4a96b5bbea..797e94b0fa 100644 --- a/crates/vim/src/utils.rs +++ b/crates/vim/src/utils.rs @@ -26,10 +26,11 @@ pub fn copy_selections_content(editor: &mut Editor, linewise: bool, cx: &mut App let is_last_line = linewise && end.row == buffer.max_buffer_row() && buffer.max_point().column > 0 + && start.row < buffer.max_buffer_row() && start == Point::new(start.row, buffer.line_len(start.row)); if is_last_line { - start = Point::new(buffer.max_buffer_row(), 0); + start = Point::new(start.row + 1, 0); } for chunk in buffer.text_for_range(start..end) { text.push_str(chunk); diff --git a/crates/vim/src/visual.rs b/crates/vim/src/visual.rs index acd55a0954..f59b1fe167 100644 --- a/crates/vim/src/visual.rs +++ b/crates/vim/src/visual.rs @@ -12,7 +12,7 @@ use language::{Selection, SelectionGoal}; use workspace::Workspace; use crate::{ - motion::Motion, + motion::{start_of_line, Motion}, object::Object, state::{Mode, Operator}, utils::copy_selections_content, @@ -326,7 +326,10 @@ pub fn yank(_: &mut Workspace, _: &VisualYank, cx: &mut ViewContext) let line_mode = editor.selections.line_mode; copy_selections_content(editor, line_mode, cx); editor.change_selections(None, cx, |s| { - s.move_with(|_, selection| { + s.move_with(|map, selection| { + if line_mode { + selection.start = start_of_line(map, false, selection.start); + }; selection.collapse_to(selection.start, SelectionGoal::None) }); if vim.state().mode == Mode::VisualBlock { @@ -672,6 +675,21 @@ mod test { the lazy dog"}) .await; cx.assert_clipboard_content(Some("The q")); + + cx.set_shared_state(indoc! {" + The quick brown + fox ˇjumps over + the lazy dog"}) + .await; + cx.simulate_shared_keystrokes(["shift-v", "shift-g", "shift-y"]) + .await; + cx.assert_shared_state(indoc! {" + The quick brown + ˇfox jumps over + the lazy dog"}) + .await; + cx.assert_shared_clipboard("fox jumps over\nthe lazy dog\n") + .await; } #[gpui::test] diff --git a/crates/vim/test_data/test_visual_yank.json b/crates/vim/test_data/test_visual_yank.json index edc3b4f83d..2e7b725371 100644 --- a/crates/vim/test_data/test_visual_yank.json +++ b/crates/vim/test_data/test_visual_yank.json @@ -27,3 +27,9 @@ {"Key":"k"} {"Key":"y"} {"Get":{"state":"ˇThe quick brown\nfox jumps over\nthe lazy dog","mode":"Normal"}} +{"Put":{"state":"The quick brown\nfox ˇjumps over\nthe lazy dog"}} +{"Key":"shift-v"} +{"Key":"shift-g"} +{"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"}}