From c1307cead48ba96c663d9d074ebeb21a1c90d96d Mon Sep 17 00:00:00 2001 From: Daniel Sauble Date: Thu, 17 Jul 2025 21:30:01 -0700 Subject: [PATCH] Add `;` key binding for Helix mode (#34315) Closes #34111 In Helix mode, the `;` key should collapse the current selection without moving the cursor. I've added a new action `vim::HelixCollapseSelection` to support this behavior. https://github.com/user-attachments/assets/1a40821a-f56f-456e-9d37-532500bef17b Release Notes: - Added `;` key binding to collapse the current text selection in Helix mode --- assets/keymaps/vim.json | 1 + crates/vim/src/normal.rs | 16 ++++++++++++++++ 2 files changed, 17 insertions(+) diff --git a/assets/keymaps/vim.json b/assets/keymaps/vim.json index dcb52e5250..89a71e59e6 100644 --- a/assets/keymaps/vim.json +++ b/assets/keymaps/vim.json @@ -377,6 +377,7 @@ "context": "vim_mode == helix_normal && !menu", "bindings": { "ctrl-[": "editor::Cancel", + ";": "vim::HelixCollapseSelection", ":": "command_palette::Toggle", "left": "vim::WrappingLeft", "right": "vim::WrappingRight", diff --git a/crates/vim/src/normal.rs b/crates/vim/src/normal.rs index 6131032f4f..13128e7b40 100644 --- a/crates/vim/src/normal.rs +++ b/crates/vim/src/normal.rs @@ -64,6 +64,8 @@ actions!( DeleteRight, /// Deletes using Helix-style behavior. HelixDelete, + /// Collapse the current selection + HelixCollapseSelection, /// Changes from cursor to end of line. ChangeToEndOfLine, /// Deletes from cursor to end of line. @@ -143,6 +145,20 @@ pub(crate) fn register(editor: &mut Editor, cx: &mut Context) { vim.switch_mode(Mode::HelixNormal, true, window, cx); }); + Vim::action(editor, cx, |vim, _: &HelixCollapseSelection, window, cx| { + vim.update_editor(window, cx, |_, editor, window, cx| { + editor.change_selections(SelectionEffects::no_scroll(), window, cx, |s| { + s.move_with(|map, selection| { + let mut point = selection.head(); + if !selection.reversed && !selection.is_empty() { + point = movement::left(map, selection.head()); + } + selection.collapse_to(point, selection.goal) + }); + }); + }); + }); + Vim::action(editor, cx, |vim, _: &ChangeToEndOfLine, window, cx| { vim.start_recording(cx); let times = Vim::take_count(cx);