@@ -210,7 +210,8 @@
"ctrl-w space": "editor::OpenExcerptsSplit",
"ctrl-w g space": "editor::OpenExcerptsSplit",
"ctrl-6": "pane::AlternateFile",
- "ctrl-^": "pane::AlternateFile"
+ "ctrl-^": "pane::AlternateFile",
+ ".": "vim::Repeat"
}
},
{
@@ -219,7 +220,6 @@
"ctrl-[": "editor::Cancel",
"escape": "editor::Cancel",
":": "command_palette::Toggle",
- ".": "vim::Repeat",
"c": "vim::PushChange",
"shift-c": "vim::ChangeToEndOfLine",
"d": "vim::PushDelete",
@@ -245,61 +245,63 @@ impl Vim {
}) else {
return;
};
- if let Some(mode) = mode {
- self.switch_mode(mode, false, window, cx)
- }
+ if mode != Some(self.mode) {
+ if let Some(mode) = mode {
+ self.switch_mode(mode, false, window, cx)
+ }
- match selection {
- RecordedSelection::SingleLine { cols } => {
- if cols > 1 {
- self.visual_motion(Motion::Right, Some(cols as usize - 1), window, cx)
+ match selection {
+ RecordedSelection::SingleLine { cols } => {
+ if cols > 1 {
+ self.visual_motion(Motion::Right, Some(cols as usize - 1), window, cx)
+ }
}
- }
- RecordedSelection::Visual { rows, cols } => {
- self.visual_motion(
- Motion::Down {
- display_lines: false,
- },
- Some(rows as usize),
- window,
- cx,
- );
- self.visual_motion(
- Motion::StartOfLine {
- display_lines: false,
- },
- None,
- window,
- cx,
- );
- if cols > 1 {
- self.visual_motion(Motion::Right, Some(cols as usize - 1), window, cx)
+ RecordedSelection::Visual { rows, cols } => {
+ self.visual_motion(
+ Motion::Down {
+ display_lines: false,
+ },
+ Some(rows as usize),
+ window,
+ cx,
+ );
+ self.visual_motion(
+ Motion::StartOfLine {
+ display_lines: false,
+ },
+ None,
+ window,
+ cx,
+ );
+ if cols > 1 {
+ self.visual_motion(Motion::Right, Some(cols as usize - 1), window, cx)
+ }
}
- }
- RecordedSelection::VisualBlock { rows, cols } => {
- self.visual_motion(
- Motion::Down {
- display_lines: false,
- },
- Some(rows as usize),
- window,
- cx,
- );
- if cols > 1 {
- self.visual_motion(Motion::Right, Some(cols as usize - 1), window, cx);
+ RecordedSelection::VisualBlock { rows, cols } => {
+ self.visual_motion(
+ Motion::Down {
+ display_lines: false,
+ },
+ Some(rows as usize),
+ window,
+ cx,
+ );
+ if cols > 1 {
+ self.visual_motion(Motion::Right, Some(cols as usize - 1), window, cx);
+ }
}
+ RecordedSelection::VisualLine { rows } => {
+ self.visual_motion(
+ Motion::Down {
+ display_lines: false,
+ },
+ Some(rows as usize),
+ window,
+ cx,
+ );
+ }
+ RecordedSelection::None => {}
}
- RecordedSelection::VisualLine { rows } => {
- self.visual_motion(
- Motion::Down {
- display_lines: false,
- },
- Some(rows as usize),
- window,
- cx,
- );
- }
- RecordedSelection::None => {}
}
// insert internally uses repeat to handle counts
@@ -2071,3 +2071,42 @@ async fn test_paragraph_multi_delete(cx: &mut gpui::TestAppContext) {
cx.simulate_shared_keystrokes("4 d a p").await;
cx.shared_state().await.assert_eq(indoc! {"ˇ"});
}
+
+#[gpui::test]
+async fn test_multi_cursor_replay(cx: &mut gpui::TestAppContext) {
+ let mut cx = VimTestContext::new(cx, true).await;
+ cx.set_state(
+ indoc! {
+ "
+ oˇne one one
+
+ two two two
+ "
+ },
+ Mode::Normal,
+ );
+
+ cx.simulate_keystrokes("3 g l s wow escape escape");
+ cx.assert_state(
+ indoc! {
+ "
+ woˇw wow wow
+
+ two two two
+ "
+ },
+ Mode::Normal,
+ );
+
+ cx.simulate_keystrokes("2 j 3 g l .");
+ cx.assert_state(
+ indoc! {
+ "
+ wow wow wow
+
+ woˇw woˇw woˇw
+ "
+ },
+ Mode::Normal,
+ );
+}