From 430f5d5d535f1a65a98c9839d09388551709e430 Mon Sep 17 00:00:00 2001 From: WindSoilder Date: Sat, 3 Feb 2024 07:44:47 +0800 Subject: [PATCH] vim: Convert from visual mode to normal mode with a single click (#6985) Release Notes: - Fixed #4319 Here is a demo after the fix: https://github.com/zed-industries/zed/assets/22256154/a690f146-73c9-4b0e-8527-e4faf690cca2 Actually I'm not really sure should I submit my idea to discussion, since it's not a large change, and it's something like a bug fix. So I directly create a pr here. --------- Co-authored-by: Conrad Irwin --- crates/vim/src/vim.rs | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) 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) } } })