diff --git a/assets/keymaps/vim.json b/assets/keymaps/vim.json index 9453607ce9..3aaa3e4e1a 100644 --- a/assets/keymaps/vim.json +++ b/assets/keymaps/vim.json @@ -126,6 +126,21 @@ "g shift-t": "pane::ActivatePrevItem", "g d": "editor::GoToDefinition", "g shift-d": "editor::GoToTypeDefinition", + "g n": "vim::SelectNext", + "g shift-n": "vim::SelectPrevious", + "g >": [ + "editor::SelectNext", + { + "replace_newest": true + } + ], + "g <": [ + "editor::SelectPrevious", + { + "replace_newest": true + } + ], + "g a": "editor::SelectAllMatches", "g s": "outline::Toggle", "g shift-s": "project_symbols::Toggle", "g .": "editor::ToggleCodeActions", // zed specific diff --git a/crates/vim/src/visual.rs b/crates/vim/src/visual.rs index f59b1fe167..eac823de61 100644 --- a/crates/vim/src/visual.rs +++ b/crates/vim/src/visual.rs @@ -1,3 +1,4 @@ +use anyhow::Result; use std::{cmp, sync::Arc}; use collections::HashMap; @@ -28,6 +29,8 @@ actions!( VisualDelete, VisualYank, OtherEnd, + SelectNext, + SelectPrevious, ] ); @@ -46,6 +49,9 @@ pub fn init(cx: &mut AppContext) { cx.add_action(other_end); cx.add_action(delete); cx.add_action(yank); + + cx.add_action(select_next); + cx.add_action(select_previous); } pub fn visual_motion(motion: Motion, times: Option, cx: &mut WindowContext) { @@ -384,6 +390,50 @@ pub(crate) fn visual_replace(text: Arc, cx: &mut WindowContext) { }); } +pub fn select_next( + _: &mut Workspace, + _: &SelectNext, + cx: &mut ViewContext, +) -> Result<()> { + Vim::update(cx, |vim, cx| { + let count = + vim.take_count(cx) + .unwrap_or_else(|| if vim.state().mode.is_visual() { 1 } else { 2 }); + vim.update_active_editor(cx, |editor, cx| { + for _ in 0..count { + match editor.select_next(&Default::default(), cx) { + Err(a) => return Err(a), + _ => {} + } + } + Ok(()) + }) + }) + .unwrap_or(Ok(())) +} + +pub fn select_previous( + _: &mut Workspace, + _: &SelectPrevious, + cx: &mut ViewContext, +) -> Result<()> { + Vim::update(cx, |vim, cx| { + let count = + vim.take_count(cx) + .unwrap_or_else(|| if vim.state().mode.is_visual() { 1 } else { 2 }); + vim.update_active_editor(cx, |editor, cx| { + for _ in 0..count { + match editor.select_previous(&Default::default(), cx) { + Err(a) => return Err(a), + _ => {} + } + } + Ok(()) + }) + }) + .unwrap_or(Ok(())) +} + #[cfg(test)] mod test { use indoc::indoc;