vim: Add multicursor shortcuts

- g n / g N to select next/previous
- g > / g < to select next/previous replacing current
- g a to select all matches
This commit is contained in:
Conrad Irwin 2023-09-25 15:23:14 -06:00
parent ff5d0f2aeb
commit b29e295e1b
2 changed files with 65 additions and 0 deletions

View file

@ -125,6 +125,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

View file

@ -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<usize>, cx: &mut WindowContext) {
@ -384,6 +390,50 @@ pub(crate) fn visual_replace(text: Arc<str>, cx: &mut WindowContext) {
});
}
pub fn select_next(
_: &mut Workspace,
_: &SelectNext,
cx: &mut ViewContext<Workspace>,
) -> 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<Workspace>,
) -> 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;