diff --git a/assets/keymaps/vim.json b/assets/keymaps/vim.json index a8c8d248df..8197e40288 100644 --- a/assets/keymaps/vim.json +++ b/assets/keymaps/vim.json @@ -335,22 +335,101 @@ } }, { - "context": "vim_mode == helix_normal", + "context": "vim_mode == helix_normal && !menu", "bindings": { + "escape": "editor::Cancel", + "ctrl-[": "editor::Cancel", + ":": "command_palette::Toggle", + "shift-d": "vim::DeleteToEndOfLine", + "shift-j": "vim::JoinLines", + "y": "editor::Copy", + "shift-y": "vim::YankLine", "i": "vim::InsertBefore", + "shift-i": "vim::InsertFirstNonWhitespace", "a": "vim::InsertAfter", - "d": "vim::HelixDelete", - "w": "vim::NextWordStart", - "e": "vim::NextWordEnd", - "b": "vim::PreviousWordStart", + "shift-a": "vim::InsertEndOfLine", + "o": "vim::InsertLineBelow", + "shift-o": "vim::InsertLineAbove", + "~": "vim::ChangeCase", + "ctrl-a": "vim::Increment", + "ctrl-x": "vim::Decrement", + "p": "vim::Paste", + "shift-p": ["vim::Paste", { "before": true }], + "u": "vim::Undo", + "ctrl-r": "vim::Redo", + "r": "vim::PushReplace", + "s": "vim::Substitute", + "shift-s": "vim::SubstituteLine", + ">": "vim::Indent", + "<": "vim::Outdent", + "=": "vim::AutoIndent", + "g u": "vim::PushLowercase", + "g shift-u": "vim::PushUppercase", + "g ~": "vim::PushOppositeCase", + "\"": "vim::PushRegister", + "g q": "vim::PushRewrap", + "g w": "vim::PushRewrap", + "ctrl-pagedown": "pane::ActivateNextItem", + "ctrl-pageup": "pane::ActivatePreviousItem", + "insert": "vim::InsertBefore", + // tree-sitter related commands + "[ x": "editor::SelectLargerSyntaxNode", + "] x": "editor::SelectSmallerSyntaxNode", + "] d": "editor::GoToDiagnostic", + "[ d": "editor::GoToPreviousDiagnostic", + "] c": "editor::GoToHunk", + "[ c": "editor::GoToPreviousHunk", + // Goto mode + "g n": "pane::ActivateNextItem", + "g p": "pane::ActivatePreviousItem", + // "tab": "pane::ActivateNextItem", + // "shift-tab": "pane::ActivatePrevItem", + "shift-h": "pane::ActivatePreviousItem", + "shift-l": "pane::ActivateNextItem", + "g l": "vim::EndOfLine", + "g h": "vim::StartOfLine", + "g s": "vim::FirstNonWhitespace", // "g s" default behavior is "space s" + "g e": "vim::EndOfDocument", + "g y": "editor::GoToTypeDefinition", + "g r": "editor::FindAllReferences", // zed specific + "g t": "vim::WindowTop", + "g c": "vim::WindowMiddle", + "g b": "vim::WindowBottom", - "h": "vim::Left", - "j": "vim::Down", - "k": "vim::Up", - "l": "vim::Right" + "x": "editor::SelectLine", + "shift-x": "editor::SelectLine", + // Window mode + "space w h": "workspace::ActivatePaneLeft", + "space w l": "workspace::ActivatePaneRight", + "space w k": "workspace::ActivatePaneUp", + "space w j": "workspace::ActivatePaneDown", + "space w q": "pane::CloseActiveItem", + "space w s": "pane::SplitRight", + "space w r": "pane::SplitRight", + "space w v": "pane::SplitDown", + "space w d": "pane::SplitDown", + // Space mode + "space f": "file_finder::Toggle", + "space k": "editor::Hover", + "space s": "outline::Toggle", + "space shift-s": "project_symbols::Toggle", + "space d": "editor::GoToDiagnostic", + "space r": "editor::Rename", + "space a": "editor::ToggleCodeActions", + "space h": "editor::SelectAllMatches", + "space c": "editor::ToggleComments", + "space y": "editor::Copy", + "space p": "editor::Paste", + // Match mode + "m m": "vim::Matching", + "m i w": ["workspace::SendKeystrokes", "v i w"], + "shift-u": "editor::Redo", + "ctrl-c": "editor::ToggleComments", + "d": "vim::HelixDelete", + "c": "vim::Substitute", + "shift-c": "editor::AddSelectionBelow" } }, - { "context": "vim_mode == insert && !(showing_code_actions || showing_completions)", "bindings": { diff --git a/crates/vim/src/normal.rs b/crates/vim/src/normal.rs index 9fb719d04d..43657ffd73 100644 --- a/crates/vim/src/normal.rs +++ b/crates/vim/src/normal.rs @@ -48,6 +48,7 @@ actions!( JoinLinesNoWhitespace, DeleteLeft, DeleteRight, + HelixDelete, ChangeToEndOfLine, DeleteToEndOfLine, Yank, @@ -92,6 +93,21 @@ pub(crate) fn register(editor: &mut Editor, cx: &mut Context) { let times = Vim::take_count(cx); vim.delete_motion(Motion::Right, times, window, cx); }); + + Vim::action(editor, cx, |vim, _: &HelixDelete, window, cx| { + vim.record_current_action(cx); + vim.update_editor(window, cx, |_, editor, window, cx| { + editor.change_selections(None, window, cx, |s| { + s.move_with(|map, selection| { + if selection.is_empty() { + selection.end = movement::right(map, selection.end) + } + }) + }) + }); + vim.visual_delete(false, window, cx); + }); + Vim::action(editor, cx, |vim, _: &ChangeToEndOfLine, window, cx| { vim.start_recording(cx); let times = Vim::take_count(cx); diff --git a/crates/vim/src/vim.rs b/crates/vim/src/vim.rs index 9a0991b653..7cea48420d 100644 --- a/crates/vim/src/vim.rs +++ b/crates/vim/src/vim.rs @@ -438,7 +438,7 @@ impl Vim { vim.update(cx, |_, cx| { Vim::action(editor, cx, |vim, _: &SwitchToNormalMode, window, cx| { - vim.switch_mode(Mode::Normal, false, window, cx) + vim.switch_mode(vim.default_mode(cx), false, window, cx) }); Vim::action(editor, cx, |vim, _: &SwitchToInsertMode, window, cx| { @@ -739,6 +739,10 @@ impl Vim { cx.on_release(|_, _| drop(subscription)).detach(); } + pub fn default_mode(&self, cx: &App) -> Mode { + VimSettings::get_global(cx).default_mode + } + pub fn editor(&self) -> Option> { self.editor.upgrade() } @@ -1105,7 +1109,7 @@ impl Vim { } } - if mode == "normal" || mode == "visual" || mode == "operator" { + if mode == "normal" || mode == "visual" || mode == "operator" || mode == "helix_normal" { context.add("VimControl"); } context.set("vim_mode", mode);