vim: Add ability to spawn multicursors at beginning/end of line (#18183)
Closes #17842 Release Notes: - Added the ability to spawn multiple cursors through the g-A and g-I motions while in visual select mode.
This commit is contained in:
parent
b69c6ee7df
commit
4a4d8c1cab
2 changed files with 86 additions and 1 deletions
|
@ -15,7 +15,7 @@ use util::ResultExt;
|
|||
use workspace::searchable::Direction;
|
||||
|
||||
use crate::{
|
||||
motion::{start_of_line, Motion},
|
||||
motion::{first_non_whitespace, next_line_end, start_of_line, Motion},
|
||||
object::Object,
|
||||
state::{Mode, Operator},
|
||||
Vim,
|
||||
|
@ -37,6 +37,8 @@ actions!(
|
|||
SelectNextMatch,
|
||||
SelectPreviousMatch,
|
||||
RestoreVisualSelection,
|
||||
VisualInsertEndOfLine,
|
||||
VisualInsertFirstNonWhiteSpace,
|
||||
]
|
||||
);
|
||||
|
||||
|
@ -51,6 +53,8 @@ pub fn register(editor: &mut Editor, cx: &mut ViewContext<Vim>) {
|
|||
vim.toggle_mode(Mode::VisualBlock, cx)
|
||||
});
|
||||
Vim::action(editor, cx, Vim::other_end);
|
||||
Vim::action(editor, cx, Vim::visual_insert_end_of_line);
|
||||
Vim::action(editor, cx, Vim::visual_insert_first_non_white_space);
|
||||
Vim::action(editor, cx, |vim, _: &VisualDelete, cx| {
|
||||
vim.record_current_action(cx);
|
||||
vim.visual_delete(false, cx);
|
||||
|
@ -374,6 +378,39 @@ impl Vim {
|
|||
}
|
||||
}
|
||||
|
||||
fn visual_insert_end_of_line(&mut self, _: &VisualInsertEndOfLine, cx: &mut ViewContext<Self>) {
|
||||
self.update_editor(cx, |_, editor, cx| {
|
||||
editor.split_selection_into_lines(&Default::default(), cx);
|
||||
editor.change_selections(Some(Autoscroll::fit()), cx, |s| {
|
||||
s.move_cursors_with(|map, cursor, _| {
|
||||
(next_line_end(map, cursor, 1), SelectionGoal::None)
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
self.switch_mode(Mode::Insert, false, cx);
|
||||
}
|
||||
|
||||
fn visual_insert_first_non_white_space(
|
||||
&mut self,
|
||||
_: &VisualInsertFirstNonWhiteSpace,
|
||||
cx: &mut ViewContext<Self>,
|
||||
) {
|
||||
self.update_editor(cx, |_, editor, cx| {
|
||||
editor.split_selection_into_lines(&Default::default(), cx);
|
||||
editor.change_selections(Some(Autoscroll::fit()), cx, |s| {
|
||||
s.move_cursors_with(|map, cursor, _| {
|
||||
(
|
||||
first_non_whitespace(map, false, cursor),
|
||||
SelectionGoal::None,
|
||||
)
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
self.switch_mode(Mode::Insert, false, cx);
|
||||
}
|
||||
|
||||
fn toggle_mode(&mut self, mode: Mode, cx: &mut ViewContext<Self>) {
|
||||
if self.mode == mode {
|
||||
self.switch_mode(Mode::Normal, false, cx);
|
||||
|
@ -714,6 +751,52 @@ mod test {
|
|||
ˇ"});
|
||||
}
|
||||
|
||||
#[gpui::test]
|
||||
async fn test_visual_insert_first_non_whitespace(cx: &mut gpui::TestAppContext) {
|
||||
let mut cx = VimTestContext::new(cx, true).await;
|
||||
|
||||
cx.set_state(
|
||||
indoc! {
|
||||
"«The quick brown
|
||||
fox jumps over
|
||||
the lazy dogˇ»"
|
||||
},
|
||||
Mode::Visual,
|
||||
);
|
||||
cx.simulate_keystrokes("g I");
|
||||
cx.assert_state(
|
||||
indoc! {
|
||||
"ˇThe quick brown
|
||||
ˇfox jumps over
|
||||
ˇthe lazy dog"
|
||||
},
|
||||
Mode::Insert,
|
||||
);
|
||||
}
|
||||
|
||||
#[gpui::test]
|
||||
async fn test_visual_insert_end_of_line(cx: &mut gpui::TestAppContext) {
|
||||
let mut cx = VimTestContext::new(cx, true).await;
|
||||
|
||||
cx.set_state(
|
||||
indoc! {
|
||||
"«The quick brown
|
||||
fox jumps over
|
||||
the lazy dogˇ»"
|
||||
},
|
||||
Mode::Visual,
|
||||
);
|
||||
cx.simulate_keystrokes("g A");
|
||||
cx.assert_state(
|
||||
indoc! {
|
||||
"The quick brownˇ
|
||||
fox jumps overˇ
|
||||
the lazy dogˇ"
|
||||
},
|
||||
Mode::Insert,
|
||||
);
|
||||
}
|
||||
|
||||
#[gpui::test]
|
||||
async fn test_enter_visual_line_mode(cx: &mut gpui::TestAppContext) {
|
||||
let mut cx = NeovimBackedTestContext::new(cx).await;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue