vim: Fix 'Y' to yank to end of line (#14783)

Vishal Bhavsar created

Instead of yanking the entire line.

Release Notes:

- vim: Updated `Y` to yank to end of line (like neovim)
https://github.com/zed-industries/zed/issues/14771

Change summary

assets/keymaps/vim.json                |  2 +-
crates/vim/src/normal.rs               | 26 ++++++++++++++++++++++++++
crates/vim/test_data/test_shift_y.json |  4 ++++
3 files changed, 31 insertions(+), 1 deletion(-)

Detailed changes

assets/keymaps/vim.json 🔗

@@ -215,7 +215,7 @@
       "shift-d": "vim::DeleteToEndOfLine",
       "shift-j": "vim::JoinLines",
       "y": ["vim::PushOperator", "Yank"],
-      "shift-y": "vim::YankLine",
+      "shift-y": "vim::YankToEndOfLine",
       "i": "vim::InsertBefore",
       "shift-i": "vim::InsertFirstNonWhitespace",
       "a": "vim::InsertAfter",

crates/vim/src/normal.rs 🔗

@@ -58,6 +58,7 @@ actions!(
         DeleteToEndOfLine,
         Yank,
         YankLine,
+        YankToEndOfLine,
         ChangeCase,
         ConvertToUpperCase,
         ConvertToLowerCase,
@@ -82,6 +83,7 @@ pub(crate) fn register(workspace: &mut Workspace, cx: &mut ViewContext<Workspace
     workspace.register_action(convert_to_upper_case);
     workspace.register_action(convert_to_lower_case);
     workspace.register_action(yank_line);
+    workspace.register_action(yank_to_end_of_line);
     workspace.register_action(toggle_comments);
 
     workspace.register_action(|_: &mut Workspace, _: &DeleteLeft, cx| {
@@ -462,6 +464,21 @@ fn yank_line(_: &mut Workspace, _: &YankLine, cx: &mut ViewContext<Workspace>) {
     })
 }
 
+fn yank_to_end_of_line(_: &mut Workspace, _: &YankToEndOfLine, cx: &mut ViewContext<Workspace>) {
+    Vim::update(cx, |vim, cx| {
+        vim.record_current_action(cx);
+        let count = vim.take_count(cx);
+        yank_motion(
+            vim,
+            motion::Motion::EndOfLine {
+                display_lines: false,
+            },
+            count,
+            cx,
+        )
+    })
+}
+
 fn toggle_comments(_: &mut Workspace, _: &ToggleComments, cx: &mut ViewContext<Workspace>) {
     Vim::update(cx, |vim, cx| {
         vim.record_current_action(cx);
@@ -1434,6 +1451,15 @@ mod test {
         );
     }
 
+    #[gpui::test]
+    async fn test_shift_y(cx: &mut gpui::TestAppContext) {
+        let mut cx = NeovimBackedTestContext::new(cx).await;
+
+        cx.set_shared_state("helˇlo\n").await;
+        cx.simulate_shared_keystrokes("shift-y").await;
+        cx.shared_clipboard().await.assert_eq("lo");
+    }
+
     #[gpui::test]
     async fn test_r(cx: &mut gpui::TestAppContext) {
         let mut cx = NeovimBackedTestContext::new(cx).await;