diff --git a/Cargo.lock b/Cargo.lock index 4501549563a34540d8abdc0709d4111626d97130..789642ec072122a5d66ba446bd69e7e6c369502f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -322,6 +322,7 @@ dependencies = [ "serde_json", "serde_json_lenient", "settings", + "vim_mode_setting", "workspace-hack", ] @@ -13980,6 +13981,7 @@ dependencies = [ "title_bar", "ui", "util", + "vim_mode_setting", "workspace", "workspace-hack", "zed_actions", diff --git a/crates/agent_settings/Cargo.toml b/crates/agent_settings/Cargo.toml index d34396a5d35dd8919e519e804a93b50dfe046133..e0df5af0aae0bf1e61142c19d7544b2362635981 100644 --- a/crates/agent_settings/Cargo.toml +++ b/crates/agent_settings/Cargo.toml @@ -21,6 +21,7 @@ schemars.workspace = true serde.workspace = true settings.workspace = true workspace-hack.workspace = true +vim_mode_setting.workspace = true [dev-dependencies] fs.workspace = true diff --git a/crates/agent_settings/src/agent_settings.rs b/crates/agent_settings/src/agent_settings.rs index 2bc7962267dbb8aa022b847583c9f24a1b162358..82ba4dc34520908c6c8ac0c88e55f4a68ef825a0 100644 --- a/crates/agent_settings/src/agent_settings.rs +++ b/crates/agent_settings/src/agent_settings.rs @@ -10,6 +10,7 @@ use schemars::{JsonSchema, json_schema}; use serde::{Deserialize, Serialize}; use settings::{Settings, SettingsSources}; use std::borrow::Cow; +use vim_mode_setting::EditorMode; pub use crate::agent_profile::*; diff --git a/crates/agent_ui/src/acp/message_editor.rs b/crates/agent_ui/src/acp/message_editor.rs index d3bacf2227f285cb36e1be1f5bed9c7aae5df7ea..887346a14ce28970edf4e2911083808163bb4688 100644 --- a/crates/agent_ui/src/acp/message_editor.rs +++ b/crates/agent_ui/src/acp/message_editor.rs @@ -113,6 +113,7 @@ impl MessageEditor { }); let mention_set = MentionSet::default(); + let settings = agent_settings::AgentSettings::get_global(cx); let editor_mode = match settings.editor_mode { agent_settings::AgentEditorMode::EditorModeOverride(mode) => mode, agent_settings::AgentEditorMode::Inherit => { @@ -128,7 +129,7 @@ impl MessageEditor { editor.set_placeholder_text(placeholder, cx); editor.set_show_indent_guides(false, cx); editor.set_soft_wrap(); - editor.set_use_modal_editing(editor_mode); + editor.set_default_editor_mode(editor_mode); editor.set_completion_provider(Some(Rc::new(completion_provider))); editor.set_context_menu_options(ContextMenuOptions { min_entries_visible: 12, diff --git a/crates/debugger_ui/src/session/running/console.rs b/crates/debugger_ui/src/session/running/console.rs index 26c2ad3477210b4aa749281872a587d86c83774c..04f3cb7af5cc58090cc8c106257d098e0ae97c6f 100644 --- a/crates/debugger_ui/src/session/running/console.rs +++ b/crates/debugger_ui/src/session/running/console.rs @@ -26,7 +26,7 @@ use std::{cell::RefCell, ops::Range, rc::Rc, usize}; use theme::{Theme, ThemeSettings}; use ui::{ContextMenu, Divider, PopoverMenu, SplitButton, Tooltip, prelude::*}; use util::ResultExt; -use vim_mode_settings::EditorMode; +use vim_mode_setting::EditorMode; actions!( console, diff --git a/crates/extensions_ui/src/extensions_ui.rs b/crates/extensions_ui/src/extensions_ui.rs index afa896cdaf23734e49c6678ac139e9f7e9863f75..58d975800dc22be7053f8ee091a0ec54cf2611bc 100644 --- a/crates/extensions_ui/src/extensions_ui.rs +++ b/crates/extensions_ui/src/extensions_ui.rs @@ -1337,7 +1337,7 @@ impl ExtensionsPage { Label::new("Enable vim mode"), { let editor_mode = EditorModeSetting::get_global(cx).0; - if matches!(editor_mode, EditorMode::Vim | EditorMode::Helix) { + if editor_mode.is_modal() { ui::ToggleState::Selected } else { ui::ToggleState::Unselected @@ -1350,9 +1350,9 @@ impl ExtensionsPage { cx, |setting, value| { *setting = Some(if value { - EditorMode::Vim + EditorMode::vim() } else { - EditorMode::Default + EditorMode::default() }); }, ); diff --git a/crates/onboarding/src/basics_page.rs b/crates/onboarding/src/basics_page.rs index 7487b04114977c45c741eda35f6b9ac0057aea49..d6790092203cd6a89c75f8f3126548b8db3dc081 100644 --- a/crates/onboarding/src/basics_page.rs +++ b/crates/onboarding/src/basics_page.rs @@ -332,10 +332,7 @@ fn render_base_keymap_section(tab_index: &mut isize, cx: &mut App) -> impl IntoE fn render_vim_mode_switch(tab_index: &mut isize, cx: &mut App) -> impl IntoElement { let editor_mode = EditorModeSetting::get_global(cx).0; - let toggle_state = if matches!( - editor_mode, - EditorMode::Vim | EditorMode::Helix | EditorMode::VimInsert - ) { + let toggle_state = if editor_mode.is_modal() { ui::ToggleState::Selected } else { ui::ToggleState::Unselected @@ -351,7 +348,7 @@ fn render_vim_mode_switch(tab_index: &mut isize, cx: &mut App) -> impl IntoEleme move |&selection, _, cx| { update_settings_file::(fs.clone(), cx, move |setting, _| { *setting = match selection { - ToggleState::Selected => Some(EditorMode::Vim), + ToggleState::Selected => Some(EditorMode::vim()), ToggleState::Unselected => Some(EditorMode::Default), ToggleState::Indeterminate => None, } diff --git a/crates/rules_library/Cargo.toml b/crates/rules_library/Cargo.toml index 298f77a2d2472dc8e01bbf0355d5193ed8832ff8..06d7ff9d40497902c08ed430e8d4ef1590bc6a06 100644 --- a/crates/rules_library/Cargo.toml +++ b/crates/rules_library/Cargo.toml @@ -33,3 +33,4 @@ util.workspace = true workspace-hack.workspace = true workspace.workspace = true zed_actions.workspace = true +vim_mode_setting.workspace = true diff --git a/crates/rules_library/src/rules_library.rs b/crates/rules_library/src/rules_library.rs index 9bacadfcbf98c1096adf2c67e437d67f5650695a..32c151fab7dd10229c2e6b2e6ed22a84e3067596 100644 --- a/crates/rules_library/src/rules_library.rs +++ b/crates/rules_library/src/rules_library.rs @@ -26,6 +26,7 @@ use ui::{ SharedString, Styled, Tooltip, Window, div, prelude::*, }; use util::{ResultExt, TryFutureExt}; +use vim_mode_setting::EditorMode; use workspace::{Workspace, client_side_decorations}; use zed_actions::assistant::InlineAssist; diff --git a/crates/vim/src/insert.rs b/crates/vim/src/insert.rs index 3e9b9eb63f157bebbf12cdf53cfe16605b92b6e6..9bc6c1c951138cc836be430cc528ca38bb74cd36 100644 --- a/crates/vim/src/insert.rs +++ b/crates/vim/src/insert.rs @@ -53,7 +53,7 @@ impl Vim { self.update_editor(cx, |_, editor, cx| { editor.dismiss_menus_and_popups(false, window, cx); - if EditorModeSetting::get_global(cx).0 != EditorMode::Helix { + if !matches!(EditorModeSetting::get_global(cx).0, EditorMode::Helix(..)) { editor.change_selections(Default::default(), window, cx, |s| { s.move_cursors_with(|map, mut cursor, _| { *cursor.column_mut() = cursor.column().saturating_sub(1); @@ -63,7 +63,7 @@ impl Vim { } }); - if EditorModeSetting::get_global(cx).0 == EditorMode::Helix { + if matches!(EditorModeSetting::get_global(cx).0, EditorMode::Helix(..)) { self.switch_mode(Mode::HelixNormal, false, window, cx); } else { self.switch_mode(Mode::Normal, false, window, cx); diff --git a/crates/vim/src/normal/paste.rs b/crates/vim/src/normal/paste.rs index be74c209dc94599f2746268897c7c389eb2cbb59..460aac80753b0959657fcd35931ae71094ad7db3 100644 --- a/crates/vim/src/normal/paste.rs +++ b/crates/vim/src/normal/paste.rs @@ -220,7 +220,7 @@ impl Vim { }); }); - if EditorModeSetting::get_global(cx).0 == EditorMode::Helix { + if matches!(EditorModeSetting::get_global(cx).0, EditorMode::Helix(_)) { self.switch_mode(Mode::HelixNormal, true, window, cx); } else { self.switch_mode(Mode::Normal, true, window, cx); diff --git a/crates/vim/src/normal/substitute.rs b/crates/vim/src/normal/substitute.rs index 889d48717068b0561fd21614dc9fb5d0581754dc..c30e8a24025685ce2c70ce55eecd50e9dac24206 100644 --- a/crates/vim/src/normal/substitute.rs +++ b/crates/vim/src/normal/substitute.rs @@ -3,8 +3,9 @@ use gpui::{Context, Window, actions}; use language::Point; use crate::{ - Mode, Vim, + Vim, motion::{Motion, MotionKind}, + state::Mode, }; actions!( diff --git a/crates/vim/src/state.rs b/crates/vim/src/state.rs index 9df762e52f7af0a2c92a0962a9345f7d51304ced..c0d48ab142fbfd2fad30663787d5a25b0ecde786 100644 --- a/crates/vim/src/state.rs +++ b/crates/vim/src/state.rs @@ -19,12 +19,11 @@ use language::{Buffer, BufferEvent, BufferId, Chunk, Point}; use multi_buffer::MultiBufferRow; use picker::{Picker, PickerDelegate}; use project::{Project, ProjectItem, ProjectPath}; -use serde::{Deserialize, Serialize}; use settings::{Settings, SettingsStore}; use std::borrow::BorrowMut; use std::collections::HashSet; use std::path::Path; -use std::{fmt::Display, ops::Range, sync::Arc}; +use std::{ops::Range, sync::Arc}; use text::{Bias, ToPoint}; use theme::ThemeSettings; use ui::{ @@ -32,7 +31,7 @@ use ui::{ StyledTypography, Window, h_flex, rems, }; use util::ResultExt; -use vim_mode_setting::ModalMode; +pub use vim_mode_setting::ModalMode as Mode; use workspace::searchable::Direction; use workspace::{Workspace, WorkspaceDb, WorkspaceId}; @@ -937,7 +936,7 @@ pub struct SearchState { pub prior_selections: Vec>, pub prior_operator: Option, - pub prior_mode: ModalMode, + pub prior_mode: Mode, } impl Operator { @@ -1004,7 +1003,7 @@ impl Operator { } } - pub fn is_waiting(&self, mode: ModalMode) -> bool { + pub fn is_waiting(&self, mode: Mode) -> bool { match self { Operator::AddSurrounds { target } => target.is_some() || mode.is_visual(), Operator::FindForward { .. } diff --git a/crates/vim/src/test/vim_test_context.rs b/crates/vim/src/test/vim_test_context.rs index b7adcccf550debd830386cc6c738aad699af27a8..b4c309c2c5e06b6b3669b5b0cfcaa89adf759692 100644 --- a/crates/vim/src/test/vim_test_context.rs +++ b/crates/vim/src/test/vim_test_context.rs @@ -4,7 +4,7 @@ use editor::test::editor_lsp_test_context::EditorLspTestContext; use gpui::{Context, Entity, SemanticVersion, UpdateGlobal}; use search::{BufferSearchBar, project_search::ProjectSearchBar}; -use crate::{state::Operator, *}; +use crate::{state::Operator, state::Mode, *}; pub struct VimTestContext { cx: EditorLspTestContext, @@ -66,7 +66,7 @@ impl VimTestContext { SettingsStore::update_global(cx, |store, cx| { store.update_user_settings::(cx, |s| { *s = Some(if enabled { - EditorMode::Vim + EditorMode::vim() } else { EditorMode::Default }) @@ -136,7 +136,9 @@ impl VimTestContext { pub fn enable_vim(&mut self) { self.cx.update(|_, cx| { SettingsStore::update_global(cx, |store, cx| { - store.update_user_settings::(cx, |s| *s = Some(EditorMode::Vim)); + store.update_user_settings::(cx, |s| { + *s = Some(EditorMode::vim()) + }); }); }) } @@ -144,7 +146,9 @@ impl VimTestContext { pub fn disable_vim(&mut self) { self.cx.update(|_, cx| { SettingsStore::update_global(cx, |store, cx| { - store.update_user_settings::(cx, |s| *s = Some(EditorMode::Vim)); + store.update_user_settings::(cx, |s| { + *s = Some(EditorMode::vim()) + }); }); }) } @@ -153,7 +157,7 @@ impl VimTestContext { self.cx.update(|_, cx| { SettingsStore::update_global(cx, |store, cx| { store.update_user_settings::(cx, |s| { - *s = Some(EditorMode::Helix) + *s = Some(EditorMode::Helix(ModalMode::HelixNormal)) }); }); }) diff --git a/crates/vim/src/vim.rs b/crates/vim/src/vim.rs index 984e11b495e858e8cc8778bc6d82129cbf73e567..1681735c5584b7edd39a9f4a8aab4545ff47fd55 100644 --- a/crates/vim/src/vim.rs +++ b/crates/vim/src/vim.rs @@ -45,7 +45,7 @@ use std::{mem, ops::Range, sync::Arc}; use surrounds::SurroundsType; use theme::ThemeSettings; use ui::{IntoElement, SharedString, px}; -use vim_mode_setting::{EditorMode, EditorModeSetting}; +use vim_mode_setting::{EditorMode, EditorModeSetting, ModalMode}; use workspace::{self, Pane, Workspace}; use crate::state::ReplayableAction; @@ -249,7 +249,7 @@ pub fn init(cx: &mut App) { *setting = Some(if currently_enabled { EditorMode::Default } else { - EditorMode::Vim + EditorMode::vim() }); }) }); @@ -448,7 +448,7 @@ impl Vim { } let mut was_toggle = VimSettings::get_global(cx).toggle_relative_line_numbers; - cx.observe_global_in::(window, move |editor, window, cx| { + cx.observe_global_in::(window, move |editor, _window, cx| { let toggle = VimSettings::get_global(cx).toggle_relative_line_numbers; if toggle != was_toggle { if toggle { @@ -464,10 +464,6 @@ impl Vim { }) .detach(); - let mut was_enabled = true; - cx.observe::(window, move |editor, window, cx| {}) - .detach(); - Self::activate(editor, window, cx) } @@ -487,12 +483,13 @@ impl Vim { entity: vim.clone(), }); + let default_editor_mode = editor.default_editor_mode(); vim.update(cx, move |_, cx| { Vim::action( editor, cx, move |vim, _: &SwitchToNormalMode, window, cx| { - if matches!(default_editor_mode, EditorMode::Helix) { + if matches!(default_editor_mode, EditorMode::Helix(_)) { vim.switch_mode(ModalMode::HelixNormal, false, window, cx) } else { vim.switch_mode(ModalMode::Normal, false, window, cx) @@ -918,20 +915,21 @@ impl Vim { }); } EditorEvent::EditorModeChanged => { - self.update_editor(cx, |vim, editor, cx| { - let enabled = editor.default_editor_mode().is_modal(); - if was_enabled == enabled { - return; - } - if !enabled { - editor.set_relative_line_number(None, cx); - } - was_enabled = enabled; - if enabled { - Self::activate(editor, window, cx) - } else { - Self::deactivate(editor, cx) - } + self.update_editor(cx, |_vim, _editor, _cx| { + // TODO + // let enabled = editor.default_editor_mode().is_modal(); + // if was_enabled == enabled { + // return; + // } + // if !enabled { + // editor.set_relative_line_number(None, cx); + // } + // was_enabled = enabled; + // if enabled { + // Self::activate(editor, window, cx) + // } else { + // Self::deactivate(editor, cx) + // } // }); } diff --git a/crates/vim_mode_setting/src/vim_mode_setting.rs b/crates/vim_mode_setting/src/vim_mode_setting.rs index 4ee6a6288b299319da9bf5e6f9652958b6e9b53c..a7f7ecf1272d30cb76034216deacd8df527ea018 100644 --- a/crates/vim_mode_setting/src/vim_mode_setting.rs +++ b/crates/vim_mode_setting/src/vim_mode_setting.rs @@ -64,7 +64,7 @@ impl Serialize for EditorMode { EditorMode::Vim(ModalMode::Visual) => "vim_visual", EditorMode::Vim(ModalMode::VisualLine) => "vim_visual_line", EditorMode::Vim(ModalMode::VisualBlock) => "vim_visual_block", - EditorMode::Helix(ModalMode::Normal) => "helix_experimental", + EditorMode::Helix(ModalMode::HelixNormal) => "helix_experimental", _ => return Err(serde::ser::Error::custom("unsupported editor mode variant")), }; serializer.serialize_str(s) @@ -136,4 +136,8 @@ impl EditorMode { pub fn is_modal(&self) -> bool { matches!(self, EditorMode::Vim(_) | EditorMode::Helix(_)) } + + pub fn vim() -> EditorMode { + EditorMode::Vim(ModalMode::default()) + } } diff --git a/crates/zed/src/zed.rs b/crates/zed/src/zed.rs index 243ab382f180a2eb919afad2973501b7b5f25b71..c8b3c9e111dfbce2e38adf52f8180e62eb41d18e 100644 --- a/crates/zed/src/zed.rs +++ b/crates/zed/src/zed.rs @@ -1492,11 +1492,8 @@ pub fn load_default_keymap(cx: &mut App) { if let Some(asset_path) = base_keymap.asset_path() { cx.bind_keys(KeymapFile::load_asset(asset_path, Some(KeybindSource::Base), cx).unwrap()); } - - if matches!( - EditorModeSetting::get_global(cx).0, - EditorMode::Vim | EditorMode::Helix | EditorMode::VimInsert - ) { + let editor_mode = EditorModeSetting::get_global(cx).0; + if editor_mode.is_modal() { cx.bind_keys( KeymapFile::load_asset(VIM_KEYMAP_PATH, Some(KeybindSource::Vim), cx).unwrap(), ); diff --git a/crates/zed/src/zed/quick_action_bar.rs b/crates/zed/src/zed/quick_action_bar.rs index 3da3db6b39d6ce20ee1acd1790f8edd0feaddeab..1a147c683467bf73491cdbb88ef47700375cd5d0 100644 --- a/crates/zed/src/zed/quick_action_bar.rs +++ b/crates/zed/src/zed/quick_action_bar.rs @@ -302,10 +302,7 @@ impl Render for QuickActionBar { let editor = editor.downgrade(); let editor_settings_dropdown = { let editor_mode = EditorModeSetting::get_global(cx).0; - let vim_mode_enabled = matches!( - editor_mode, - EditorMode::Vim | EditorMode::Helix | EditorMode::VimInsert - ); + let vim_mode_enabled = editor_mode.is_modal(); PopoverMenu::new("editor-settings") .trigger_with_tooltip(