diff --git a/crates/vim/src/vim.rs b/crates/vim/src/vim.rs index d35a2b9a6faf1b01c1347998f4ef2147d074ca7f..41ae6c4f4c8527b226b9b0a89968746f79b0467d 100644 --- a/crates/vim/src/vim.rs +++ b/crates/vim/src/vim.rs @@ -204,7 +204,8 @@ impl Vim { let editor = editor.read(cx); if editor.leader_peer_id().is_none() { let newest = editor.selections.newest::(cx); - local_selections_changed(newest, cx); + let is_multicursor = editor.selections.count() > 1; + local_selections_changed(newest, is_multicursor, cx); } } EditorEvent::InputIgnored { text } => { @@ -626,13 +627,24 @@ impl Settings for VimModeSetting { } } -fn local_selections_changed(newest: Selection, cx: &mut WindowContext) { +fn local_selections_changed( + newest: Selection, + is_multicursor: bool, + cx: &mut WindowContext, +) { Vim::update(cx, |vim, cx| { - if vim.enabled && vim.state().mode == Mode::Normal && !newest.is_empty() { - if matches!(newest.goal, SelectionGoal::HorizontalRange { .. }) { - vim.switch_mode(Mode::VisualBlock, false, cx); - } else { - vim.switch_mode(Mode::Visual, false, cx) + if vim.enabled { + if vim.state().mode == Mode::Normal && !newest.is_empty() { + if matches!(newest.goal, SelectionGoal::HorizontalRange { .. }) { + vim.switch_mode(Mode::VisualBlock, false, cx); + } else { + vim.switch_mode(Mode::Visual, false, cx) + } + } else if newest.is_empty() + && !is_multicursor + && [Mode::Visual, Mode::VisualLine, Mode::VisualBlock].contains(&vim.state().mode) + { + vim.switch_mode(Mode::Normal, true, cx) } } })