From 0d5becfadf09dca1e92b6d12ff550aad277827f6 Mon Sep 17 00:00:00 2001 From: Smit Barmase Date: Thu, 21 Aug 2025 21:28:04 +0530 Subject: [PATCH 01/15] global editor mode setting Co-authored-by: Oleksiy Syvokon --- Cargo.lock | 2 + crates/extensions_ui/src/extensions_ui.rs | 23 ++++++--- crates/onboarding/src/basics_page.rs | 12 +++-- crates/vim/src/insert.rs | 6 +-- crates/vim/src/normal/paste.rs | 4 +- crates/vim/src/test/vim_test_context.rs | 16 ++++-- crates/vim/src/vim.rs | 23 ++++++--- crates/vim_mode_setting/Cargo.toml | 2 + .../vim_mode_setting/src/vim_mode_setting.rs | 49 ++++++------------- crates/zed/src/zed.rs | 21 ++++---- crates/zed/src/zed/quick_action_bar.rs | 13 +++-- 11 files changed, 93 insertions(+), 78 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2b3d7b2691..30e76ca131 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -17993,6 +17993,8 @@ version = "0.1.0" dependencies = [ "anyhow", "gpui", + "schemars", + "serde", "settings", "workspace-hack", ] diff --git a/crates/extensions_ui/src/extensions_ui.rs b/crates/extensions_ui/src/extensions_ui.rs index fd504764b6..afa896cdaf 100644 --- a/crates/extensions_ui/src/extensions_ui.rs +++ b/crates/extensions_ui/src/extensions_ui.rs @@ -27,7 +27,7 @@ use ui::{ CheckboxWithLabel, Chip, ContextMenu, PopoverMenu, ScrollableHandle, Scrollbar, ScrollbarState, ToggleButton, Tooltip, prelude::*, }; -use vim_mode_setting::VimModeSetting; +use vim_mode_setting::{EditorMode, EditorModeSetting}; use workspace::{ Workspace, WorkspaceId, item::{Item, ItemEvent}, @@ -1335,17 +1335,26 @@ impl ExtensionsPage { .child(CheckboxWithLabel::new( "enable-vim", Label::new("Enable vim mode"), - if VimModeSetting::get_global(cx).0 { - ui::ToggleState::Selected - } else { - ui::ToggleState::Unselected + { + let editor_mode = EditorModeSetting::get_global(cx).0; + if matches!(editor_mode, EditorMode::Vim | EditorMode::Helix) { + ui::ToggleState::Selected + } else { + ui::ToggleState::Unselected + } }, cx.listener(move |this, selection, _, cx| { telemetry::event!("Vim Mode Toggled", source = "Feature Upsell"); - this.update_settings::( + this.update_settings::( selection, cx, - |setting, value| *setting = Some(value), + |setting, value| { + *setting = Some(if value { + EditorMode::Vim + } else { + EditorMode::Default + }); + }, ); }), )), diff --git a/crates/onboarding/src/basics_page.rs b/crates/onboarding/src/basics_page.rs index 441d2ca4b7..30c1b5d3f7 100644 --- a/crates/onboarding/src/basics_page.rs +++ b/crates/onboarding/src/basics_page.rs @@ -12,7 +12,7 @@ use ui::{ ParentElement as _, StatefulInteractiveElement, SwitchField, ToggleButtonGroup, ToggleButtonSimple, ToggleButtonWithIcon, prelude::*, rems_from_px, }; -use vim_mode_setting::VimModeSetting; +use vim_mode_setting::{EditorMode, EditorModeSetting}; use crate::theme_preview::{ThemePreviewStyle, ThemePreviewTile}; @@ -331,11 +331,13 @@ 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 toggle_state = if VimModeSetting::get_global(cx).0 { + let editor_mode = EditorModeSetting::get_global(cx).0; + let toggle_state = if matches!(editor_mode, EditorMode::Vim | EditorMode::Helix) { ui::ToggleState::Selected } else { ui::ToggleState::Unselected }; + SwitchField::new( "onboarding-vim-mode", "Vim Mode", @@ -344,10 +346,10 @@ fn render_vim_mode_switch(tab_index: &mut isize, cx: &mut App) -> impl IntoEleme { let fs = ::global(cx); move |&selection, _, cx| { - update_settings_file::(fs.clone(), cx, move |setting, _| { + update_settings_file::(fs.clone(), cx, move |setting, _| { *setting = match selection { - ToggleState::Selected => Some(true), - ToggleState::Unselected => Some(false), + ToggleState::Selected => Some(EditorMode::Vim), + ToggleState::Unselected => Some(EditorMode::Default), ToggleState::Indeterminate => None, } }); diff --git a/crates/vim/src/insert.rs b/crates/vim/src/insert.rs index 8ef1cd7811..3e9b9eb63f 100644 --- a/crates/vim/src/insert.rs +++ b/crates/vim/src/insert.rs @@ -4,7 +4,7 @@ use gpui::{Action, Context, Window, actions}; use language::SelectionGoal; use settings::Settings; use text::Point; -use vim_mode_setting::HelixModeSetting; +use vim_mode_setting::{EditorMode, EditorModeSetting}; use workspace::searchable::Direction; actions!( @@ -53,7 +53,7 @@ impl Vim { self.update_editor(cx, |_, editor, cx| { editor.dismiss_menus_and_popups(false, window, cx); - if !HelixModeSetting::get_global(cx).0 { + if 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 HelixModeSetting::get_global(cx).0 { + if 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 933b119d37..be74c209dc 100644 --- a/crates/vim/src/normal/paste.rs +++ b/crates/vim/src/normal/paste.rs @@ -5,7 +5,7 @@ use schemars::JsonSchema; use serde::Deserialize; use settings::Settings; use std::cmp; -use vim_mode_setting::HelixModeSetting; +use vim_mode_setting::{EditorMode, EditorModeSetting}; use crate::{ Vim, @@ -220,7 +220,7 @@ impl Vim { }); }); - if HelixModeSetting::get_global(cx).0 { + if 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/test/vim_test_context.rs b/crates/vim/src/test/vim_test_context.rs index e7ac692df1..b7adcccf55 100644 --- a/crates/vim/src/test/vim_test_context.rs +++ b/crates/vim/src/test/vim_test_context.rs @@ -64,7 +64,13 @@ impl VimTestContext { pub fn init_keybindings(enabled: bool, cx: &mut App) { SettingsStore::update_global(cx, |store, cx| { - store.update_user_settings::(cx, |s| *s = Some(enabled)); + store.update_user_settings::(cx, |s| { + *s = Some(if enabled { + EditorMode::Vim + } else { + EditorMode::Default + }) + }); }); let default_key_bindings = settings::KeymapFile::load_asset_allow_partial_failure( "keymaps/default-macos.json", @@ -130,7 +136,7 @@ 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(true)); + store.update_user_settings::(cx, |s| *s = Some(EditorMode::Vim)); }); }) } @@ -138,7 +144,7 @@ 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(false)); + store.update_user_settings::(cx, |s| *s = Some(EditorMode::Vim)); }); }) } @@ -146,8 +152,8 @@ impl VimTestContext { pub fn enable_helix(&mut self) { self.cx.update(|_, cx| { SettingsStore::update_global(cx, |store, cx| { - store.update_user_settings::(cx, |s| { - *s = Some(true) + store.update_user_settings::(cx, |s| { + *s = Some(EditorMode::Helix) }); }); }) diff --git a/crates/vim/src/vim.rs b/crates/vim/src/vim.rs index 9da01e6f44..46325dfa36 100644 --- a/crates/vim/src/vim.rs +++ b/crates/vim/src/vim.rs @@ -45,8 +45,7 @@ use std::{mem, ops::Range, sync::Arc}; use surrounds::SurroundsType; use theme::ThemeSettings; use ui::{IntoElement, SharedString, px}; -use vim_mode_setting::HelixModeSetting; -use vim_mode_setting::VimModeSetting; +use vim_mode_setting::{EditorMode, EditorModeSetting}; use workspace::{self, Pane, Workspace}; use crate::state::ReplayableAction; @@ -246,8 +245,12 @@ pub fn init(cx: &mut App) { workspace.register_action(|workspace, _: &ToggleVimMode, _, cx| { let fs = workspace.app_state().fs.clone(); let currently_enabled = Vim::enabled(cx); - update_settings_file::(fs, cx, move |setting, _| { - *setting = Some(!currently_enabled) + update_settings_file::(fs, cx, move |setting, _| { + *setting = Some(if currently_enabled { + EditorMode::Default + } else { + EditorMode::Vim + }); }) }); @@ -405,7 +408,9 @@ impl Vim { let editor = cx.entity(); let mut initial_mode = VimSettings::get_global(cx).default_mode; - if initial_mode == Mode::Normal && HelixModeSetting::get_global(cx).0 { + if initial_mode == Mode::Normal + && matches!(EditorModeSetting::get_global(cx).0, EditorMode::Helix) + { initial_mode = Mode::HelixNormal; } @@ -496,7 +501,7 @@ impl Vim { vim.update(cx, |_, cx| { Vim::action(editor, cx, |vim, _: &SwitchToNormalMode, window, cx| { - if HelixModeSetting::get_global(cx).0 { + if matches!(EditorModeSetting::get_global(cx).0, EditorMode::Helix) { vim.switch_mode(Mode::HelixNormal, false, window, cx) } else { vim.switch_mode(Mode::Normal, false, window, cx) @@ -819,7 +824,11 @@ impl Vim { } pub fn enabled(cx: &mut App) -> bool { - VimModeSetting::get_global(cx).0 || HelixModeSetting::get_global(cx).0 + if EditorModeSetting::get_global(cx).0 == EditorMode::Default { + return false; + } + return true; + // VimModeSetting::get_global(cx).0 || HelixModeSetting::get_global(cx).0 } /// Called whenever an keystroke is typed so vim can observe all actions diff --git a/crates/vim_mode_setting/Cargo.toml b/crates/vim_mode_setting/Cargo.toml index fbb7f30b4c..ef4fde738f 100644 --- a/crates/vim_mode_setting/Cargo.toml +++ b/crates/vim_mode_setting/Cargo.toml @@ -14,5 +14,7 @@ path = "src/vim_mode_setting.rs" [dependencies] anyhow.workspace = true gpui.workspace = true +schemars.workspace = true settings.workspace = true workspace-hack.workspace = true +serde.workspace = true diff --git a/crates/vim_mode_setting/src/vim_mode_setting.rs b/crates/vim_mode_setting/src/vim_mode_setting.rs index 6f60d3f21f..e9606419df 100644 --- a/crates/vim_mode_setting/src/vim_mode_setting.rs +++ b/crates/vim_mode_setting/src/vim_mode_setting.rs @@ -6,23 +6,32 @@ use anyhow::Result; use gpui::App; +use schemars::JsonSchema; +use serde::{Deserialize, Serialize}; use settings::{Settings, SettingsSources}; /// Initializes the `vim_mode_setting` crate. pub fn init(cx: &mut App) { - VimModeSetting::register(cx); - HelixModeSetting::register(cx); + EditorModeSetting::register(cx); } /// Whether or not to enable Vim mode. /// -/// Default: false -pub struct VimModeSetting(pub bool); +/// Default: `EditMode::Default` +pub struct EditorModeSetting(pub EditorMode); -impl Settings for VimModeSetting { - const KEY: Option<&'static str> = Some("vim_mode"); +#[derive(Copy, Clone, Debug, PartialEq, Eq, Serialize, Deserialize, JsonSchema, Default)] +pub enum EditorMode { + Vim, + Helix, + #[default] + Default, +} - type FileContent = Option; +impl Settings for EditorModeSetting { + const KEY: Option<&'static str> = Some("editor_mode"); + + type FileContent = Option; fn load(sources: SettingsSources, _: &mut App) -> Result { Ok(Self( @@ -39,29 +48,3 @@ impl Settings for VimModeSetting { // TODO: could possibly check if any of the `vim.` keys are set? } } - -/// Whether or not to enable Helix mode. -/// -/// Default: false -pub struct HelixModeSetting(pub bool); - -impl Settings for HelixModeSetting { - const KEY: Option<&'static str> = Some("helix_mode"); - - type FileContent = Option; - - fn load(sources: SettingsSources, _: &mut App) -> Result { - Ok(Self( - sources - .user - .or(sources.server) - .copied() - .flatten() - .unwrap_or(sources.default.ok_or_else(Self::missing_default)?), - )) - } - - fn import_from_vscode(_vscode: &settings::VsCodeSettings, _current: &mut Self::FileContent) { - // TODO: could possibly check if any of the `helix.` keys are set? - } -} diff --git a/crates/zed/src/zed.rs b/crates/zed/src/zed.rs index 638e1dca0e..d955fd11a8 100644 --- a/crates/zed/src/zed.rs +++ b/crates/zed/src/zed.rs @@ -70,7 +70,7 @@ use ui::{PopoverMenuHandle, prelude::*}; use util::markdown::MarkdownString; use util::{ResultExt, asset_str}; use uuid::Uuid; -use vim_mode_setting::VimModeSetting; +use vim_mode_setting::{EditorMode, EditorModeSetting}; use workspace::notifications::{ NotificationId, SuppressEvent, dismiss_app_notification, show_app_notification, }; @@ -1287,21 +1287,15 @@ pub fn handle_keymap_file_changes( let (base_keymap_tx, mut base_keymap_rx) = mpsc::unbounded(); let (keyboard_layout_tx, mut keyboard_layout_rx) = mpsc::unbounded(); let mut old_base_keymap = *BaseKeymap::get_global(cx); - let mut old_vim_enabled = VimModeSetting::get_global(cx).0; - let mut old_helix_enabled = vim_mode_setting::HelixModeSetting::get_global(cx).0; + let mut old_editor_mode = EditorModeSetting::get_global(cx).0; cx.observe_global::(move |cx| { let new_base_keymap = *BaseKeymap::get_global(cx); - let new_vim_enabled = VimModeSetting::get_global(cx).0; - let new_helix_enabled = vim_mode_setting::HelixModeSetting::get_global(cx).0; + let new_editor_mode = EditorModeSetting::get_global(cx).0; - if new_base_keymap != old_base_keymap - || new_vim_enabled != old_vim_enabled - || new_helix_enabled != old_helix_enabled - { + if new_base_keymap != old_base_keymap || new_editor_mode != old_editor_mode { old_base_keymap = new_base_keymap; - old_vim_enabled = new_vim_enabled; - old_helix_enabled = new_helix_enabled; + old_editor_mode = new_editor_mode; base_keymap_tx.unbounded_send(()).unwrap(); } @@ -1499,7 +1493,10 @@ pub fn load_default_keymap(cx: &mut App) { cx.bind_keys(KeymapFile::load_asset(asset_path, Some(KeybindSource::Base), cx).unwrap()); } - if VimModeSetting::get_global(cx).0 || vim_mode_setting::HelixModeSetting::get_global(cx).0 { + if matches!( + EditorModeSetting::get_global(cx).0, + EditorMode::Vim | EditorMode::Helix + ) { 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 e57d5d3889..fee96727ea 100644 --- a/crates/zed/src/zed/quick_action_bar.rs +++ b/crates/zed/src/zed/quick_action_bar.rs @@ -23,7 +23,7 @@ use ui::{ ButtonStyle, ContextMenu, ContextMenuEntry, DocumentationSide, IconButton, IconName, IconSize, PopoverMenu, PopoverMenuHandle, Tooltip, prelude::*, }; -use vim_mode_setting::VimModeSetting; +use vim_mode_setting::{EditorMode, EditorModeSetting}; use workspace::{ ToolbarItemEvent, ToolbarItemLocation, ToolbarItemView, Workspace, item::ItemHandle, }; @@ -301,7 +301,8 @@ impl Render for QuickActionBar { let editor_focus_handle = editor.focus_handle(cx); let editor = editor.downgrade(); let editor_settings_dropdown = { - let vim_mode_enabled = VimModeSetting::get_global(cx).0; + let editor_mode = EditorModeSetting::get_global(cx).0; + let vim_mode_enabled = matches!(editor_mode, EditorMode::Vim | EditorMode::Helix); PopoverMenu::new("editor-settings") .trigger_with_tooltip( @@ -576,8 +577,12 @@ impl Render for QuickActionBar { None, { move |window, cx| { - let new_value = !vim_mode_enabled; - VimModeSetting::override_global(VimModeSetting(new_value), cx); + let new_value = if vim_mode_enabled { + EditorMode::Default + } else { + EditorMode::Vim + }; + EditorModeSetting::override_global(EditorModeSetting(new_value), cx); window.refresh(); } }, From 854b7e104ef838fb92980c938bacd08b30fd3a67 Mon Sep 17 00:00:00 2001 From: Smit Barmase Date: Thu, 21 Aug 2025 21:35:13 +0530 Subject: [PATCH 02/15] add editor_mode to agent settings Co-authored-by: Oleksiy Syvokon --- assets/settings/default.json | 6 +++++- crates/agent_settings/src/agent_settings.rs | 15 +++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/assets/settings/default.json b/assets/settings/default.json index c290baf003..3f2b0a159f 100644 --- a/assets/settings/default.json +++ b/assets/settings/default.json @@ -885,7 +885,11 @@ /// Whether to have terminal cards in the agent panel expanded, showing the whole command output. /// /// Default: true - "expand_terminal_card": true + "expand_terminal_card": true, + /// Weather to inherit or override the editor mode for the agent panel. + /// + /// Default: inherit + "editor_mode": "inherit" }, // The settings for slash commands. "slash_commands": { diff --git a/crates/agent_settings/src/agent_settings.rs b/crates/agent_settings/src/agent_settings.rs index ed1ed2b898..88ef505053 100644 --- a/crates/agent_settings/src/agent_settings.rs +++ b/crates/agent_settings/src/agent_settings.rs @@ -48,6 +48,16 @@ pub enum NotifyWhenAgentWaiting { Never, } +#[derive(Copy, Clone, Debug, PartialEq, Eq, Serialize, Deserialize, JsonSchema, Default)] +pub enum AgentEditorMode { + Vim, + VimInsert, + Helix, + Default, + #[default] + Inherit, +} + #[derive(Default, Clone, Debug)] pub struct AgentSettings { pub enabled: bool, @@ -75,6 +85,7 @@ pub struct AgentSettings { pub expand_edit_card: bool, pub expand_terminal_card: bool, pub use_modifier_to_send: bool, + pub editor_mode: AgentEditorMode, } impl AgentSettings { @@ -315,6 +326,10 @@ pub struct AgentSettingsContent { /// /// Default: false use_modifier_to_send: Option, + /// Weather to inherit or override the editor mode for the agent panel. + /// + /// Default: inherit + editor_mode: Option, } #[derive(Clone, Copy, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Default)] From 57a0bb327da103a7e88ce3fd7814414ba4bd632f Mon Sep 17 00:00:00 2001 From: Smit Barmase Date: Thu, 21 Aug 2025 22:47:32 +0530 Subject: [PATCH 03/15] editor mode in editor.rs Co-authored-by: Oleksiy Syvokon --- Cargo.lock | 2 + crates/agent_ui/Cargo.toml | 1 + crates/agent_ui/src/message_editor.rs | 13 ++++++ crates/editor/Cargo.toml | 1 + crates/editor/src/editor.rs | 45 ++++++++++++++++--- crates/onboarding/src/basics_page.rs | 5 ++- crates/vim/src/vim.rs | 32 ++++++++----- .../vim_mode_setting/src/vim_mode_setting.rs | 1 + crates/zed/src/zed.rs | 2 +- crates/zed/src/zed/quick_action_bar.rs | 5 ++- 10 files changed, 89 insertions(+), 18 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 30e76ca131..87dd37c309 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -415,6 +415,7 @@ dependencies = [ "urlencoding", "util", "uuid", + "vim_mode_setting", "watch", "workspace", "workspace-hack", @@ -5115,6 +5116,7 @@ dependencies = [ "url", "util", "uuid", + "vim_mode_setting", "workspace", "workspace-hack", "zed_actions", diff --git a/crates/agent_ui/Cargo.toml b/crates/agent_ui/Cargo.toml index 43e3b25124..52ee0f600a 100644 --- a/crates/agent_ui/Cargo.toml +++ b/crates/agent_ui/Cargo.toml @@ -100,6 +100,7 @@ watch.workspace = true workspace-hack.workspace = true workspace.workspace = true zed_actions.workspace = true +vim_mode_setting.workspace = true [dev-dependencies] acp_thread = { workspace = true, features = ["test-support"] } diff --git a/crates/agent_ui/src/message_editor.rs b/crates/agent_ui/src/message_editor.rs index bed10e90a7..f578ccabe4 100644 --- a/crates/agent_ui/src/message_editor.rs +++ b/crates/agent_ui/src/message_editor.rs @@ -114,6 +114,18 @@ pub(crate) fn create_editor( let editor = cx.new(|cx| { let buffer = cx.new(|cx| Buffer::local("", cx).with_language(Arc::new(language), cx)); let buffer = cx.new(|cx| MultiBuffer::singleton(buffer, cx)); + let settings = agent_settings::AgentSettings::get_global(cx); + + let editor_mode = match settings.editor_mode { + agent_settings::AgentEditorMode::Vim => vim_mode_setting::EditorMode::Vim, + agent_settings::AgentEditorMode::VimInsert => vim_mode_setting::EditorMode::VimInsert, + agent_settings::AgentEditorMode::Helix => vim_mode_setting::EditorMode::Helix, + agent_settings::AgentEditorMode::Default => vim_mode_setting::EditorMode::Default, + agent_settings::AgentEditorMode::Inherit => { + vim_mode_setting::EditorModeSetting::get_global(cx).0 + } + }; + let mut editor = Editor::new( editor::EditorMode::AutoHeight { min_lines, @@ -128,6 +140,7 @@ pub(crate) fn create_editor( editor.set_show_indent_guides(false, cx); editor.set_soft_wrap(); editor.set_use_modal_editing(true); + editor.set_default_editor_mode(editor_mode); editor.set_context_menu_options(ContextMenuOptions { min_entries_visible: 12, max_entries_visible: 12, diff --git a/crates/editor/Cargo.toml b/crates/editor/Cargo.toml index 339f98ae8b..c3a9f0f3c7 100644 --- a/crates/editor/Cargo.toml +++ b/crates/editor/Cargo.toml @@ -92,6 +92,7 @@ uuid.workspace = true workspace.workspace = true zed_actions.workspace = true workspace-hack.workspace = true +vim_mode_setting.workspace = true [dev-dependencies] ctor.workspace = true diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index 2af8e6c0e4..f0745c8850 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -165,6 +165,7 @@ use project::{ }; use rand::{seq::SliceRandom, thread_rng}; use rpc::{ErrorCode, ErrorExt, proto::PeerId}; +use schemars::JsonSchema; use scroll::{Autoscroll, OngoingScroll, ScrollAnchor, ScrollManager, ScrollbarAutoHide}; use selections_collection::{ MutableSelectionsCollection, SelectionsCollection, resolve_selections, @@ -201,6 +202,7 @@ use ui::{ IconSize, Indicator, Key, Tooltip, h_flex, prelude::*, }; use util::{RangeExt, ResultExt, TryFutureExt, maybe, post_inc}; +use vim_mode_setting::EditorModeSetting; use workspace::{ CollaboratorId, Item as WorkspaceItem, ItemId, ItemNavHistory, OpenInTerminal, OpenTerminal, RestoreOnStartupBehavior, SERIALIZATION_THROTTLE_TIME, SplitDirection, TabBarSettings, Toast, @@ -1092,7 +1094,6 @@ pub struct Editor { autoindent_mode: Option, workspace: Option<(WeakEntity, Option)>, input_enabled: bool, - use_modal_editing: bool, read_only: bool, leader_id: Option, remote_id: Option, @@ -1180,6 +1181,39 @@ pub struct Editor { next_color_inlay_id: usize, colors: Option, folding_newlines: Task<()>, + default_editor_mode: vim_mode_setting::EditorMode, + // editor_mode: EditorMode, <-- while init define which editor, + + // agenty subscribe to agen settings + // + // editor <- agent + // + // settings listent to event emitted by editor, + // + + // agent will set_editor_mode(AgentPanelSettings::read("editor_mode")) on init + // vim.rs will get_editor_mode() on init / activate / register + // + // match editor_mode { + // // which setting to use + // } + // + // + + // editor_mode: EditorMode, <-- while init define which editor, + // pros -> jsut set enum + // cons -> actual setting check lives in either editor.rs or vim.rs?? + // + // set_edutr(); + // + // Fn () -> weather mode this editor is, and what;s the default value? + // pros -> all setting lives in agent, git. + // cons -> if someone wants to use agent setting in their editor, they need to copy paste code + // + // // agent.rs + // set_vim_setting_fn(|| { + // // edito seting agnet + // }); } #[derive(Copy, Clone, Debug, PartialEq, Eq, Default)] @@ -2258,6 +2292,7 @@ impl Editor { mode, selection_drag_state: SelectionDragState::None, folding_newlines: Task::ready(()), + default_editor_mode: vim_mode_setting::EditorMode::default(), }; if is_minimap { @@ -2994,12 +3029,12 @@ impl Editor { }) } - pub fn set_use_modal_editing(&mut self, to: bool) { - self.use_modal_editing = to; + pub fn set_default_editor_mode(&mut self, to: vim_mode_setting::EditorMode) { + self.default_editor_mode = to; } - pub fn use_modal_editing(&self) -> bool { - self.use_modal_editing + pub fn default_editor_mode(&self) -> vim_mode_setting::EditorMode { + self.default_editor_mode } fn selections_did_change( diff --git a/crates/onboarding/src/basics_page.rs b/crates/onboarding/src/basics_page.rs index 30c1b5d3f7..7487b04114 100644 --- a/crates/onboarding/src/basics_page.rs +++ b/crates/onboarding/src/basics_page.rs @@ -332,7 +332,10 @@ 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) { + let toggle_state = if matches!( + editor_mode, + EditorMode::Vim | EditorMode::Helix | EditorMode::VimInsert + ) { ui::ToggleState::Selected } else { ui::ToggleState::Unselected diff --git a/crates/vim/src/vim.rs b/crates/vim/src/vim.rs index 46325dfa36..bc275ac688 100644 --- a/crates/vim/src/vim.rs +++ b/crates/vim/src/vim.rs @@ -454,6 +454,10 @@ impl Vim { return; } + if editor.default_editor_mode() == EditorMode::Default { + return; + } + let mut was_enabled = Vim::enabled(cx); let mut was_toggle = VimSettings::get_global(cx).toggle_relative_line_numbers; cx.observe_global_in::(window, move |editor, window, cx| { @@ -489,7 +493,9 @@ impl Vim { fn activate(editor: &mut Editor, window: &mut Window, cx: &mut Context) { let vim = Vim::new(window, cx); - if !editor.mode().is_full() { + let default_editor_mode = editor.default_editor_mode(); + + if default_editor_mode == EditorMode::VimInsert { vim.update(cx, |vim, _| { vim.mode = Mode::Insert; }); @@ -499,14 +505,18 @@ impl Vim { entity: vim.clone(), }); - vim.update(cx, |_, cx| { - Vim::action(editor, cx, |vim, _: &SwitchToNormalMode, window, cx| { - if matches!(EditorModeSetting::get_global(cx).0, EditorMode::Helix) { - vim.switch_mode(Mode::HelixNormal, false, window, cx) - } else { - vim.switch_mode(Mode::Normal, false, window, cx) - } - }); + vim.update(cx, move |_, cx| { + Vim::action( + editor, + cx, + move |vim, _: &SwitchToNormalMode, window, cx| { + if matches!(default_editor_mode, EditorMode::Helix) { + vim.switch_mode(Mode::HelixNormal, false, window, cx) + } else { + vim.switch_mode(Mode::Normal, false, window, cx) + } + }, + ); Vim::action(editor, cx, |vim, _: &SwitchToInsertMode, window, cx| { vim.switch_mode(Mode::Insert, false, window, cx) @@ -827,8 +837,10 @@ impl Vim { if EditorModeSetting::get_global(cx).0 == EditorMode::Default { return false; } + + // check for agent.editor_mode + // return true; - // VimModeSetting::get_global(cx).0 || HelixModeSetting::get_global(cx).0 } /// Called whenever an keystroke is typed so vim can observe all actions diff --git a/crates/vim_mode_setting/src/vim_mode_setting.rs b/crates/vim_mode_setting/src/vim_mode_setting.rs index e9606419df..c8d05a1af6 100644 --- a/crates/vim_mode_setting/src/vim_mode_setting.rs +++ b/crates/vim_mode_setting/src/vim_mode_setting.rs @@ -23,6 +23,7 @@ pub struct EditorModeSetting(pub EditorMode); #[derive(Copy, Clone, Debug, PartialEq, Eq, Serialize, Deserialize, JsonSchema, Default)] pub enum EditorMode { Vim, + VimInsert, Helix, #[default] Default, diff --git a/crates/zed/src/zed.rs b/crates/zed/src/zed.rs index d955fd11a8..243ab382f1 100644 --- a/crates/zed/src/zed.rs +++ b/crates/zed/src/zed.rs @@ -1495,7 +1495,7 @@ pub fn load_default_keymap(cx: &mut App) { if matches!( EditorModeSetting::get_global(cx).0, - EditorMode::Vim | EditorMode::Helix + EditorMode::Vim | EditorMode::Helix | EditorMode::VimInsert ) { 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 fee96727ea..75015eb5f2 100644 --- a/crates/zed/src/zed/quick_action_bar.rs +++ b/crates/zed/src/zed/quick_action_bar.rs @@ -302,7 +302,10 @@ 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); + let vim_mode_enabled = matches!( + editor_mode, + EditorMode::Vim | EditorMode::Helix | EditorMode::VimInsert + ); PopoverMenu::new("editor-settings") .trigger_with_tooltip( From c6d0d757112fca37bd81c447cf3b3182c608d91d Mon Sep 17 00:00:00 2001 From: Smit Barmase Date: Fri, 22 Aug 2025 14:08:21 +0530 Subject: [PATCH 04/15] editor mode -> display mode Co-authored-by: Oleksiy Syvokon --- crates/agent_ui/src/acp/entry_view_state.rs | 6 +- crates/agent_ui/src/acp/message_editor.rs | 18 +- crates/agent_ui/src/acp/thread_view.rs | 14 +- crates/agent_ui/src/active_thread.rs | 2 +- crates/agent_ui/src/agent_diff.rs | 4 +- .../src/context_picker/completion_provider.rs | 2 +- crates/agent_ui/src/inline_prompt_editor.rs | 7 +- crates/agent_ui/src/message_editor.rs | 10 +- crates/assistant_tools/src/edit_file_tool.rs | 4 +- .../debugger_ui/src/tests/debugger_panel.rs | 12 +- crates/debugger_ui/src/tests/inline_values.rs | 8 +- crates/editor/src/editor.rs | 194 +++++++++--------- crates/editor/src/editor_tests.rs | 52 +++-- crates/editor/src/element.rs | 75 +++---- crates/editor/src/items.rs | 4 +- crates/editor/src/lsp_colors.rs | 2 +- crates/editor/src/mouse_context_menu.rs | 2 +- crates/editor/src/scroll.rs | 4 +- crates/editor/src/scroll/actions.rs | 4 +- crates/editor/src/scroll/autoscroll.rs | 4 +- crates/editor/src/test.rs | 6 +- crates/git_ui/src/conflict_view.rs | 2 +- crates/git_ui/src/git_panel.rs | 4 +- crates/go_to_line/src/cursor_position.rs | 10 +- crates/inspector_ui/src/div_inspector.rs | 4 +- crates/outline/src/outline.rs | 2 +- crates/outline_panel/src/outline_panel.rs | 2 +- crates/repl/src/notebook/cell.rs | 4 +- crates/settings_ui/src/keybindings.rs | 2 +- crates/vim/src/test.rs | 10 +- crates/vim/src/vim.rs | 2 +- .../zed/src/zed/edit_prediction_registry.rs | 2 +- crates/zed/src/zed/quick_action_bar.rs | 2 +- 33 files changed, 255 insertions(+), 225 deletions(-) diff --git a/crates/agent_ui/src/acp/entry_view_state.rs b/crates/agent_ui/src/acp/entry_view_state.rs index 0e4080d689..0c3af286cb 100644 --- a/crates/agent_ui/src/acp/entry_view_state.rs +++ b/crates/agent_ui/src/acp/entry_view_state.rs @@ -4,7 +4,7 @@ use acp_thread::{AcpThread, AgentThreadEntry}; use agent_client_protocol::{PromptCapabilities, ToolCallId}; use agent2::HistoryStore; use collections::HashMap; -use editor::{Editor, EditorMode, MinimapVisibility}; +use editor::{Editor, EditorDisplayMode, MinimapVisibility}; use gpui::{ AnyEntity, App, AppContext as _, Entity, EntityId, EventEmitter, Focusable, TextStyleRefinement, WeakEntity, Window, @@ -87,7 +87,7 @@ impl EntryViewState { self.prompt_capabilities.clone(), "Edit message - @ to include context", self.prevent_slash_commands, - editor::EditorMode::AutoHeight { + editor::EditorDisplayMode::AutoHeight { min_lines: 1, max_lines: None, }, @@ -287,7 +287,7 @@ fn create_editor_diff( ) -> Entity { cx.new(|cx| { let mut editor = Editor::new( - EditorMode::Full { + EditorDisplayMode::Full { scale_ui_elements_with_buffer_font_size: false, show_active_line_background: false, sized_by_content: true, diff --git a/crates/agent_ui/src/acp/message_editor.rs b/crates/agent_ui/src/acp/message_editor.rs index 7d73ebeb19..dda0f9f04b 100644 --- a/crates/agent_ui/src/acp/message_editor.rs +++ b/crates/agent_ui/src/acp/message_editor.rs @@ -10,9 +10,9 @@ use anyhow::{Context as _, Result, anyhow}; use assistant_slash_commands::codeblock_fence_for_path; use collections::{HashMap, HashSet}; use editor::{ - Addon, Anchor, AnchorRangeExt, ContextMenuOptions, ContextMenuPlacement, Editor, EditorElement, - EditorEvent, EditorMode, EditorSnapshot, EditorStyle, ExcerptId, FoldPlaceholder, MultiBuffer, - SemanticsProvider, ToOffset, + Addon, Anchor, AnchorRangeExt, ContextMenuOptions, ContextMenuPlacement, Editor, + EditorDisplayMode, EditorElement, EditorEvent, EditorSnapshot, EditorStyle, ExcerptId, + FoldPlaceholder, MultiBuffer, SemanticsProvider, ToOffset, actions::Paste, display_map::{Crease, CreaseId, FoldId}, }; @@ -90,7 +90,7 @@ impl MessageEditor { prompt_capabilities: Rc>, placeholder: impl Into>, prevent_slash_commands: bool, - mode: EditorMode, + mode: EditorDisplayMode, window: &mut Window, cx: &mut Context, ) -> Self { @@ -1056,9 +1056,9 @@ impl MessageEditor { }) } - pub fn set_mode(&mut self, mode: EditorMode, cx: &mut Context) { + pub fn set_display_mode(&mut self, mode: EditorDisplayMode, cx: &mut Context) { self.editor.update(cx, |editor, cx| { - editor.set_mode(mode); + editor.set_display_mode(mode); cx.notify() }); } @@ -1858,7 +1858,7 @@ mod tests { use agent_client_protocol as acp; use agent2::HistoryStore; use assistant_context::ContextStore; - use editor::{AnchorRangeExt as _, Editor, EditorMode}; + use editor::{AnchorRangeExt as _, Editor, EditorDisplayMode}; use fs::FakeFs; use futures::StreamExt as _; use gpui::{ @@ -1901,7 +1901,7 @@ mod tests { Default::default(), "Test", false, - EditorMode::AutoHeight { + EditorDisplayMode::AutoHeight { min_lines: 1, max_lines: None, }, @@ -2102,7 +2102,7 @@ mod tests { prompt_capabilities.clone(), "Test", false, - EditorMode::AutoHeight { + EditorDisplayMode::AutoHeight { max_lines: None, min_lines: 1, }, diff --git a/crates/agent_ui/src/acp/thread_view.rs b/crates/agent_ui/src/acp/thread_view.rs index 619885144a..ba900ea803 100644 --- a/crates/agent_ui/src/acp/thread_view.rs +++ b/crates/agent_ui/src/acp/thread_view.rs @@ -15,7 +15,7 @@ use buffer_diff::BufferDiff; use client::zed_urls; use collections::{HashMap, HashSet}; use editor::scroll::Autoscroll; -use editor::{Editor, EditorEvent, EditorMode, MultiBuffer, PathKey, SelectionEffects}; +use editor::{Editor, EditorDisplayMode, EditorEvent, MultiBuffer, PathKey, SelectionEffects}; use file_icons::FileIcons; use fs::Fs; use gpui::{ @@ -228,7 +228,7 @@ impl ThreadFeedbackState { let editor = cx.new(|cx| { let mut editor = Editor::new( - editor::EditorMode::AutoHeight { + editor::EditorDisplayMode::AutoHeight { min_lines: 1, max_lines: Some(4), }, @@ -321,7 +321,7 @@ impl AcpThreadView { prompt_capabilities.clone(), "Message the agent — @ to include context", prevent_slash_commands, - editor::EditorMode::AutoHeight { + editor::EditorDisplayMode::AutoHeight { min_lines: MIN_EDITOR_LINES, max_lines: Some(MAX_EDITOR_LINES), }, @@ -673,8 +673,8 @@ impl AcpThreadView { self.editor_expanded = is_expanded; self.message_editor.update(cx, |editor, cx| { if is_expanded { - editor.set_mode( - EditorMode::Full { + editor.set_display_mode( + EditorDisplayMode::Full { scale_ui_elements_with_buffer_font_size: false, show_active_line_background: false, sized_by_content: false, @@ -682,8 +682,8 @@ impl AcpThreadView { cx, ) } else { - editor.set_mode( - EditorMode::AutoHeight { + editor.set_display_mode( + EditorDisplayMode::AutoHeight { min_lines: MIN_EDITOR_LINES, max_lines: Some(MAX_EDITOR_LINES), }, diff --git a/crates/agent_ui/src/active_thread.rs b/crates/agent_ui/src/active_thread.rs index 2cad913295..2c72c91e27 100644 --- a/crates/agent_ui/src/active_thread.rs +++ b/crates/agent_ui/src/active_thread.rs @@ -1723,7 +1723,7 @@ impl ActiveThread { let editor = cx.new(|cx| { let mut editor = Editor::new( - editor::EditorMode::AutoHeight { + editor::EditorDisplayMode::AutoHeight { min_lines: 1, max_lines: Some(4), }, diff --git a/crates/agent_ui/src/agent_diff.rs b/crates/agent_ui/src/agent_diff.rs index e07424987c..86e5f8a1ed 100644 --- a/crates/agent_ui/src/agent_diff.rs +++ b/crates/agent_ui/src/agent_diff.rs @@ -1046,7 +1046,7 @@ impl ToolbarItemView for AgentDiffToolbar { } if let Some(editor) = item.act_as::(cx) - && editor.read(cx).mode().is_full() + && editor.read(cx).display_mode().is_full() { let agent_diff = AgentDiff::global(cx); @@ -1549,7 +1549,7 @@ impl AgentDiff { } fn full_editor_buffer(editor: &Editor, cx: &App) -> Option> { - if editor.mode().is_full() { + if editor.display_mode().is_full() { editor .buffer() .read(cx) diff --git a/crates/agent_ui/src/context_picker/completion_provider.rs b/crates/agent_ui/src/context_picker/completion_provider.rs index 020d799c79..978052712c 100644 --- a/crates/agent_ui/src/context_picker/completion_provider.rs +++ b/crates/agent_ui/src/context_picker/completion_provider.rs @@ -1244,7 +1244,7 @@ mod tests { let editor = workspace.update_in(&mut cx, |workspace, window, cx| { let editor = cx.new(|cx| { Editor::new( - editor::EditorMode::full(), + editor::EditorDisplayMode::full(), multi_buffer::MultiBuffer::build_simple("", cx), None, window, diff --git a/crates/agent_ui/src/inline_prompt_editor.rs b/crates/agent_ui/src/inline_prompt_editor.rs index a626122769..4009272816 100644 --- a/crates/agent_ui/src/inline_prompt_editor.rs +++ b/crates/agent_ui/src/inline_prompt_editor.rs @@ -16,7 +16,8 @@ use db::kvp::Dismissable; use editor::actions::Paste; use editor::display_map::EditorMargins; use editor::{ - ContextMenuOptions, Editor, EditorElement, EditorEvent, EditorMode, EditorStyle, MultiBuffer, + ContextMenuOptions, Editor, EditorDisplayMode, EditorElement, EditorEvent, EditorStyle, + MultiBuffer, actions::{MoveDown, MoveUp}, }; use feature_flags::{FeatureFlagAppExt as _, ZedProFeatureFlag}; @@ -869,7 +870,7 @@ impl PromptEditor { let prompt_editor = cx.new(|cx| { let mut editor = Editor::new( - EditorMode::AutoHeight { + EditorDisplayMode::AutoHeight { min_lines: 1, max_lines: Some(Self::MAX_LINES as usize), }, @@ -1048,7 +1049,7 @@ impl PromptEditor { let prompt_editor = cx.new(|cx| { let mut editor = Editor::new( - EditorMode::AutoHeight { + EditorDisplayMode::AutoHeight { min_lines: 1, max_lines: Some(Self::MAX_LINES as usize), }, diff --git a/crates/agent_ui/src/message_editor.rs b/crates/agent_ui/src/message_editor.rs index f578ccabe4..7f0254564f 100644 --- a/crates/agent_ui/src/message_editor.rs +++ b/crates/agent_ui/src/message_editor.rs @@ -22,8 +22,8 @@ use collections::{HashMap, HashSet}; use editor::actions::{MoveUp, Paste}; use editor::display_map::CreaseId; use editor::{ - Addon, AnchorRangeExt, ContextMenuOptions, ContextMenuPlacement, Editor, EditorElement, - EditorEvent, EditorMode, EditorStyle, MultiBuffer, + Addon, AnchorRangeExt, ContextMenuOptions, ContextMenuPlacement, Editor, EditorDisplayMode, + EditorElement, EditorEvent, EditorStyle, MultiBuffer, }; use file_icons::FileIcons; use fs::Fs; @@ -127,7 +127,7 @@ pub(crate) fn create_editor( }; let mut editor = Editor::new( - editor::EditorMode::AutoHeight { + editor::EditorDisplayMode::AutoHeight { min_lines, max_lines, }, @@ -312,13 +312,13 @@ impl MessageEditor { self.editor_is_expanded = is_expanded; self.editor.update(cx, |editor, _| { if self.editor_is_expanded { - editor.set_mode(EditorMode::Full { + editor.set_display_mode(EditorDisplayMode::Full { scale_ui_elements_with_buffer_font_size: false, show_active_line_background: false, sized_by_content: false, }) } else { - editor.set_mode(EditorMode::AutoHeight { + editor.set_display_mode(EditorDisplayMode::AutoHeight { min_lines: MIN_EDITOR_LINES, max_lines: Some(MAX_EDITOR_LINES), }) diff --git a/crates/assistant_tools/src/edit_file_tool.rs b/crates/assistant_tools/src/edit_file_tool.rs index 95b01c40eb..165a46a5cb 100644 --- a/crates/assistant_tools/src/edit_file_tool.rs +++ b/crates/assistant_tools/src/edit_file_tool.rs @@ -11,7 +11,7 @@ use assistant_tool::{ AnyToolCard, Tool, ToolCard, ToolResult, ToolResultContent, ToolResultOutput, ToolUseStatus, }; use buffer_diff::{BufferDiff, BufferDiffSnapshot}; -use editor::{Editor, EditorMode, MinimapVisibility, MultiBuffer, PathKey}; +use editor::{Editor, EditorDisplayMode, MinimapVisibility, MultiBuffer, PathKey}; use futures::StreamExt; use gpui::{ Animation, AnimationExt, AnyWindowHandle, App, AppContext, AsyncApp, Entity, Task, @@ -582,7 +582,7 @@ impl EditFileToolCard { let editor = cx.new(|cx| { let mut editor = Editor::new( - EditorMode::Full { + EditorDisplayMode::Full { scale_ui_elements_with_buffer_font_size: false, show_active_line_background: false, sized_by_content: true, diff --git a/crates/debugger_ui/src/tests/debugger_panel.rs b/crates/debugger_ui/src/tests/debugger_panel.rs index ab6d5cb960..e3fde56b20 100644 --- a/crates/debugger_ui/src/tests/debugger_panel.rs +++ b/crates/debugger_ui/src/tests/debugger_panel.rs @@ -14,7 +14,7 @@ use dap::{ }, }; use editor::{ - ActiveDebugLine, Editor, EditorMode, MultiBuffer, + ActiveDebugLine, Editor, EditorDisplayMode, MultiBuffer, actions::{self}, }; use gpui::{BackgroundExecutor, TestAppContext, VisualTestContext}; @@ -1121,7 +1121,7 @@ async fn test_send_breakpoints_when_editor_has_been_saved( let (editor, cx) = cx.add_window_view(|window, cx| { Editor::new( - EditorMode::full(), + EditorDisplayMode::full(), MultiBuffer::build_from_buffer(buffer, cx), Some(project.clone()), window, @@ -1290,7 +1290,7 @@ async fn test_unsetting_breakpoints_on_clear_breakpoint_action( let (first_editor, cx) = cx.add_window_view(|window, cx| { Editor::new( - EditorMode::full(), + EditorDisplayMode::full(), MultiBuffer::build_from_buffer(first, cx), Some(project.clone()), window, @@ -1300,7 +1300,7 @@ async fn test_unsetting_breakpoints_on_clear_breakpoint_action( let (second_editor, cx) = cx.add_window_view(|window, cx| { Editor::new( - EditorMode::full(), + EditorDisplayMode::full(), MultiBuffer::build_from_buffer(second, cx), Some(project.clone()), window, @@ -1513,7 +1513,7 @@ async fn test_active_debug_line_setting(executor: BackgroundExecutor, cx: &mut T let (main_editor, cx) = cx.add_window_view(|window, cx| { Editor::new( - EditorMode::full(), + EditorDisplayMode::full(), MultiBuffer::build_from_buffer(main_buffer, cx), Some(project.clone()), window, @@ -1523,7 +1523,7 @@ async fn test_active_debug_line_setting(executor: BackgroundExecutor, cx: &mut T let (second_editor, cx) = cx.add_window_view(|window, cx| { Editor::new( - EditorMode::full(), + EditorDisplayMode::full(), MultiBuffer::build_from_buffer(second_buffer, cx), Some(project.clone()), window, diff --git a/crates/debugger_ui/src/tests/inline_values.rs b/crates/debugger_ui/src/tests/inline_values.rs index 9f921ec969..87abb2a81b 100644 --- a/crates/debugger_ui/src/tests/inline_values.rs +++ b/crates/debugger_ui/src/tests/inline_values.rs @@ -1,7 +1,7 @@ use std::{path::Path, sync::Arc}; use dap::{Scope, StackFrame, Variable, requests::Variables}; -use editor::{Editor, EditorMode, MultiBuffer}; +use editor::{Editor, EditorDisplayMode, MultiBuffer}; use gpui::{BackgroundExecutor, TestAppContext, VisualTestContext}; use language::{Language, LanguageConfig, LanguageMatcher, tree_sitter_python, tree_sitter_rust}; use project::{FakeFs, Project}; @@ -226,7 +226,7 @@ fn main() { let (editor, cx) = cx.add_window_view(|window, cx| { Editor::new( - EditorMode::full(), + EditorDisplayMode::full(), MultiBuffer::build_from_buffer(buffer, cx), Some(project), window, @@ -1595,7 +1595,7 @@ def process_data(untyped_param, typed_param: int, another_typed: str): let (editor, cx) = cx.add_window_view(|window, cx| { Editor::new( - EditorMode::full(), + EditorDisplayMode::full(), MultiBuffer::build_from_buffer(buffer, cx), Some(project), window, @@ -2093,7 +2093,7 @@ async fn test_inline_values_util( let (editor, cx) = cx.add_window_view(|window, cx| { Editor::new( - EditorMode::full(), + EditorDisplayMode::full(), MultiBuffer::build_from_buffer(buffer, cx), Some(project), window, diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index f0745c8850..0412ee1764 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -496,7 +496,7 @@ pub enum SelectMode { } #[derive(Clone, PartialEq, Eq, Debug)] -pub enum EditorMode { +pub enum EditorDisplayMode { SingleLine, AutoHeight { min_lines: usize, @@ -515,7 +515,7 @@ pub enum EditorMode { }, } -impl EditorMode { +impl EditorDisplayMode { pub fn full() -> Self { Self::Full { scale_ui_elements_with_buffer_font_size: true, @@ -759,7 +759,7 @@ pub enum MinimapVisibility { } impl MinimapVisibility { - fn for_mode(mode: &EditorMode, cx: &App) -> Self { + fn for_display_mode(mode: &EditorDisplayMode, cx: &App) -> Self { if mode.is_full() { Self::Enabled { setting_configuration: EditorSettings::get_global(cx).minimap.minimap_enabled(), @@ -1046,7 +1046,7 @@ pub struct Editor { show_cursor_names: bool, hovered_cursors: HashMap>, pub show_local_selections: bool, - mode: EditorMode, + display_mode: EditorDisplayMode, show_breadcrumbs: bool, show_gutter: bool, show_scrollbars: ScrollbarAxes, @@ -1236,7 +1236,7 @@ impl NextScrollCursorCenterTopBottom { #[derive(Clone)] pub struct EditorSnapshot { - pub mode: EditorMode, + pub display_mode: EditorDisplayMode, show_gutter: bool, show_line_numbers: Option, show_git_diff_gutter: Option, @@ -1704,13 +1704,13 @@ impl Editor { pub fn single_line(window: &mut Window, cx: &mut Context) -> Self { let buffer = cx.new(|cx| Buffer::local("", cx)); let buffer = cx.new(|cx| MultiBuffer::singleton(buffer, cx)); - Self::new(EditorMode::SingleLine, buffer, None, window, cx) + Self::new(EditorDisplayMode::SingleLine, buffer, None, window, cx) } pub fn multi_line(window: &mut Window, cx: &mut Context) -> Self { let buffer = cx.new(|cx| Buffer::local("", cx)); let buffer = cx.new(|cx| MultiBuffer::singleton(buffer, cx)); - Self::new(EditorMode::full(), buffer, None, window, cx) + Self::new(EditorDisplayMode::full(), buffer, None, window, cx) } pub fn auto_height( @@ -1722,7 +1722,7 @@ impl Editor { let buffer = cx.new(|cx| Buffer::local("", cx)); let buffer = cx.new(|cx| MultiBuffer::singleton(buffer, cx)); Self::new( - EditorMode::AutoHeight { + EditorDisplayMode::AutoHeight { min_lines, max_lines: Some(max_lines), }, @@ -1743,7 +1743,7 @@ impl Editor { let buffer = cx.new(|cx| Buffer::local("", cx)); let buffer = cx.new(|cx| MultiBuffer::singleton(buffer, cx)); Self::new( - EditorMode::AutoHeight { + EditorDisplayMode::AutoHeight { min_lines, max_lines: None, }, @@ -1761,7 +1761,7 @@ impl Editor { cx: &mut Context, ) -> Self { let buffer = cx.new(|cx| MultiBuffer::singleton(buffer, cx)); - Self::new(EditorMode::full(), buffer, project, window, cx) + Self::new(EditorDisplayMode::full(), buffer, project, window, cx) } pub fn for_multibuffer( @@ -1770,12 +1770,12 @@ impl Editor { window: &mut Window, cx: &mut Context, ) -> Self { - Self::new(EditorMode::full(), buffer, project, window, cx) + Self::new(EditorDisplayMode::full(), buffer, project, window, cx) } pub fn clone(&self, window: &mut Window, cx: &mut Context) -> Self { let mut clone = Self::new( - self.mode.clone(), + self.display_mode.clone(), self.buffer.clone(), self.project.clone(), window, @@ -1796,7 +1796,7 @@ impl Editor { } pub fn new( - mode: EditorMode, + mode: EditorDisplayMode, buffer: Entity, project: Option>, window: &mut Window, @@ -1806,7 +1806,7 @@ impl Editor { } fn new_internal( - mode: EditorMode, + mode: EditorDisplayMode, buffer: Entity, project: Option>, display_map: Option>, @@ -1888,8 +1888,8 @@ impl Editor { blink_manager }); - let soft_wrap_mode_override = - matches!(mode, EditorMode::SingleLine).then(|| language_settings::SoftWrap::None); + let soft_wrap_mode_override = matches!(mode, EditorDisplayMode::SingleLine) + .then(|| language_settings::SoftWrap::None); let mut project_subscriptions = Vec::new(); if full_mode && let Some(project) = project.as_ref() { @@ -2068,15 +2068,19 @@ impl Editor { .detach(); } - let show_indent_guides = - if matches!(mode, EditorMode::SingleLine | EditorMode::Minimap { .. }) { - Some(false) - } else { - None - }; + let show_indent_guides = if matches!( + mode, + EditorDisplayMode::SingleLine | EditorDisplayMode::Minimap { .. } + ) { + Some(false) + } else { + None + }; let breakpoint_store = match (&mode, project.as_ref()) { - (EditorMode::Full { .. }, Some(project)) => Some(project.read(cx).breakpoint_store()), + (EditorDisplayMode::Full { .. }, Some(project)) => { + Some(project.read(cx).breakpoint_store()) + } _ => None, }; @@ -2132,8 +2136,8 @@ impl Editor { horizontal: full_mode, vertical: full_mode, }, - minimap_visibility: MinimapVisibility::for_mode(&mode, cx), - offset_content: !matches!(mode, EditorMode::SingleLine), + minimap_visibility: MinimapVisibility::for_display_mode(&mode, cx), + offset_content: !matches!(mode, EditorDisplayMode::SingleLine), show_breadcrumbs: EditorSettings::get_global(cx).toolbar.breadcrumbs, show_gutter: full_mode, show_line_numbers: (!full_mode).then_some(false), @@ -2289,7 +2293,7 @@ impl Editor { .hide_mouse .unwrap_or_default(), change_list: ChangeList::new(), - mode, + display_mode: mode, selection_drag_state: SelectionDragState::None, folding_newlines: Task::ready(()), default_editor_mode: vim_mode_setting::EditorMode::default(), @@ -2418,7 +2422,7 @@ impl Editor { editor.update_lsp_data(false, None, window, cx); } - if editor.mode.is_full() { + if editor.display_mode.is_full() { editor.report_editor_event(ReportEditorEvent::EditorOpened, None, cx); } @@ -2487,11 +2491,11 @@ impl Editor { ) -> KeyContext { let mut key_context = KeyContext::new_with_defaults(); key_context.add("Editor"); - let mode = match self.mode { - EditorMode::SingleLine => "single_line", - EditorMode::AutoHeight { .. } => "auto_height", - EditorMode::Minimap { .. } => "minimap", - EditorMode::Full { .. } => "full", + let mode = match self.display_mode { + EditorDisplayMode::SingleLine => "single_line", + EditorDisplayMode::AutoHeight { .. } => "auto_height", + EditorDisplayMode::Minimap { .. } => "minimap", + EditorDisplayMode::Full { .. } => "full", }; if EditorSettings::jupyter_enabled(cx) { @@ -2755,7 +2759,7 @@ impl Editor { .flatten(); EditorSnapshot { - mode: self.mode.clone(), + display_mode: self.display_mode.clone(), show_gutter: self.show_gutter, show_line_numbers: self.show_line_numbers, show_git_diff_gutter: self.show_git_diff_gutter, @@ -2792,12 +2796,12 @@ impl Editor { .excerpt_containing(self.selections.newest_anchor().head(), cx) } - pub fn mode(&self) -> &EditorMode { - &self.mode + pub fn display_mode(&self) -> &EditorDisplayMode { + &self.display_mode } - pub fn set_mode(&mut self, mode: EditorMode) { - self.mode = mode; + pub fn set_display_mode(&mut self, mode: EditorDisplayMode) { + self.display_mode = mode; } pub fn collaboration_hub(&self) -> Option<&dyn CollaborationHub> { @@ -3237,7 +3241,7 @@ impl Editor { use text::ToOffset as _; use text::ToPoint as _; - if self.mode.is_minimap() + if self.display_mode.is_minimap() || WorkspaceSettings::get(None, cx).restore_on_startup == RestoreOnStartupBehavior::None { return; @@ -3920,7 +3924,7 @@ impl Editor { return; } - if self.mode.is_full() + if self.display_mode.is_full() && self.change_selections(Default::default(), window, cx, |s| s.try_cancel()) { return; @@ -3963,7 +3967,9 @@ impl Editor { return true; } - if self.mode.is_full() && matches!(self.active_diagnostics, ActiveDiagnostic::Group(_)) { + if self.display_mode.is_full() + && matches!(self.active_diagnostics, ActiveDiagnostic::Group(_)) + { self.dismiss_diagnostics(cx); return true; } @@ -5177,7 +5183,7 @@ impl Editor { } fn refresh_inlay_hints(&mut self, reason: InlayHintRefreshReason, cx: &mut Context) { - if self.semantics_provider.is_none() || !self.mode.is_full() { + if self.semantics_provider.is_none() || !self.display_mode.is_full() { return; } @@ -6854,7 +6860,7 @@ impl Editor { &mut self, cx: &mut Context, ) -> Option<(String, Range)> { - if matches!(self.mode, EditorMode::SingleLine) { + if matches!(self.display_mode, EditorDisplayMode::SingleLine) { return None; } if !EditorSettings::get_global(cx).selection_highlight { @@ -6953,7 +6959,7 @@ impl Editor { fn refresh_single_line_folds(&mut self, window: &mut Window, cx: &mut Context) { struct NewlineFold; let type_id = std::any::TypeId::of::(); - if !self.mode.is_single_line() { + if !self.display_mode.is_single_line() { return; } let snapshot = self.snapshot(window, cx); @@ -7179,7 +7185,7 @@ impl Editor { buffer_position: language::Anchor, cx: &App, ) -> EditPredictionSettings { - if !self.mode.is_full() + if !self.display_mode.is_full() || !self.show_edit_predictions_override.unwrap_or(true) || self.edit_predictions_disabled_in_scope(buffer, buffer_position, cx) { @@ -8518,7 +8524,7 @@ impl Editor { window: &mut Window, cx: &mut App, ) -> Option<(AnyElement, gpui::Point)> { - if self.mode().is_minimap() { + if self.display_mode().is_minimap() { return None; } let active_edit_prediction = self.active_edit_prediction.as_ref()?; @@ -9955,7 +9961,7 @@ impl Editor { } pub fn backtab(&mut self, _: &Backtab, window: &mut Window, cx: &mut Context) { - if self.mode.is_single_line() { + if self.display_mode.is_single_line() { cx.propagate(); return; } @@ -9968,7 +9974,7 @@ impl Editor { } pub fn tab(&mut self, _: &Tab, window: &mut Window, cx: &mut Context) { - if self.mode.is_single_line() { + if self.display_mode.is_single_line() { cx.propagate(); return; } @@ -10091,7 +10097,7 @@ impl Editor { if self.read_only(cx) { return; } - if self.mode.is_single_line() { + if self.display_mode.is_single_line() { cx.propagate(); return; } @@ -10199,7 +10205,7 @@ impl Editor { if self.read_only(cx) { return; } - if self.mode.is_single_line() { + if self.display_mode.is_single_line() { cx.propagate(); return; } @@ -10276,7 +10282,7 @@ impl Editor { if self.read_only(cx) { return; } - if self.mode.is_single_line() { + if self.display_mode.is_single_line() { cx.propagate(); return; } @@ -11521,7 +11527,7 @@ impl Editor { pub fn move_line_up(&mut self, _: &MoveLineUp, window: &mut Window, cx: &mut Context) { self.hide_mouse_cursor(HideMouseCursorOrigin::TypingAction, cx); - if self.mode.is_single_line() { + if self.display_mode.is_single_line() { cx.propagate(); return; } @@ -11632,7 +11638,7 @@ impl Editor { cx: &mut Context, ) { self.hide_mouse_cursor(HideMouseCursorOrigin::TypingAction, cx); - if self.mode.is_single_line() { + if self.display_mode.is_single_line() { cx.propagate(); return; } @@ -11784,7 +11790,7 @@ impl Editor { pub fn rewrap(&mut self, _: &Rewrap, _: &mut Window, cx: &mut Context) { self.hide_mouse_cursor(HideMouseCursorOrigin::TypingAction, cx); - if self.mode.is_single_line() { + if self.display_mode.is_single_line() { cx.propagate(); return; } @@ -12495,7 +12501,7 @@ impl Editor { return; } - if self.mode.is_single_line() { + if self.display_mode.is_single_line() { cx.propagate(); return; } @@ -12538,7 +12544,7 @@ impl Editor { return; } - if self.mode.is_single_line() { + if self.display_mode.is_single_line() { cx.propagate(); return; } @@ -12575,7 +12581,7 @@ impl Editor { return; } - if self.mode.is_single_line() { + if self.display_mode.is_single_line() { cx.propagate(); return; } @@ -12673,7 +12679,7 @@ impl Editor { return; } - if matches!(self.mode, EditorMode::SingleLine) { + if matches!(self.display_mode, EditorDisplayMode::SingleLine) { cx.propagate(); return; } @@ -12723,7 +12729,7 @@ impl Editor { pub fn move_down(&mut self, _: &MoveDown, window: &mut Window, cx: &mut Context) { self.take_rename(true, window, cx); - if self.mode.is_single_line() { + if self.display_mode.is_single_line() { cx.propagate(); return; } @@ -12797,7 +12803,7 @@ impl Editor { return; } - if matches!(self.mode, EditorMode::SingleLine) { + if matches!(self.display_mode, EditorDisplayMode::SingleLine) { cx.propagate(); return; } @@ -13281,7 +13287,7 @@ impl Editor { window: &mut Window, cx: &mut Context, ) { - if matches!(self.mode, EditorMode::SingleLine) { + if matches!(self.display_mode, EditorDisplayMode::SingleLine) { cx.propagate(); return; } @@ -13302,7 +13308,7 @@ impl Editor { window: &mut Window, cx: &mut Context, ) { - if matches!(self.mode, EditorMode::SingleLine) { + if matches!(self.display_mode, EditorDisplayMode::SingleLine) { cx.propagate(); return; } @@ -13323,7 +13329,7 @@ impl Editor { window: &mut Window, cx: &mut Context, ) { - if matches!(self.mode, EditorMode::SingleLine) { + if matches!(self.display_mode, EditorDisplayMode::SingleLine) { cx.propagate(); return; } @@ -13344,7 +13350,7 @@ impl Editor { window: &mut Window, cx: &mut Context, ) { - if matches!(self.mode, EditorMode::SingleLine) { + if matches!(self.display_mode, EditorDisplayMode::SingleLine) { cx.propagate(); return; } @@ -13365,7 +13371,7 @@ impl Editor { window: &mut Window, cx: &mut Context, ) { - if matches!(self.mode, EditorMode::SingleLine) { + if matches!(self.display_mode, EditorDisplayMode::SingleLine) { cx.propagate(); return; } @@ -13390,7 +13396,7 @@ impl Editor { window: &mut Window, cx: &mut Context, ) { - if matches!(self.mode, EditorMode::SingleLine) { + if matches!(self.display_mode, EditorDisplayMode::SingleLine) { cx.propagate(); return; } @@ -13415,7 +13421,7 @@ impl Editor { window: &mut Window, cx: &mut Context, ) { - if matches!(self.mode, EditorMode::SingleLine) { + if matches!(self.display_mode, EditorDisplayMode::SingleLine) { cx.propagate(); return; } @@ -13440,7 +13446,7 @@ impl Editor { window: &mut Window, cx: &mut Context, ) { - if matches!(self.mode, EditorMode::SingleLine) { + if matches!(self.display_mode, EditorDisplayMode::SingleLine) { cx.propagate(); return; } @@ -13465,7 +13471,7 @@ impl Editor { window: &mut Window, cx: &mut Context, ) { - if matches!(self.mode, EditorMode::SingleLine) { + if matches!(self.display_mode, EditorDisplayMode::SingleLine) { cx.propagate(); return; } @@ -13486,7 +13492,7 @@ impl Editor { window: &mut Window, cx: &mut Context, ) { - if matches!(self.mode, EditorMode::SingleLine) { + if matches!(self.display_mode, EditorDisplayMode::SingleLine) { cx.propagate(); return; } @@ -13507,7 +13513,7 @@ impl Editor { window: &mut Window, cx: &mut Context, ) { - if matches!(self.mode, EditorMode::SingleLine) { + if matches!(self.display_mode, EditorDisplayMode::SingleLine) { cx.propagate(); return; } @@ -13528,7 +13534,7 @@ impl Editor { window: &mut Window, cx: &mut Context, ) { - if matches!(self.mode, EditorMode::SingleLine) { + if matches!(self.display_mode, EditorDisplayMode::SingleLine) { cx.propagate(); return; } @@ -13549,7 +13555,7 @@ impl Editor { window: &mut Window, cx: &mut Context, ) { - if matches!(self.mode, EditorMode::SingleLine) { + if matches!(self.display_mode, EditorDisplayMode::SingleLine) { cx.propagate(); return; } @@ -13574,7 +13580,7 @@ impl Editor { } pub fn move_to_end(&mut self, _: &MoveToEnd, window: &mut Window, cx: &mut Context) { - if matches!(self.mode, EditorMode::SingleLine) { + if matches!(self.display_mode, EditorDisplayMode::SingleLine) { cx.propagate(); return; } @@ -14623,7 +14629,7 @@ impl Editor { let advance_downwards = action.advance_downwards && selections_on_single_row && !selections_selecting - && !matches!(this.mode, EditorMode::SingleLine); + && !matches!(this.display_mode, EditorDisplayMode::SingleLine); if advance_downwards { let snapshot = this.buffer.read(cx).snapshot(cx); @@ -16948,7 +16954,7 @@ impl Editor { } pub fn diagnostics_enabled(&self) -> bool { - self.diagnostics_enabled && self.mode.is_full() + self.diagnostics_enabled && self.display_mode.is_full() } pub fn inline_diagnostics_enabled(&self) -> bool { @@ -17108,7 +17114,7 @@ impl Editor { window: &Window, cx: &mut Context, ) -> Option<()> { - if !self.mode().is_full() { + if !self.display_mode().is_full() { return None; } let pull_diagnostics_settings = ProjectSettings::get_global(cx) @@ -18390,7 +18396,7 @@ impl Editor { const MINIMAP_FONT_WEIGHT: gpui::FontWeight = gpui::FontWeight::BLACK; let mut minimap = Editor::new_internal( - EditorMode::Minimap { + EditorDisplayMode::Minimap { parent: cx.weak_entity(), }, self.buffer.clone(), @@ -18492,7 +18498,7 @@ impl Editor { // We intentionally do not inform the display map about the minimap style // so that wrapping is not recalculated and stays consistent for the editor // and its linked minimap. - if !self.mode.is_minimap() { + if !self.display_mode.is_minimap() { let rem_size = window.rem_size(); self.display_map.update(cx, |map, cx| { map.set_font( @@ -19038,7 +19044,9 @@ impl Editor { } pub fn render_git_blame_gutter(&self, cx: &App) -> bool { - !self.mode().is_minimap() && self.show_git_blame_gutter && self.has_blame_entries(cx) + !self.display_mode().is_minimap() + && self.show_git_blame_gutter + && self.has_blame_entries(cx) } pub fn render_git_blame_inline(&self, window: &Window, cx: &App) -> bool { @@ -20309,9 +20317,9 @@ impl Editor { let project_settings = ProjectSettings::get_global(cx); self.serialize_dirty_buffers = - !self.mode.is_minimap() && project_settings.session.restore_unsaved_buffers; + !self.display_mode.is_minimap() && project_settings.session.restore_unsaved_buffers; - if self.mode.is_full() { + if self.display_mode.is_full() { let show_inline_diagnostics = project_settings.diagnostics.inline.enabled; let inline_blame_enabled = project_settings.git.inline_blame_enabled(); if self.show_inline_diagnostics != show_inline_diagnostics { @@ -20329,7 +20337,7 @@ impl Editor { != minimap_settings.minimap_enabled() { self.set_minimap_visibility( - MinimapVisibility::for_mode(self.mode(), cx), + MinimapVisibility::for_display_mode(self.display_mode(), cx), window, cx, ); @@ -21162,7 +21170,7 @@ impl Editor { } pub fn register_addon(&mut self, instance: T) { - if self.mode.is_minimap() { + if self.display_mode.is_minimap() { return; } self.addons @@ -21215,7 +21223,7 @@ impl Editor { cx: &mut Context, ) { if self.is_singleton(cx) - && !self.mode.is_minimap() + && !self.display_mode.is_minimap() && WorkspaceSettings::get(None, cx).restore_on_startup != RestoreOnStartupBehavior::None { let buffer_snapshot = OnceCell::new(); @@ -22946,8 +22954,8 @@ impl Render for Editor { fn render(&mut self, _: &mut Window, cx: &mut Context) -> impl IntoElement { let settings = ThemeSettings::get_global(cx); - let mut text_style = match self.mode { - EditorMode::SingleLine | EditorMode::AutoHeight { .. } => TextStyle { + let mut text_style = match self.display_mode { + EditorDisplayMode::SingleLine | EditorDisplayMode::AutoHeight { .. } => TextStyle { color: cx.theme().colors().editor_foreground, font_family: settings.ui_font.family.clone(), font_features: settings.ui_font.features.clone(), @@ -22957,7 +22965,7 @@ impl Render for Editor { line_height: relative(settings.buffer_line_height.value()), ..Default::default() }, - EditorMode::Full { .. } | EditorMode::Minimap { .. } => TextStyle { + EditorDisplayMode::Full { .. } | EditorDisplayMode::Minimap { .. } => TextStyle { color: cx.theme().colors().editor_foreground, font_family: settings.buffer_font.family.clone(), font_features: settings.buffer_font.features.clone(), @@ -22972,11 +22980,11 @@ impl Render for Editor { text_style.refine(text_style_refinement) } - let background = match self.mode { - EditorMode::SingleLine => cx.theme().system().transparent, - EditorMode::AutoHeight { .. } => cx.theme().system().transparent, - EditorMode::Full { .. } => cx.theme().colors().editor_background, - EditorMode::Minimap { .. } => cx.theme().colors().editor_background.opacity(0.7), + let background = match self.display_mode { + EditorDisplayMode::SingleLine => cx.theme().system().transparent, + EditorDisplayMode::AutoHeight { .. } => cx.theme().system().transparent, + EditorDisplayMode::Full { .. } => cx.theme().colors().editor_background, + EditorDisplayMode::Minimap { .. } => cx.theme().colors().editor_background.opacity(0.7), }; EditorElement::new( @@ -23661,7 +23669,7 @@ impl BreakpointPromptEditor { let prompt = cx.new(|cx| { let mut prompt = Editor::new( - EditorMode::AutoHeight { + EditorDisplayMode::AutoHeight { min_lines: 1, max_lines: Some(Self::MAX_LINES as usize), }, diff --git a/crates/editor/src/editor_tests.rs b/crates/editor/src/editor_tests.rs index 96261fdb2c..9601c70d83 100644 --- a/crates/editor/src/editor_tests.rs +++ b/crates/editor/src/editor_tests.rs @@ -10075,7 +10075,7 @@ async fn test_multibuffer_format_during_save(cx: &mut TestAppContext) { }); let multi_buffer_editor = cx.new_window_entity(|window, cx| { Editor::new( - EditorMode::full(), + EditorDisplayMode::full(), multi_buffer, Some(project.clone()), window, @@ -10252,7 +10252,7 @@ async fn test_autosave_with_dirty_buffers(cx: &mut TestAppContext) { let editor = cx.new_window_entity(|window, cx| { Editor::new( - EditorMode::full(), + EditorDisplayMode::full(), multi_buffer, Some(project.clone()), window, @@ -12646,7 +12646,7 @@ async fn test_completion_in_multibuffer_with_replace_range(cx: &mut TestAppConte .update(cx, |_, window, cx| { cx.new(|cx| { Editor::new( - EditorMode::Full { + EditorDisplayMode::Full { scale_ui_elements_with_buffer_font_size: false, show_active_line_background: false, sized_by_content: false, @@ -17433,7 +17433,7 @@ async fn test_multibuffer_in_navigation_history(cx: &mut TestAppContext) { let cx = &mut VisualTestContext::from_window(*workspace.deref(), cx); let multi_buffer_editor = cx.new_window_entity(|window, cx| { Editor::new( - EditorMode::full(), + EditorDisplayMode::full(), multi_buffer, Some(project.clone()), window, @@ -17900,8 +17900,9 @@ async fn test_toggle_diff_expand_in_multi_buffer(cx: &mut TestAppContext) { multibuffer }); - let editor = - cx.add_window(|window, cx| Editor::new(EditorMode::full(), multi_buffer, None, window, cx)); + let editor = cx.add_window(|window, cx| { + Editor::new(EditorDisplayMode::full(), multi_buffer, None, window, cx) + }); editor .update(cx, |editor, _window, cx| { for (buffer, diff_base) in [ @@ -18011,8 +18012,9 @@ async fn test_expand_diff_hunk_at_excerpt_boundary(cx: &mut TestAppContext) { multibuffer }); - let editor = - cx.add_window(|window, cx| Editor::new(EditorMode::full(), multi_buffer, None, window, cx)); + let editor = cx.add_window(|window, cx| { + Editor::new(EditorDisplayMode::full(), multi_buffer, None, window, cx) + }); editor .update(cx, |editor, _window, cx| { let diff = cx.new(|cx| BufferDiff::new_with_base_text(base, &buffer, cx)); @@ -19693,7 +19695,13 @@ async fn test_display_diff_hunks(cx: &mut TestAppContext) { }); let editor = cx.add_window(|window, cx| { - Editor::new(EditorMode::full(), multibuffer, Some(project), window, cx) + Editor::new( + EditorDisplayMode::full(), + multibuffer, + Some(project), + window, + cx, + ) }); cx.run_until_parked(); @@ -20205,7 +20213,7 @@ async fn test_find_enclosing_node_with_task(cx: &mut TestAppContext) { let editor = cx.new_window_entity(|window, cx| { Editor::new( - EditorMode::full(), + EditorDisplayMode::full(), multi_buffer, Some(project.clone()), window, @@ -20332,7 +20340,7 @@ async fn test_folding_buffers(cx: &mut TestAppContext) { }); let multi_buffer_editor = cx.new_window_entity(|window, cx| { Editor::new( - EditorMode::full(), + EditorDisplayMode::full(), multi_buffer.clone(), Some(project.clone()), window, @@ -20489,7 +20497,7 @@ async fn test_folding_buffers_with_one_excerpt(cx: &mut TestAppContext) { let multi_buffer_editor = cx.new_window_entity(|window, cx| { Editor::new( - EditorMode::full(), + EditorDisplayMode::full(), multi_buffer, Some(project.clone()), window, @@ -20607,7 +20615,7 @@ async fn test_folding_buffer_when_multibuffer_has_only_one_excerpt(cx: &mut Test }); let multi_buffer_editor = cx.new_window_entity(|window, cx| { Editor::new( - EditorMode::full(), + EditorDisplayMode::full(), multi_buffer, Some(project.clone()), window, @@ -20659,7 +20667,13 @@ async fn test_multi_buffer_navigation_with_folded_buffers(cx: &mut TestAppContex ], cx, ); - let mut editor = Editor::new(EditorMode::full(), multi_buffer.clone(), None, window, cx); + let mut editor = Editor::new( + EditorDisplayMode::full(), + multi_buffer.clone(), + None, + window, + cx, + ); let buffer_ids = multi_buffer.read(cx).excerpt_buffer_ids(); // fold all but the second buffer, so that we test navigating between two @@ -20971,7 +20985,7 @@ async fn assert_highlighted_edits( ) { let window = cx.add_window(|window, cx| { let buffer = MultiBuffer::build_simple(text, cx); - Editor::new(EditorMode::full(), buffer, None, window, cx) + Editor::new(EditorDisplayMode::full(), buffer, None, window, cx) }); let cx = &mut VisualTestContext::from_window(*window, cx); @@ -21131,7 +21145,7 @@ async fn test_breakpoint_toggling(cx: &mut TestAppContext) { let (editor, cx) = cx.add_window_view(|window, cx| { Editor::new( - EditorMode::full(), + EditorDisplayMode::full(), MultiBuffer::build_from_buffer(buffer, cx), Some(project.clone()), window, @@ -21245,7 +21259,7 @@ async fn test_log_breakpoint_editing(cx: &mut TestAppContext) { let (editor, cx) = cx.add_window_view(|window, cx| { Editor::new( - EditorMode::full(), + EditorDisplayMode::full(), MultiBuffer::build_from_buffer(buffer, cx), Some(project.clone()), window, @@ -21415,7 +21429,7 @@ async fn test_breakpoint_enabling_and_disabling(cx: &mut TestAppContext) { let (editor, cx) = cx.add_window_view(|window, cx| { Editor::new( - EditorMode::full(), + EditorDisplayMode::full(), MultiBuffer::build_from_buffer(buffer, cx), Some(project.clone()), window, @@ -22373,7 +22387,7 @@ async fn test_hide_mouse_context_menu_on_modal_opened(cx: &mut TestAppContext) { let cx = &mut VisualTestContext::from_window(*workspace.deref(), cx); let editor = cx.new_window_entity(|window, cx| { Editor::new( - EditorMode::full(), + EditorDisplayMode::full(), buffer, Some(project.clone()), window, diff --git a/crates/editor/src/element.rs b/crates/editor/src/element.rs index 797b0d6634..7adbff2629 100644 --- a/crates/editor/src/element.rs +++ b/crates/editor/src/element.rs @@ -3,7 +3,7 @@ use crate::{ CodeActionSource, ColumnarMode, ConflictsOurs, ConflictsOursMarker, ConflictsOuter, ConflictsTheirs, ConflictsTheirsMarker, ContextMenuPlacement, CursorShape, CustomBlockId, DisplayDiffHunk, DisplayPoint, DisplayRow, DocumentHighlightRead, DocumentHighlightWrite, - EditDisplayMode, EditPrediction, Editor, EditorMode, EditorSettings, EditorSnapshot, + EditDisplayMode, EditPrediction, Editor, EditorDisplayMode, EditorSettings, EditorSnapshot, EditorStyle, FILE_HEADER_HEIGHT, FocusedBlock, GutterDimensions, HalfPageDown, HalfPageUp, HandleInput, HoveredCursor, InlayHintRefreshReason, JumpData, LineDown, LineHighlight, LineUp, MAX_LINE_LEN, MINIMAP_FONT_SIZE, MULTI_BUFFER_EXCERPT_HEADER_HEIGHT, OpenExcerpts, PageDown, @@ -1816,7 +1816,7 @@ impl EditorElement { } } - if !snapshot.mode.is_full() + if !snapshot.display_mode.is_full() || minimap_width.is_zero() || matches!( minimap_settings.show, @@ -3212,7 +3212,7 @@ impl EditorElement { cx: &mut App, ) -> Vec> { let include_fold_statuses = EditorSettings::get_global(cx).gutter.folds - && snapshot.mode.is_full() + && snapshot.display_mode.is_full() && self.editor.read(cx).is_singleton(cx); if include_fold_statuses { row_infos @@ -3314,7 +3314,7 @@ impl EditorElement { style, MAX_LINE_LEN, rows.len(), - &snapshot.mode, + &snapshot.display_mode, editor_width, is_row_soft_wrapped, window, @@ -5282,14 +5282,14 @@ impl EditorElement { if matches!( layout.mode, - EditorMode::Full { .. } | EditorMode::Minimap { .. } + EditorDisplayMode::Full { .. } | EditorDisplayMode::Minimap { .. } ) { let show_active_line_background = match layout.mode { - EditorMode::Full { + EditorDisplayMode::Full { show_active_line_background, .. } => show_active_line_background, - EditorMode::Minimap { .. } => true, + EditorDisplayMode::Minimap { .. } => true, _ => false, }; let mut active_rows = layout.active_rows.iter().peekable(); @@ -7311,7 +7311,7 @@ impl LineWithInvisibles { editor_style: &EditorStyle, max_line_len: usize, max_line_count: usize, - editor_mode: &EditorMode, + editor_mode: &EditorDisplayMode, text_width: Pixels, is_row_soft_wrapped: impl Copy + Fn(usize) -> bool, window: &mut Window, @@ -7839,12 +7839,12 @@ impl EditorElement { /// /// This allows UI elements to scale based on the `buffer_font_size`. fn rem_size(&self, cx: &mut App) -> Option { - match self.editor.read(cx).mode { - EditorMode::Full { + match self.editor.read(cx).display_mode { + EditorDisplayMode::Full { scale_ui_elements_with_buffer_font_size: true, .. } - | EditorMode::Minimap { .. } => { + | EditorDisplayMode::Minimap { .. } => { let buffer_font_size = self.style.text.font_size; match buffer_font_size { AbsoluteLength::Pixels(pixels) => { @@ -7877,7 +7877,7 @@ impl EditorElement { } fn editor_with_selections(&self, cx: &App) -> Option> { - if let EditorMode::Minimap { parent } = self.editor.read(cx).mode() { + if let EditorDisplayMode::Minimap { parent } = self.editor.read(cx).display_mode() { parent.upgrade() } else { Some(self.editor.clone()) @@ -7909,8 +7909,8 @@ impl Element for EditorElement { self.editor.update(cx, |editor, cx| { editor.set_style(self.style.clone(), window, cx); - let layout_id = match editor.mode { - EditorMode::SingleLine => { + let layout_id = match editor.display_mode { + EditorDisplayMode::SingleLine => { let rem_size = window.rem_size(); let height = self.style.text.line_height_in_pixels(rem_size); let mut style = Style::default(); @@ -7918,7 +7918,7 @@ impl Element for EditorElement { style.size.width = relative(1.).into(); window.request_layout(style, None, cx) } - EditorMode::AutoHeight { + EditorDisplayMode::AutoHeight { min_lines, max_lines, } => { @@ -7945,13 +7945,13 @@ impl Element for EditorElement { }, ) } - EditorMode::Minimap { .. } => { + EditorDisplayMode::Minimap { .. } => { let mut style = Style::default(); style.size.width = relative(1.).into(); style.size.height = relative(1.).into(); window.request_layout(style, None, cx) } - EditorMode::Full { + EditorDisplayMode::Full { sized_by_content, .. } => { let mut style = Style::default(); @@ -7990,7 +7990,7 @@ impl Element for EditorElement { ..Default::default() }; - let is_minimap = self.editor.read(cx).mode.is_minimap(); + let is_minimap = self.editor.read(cx).display_mode.is_minimap(); if !is_minimap { let focus_handle = self.editor.focus_handle(cx); @@ -8065,8 +8065,9 @@ impl Element for EditorElement { editor.set_visible_column_count(editor_width / em_advance); if matches!( - editor.mode, - EditorMode::AutoHeight { .. } | EditorMode::Minimap { .. } + editor.display_mode, + EditorDisplayMode::AutoHeight { .. } + | EditorDisplayMode::Minimap { .. } ) { snapshot } else { @@ -8112,10 +8113,10 @@ impl Element for EditorElement { // The max scroll position for the top of the window let max_scroll_top = if matches!( - snapshot.mode, - EditorMode::SingleLine - | EditorMode::AutoHeight { .. } - | EditorMode::Full { + snapshot.display_mode, + EditorDisplayMode::SingleLine + | EditorDisplayMode::AutoHeight { .. } + | EditorDisplayMode::Full { sized_by_content: true, .. } @@ -8980,7 +8981,7 @@ impl Element for EditorElement { None, ); - let mode = snapshot.mode.clone(); + let mode = snapshot.display_mode.clone(); let (diff_hunk_controls, diff_hunk_control_bounds) = if is_read_only { (vec![], vec![]) @@ -9209,7 +9210,7 @@ pub struct EditorLayout { content_origin: gpui::Point, scrollbars_layout: Option, minimap: Option, - mode: EditorMode, + mode: EditorDisplayMode, wrap_guides: SmallVec<[(Pixels, bool); 2]>, indent_guides: Option>, visible_display_row_range: Range, @@ -9788,7 +9789,7 @@ pub fn layout_line( style, MAX_LINE_LEN, 1, - &snapshot.mode, + &snapshot.display_mode, text_width, is_row_soft_wrapped, window, @@ -10197,7 +10198,7 @@ mod tests { let window = cx.add_window(|window, cx| { let buffer = MultiBuffer::build_simple(&"a ".to_string().repeat(100), cx); let mut editor = Editor::new( - EditorMode::AutoHeight { + EditorDisplayMode::AutoHeight { min_lines: 1, max_lines: None, }, @@ -10233,7 +10234,7 @@ mod tests { let window = cx.add_window(|window, cx| { let buffer = MultiBuffer::build_simple(&"a ".to_string().repeat(100), cx); - let mut editor = Editor::new(EditorMode::full(), buffer, None, window, cx); + let mut editor = Editor::new(EditorDisplayMode::full(), buffer, None, window, cx); editor.set_soft_wrap_mode(language_settings::SoftWrap::EditorWidth, cx); editor }); @@ -10260,7 +10261,7 @@ mod tests { init_test(cx, |_| {}); let window = cx.add_window(|window, cx| { let buffer = MultiBuffer::build_simple(&sample_text(6, 6, 'a'), cx); - Editor::new(EditorMode::full(), buffer, None, window, cx) + Editor::new(EditorDisplayMode::full(), buffer, None, window, cx) }); let editor = window.root(cx).unwrap(); @@ -10361,7 +10362,7 @@ mod tests { let window = cx.add_window(|window, cx| { let buffer = MultiBuffer::build_simple(&(sample_text(6, 6, 'a') + "\n"), cx); - Editor::new(EditorMode::full(), buffer, None, window, cx) + Editor::new(EditorDisplayMode::full(), buffer, None, window, cx) }); let cx = &mut VisualTestContext::from_window(*window, cx); let editor = window.root(cx).unwrap(); @@ -10432,7 +10433,7 @@ mod tests { let window = cx.add_window(|window, cx| { let buffer = MultiBuffer::build_simple("", cx); - Editor::new(EditorMode::full(), buffer, None, window, cx) + Editor::new(EditorDisplayMode::full(), buffer, None, window, cx) }); let cx = &mut VisualTestContext::from_window(*window, cx); let editor = window.root(cx).unwrap(); @@ -10518,7 +10519,7 @@ mod tests { let actual_invisibles = collect_invisibles_from_new_editor( cx, - EditorMode::full(), + EditorDisplayMode::full(), input_text, px(500.0), show_line_numbers, @@ -10536,8 +10537,8 @@ mod tests { }); for editor_mode_without_invisibles in [ - EditorMode::SingleLine, - EditorMode::AutoHeight { + EditorDisplayMode::SingleLine, + EditorDisplayMode::AutoHeight { min_lines: 1, max_lines: Some(100), }, @@ -10615,7 +10616,7 @@ mod tests { let actual_invisibles = collect_invisibles_from_new_editor( cx, - EditorMode::full(), + EditorDisplayMode::full(), &input_text, px(editor_width), show_line_numbers, @@ -10654,7 +10655,7 @@ mod tests { fn collect_invisibles_from_new_editor( cx: &mut TestAppContext, - editor_mode: EditorMode, + editor_mode: EditorDisplayMode, input_text: &str, editor_width: Pixels, show_line_numbers: bool, diff --git a/crates/editor/src/items.rs b/crates/editor/src/items.rs index afc5767de0..a3aa255819 100644 --- a/crates/editor/src/items.rs +++ b/crates/editor/src/items.rs @@ -1267,7 +1267,7 @@ impl SerializableItem for Editor { window: &mut Window, cx: &mut Context, ) -> Option>> { - if self.mode.is_minimap() { + if self.display_mode.is_minimap() { return None; } let mut serialize_dirty_buffers = self.serialize_dirty_buffers; @@ -1424,7 +1424,7 @@ impl Editor { cx: &mut Context, write: impl for<'a> FnOnce(&'a mut RestorationData) + 'static, ) { - if self.mode.is_minimap() || !WorkspaceSettings::get(None, cx).restore_on_file_reopen { + if self.display_mode.is_minimap() || !WorkspaceSettings::get(None, cx).restore_on_file_reopen { return; } diff --git a/crates/editor/src/lsp_colors.rs b/crates/editor/src/lsp_colors.rs index 29eb9f249a..967e32458d 100644 --- a/crates/editor/src/lsp_colors.rs +++ b/crates/editor/src/lsp_colors.rs @@ -150,7 +150,7 @@ impl Editor { _: &Window, cx: &mut Context, ) { - if !self.mode().is_full() { + if !self.display_mode().is_full() { return; } let Some(project) = self.project.clone() else { diff --git a/crates/editor/src/mouse_context_menu.rs b/crates/editor/src/mouse_context_menu.rs index 3bc334c54c..0369ea00da 100644 --- a/crates/editor/src/mouse_context_menu.rs +++ b/crates/editor/src/mouse_context_menu.rs @@ -153,7 +153,7 @@ pub fn deploy_context_menu( } // Don't show context menu for inline editors - if !editor.mode().is_full() { + if !editor.display_mode().is_full() { return; } diff --git a/crates/editor/src/scroll.rs b/crates/editor/src/scroll.rs index 8231448618..b7e2e0e398 100644 --- a/crates/editor/src/scroll.rs +++ b/crates/editor/src/scroll.rs @@ -4,7 +4,7 @@ pub(crate) mod scroll_amount; use crate::editor_settings::ScrollBeyondLastLine; use crate::{ - Anchor, DisplayPoint, DisplayRow, Editor, EditorEvent, EditorMode, EditorSettings, + Anchor, DisplayPoint, DisplayRow, Editor, EditorDisplayMode, EditorEvent, EditorSettings, InlayHintRefreshReason, MultiBufferSnapshot, RowExt, ToPoint, display_map::{DisplaySnapshot, ToDisplayPoint}, hover_popover::hide_hover, @@ -675,7 +675,7 @@ impl Editor { window: &mut Window, cx: &mut Context, ) { - if matches!(self.mode, EditorMode::SingleLine) { + if matches!(self.display_mode, EditorDisplayMode::SingleLine) { cx.propagate(); return; } diff --git a/crates/editor/src/scroll/actions.rs b/crates/editor/src/scroll/actions.rs index f8104665f9..90055bb54f 100644 --- a/crates/editor/src/scroll/actions.rs +++ b/crates/editor/src/scroll/actions.rs @@ -1,6 +1,6 @@ use super::Axis; use crate::{ - Autoscroll, Editor, EditorMode, NextScreen, NextScrollCursorCenterTopBottom, + Autoscroll, Editor, EditorDisplayMode, NextScreen, NextScrollCursorCenterTopBottom, SCROLL_CENTER_TOP_BOTTOM_DEBOUNCE_TIMEOUT, ScrollCursorBottom, ScrollCursorCenter, ScrollCursorCenterTopBottom, ScrollCursorTop, display_map::DisplayRow, }; @@ -16,7 +16,7 @@ impl Editor { return; } - if matches!(self.mode, EditorMode::SingleLine) { + if matches!(self.display_mode, EditorDisplayMode::SingleLine) { cx.propagate(); return; } diff --git a/crates/editor/src/scroll/autoscroll.rs b/crates/editor/src/scroll/autoscroll.rs index 057d622903..712e22250e 100644 --- a/crates/editor/src/scroll/autoscroll.rs +++ b/crates/editor/src/scroll/autoscroll.rs @@ -1,5 +1,5 @@ use crate::{ - DisplayRow, Editor, EditorMode, LineWithInvisibles, RowExt, SelectionEffects, + DisplayRow, Editor, EditorDisplayMode, LineWithInvisibles, RowExt, SelectionEffects, display_map::ToDisplayPoint, scroll::WasScrolled, }; use gpui::{Bounds, Context, Pixels, Window, px}; @@ -184,7 +184,7 @@ impl Editor { } } - let margin = if matches!(self.mode, EditorMode::AutoHeight { .. }) { + let margin = if matches!(self.display_mode, EditorDisplayMode::AutoHeight { .. }) { 0. } else { ((visible_lines - (target_bottom - target_top)) / 2.0).floor() diff --git a/crates/editor/src/test.rs b/crates/editor/src/test.rs index 960fecf59a..f1b04328a2 100644 --- a/crates/editor/src/test.rs +++ b/crates/editor/src/test.rs @@ -5,7 +5,7 @@ use std::{rc::Rc, sync::LazyLock}; pub use crate::rust_analyzer_ext::expand_macro_recursively; use crate::{ - DisplayPoint, Editor, EditorMode, FoldPlaceholder, MultiBuffer, SelectionEffects, + DisplayPoint, Editor, EditorDisplayMode, FoldPlaceholder, MultiBuffer, SelectionEffects, display_map::{ Block, BlockPlacement, CustomBlockId, DisplayMap, DisplayRow, DisplaySnapshot, ToDisplayPoint, @@ -121,7 +121,7 @@ pub(crate) fn build_editor( window: &mut Window, cx: &mut Context, ) -> Editor { - Editor::new(EditorMode::full(), buffer, None, window, cx) + Editor::new(EditorDisplayMode::full(), buffer, None, window, cx) } pub(crate) fn build_editor_with_project( @@ -130,7 +130,7 @@ pub(crate) fn build_editor_with_project( window: &mut Window, cx: &mut Context, ) -> Editor { - Editor::new(EditorMode::full(), buffer, Some(project), window, cx) + Editor::new(EditorDisplayMode::full(), buffer, Some(project), window, cx) } #[derive(Default)] diff --git a/crates/git_ui/src/conflict_view.rs b/crates/git_ui/src/conflict_view.rs index ee1b82920d..590ada27f6 100644 --- a/crates/git_ui/src/conflict_view.rs +++ b/crates/git_ui/src/conflict_view.rs @@ -44,7 +44,7 @@ impl editor::Addon for ConflictAddon { pub fn register_editor(editor: &mut Editor, buffer: Entity, cx: &mut Context) { // Only show conflict UI for singletons and in the project diff. - if !editor.mode().is_full() + if !editor.display_mode().is_full() || (!editor.buffer().read(cx).is_singleton() && !editor.buffer().read(cx).all_diff_hunks_expanded()) { diff --git a/crates/git_ui/src/git_panel.rs b/crates/git_ui/src/git_panel.rs index 958a609a09..1b3aa0d222 100644 --- a/crates/git_ui/src/git_panel.rs +++ b/crates/git_ui/src/git_panel.rs @@ -14,7 +14,7 @@ use anyhow::Context as _; use askpass::AskPassDelegate; use db::kvp::KEY_VALUE_STORE; use editor::{ - Editor, EditorElement, EditorMode, EditorSettings, MultiBuffer, ShowScrollbar, + Editor, EditorDisplayMode, EditorElement, EditorSettings, MultiBuffer, ShowScrollbar, scroll::ScrollbarAutoHide, }; use futures::StreamExt as _; @@ -394,7 +394,7 @@ pub(crate) fn commit_message_editor( let buffer = cx.new(|cx| MultiBuffer::singleton(commit_message_buffer, cx)); let max_lines = if in_panel { MAX_PANEL_EDITOR_LINES } else { 18 }; let mut commit_editor = Editor::new( - EditorMode::AutoHeight { + EditorDisplayMode::AutoHeight { min_lines: 1, max_lines: Some(max_lines), }, diff --git a/crates/go_to_line/src/cursor_position.rs b/crates/go_to_line/src/cursor_position.rs index e60a3651aa..83c372b4c3 100644 --- a/crates/go_to_line/src/cursor_position.rs +++ b/crates/go_to_line/src/cursor_position.rs @@ -104,14 +104,14 @@ impl CursorPosition { cursor_position.update(cx, |cursor_position, cx| { cursor_position.selected_count = SelectionStats::default(); cursor_position.selected_count.selections = editor.selections.count(); - match editor.mode() { - editor::EditorMode::AutoHeight { .. } - | editor::EditorMode::SingleLine - | editor::EditorMode::Minimap { .. } => { + match editor.display_mode() { + editor::EditorDisplayMode::AutoHeight { .. } + | editor::EditorDisplayMode::SingleLine + | editor::EditorDisplayMode::Minimap { .. } => { cursor_position.position = None; cursor_position.context = None; } - editor::EditorMode::Full { .. } => { + editor::EditorDisplayMode::Full { .. } => { let mut last_selection = None::>; let snapshot = editor.buffer().read(cx).snapshot(cx); if snapshot.excerpts().count() > 0 { diff --git a/crates/inspector_ui/src/div_inspector.rs b/crates/inspector_ui/src/div_inspector.rs index 0c2b16b9f4..ac57c83f10 100644 --- a/crates/inspector_ui/src/div_inspector.rs +++ b/crates/inspector_ui/src/div_inspector.rs @@ -1,6 +1,6 @@ use anyhow::{Result, anyhow}; use editor::{ - Bias, CompletionProvider, Editor, EditorEvent, EditorMode, ExcerptId, MinimapVisibility, + Bias, CompletionProvider, Editor, EditorDisplayMode, EditorEvent, ExcerptId, MinimapVisibility, MultiBuffer, }; use fuzzy::StringMatch; @@ -483,7 +483,7 @@ impl DivInspector { cx.new(|cx| { let multi_buffer = cx.new(|cx| MultiBuffer::singleton(buffer, cx)); let mut editor = Editor::new( - EditorMode::full(), + EditorDisplayMode::full(), multi_buffer, Some(self.project.clone()), window, diff --git a/crates/outline/src/outline.rs b/crates/outline/src/outline.rs index 8c5e78d77b..9beb62a0a0 100644 --- a/crates/outline/src/outline.rs +++ b/crates/outline/src/outline.rs @@ -88,7 +88,7 @@ impl Render for OutlineView { impl OutlineView { fn register(editor: &mut Editor, _: Option<&mut Window>, cx: &mut Context) { - if editor.mode().is_full() { + if editor.display_mode().is_full() { let handle = cx.entity().downgrade(); editor .register_action(move |action, window, cx| { diff --git a/crates/outline_panel/src/outline_panel.rs b/crates/outline_panel/src/outline_panel.rs index 10698cead8..9593d60dd1 100644 --- a/crates/outline_panel/src/outline_panel.rs +++ b/crates/outline_panel/src/outline_panel.rs @@ -4949,7 +4949,7 @@ fn workspace_active_editor( let active_item = workspace.active_item(cx)?; let active_editor = active_item .act_as::(cx) - .filter(|editor| editor.read(cx).mode().is_full())?; + .filter(|editor| editor.read(cx).display_mode().is_full())?; Some((active_item, active_editor)) } diff --git a/crates/repl/src/notebook/cell.rs b/crates/repl/src/notebook/cell.rs index 87b8e1d55a..d39efd7abf 100644 --- a/crates/repl/src/notebook/cell.rs +++ b/crates/repl/src/notebook/cell.rs @@ -1,7 +1,7 @@ #![allow(unused, dead_code)] use std::sync::Arc; -use editor::{Editor, EditorMode, MultiBuffer}; +use editor::{Editor, EditorDisplayMode, MultiBuffer}; use futures::future::Shared; use gpui::{ App, Entity, Hsla, RetainAllImageCache, Task, TextStyleRefinement, image_cache, prelude::*, @@ -177,7 +177,7 @@ impl Cell { let editor_view = cx.new(|cx| { let mut editor = Editor::new( - EditorMode::AutoHeight { + EditorDisplayMode::AutoHeight { min_lines: 1, max_lines: Some(1024), }, diff --git a/crates/settings_ui/src/keybindings.rs b/crates/settings_ui/src/keybindings.rs index 9c76725972..49dbfcf0bd 100644 --- a/crates/settings_ui/src/keybindings.rs +++ b/crates/settings_ui/src/keybindings.rs @@ -2699,7 +2699,7 @@ impl ActionArgumentsEditor { let editor = cx.new_window_entity(|window, cx| { let multi_buffer = cx.new(|cx| editor::MultiBuffer::singleton(buffer, cx)); let mut editor = Editor::new( - editor::EditorMode::Full { + editor::EditorDisplayMode::Full { scale_ui_elements_with_buffer_font_size: true, show_active_line_background: false, sized_by_content: true, diff --git a/crates/vim/src/test.rs b/crates/vim/src/test.rs index ce04b621cb..a2136de2bc 100644 --- a/crates/vim/src/test.rs +++ b/crates/vim/src/test.rs @@ -7,7 +7,7 @@ use std::time::Duration; use collections::HashMap; use command_palette::CommandPalette; use editor::{ - AnchorRangeExt, DisplayPoint, Editor, EditorMode, MultiBuffer, actions::DeleteLine, + AnchorRangeExt, DisplayPoint, Editor, EditorDisplayMode, MultiBuffer, actions::DeleteLine, display_map::DisplayRow, test::editor_test_context::EditorTestContext, }; use futures::StreamExt; @@ -1784,7 +1784,13 @@ async fn test_folded_multibuffer_excerpts(cx: &mut gpui::TestAppContext) { ], cx, ); - let mut editor = Editor::new(EditorMode::full(), multi_buffer.clone(), None, window, cx); + let mut editor = Editor::new( + EditorDisplayMode::full(), + multi_buffer.clone(), + None, + window, + cx, + ); let buffer_ids = multi_buffer.read(cx).excerpt_buffer_ids(); // fold all but the second buffer, so that we test navigating between two diff --git a/crates/vim/src/vim.rs b/crates/vim/src/vim.rs index bc275ac688..4b89539f50 100644 --- a/crates/vim/src/vim.rs +++ b/crates/vim/src/vim.rs @@ -1222,7 +1222,7 @@ impl Vim { editor.selections.newest::(cx).is_empty() }); let editor = editor.read(cx); - let editor_mode = editor.mode(); + let editor_mode = editor.display_mode(); if editor_mode.is_full() && !newest_selection_empty diff --git a/crates/zed/src/zed/edit_prediction_registry.rs b/crates/zed/src/zed/edit_prediction_registry.rs index a9abd9bc74..77d7022483 100644 --- a/crates/zed/src/zed/edit_prediction_registry.rs +++ b/crates/zed/src/zed/edit_prediction_registry.rs @@ -18,7 +18,7 @@ pub fn init(client: Arc, user_store: Entity, cx: &mut App) { let client = client.clone(); let user_store = user_store.clone(); move |editor: &mut Editor, window, cx: &mut Context| { - if !editor.mode().is_full() { + if !editor.display_mode().is_full() { return; } diff --git a/crates/zed/src/zed/quick_action_bar.rs b/crates/zed/src/zed/quick_action_bar.rs index 75015eb5f2..3da3db6b39 100644 --- a/crates/zed/src/zed/quick_action_bar.rs +++ b/crates/zed/src/zed/quick_action_bar.rs @@ -119,7 +119,7 @@ impl Render for QuickActionBar { let selection_menu_enabled = editor_value.selection_menu_enabled(cx); let inlay_hints_enabled = editor_value.inlay_hints_enabled(); let inline_values_enabled = editor_value.inline_values_enabled(); - let supports_diagnostics = editor_value.mode().is_full(); + let supports_diagnostics = editor_value.display_mode().is_full(); let diagnostics_enabled = editor_value.diagnostics_max_severity != DiagnosticSeverity::Off; let supports_inline_diagnostics = editor_value.inline_diagnostics_enabled(); let inline_diagnostics_enabled = editor_value.show_inline_diagnostics(); From fd0316f7d1e12067054266412773fe5f9b3d8946 Mon Sep 17 00:00:00 2001 From: Smit Barmase Date: Fri, 22 Aug 2025 15:23:27 +0530 Subject: [PATCH 05/15] extend eidtor mode Co-authored-by: Oleksiy Syvokon --- crates/agent_settings/src/agent_settings.rs | 11 +- crates/agent_ui/src/acp/message_editor.rs | 10 +- crates/agent_ui/src/message_editor.rs | 6 +- crates/debugger_ui/Cargo.toml | 1 + .../src/session/running/console.rs | 3 +- crates/editor/src/editor.rs | 4 +- crates/git_ui/src/git_panel.rs | 2 +- crates/repl/src/repl_sessions_ui.rs | 3 +- crates/rules_library/src/rules_library.rs | 2 +- crates/vim/src/state.rs | 45 +-- crates/vim/src/vim.rs | 303 ++++++++---------- .../vim_mode_setting/src/vim_mode_setting.rs | 98 +++++- 12 files changed, 261 insertions(+), 227 deletions(-) diff --git a/crates/agent_settings/src/agent_settings.rs b/crates/agent_settings/src/agent_settings.rs index 88ef505053..2bc7962267 100644 --- a/crates/agent_settings/src/agent_settings.rs +++ b/crates/agent_settings/src/agent_settings.rs @@ -50,14 +50,17 @@ pub enum NotifyWhenAgentWaiting { #[derive(Copy, Clone, Debug, PartialEq, Eq, Serialize, Deserialize, JsonSchema, Default)] pub enum AgentEditorMode { - Vim, - VimInsert, - Helix, - Default, + EditorModeOverride(EditorMode), #[default] Inherit, } +impl From for AgentEditorMode { + fn from(b: EditorMode) -> Self { + AgentEditorMode::EditorModeOverride(b) + } +} + #[derive(Default, Clone, Debug)] pub struct AgentSettings { pub enabled: bool, diff --git a/crates/agent_ui/src/acp/message_editor.rs b/crates/agent_ui/src/acp/message_editor.rs index dda0f9f04b..d3bacf2227 100644 --- a/crates/agent_ui/src/acp/message_editor.rs +++ b/crates/agent_ui/src/acp/message_editor.rs @@ -112,6 +112,14 @@ impl MessageEditor { range: Cell::new(None), }); let mention_set = MentionSet::default(); + + let editor_mode = match settings.editor_mode { + agent_settings::AgentEditorMode::EditorModeOverride(mode) => mode, + agent_settings::AgentEditorMode::Inherit => { + vim_mode_setting::EditorModeSetting::get_global(cx).0 + } + }; + let editor = cx.new(|cx| { let buffer = cx.new(|cx| Buffer::local("", cx).with_language(Arc::new(language), cx)); let buffer = cx.new(|cx| MultiBuffer::singleton(buffer, cx)); @@ -120,7 +128,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(true); + editor.set_use_modal_editing(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/agent_ui/src/message_editor.rs b/crates/agent_ui/src/message_editor.rs index 7f0254564f..a5f1830e97 100644 --- a/crates/agent_ui/src/message_editor.rs +++ b/crates/agent_ui/src/message_editor.rs @@ -117,10 +117,7 @@ pub(crate) fn create_editor( let settings = agent_settings::AgentSettings::get_global(cx); let editor_mode = match settings.editor_mode { - agent_settings::AgentEditorMode::Vim => vim_mode_setting::EditorMode::Vim, - agent_settings::AgentEditorMode::VimInsert => vim_mode_setting::EditorMode::VimInsert, - agent_settings::AgentEditorMode::Helix => vim_mode_setting::EditorMode::Helix, - agent_settings::AgentEditorMode::Default => vim_mode_setting::EditorMode::Default, + agent_settings::AgentEditorMode::EditorModeOverride(mode) => mode, agent_settings::AgentEditorMode::Inherit => { vim_mode_setting::EditorModeSetting::get_global(cx).0 } @@ -139,7 +136,6 @@ pub(crate) fn create_editor( editor.set_placeholder_text("Message the agent – @ to include context", cx); editor.set_show_indent_guides(false, cx); editor.set_soft_wrap(); - editor.set_use_modal_editing(true); editor.set_default_editor_mode(editor_mode); editor.set_context_menu_options(ContextMenuOptions { min_entries_visible: 12, diff --git a/crates/debugger_ui/Cargo.toml b/crates/debugger_ui/Cargo.toml index df4125860f..2543102dd8 100644 --- a/crates/debugger_ui/Cargo.toml +++ b/crates/debugger_ui/Cargo.toml @@ -76,6 +76,7 @@ util.workspace = true workspace-hack.workspace = true workspace.workspace = true zed_actions.workspace = true +vim_mode_settings.workspace = true [dev-dependencies] dap = { workspace = true, features = ["test-support"] } diff --git a/crates/debugger_ui/src/session/running/console.rs b/crates/debugger_ui/src/session/running/console.rs index a801cedd26..26c2ad3477 100644 --- a/crates/debugger_ui/src/session/running/console.rs +++ b/crates/debugger_ui/src/session/running/console.rs @@ -26,6 +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; actions!( console, @@ -74,7 +75,7 @@ impl Console { editor.set_show_wrap_guides(false, cx); editor.set_show_indent_guides(false, cx); editor.set_show_edit_predictions(Some(false), window, cx); - editor.set_use_modal_editing(false); + editor.set_default_editor_mode(EditorMode::Default); editor.set_soft_wrap_mode(language::language_settings::SoftWrap::EditorWidth, cx); editor }); diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index 0412ee1764..29e8d26ac7 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -165,7 +165,6 @@ use project::{ }; use rand::{seq::SliceRandom, thread_rng}; use rpc::{ErrorCode, ErrorExt, proto::PeerId}; -use schemars::JsonSchema; use scroll::{Autoscroll, OngoingScroll, ScrollAnchor, ScrollManager, ScrollbarAutoHide}; use selections_collection::{ MutableSelectionsCollection, SelectionsCollection, resolve_selections, @@ -202,7 +201,6 @@ use ui::{ IconSize, Indicator, Key, Tooltip, h_flex, prelude::*, }; use util::{RangeExt, ResultExt, TryFutureExt, maybe, post_inc}; -use vim_mode_setting::EditorModeSetting; use workspace::{ CollaboratorId, Item as WorkspaceItem, ItemId, ItemNavHistory, OpenInTerminal, OpenTerminal, RestoreOnStartupBehavior, SERIALIZATION_THROTTLE_TIME, SplitDirection, TabBarSettings, Toast, @@ -2185,7 +2183,6 @@ impl Editor { collapse_matches: false, workspace: None, input_enabled: !is_minimap, - use_modal_editing: full_mode, read_only: is_minimap, use_autoclose: true, use_auto_surround: true, @@ -22940,6 +22937,7 @@ pub enum EditorEvent { anchor: Anchor, is_deactivate: bool, }, + EditorModeChanged, } impl EventEmitter for Editor {} diff --git a/crates/git_ui/src/git_panel.rs b/crates/git_ui/src/git_panel.rs index 1b3aa0d222..456f043771 100644 --- a/crates/git_ui/src/git_panel.rs +++ b/crates/git_ui/src/git_panel.rs @@ -406,7 +406,7 @@ pub(crate) fn commit_message_editor( commit_editor.set_collaboration_hub(Box::new(project)); commit_editor.set_use_autoclose(false); commit_editor.set_show_gutter(false, cx); - commit_editor.set_use_modal_editing(true); + // commit_editor.set_use_modal_editing(true); TODO commit_editor.set_show_wrap_guides(false, cx); commit_editor.set_show_indent_guides(false, cx); let placeholder = placeholder.unwrap_or("Enter commit message".into()); diff --git a/crates/repl/src/repl_sessions_ui.rs b/crates/repl/src/repl_sessions_ui.rs index 493b8aa950..de7cbf2b0e 100644 --- a/crates/repl/src/repl_sessions_ui.rs +++ b/crates/repl/src/repl_sessions_ui.rs @@ -75,7 +75,8 @@ pub fn init(cx: &mut App) { return; }; - if !editor.use_modal_editing() || !editor.buffer().read(cx).is_singleton() { + if !editor.default_editor_mode().is_modal() || !editor.buffer().read(cx).is_singleton() + { return; } diff --git a/crates/rules_library/src/rules_library.rs b/crates/rules_library/src/rules_library.rs index 5ad3996e78..9bacadfcbf 100644 --- a/crates/rules_library/src/rules_library.rs +++ b/crates/rules_library/src/rules_library.rs @@ -637,7 +637,7 @@ impl RulesLibrary { editor.set_show_gutter(false, cx); editor.set_show_wrap_guides(false, cx); editor.set_show_indent_guides(false, cx); - editor.set_use_modal_editing(false); + editor.set_default_editor_mode(EditorMode::Default); editor.set_current_line_highlight(Some(CurrentLineHighlight::None)); editor.set_completion_provider(Some(make_completion_provider())); if focus { diff --git a/crates/vim/src/state.rs b/crates/vim/src/state.rs index c0176cb12c..9df762e52f 100644 --- a/crates/vim/src/state.rs +++ b/crates/vim/src/state.rs @@ -32,49 +32,10 @@ use ui::{ StyledTypography, Window, h_flex, rems, }; use util::ResultExt; +use vim_mode_setting::ModalMode; use workspace::searchable::Direction; use workspace::{Workspace, WorkspaceDb, WorkspaceId}; -#[derive(Clone, Copy, Debug, PartialEq, Serialize, Deserialize)] -pub enum Mode { - Normal, - Insert, - Replace, - Visual, - VisualLine, - VisualBlock, - HelixNormal, -} - -impl Display for Mode { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self { - Mode::Normal => write!(f, "NORMAL"), - Mode::Insert => write!(f, "INSERT"), - Mode::Replace => write!(f, "REPLACE"), - Mode::Visual => write!(f, "VISUAL"), - Mode::VisualLine => write!(f, "VISUAL LINE"), - Mode::VisualBlock => write!(f, "VISUAL BLOCK"), - Mode::HelixNormal => write!(f, "HELIX NORMAL"), - } - } -} - -impl Mode { - pub fn is_visual(&self) -> bool { - match self { - Self::Visual | Self::VisualLine | Self::VisualBlock => true, - Self::Normal | Self::Insert | Self::Replace | Self::HelixNormal => false, - } - } -} - -impl Default for Mode { - fn default() -> Self { - Self::Normal - } -} - #[derive(Clone, Debug, PartialEq)] pub enum Operator { Change, @@ -976,7 +937,7 @@ pub struct SearchState { pub prior_selections: Vec>, pub prior_operator: Option, - pub prior_mode: Mode, + pub prior_mode: ModalMode, } impl Operator { @@ -1043,7 +1004,7 @@ impl Operator { } } - pub fn is_waiting(&self, mode: Mode) -> bool { + pub fn is_waiting(&self, mode: ModalMode) -> bool { match self { Operator::AddSurrounds { target } => target.is_some() || mode.is_visual(), Operator::FindForward { .. } diff --git a/crates/vim/src/vim.rs b/crates/vim/src/vim.rs index 4b89539f50..984e11b495 100644 --- a/crates/vim/src/vim.rs +++ b/crates/vim/src/vim.rs @@ -40,7 +40,7 @@ use schemars::JsonSchema; use serde::Deserialize; use serde_derive::Serialize; use settings::{Settings, SettingsSources, SettingsStore, update_settings_file}; -use state::{Mode, Operator, RecordedSelection, SearchState, VimGlobals}; +use state::{Operator, RecordedSelection, SearchState, VimGlobals}; use std::{mem, ops::Range, sync::Arc}; use surrounds::SurroundsType; use theme::ThemeSettings; @@ -360,8 +360,8 @@ impl editor::Addon for VimAddon { /// The state pertaining to Vim mode. pub(crate) struct Vim { - pub(crate) mode: Mode, - pub last_mode: Mode, + pub(crate) mode: ModalMode, + pub last_mode: ModalMode, pub temp_mode: bool, pub status_label: Option, pub exit_temporary_mode: bool, @@ -369,11 +369,11 @@ pub(crate) struct Vim { operator_stack: Vec, pub(crate) replacements: Vec<(Range, String)>, - pub(crate) stored_visual_mode: Option<(Mode, Vec)>, + pub(crate) stored_visual_mode: Option<(ModalMode, Vec)>, pub(crate) current_tx: Option, pub(crate) current_anchor: Option>, - pub(crate) undo_modes: HashMap, + pub(crate) undo_modes: HashMap, pub(crate) undo_last_line_tx: Option, selected_register: Option, @@ -407,16 +407,9 @@ impl Vim { pub fn new(window: &mut Window, cx: &mut Context) -> Entity { let editor = cx.entity(); - let mut initial_mode = VimSettings::get_global(cx).default_mode; - if initial_mode == Mode::Normal - && matches!(EditorModeSetting::get_global(cx).0, EditorMode::Helix) - { - initial_mode = Mode::HelixNormal; - } - cx.new(|cx| Vim { - mode: initial_mode, - last_mode: Mode::Normal, + mode: ModalMode::Normal, + last_mode: ModalMode::Normal, temp_mode: false, exit_temporary_mode: false, operator_stack: Vec::new(), @@ -450,56 +443,45 @@ impl Vim { return; }; - if !editor.use_modal_editing() { + if !editor.default_editor_mode().is_modal() { return; } - if editor.default_editor_mode() == EditorMode::Default { - return; - } - - let mut was_enabled = Vim::enabled(cx); let mut was_toggle = VimSettings::get_global(cx).toggle_relative_line_numbers; cx.observe_global_in::(window, move |editor, window, cx| { - let enabled = Vim::enabled(cx); let toggle = VimSettings::get_global(cx).toggle_relative_line_numbers; - if enabled && was_enabled && (toggle != was_toggle) { + if toggle != was_toggle { if toggle { let is_relative = editor .addon::() - .map(|vim| vim.entity.read(cx).mode != Mode::Insert); + .map(|vim| vim.entity.read(cx).mode != ModalMode::Insert); editor.set_relative_line_number(is_relative, cx) } else { editor.set_relative_line_number(None, cx) } } was_toggle = VimSettings::get_global(cx).toggle_relative_line_numbers; - if was_enabled == enabled { - return; - } - was_enabled = enabled; - if enabled { - Self::activate(editor, window, cx) - } else { - Self::deactivate(editor, cx) - } }) .detach(); - if was_enabled { - Self::activate(editor, window, cx) - } + + let mut was_enabled = true; + cx.observe::(window, move |editor, window, cx| {}) + .detach(); + + Self::activate(editor, window, cx) } fn activate(editor: &mut Editor, window: &mut Window, cx: &mut Context) { let vim = Vim::new(window, cx); - let default_editor_mode = editor.default_editor_mode(); - - if default_editor_mode == EditorMode::VimInsert { - vim.update(cx, |vim, _| { - vim.mode = Mode::Insert; - }); - } + vim.update(cx, |vim, _| { + let initial_mode = match editor.default_editor_mode() { + EditorMode::Default => return, + EditorMode::Vim(modal_mode) => modal_mode, + EditorMode::Helix(modal_mode) => modal_mode, + }; + vim.mode = initial_mode; + }); editor.register_addon(VimAddon { entity: vim.clone(), @@ -511,34 +493,34 @@ impl Vim { cx, move |vim, _: &SwitchToNormalMode, window, cx| { if matches!(default_editor_mode, EditorMode::Helix) { - vim.switch_mode(Mode::HelixNormal, false, window, cx) + vim.switch_mode(ModalMode::HelixNormal, false, window, cx) } else { - vim.switch_mode(Mode::Normal, false, window, cx) + vim.switch_mode(ModalMode::Normal, false, window, cx) } }, ); Vim::action(editor, cx, |vim, _: &SwitchToInsertMode, window, cx| { - vim.switch_mode(Mode::Insert, false, window, cx) + vim.switch_mode(ModalMode::Insert, false, window, cx) }); Vim::action(editor, cx, |vim, _: &SwitchToReplaceMode, window, cx| { - vim.switch_mode(Mode::Replace, false, window, cx) + vim.switch_mode(ModalMode::Replace, false, window, cx) }); Vim::action(editor, cx, |vim, _: &SwitchToVisualMode, window, cx| { - vim.switch_mode(Mode::Visual, false, window, cx) + vim.switch_mode(ModalMode::Visual, false, window, cx) }); Vim::action(editor, cx, |vim, _: &SwitchToVisualLineMode, window, cx| { - vim.switch_mode(Mode::VisualLine, false, window, cx) + vim.switch_mode(ModalMode::VisualLine, false, window, cx) }); Vim::action( editor, cx, |vim, _: &SwitchToVisualBlockMode, window, cx| { - vim.switch_mode(Mode::VisualBlock, false, window, cx) + vim.switch_mode(ModalMode::VisualBlock, false, window, cx) }, ); @@ -546,7 +528,7 @@ impl Vim { editor, cx, |vim, _: &SwitchToHelixNormalMode, window, cx| { - vim.switch_mode(Mode::HelixNormal, false, window, cx) + vim.switch_mode(ModalMode::HelixNormal, false, window, cx) }, ); Vim::action(editor, cx, |_, _: &PushForcedMotion, _, cx| { @@ -766,8 +748,8 @@ impl Vim { // displayed (and performed by `accept_edit_prediction`). This switches to // insert mode so that the prediction is displayed after the jump. match vim.mode { - Mode::Replace => {} - _ => vim.switch_mode(Mode::Insert, true, window, cx), + ModalMode::Replace => {} + _ => vim.switch_mode(ModalMode::Insert, true, window, cx), }; }, ); @@ -859,7 +841,7 @@ impl Vim { { return; } - self.switch_mode(Mode::Insert, false, window, cx) + self.switch_mode(ModalMode::Insert, false, window, cx) } if let Some(action) = keystroke_event.action.as_ref() { // Keystroke is handled by the vim system, so continue forward @@ -935,6 +917,24 @@ impl Vim { vim.set_mark(mark, vec![*anchor], editor.buffer(), window, cx); }); } + 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) + } + // + }); + } _ => {} } } @@ -961,18 +961,21 @@ impl Vim { pub fn switch_mode( &mut self, - mode: Mode, + mode: ModalMode, leave_selections: bool, window: &mut Window, cx: &mut Context, ) { - if self.temp_mode && mode == Mode::Normal { + if self.temp_mode && mode == ModalMode::Normal { self.temp_mode = false; - self.switch_mode(Mode::Normal, leave_selections, window, cx); - self.switch_mode(Mode::Insert, false, window, cx); + self.switch_mode(ModalMode::Normal, leave_selections, window, cx); + self.switch_mode(ModalMode::Insert, false, window, cx); return; } else if self.temp_mode - && !matches!(mode, Mode::Visual | Mode::VisualLine | Mode::VisualBlock) + && !matches!( + mode, + ModalMode::Visual | ModalMode::VisualLine | ModalMode::VisualBlock + ) { self.temp_mode = false; } @@ -986,7 +989,7 @@ impl Vim { self.operator_stack.clear(); self.selected_register.take(); self.cancel_running_command(window, cx); - if mode == Mode::Normal || mode != last_mode { + if mode == ModalMode::Normal || mode != last_mode { self.current_tx.take(); self.current_anchor.take(); self.update_editor(cx, |_, editor, _| { @@ -994,7 +997,7 @@ impl Vim { }); } Vim::take_forced_motion(cx); - if mode != Mode::Insert && mode != Mode::Replace { + if mode != ModalMode::Insert && mode != ModalMode::Replace { Vim::take_count(cx); } @@ -1003,10 +1006,10 @@ impl Vim { if VimSettings::get_global(cx).toggle_relative_line_numbers && self.mode != self.last_mode - && (self.mode == Mode::Insert || self.last_mode == Mode::Insert) + && (self.mode == ModalMode::Insert || self.last_mode == ModalMode::Insert) { self.update_editor(cx, |vim, editor, cx| { - let is_relative = vim.mode != Mode::Insert; + let is_relative = vim.mode != ModalMode::Insert; editor.set_relative_line_number(Some(is_relative), cx) }); } @@ -1021,13 +1024,15 @@ impl Vim { // Adjust selections self.update_editor(cx, |vim, editor, cx| { - if last_mode != Mode::VisualBlock && last_mode.is_visual() && mode == Mode::VisualBlock + if last_mode != ModalMode::VisualBlock + && last_mode.is_visual() + && mode == ModalMode::VisualBlock { vim.visual_block_motion(true, editor, window, cx, |_, point, goal| { Some((point, goal)) }) } - if (last_mode == Mode::Insert || last_mode == Mode::Replace) + if (last_mode == ModalMode::Insert || last_mode == ModalMode::Replace) && let Some(prior_tx) = prior_tx { editor.group_until_transaction(prior_tx, cx) @@ -1037,15 +1042,15 @@ impl Vim { // we cheat with visual block mode and use multiple cursors. // the cost of this cheat is we need to convert back to a single // cursor whenever vim would. - if last_mode == Mode::VisualBlock - && (mode != Mode::VisualBlock && mode != Mode::Insert) + if last_mode == ModalMode::VisualBlock + && (mode != ModalMode::VisualBlock && mode != ModalMode::Insert) { let tail = s.oldest_anchor().tail(); let head = s.newest_anchor().head(); s.select_anchor_ranges(vec![tail..head]); - } else if last_mode == Mode::Insert - && prior_mode == Mode::VisualBlock - && mode != Mode::VisualBlock + } else if last_mode == ModalMode::Insert + && prior_mode == ModalMode::VisualBlock + && mode != ModalMode::VisualBlock { let pos = s.first_anchor().head(); s.select_anchor_ranges(vec![pos..pos]) @@ -1110,7 +1115,7 @@ impl Vim { pub fn cursor_shape(&self, cx: &mut App) -> CursorShape { let cursor_shape = VimSettings::get_global(cx).cursor_shape; match self.mode { - Mode::Normal => { + ModalMode::Normal => { if let Some(operator) = self.operator_stack.last() { match operator { // Navigation operators -> Block cursor @@ -1129,12 +1134,12 @@ impl Vim { cursor_shape.normal.unwrap_or(CursorShape::Block) } } - Mode::HelixNormal => cursor_shape.normal.unwrap_or(CursorShape::Block), - Mode::Replace => cursor_shape.replace.unwrap_or(CursorShape::Underline), - Mode::Visual | Mode::VisualLine | Mode::VisualBlock => { + ModalMode::HelixNormal => cursor_shape.normal.unwrap_or(CursorShape::Block), + ModalMode::Replace => cursor_shape.replace.unwrap_or(CursorShape::Underline), + ModalMode::Visual | ModalMode::VisualLine | ModalMode::VisualBlock => { cursor_shape.visual.unwrap_or(CursorShape::Block) } - Mode::Insert => cursor_shape.insert.unwrap_or({ + ModalMode::Insert => cursor_shape.insert.unwrap_or({ let editor_settings = EditorSettings::get_global(cx); editor_settings.cursor_shape.unwrap_or_default() }), @@ -1143,45 +1148,45 @@ impl Vim { pub fn editor_input_enabled(&self) -> bool { match self.mode { - Mode::Insert => { + ModalMode::Insert => { if let Some(operator) = self.operator_stack.last() { !operator.is_waiting(self.mode) } else { true } } - Mode::Normal - | Mode::HelixNormal - | Mode::Replace - | Mode::Visual - | Mode::VisualLine - | Mode::VisualBlock => false, + ModalMode::Normal + | ModalMode::HelixNormal + | ModalMode::Replace + | ModalMode::Visual + | ModalMode::VisualLine + | ModalMode::VisualBlock => false, } } pub fn should_autoindent(&self) -> bool { - !(self.mode == Mode::Insert && self.last_mode == Mode::VisualBlock) + !(self.mode == ModalMode::Insert && self.last_mode == ModalMode::VisualBlock) } pub fn clip_at_line_ends(&self) -> bool { match self.mode { - Mode::Insert - | Mode::Visual - | Mode::VisualLine - | Mode::VisualBlock - | Mode::Replace - | Mode::HelixNormal => false, - Mode::Normal => true, + ModalMode::Insert + | ModalMode::Visual + | ModalMode::VisualLine + | ModalMode::VisualBlock + | ModalMode::Replace + | ModalMode::HelixNormal => false, + ModalMode::Normal => true, } } pub fn extend_key_context(&self, context: &mut KeyContext, cx: &App) { let mut mode = match self.mode { - Mode::Normal => "normal", - Mode::Visual | Mode::VisualLine | Mode::VisualBlock => "visual", - Mode::Insert => "insert", - Mode::Replace => "replace", - Mode::HelixNormal => "helix_normal", + ModalMode::Normal => "normal", + ModalMode::Visual | ModalMode::VisualLine | ModalMode::VisualBlock => "visual", + ModalMode::Insert => "insert", + ModalMode::Replace => "replace", + ModalMode::HelixNormal => "helix_normal", } .to_string(); @@ -1226,12 +1231,12 @@ impl Vim { if editor_mode.is_full() && !newest_selection_empty - && self.mode == Mode::Normal + && self.mode == ModalMode::Normal // When following someone, don't switch vim mode. && editor.leader_id().is_none() { if preserve_selection { - self.switch_mode(Mode::Visual, true, window, cx); + self.switch_mode(ModalMode::Visual, true, window, cx); } else { self.update_editor(cx, |_, editor, cx| { editor.set_clip_at_line_ends(false, cx); @@ -1257,13 +1262,13 @@ impl Vim { }); self.update_editor(cx, |vim, editor, cx| { - let is_relative = vim.mode != Mode::Insert; + let is_relative = vim.mode != ModalMode::Insert; editor.set_relative_line_number(Some(is_relative), cx) }); } } else { self.update_editor(cx, |vim, editor, cx| { - let is_relative = vim.mode != Mode::Insert; + let is_relative = vim.mode != ModalMode::Insert; editor.set_relative_line_number(Some(is_relative), cx) }); } @@ -1351,19 +1356,19 @@ impl Vim { if let Some((oldest, newest)) = selections { globals.recorded_selection = match self.mode { - Mode::Visual if newest.end.row == newest.start.row => { + ModalMode::Visual if newest.end.row == newest.start.row => { RecordedSelection::SingleLine { cols: newest.end.column - newest.start.column, } } - Mode::Visual => RecordedSelection::Visual { + ModalMode::Visual => RecordedSelection::Visual { rows: newest.end.row - newest.start.row, cols: newest.end.column, }, - Mode::VisualLine => RecordedSelection::VisualLine { + ModalMode::VisualLine => RecordedSelection::VisualLine { rows: newest.end.row - newest.start.row, }, - Mode::VisualBlock => RecordedSelection::VisualBlock { + ModalMode::VisualBlock => RecordedSelection::VisualBlock { rows: newest.end.row.abs_diff(oldest.start.row), cols: newest.end.column.abs_diff(oldest.start.column), }, @@ -1480,9 +1485,9 @@ impl Vim { _window: &mut Window, _: &mut Context, ) { - let mode = if (self.mode == Mode::Insert - || self.mode == Mode::Replace - || self.mode == Mode::Normal) + let mode = if (self.mode == ModalMode::Insert + || self.mode == ModalMode::Replace + || self.mode == ModalMode::Normal) && self.current_tx.is_none() { self.current_tx = Some(transaction_id); @@ -1490,7 +1495,7 @@ impl Vim { } else { self.mode }; - if mode == Mode::VisualLine || mode == Mode::VisualBlock { + if mode == ModalMode::VisualLine || mode == ModalMode::VisualBlock { self.undo_modes.insert(transaction_id, mode); } } @@ -1502,12 +1507,12 @@ impl Vim { cx: &mut Context, ) { match self.mode { - Mode::VisualLine | Mode::VisualBlock | Mode::Visual => { + ModalMode::VisualLine | ModalMode::VisualBlock | ModalMode::Visual => { self.update_editor(cx, |vim, editor, cx| { let original_mode = vim.undo_modes.get(transaction_id); editor.change_selections(SelectionEffects::no_scroll(), window, cx, |s| { match original_mode { - Some(Mode::VisualLine) => { + Some(ModalMode::VisualLine) => { s.move_with(|map, selection| { selection.collapse_to( map.prev_line_boundary(selection.start.to_point(map)).1, @@ -1515,7 +1520,7 @@ impl Vim { ) }); } - Some(Mode::VisualBlock) => { + Some(ModalMode::VisualBlock) => { let mut first = s.first_anchor(); first.collapse_to(first.start, first.goal); s.select_anchors(vec![first]); @@ -1531,9 +1536,9 @@ impl Vim { } }); }); - self.switch_mode(Mode::Normal, true, window, cx) + self.switch_mode(ModalMode::Normal, true, window, cx) } - Mode::Normal => { + ModalMode::Normal => { self.update_editor(cx, |_, editor, cx| { editor.change_selections(SelectionEffects::no_scroll(), window, cx, |s| { s.move_with(|map, selection| { @@ -1543,7 +1548,7 @@ impl Vim { }) }); } - Mode::Insert | Mode::Replace | Mode::HelixNormal => {} + ModalMode::Insert | ModalMode::Replace | ModalMode::HelixNormal => {} } } @@ -1556,7 +1561,7 @@ impl Vim { let newest = editor.read(cx).selections.newest_anchor().clone(); let is_multicursor = editor.read(cx).selections.count() > 1; - if self.mode == Mode::Insert && self.current_tx.is_some() { + if self.mode == ModalMode::Insert && self.current_tx.is_some() { if self.current_anchor.is_none() { self.current_anchor = Some(newest); } else if self.current_anchor.as_ref().unwrap() != &newest @@ -1566,17 +1571,22 @@ impl Vim { editor.group_until_transaction(tx_id, cx) }); } - } else if self.mode == Mode::Normal && newest.start != newest.end { + } else if self.mode == ModalMode::Normal && newest.start != newest.end { if matches!(newest.goal, SelectionGoal::HorizontalRange { .. }) { - self.switch_mode(Mode::VisualBlock, false, window, cx); + self.switch_mode(ModalMode::VisualBlock, false, window, cx); } else { - self.switch_mode(Mode::Visual, false, window, cx) + self.switch_mode(ModalMode::Visual, false, window, cx) } } else if newest.start == newest.end && !is_multicursor - && [Mode::Visual, Mode::VisualLine, Mode::VisualBlock].contains(&self.mode) + && [ + ModalMode::Visual, + ModalMode::VisualLine, + ModalMode::VisualBlock, + ] + .contains(&self.mode) { - self.switch_mode(Mode::Normal, true, window, cx); + self.switch_mode(ModalMode::Normal, true, window, cx); } } @@ -1649,11 +1659,11 @@ impl Vim { } } Some(Operator::Replace) => match self.mode { - Mode::Normal => self.normal_replace(text, window, cx), - Mode::Visual | Mode::VisualLine | Mode::VisualBlock => { + ModalMode::Normal => self.normal_replace(text, window, cx), + ModalMode::Visual | ModalMode::VisualLine | ModalMode::VisualBlock => { self.visual_replace(text, window, cx) } - Mode::HelixNormal => self.helix_replace(&text, window, cx), + ModalMode::HelixNormal => self.helix_replace(&text, window, cx), _ => self.clear_operator(window, cx), }, Some(Operator::Digraph { first_char }) => { @@ -1671,20 +1681,20 @@ impl Vim { self.handle_literal_input(prefix.unwrap_or_default(), &text, window, cx) } Some(Operator::AddSurrounds { target }) => match self.mode { - Mode::Normal => { + ModalMode::Normal => { if let Some(target) = target { self.add_surrounds(text, target, window, cx); self.clear_operator(window, cx); } } - Mode::Visual | Mode::VisualLine | Mode::VisualBlock => { + ModalMode::Visual | ModalMode::VisualLine | ModalMode::VisualBlock => { self.add_surrounds(text, SurroundsType::Selection, window, cx); self.clear_operator(window, cx); } _ => self.clear_operator(window, cx), }, Some(Operator::ChangeSurrounds { target }) => match self.mode { - Mode::Normal => { + ModalMode::Normal => { if let Some(target) = target { self.change_surrounds(text, target, window, cx); self.clear_operator(window, cx); @@ -1693,7 +1703,7 @@ impl Vim { _ => self.clear_operator(window, cx), }, Some(Operator::DeleteSurrounds) => match self.mode { - Mode::Normal => { + ModalMode::Normal => { self.delete_surrounds(text, window, cx); self.clear_operator(window, cx); } @@ -1707,7 +1717,7 @@ impl Vim { self.replay_register(text.chars().next().unwrap(), window, cx) } Some(Operator::Register) => match self.mode { - Mode::Insert => { + ModalMode::Insert => { self.update_editor(cx, |_, editor, cx| { if let Some(register) = Vim::update_globals(cx, |globals, cx| { globals.read_register(text.chars().next(), Some(editor), cx) @@ -1729,11 +1739,11 @@ impl Vim { }, Some(Operator::Jump { line }) => self.jump(text, line, true, window, cx), _ => { - if self.mode == Mode::Replace { + if self.mode == ModalMode::Replace { self.multi_replace(text, window, cx) } - if self.mode == Mode::Normal { + if self.mode == ModalMode::Normal { self.update_editor(cx, |_, editor, cx| { editor.accept_edit_prediction( &editor::actions::AcceptEditPrediction {}, @@ -1753,9 +1763,9 @@ impl Vim { editor.set_collapse_matches(true); editor.set_input_enabled(vim.editor_input_enabled()); editor.set_autoindent(vim.should_autoindent()); - editor.selections.line_mode = matches!(vim.mode, Mode::VisualLine); + editor.selections.line_mode = matches!(vim.mode, ModalMode::VisualLine); - let hide_edit_predictions = !matches!(vim.mode, Mode::Insert | Mode::Replace); + let hide_edit_predictions = !matches!(vim.mode, ModalMode::Insert | ModalMode::Replace); editor.set_edit_predictions_hidden_for_vim_mode(hide_edit_predictions, window, cx); }); cx.notify() @@ -1797,7 +1807,6 @@ struct CursorShapeSettings { #[derive(Deserialize)] struct VimSettings { - pub default_mode: Mode, pub toggle_relative_line_numbers: bool, pub use_system_clipboard: UseSystemClipboard, pub use_smartcase_find: bool, @@ -1808,7 +1817,6 @@ struct VimSettings { #[derive(Clone, Default, Serialize, Deserialize, JsonSchema)] struct VimSettingsContent { - pub default_mode: Option, pub toggle_relative_line_numbers: Option, pub use_system_clipboard: Option, pub use_smartcase_find: Option, @@ -1817,33 +1825,6 @@ struct VimSettingsContent { pub cursor_shape: Option, } -#[derive(Clone, Default, Serialize, Deserialize, JsonSchema)] -#[serde(rename_all = "snake_case")] -pub enum ModeContent { - #[default] - Normal, - Insert, - Replace, - Visual, - VisualLine, - VisualBlock, - HelixNormal, -} - -impl From for Mode { - fn from(mode: ModeContent) -> Self { - match mode { - ModeContent::Normal => Self::Normal, - ModeContent::Insert => Self::Insert, - ModeContent::Replace => Self::Replace, - ModeContent::Visual => Self::Visual, - ModeContent::VisualLine => Self::VisualLine, - ModeContent::VisualBlock => Self::VisualBlock, - ModeContent::HelixNormal => Self::HelixNormal, - } - } -} - impl Settings for VimSettings { const KEY: Option<&'static str> = Some("vim"); @@ -1853,10 +1834,6 @@ impl Settings for VimSettings { let settings: VimSettingsContent = sources.json_merge()?; Ok(Self { - default_mode: settings - .default_mode - .ok_or_else(Self::missing_default)? - .into(), toggle_relative_line_numbers: settings .toggle_relative_line_numbers .ok_or_else(Self::missing_default)?, diff --git a/crates/vim_mode_setting/src/vim_mode_setting.rs b/crates/vim_mode_setting/src/vim_mode_setting.rs index c8d05a1af6..4ee6a6288b 100644 --- a/crates/vim_mode_setting/src/vim_mode_setting.rs +++ b/crates/vim_mode_setting/src/vim_mode_setting.rs @@ -7,8 +7,10 @@ use anyhow::Result; use gpui::App; use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; +use serde::de::Error; +use serde::{Deserialize, Deserializer, Serialize, Serializer}; use settings::{Settings, SettingsSources}; +use std::fmt::Display; /// Initializes the `vim_mode_setting` crate. pub fn init(cx: &mut App) { @@ -20,13 +22,93 @@ pub fn init(cx: &mut App) { /// Default: `EditMode::Default` pub struct EditorModeSetting(pub EditorMode); -#[derive(Copy, Clone, Debug, PartialEq, Eq, Serialize, Deserialize, JsonSchema, Default)] +#[derive(Copy, Clone, Debug, PartialEq, Eq, JsonSchema, Default)] pub enum EditorMode { - Vim, - VimInsert, - Helix, #[default] Default, + Vim(ModalMode), + Helix(ModalMode), +} + +impl<'de> Deserialize<'de> for EditorMode { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + let s = String::deserialize(deserializer)?; + match s.as_str() { + "default" => Ok(EditorMode::Default), + "vim" => Ok(EditorMode::Vim(ModalMode::Normal)), + "vim_normal" => Ok(EditorMode::Vim(ModalMode::Normal)), + "vim_insert" => Ok(EditorMode::Vim(ModalMode::Insert)), + "vim_replace" => Ok(EditorMode::Vim(ModalMode::Replace)), + "vim_visual" => Ok(EditorMode::Vim(ModalMode::Visual)), + "vim_visual_line" => Ok(EditorMode::Vim(ModalMode::VisualLine)), + "vim_visual_block" => Ok(EditorMode::Vim(ModalMode::VisualBlock)), + "helix_experimental" => Ok(EditorMode::Helix(ModalMode::HelixNormal)), + _ => Err(D::Error::custom(format!("Unknown editor mode: {}", s))), + } + } +} + +impl Serialize for EditorMode { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + let s = match self { + EditorMode::Default => "default", + EditorMode::Vim(ModalMode::Normal) => "vim", + EditorMode::Vim(ModalMode::Insert) => "vim_insert", + EditorMode::Vim(ModalMode::Replace) => "vim_replace", + 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", + _ => return Err(serde::ser::Error::custom("unsupported editor mode variant")), + }; + serializer.serialize_str(s) + } +} + +#[derive(Copy, Clone, Debug, PartialEq, Eq, Serialize, Deserialize, JsonSchema)] +pub enum ModalMode { + Normal, + Insert, + Replace, + Visual, + VisualLine, + VisualBlock, + HelixNormal, +} + +impl Display for ModalMode { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + ModalMode::Normal => write!(f, "NORMAL"), + ModalMode::Insert => write!(f, "INSERT"), + ModalMode::Replace => write!(f, "REPLACE"), + ModalMode::Visual => write!(f, "VISUAL"), + ModalMode::VisualLine => write!(f, "VISUAL LINE"), + ModalMode::VisualBlock => write!(f, "VISUAL BLOCK"), + ModalMode::HelixNormal => write!(f, "HELIX NORMAL"), + } + } +} + +impl ModalMode { + pub fn is_visual(&self) -> bool { + match self { + Self::Visual | Self::VisualLine | Self::VisualBlock => true, + Self::Normal | Self::Insert | Self::Replace | Self::HelixNormal => false, + } + } +} + +impl Default for ModalMode { + fn default() -> Self { + Self::Normal + } } impl Settings for EditorModeSetting { @@ -49,3 +131,9 @@ impl Settings for EditorModeSetting { // TODO: could possibly check if any of the `vim.` keys are set? } } + +impl EditorMode { + pub fn is_modal(&self) -> bool { + matches!(self, EditorMode::Vim(_) | EditorMode::Helix(_)) + } +} From 1ecb2ff30b2f476172df44bf3e7cf38bbcd67dfb Mon Sep 17 00:00:00 2001 From: Smit Barmase Date: Fri, 22 Aug 2025 15:24:45 +0530 Subject: [PATCH 06/15] fix cargo toml Co-authored-by: Oleksiy Syvokon --- Cargo.lock | 1 + crates/debugger_ui/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index 87dd37c309..4501549563 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4585,6 +4585,7 @@ dependencies = [ "ui", "unindent", "util", + "vim_mode_setting", "workspace", "workspace-hack", "zed_actions", diff --git a/crates/debugger_ui/Cargo.toml b/crates/debugger_ui/Cargo.toml index 2543102dd8..4ea0ddf95c 100644 --- a/crates/debugger_ui/Cargo.toml +++ b/crates/debugger_ui/Cargo.toml @@ -76,7 +76,7 @@ util.workspace = true workspace-hack.workspace = true workspace.workspace = true zed_actions.workspace = true -vim_mode_settings.workspace = true +vim_mode_setting.workspace = true [dev-dependencies] dap = { workspace = true, features = ["test-support"] } From 66fac38cf8ae907e26da6fd191c97775aa93a765 Mon Sep 17 00:00:00 2001 From: Smit Barmase Date: Fri, 22 Aug 2025 15:48:08 +0530 Subject: [PATCH 07/15] fix diagnostic Co-authored-by: Oleksiy Syvokon --- Cargo.lock | 2 + crates/agent_settings/Cargo.toml | 1 + crates/agent_settings/src/agent_settings.rs | 1 + crates/agent_ui/src/acp/message_editor.rs | 3 +- .../src/session/running/console.rs | 2 +- crates/extensions_ui/src/extensions_ui.rs | 6 +-- crates/onboarding/src/basics_page.rs | 7 +--- crates/rules_library/Cargo.toml | 1 + crates/rules_library/src/rules_library.rs | 1 + crates/vim/src/insert.rs | 4 +- crates/vim/src/normal/paste.rs | 2 +- crates/vim/src/normal/substitute.rs | 3 +- crates/vim/src/state.rs | 9 ++-- crates/vim/src/test/vim_test_context.rs | 14 ++++--- crates/vim/src/vim.rs | 42 +++++++++---------- .../vim_mode_setting/src/vim_mode_setting.rs | 6 ++- crates/zed/src/zed.rs | 7 +--- crates/zed/src/zed/quick_action_bar.rs | 5 +-- 18 files changed, 60 insertions(+), 56 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4501549563..789642ec07 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 d34396a5d3..e0df5af0aa 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 2bc7962267..82ba4dc345 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 d3bacf2227..887346a14c 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 26c2ad3477..04f3cb7af5 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 afa896cdaf..58d975800d 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 7487b04114..d679009220 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 298f77a2d2..06d7ff9d40 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 9bacadfcbf..32c151fab7 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 3e9b9eb63f..9bc6c1c951 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 be74c209dc..460aac8075 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 889d487170..c30e8a2402 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 9df762e52f..c0d48ab142 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 b7adcccf55..b4c309c2c5 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 984e11b495..1681735c55 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 4ee6a6288b..a7f7ecf127 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 243ab382f1..c8b3c9e111 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 3da3db6b39..1a147c6834 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( From bbbc168f50cdb448ceef6f8f67da29de0475cdd2 Mon Sep 17 00:00:00 2001 From: Smit Barmase Date: Fri, 22 Aug 2025 15:53:14 +0530 Subject: [PATCH 08/15] clean up Co-authored-by: Oleksiy Syvokon --- assets/settings/default.json | 4 ++++ crates/zed/src/zed.rs | 2 +- crates/zed/src/zed/quick_action_bar.rs | 4 ++-- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/assets/settings/default.json b/assets/settings/default.json index 3f2b0a159f..2f24416f42 100644 --- a/assets/settings/default.json +++ b/assets/settings/default.json @@ -111,6 +111,10 @@ // 2. Maps `Control` on Linux and Windows and to `Command` on MacOS: // "cmd_or_ctrl" (alias: "cmd", "ctrl") "multi_cursor_modifier": "alt", + /// Weather to set editor mode to vim, vim insert, helix, etc. + /// + /// Default: default + "editor_mode": "default", // Whether to enable vim modes and key bindings. "vim_mode": false, // Whether to enable helix mode and key bindings. diff --git a/crates/zed/src/zed.rs b/crates/zed/src/zed.rs index c8b3c9e111..2d47c07ad6 100644 --- a/crates/zed/src/zed.rs +++ b/crates/zed/src/zed.rs @@ -70,7 +70,7 @@ use ui::{PopoverMenuHandle, prelude::*}; use util::markdown::MarkdownString; use util::{ResultExt, asset_str}; use uuid::Uuid; -use vim_mode_setting::{EditorMode, EditorModeSetting}; +use vim_mode_setting::EditorModeSetting; use workspace::notifications::{ NotificationId, SuppressEvent, dismiss_app_notification, show_app_notification, }; diff --git a/crates/zed/src/zed/quick_action_bar.rs b/crates/zed/src/zed/quick_action_bar.rs index 1a147c6834..34eac520f2 100644 --- a/crates/zed/src/zed/quick_action_bar.rs +++ b/crates/zed/src/zed/quick_action_bar.rs @@ -578,9 +578,9 @@ impl Render for QuickActionBar { { move |window, cx| { let new_value = if vim_mode_enabled { - EditorMode::Default + EditorMode::default() } else { - EditorMode::Vim + EditorMode::vim() }; EditorModeSetting::override_global(EditorModeSetting(new_value), cx); window.refresh(); From dfa7cd431a1cbc1d71166e23ee26a6d1677e1b7b Mon Sep 17 00:00:00 2001 From: Smit Barmase Date: Fri, 22 Aug 2025 15:58:00 +0530 Subject: [PATCH 09/15] add serialize and deserialize for agent settings Co-authored-by: Oleksiy Syvokon --- crates/agent_settings/src/agent_settings.rs | 31 +++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/crates/agent_settings/src/agent_settings.rs b/crates/agent_settings/src/agent_settings.rs index 82ba4dc345..c7772a6a1b 100644 --- a/crates/agent_settings/src/agent_settings.rs +++ b/crates/agent_settings/src/agent_settings.rs @@ -7,7 +7,7 @@ use collections::IndexMap; use gpui::{App, Pixels, SharedString}; use language_model::LanguageModel; use schemars::{JsonSchema, json_schema}; -use serde::{Deserialize, Serialize}; +use serde::{Deserialize, Deserializer, Serialize, Serializer}; use settings::{Settings, SettingsSources}; use std::borrow::Cow; use vim_mode_setting::EditorMode; @@ -49,13 +49,40 @@ pub enum NotifyWhenAgentWaiting { Never, } -#[derive(Copy, Clone, Debug, PartialEq, Eq, Serialize, Deserialize, JsonSchema, Default)] +#[derive(Copy, Clone, Debug, PartialEq, Eq, JsonSchema, Default)] pub enum AgentEditorMode { EditorModeOverride(EditorMode), #[default] Inherit, } +impl<'de> Deserialize<'de> for AgentEditorMode { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + let s = String::deserialize(deserializer)?; + if s == "inherit" { + Ok(AgentEditorMode::Inherit) + } else { + let mode = EditorMode::deserialize(serde::de::value::StringDeserializer::new(s))?; + Ok(AgentEditorMode::EditorModeOverride(mode)) + } + } +} + +impl Serialize for AgentEditorMode { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + match self { + AgentEditorMode::EditorModeOverride(mode) => mode.serialize(serializer), + AgentEditorMode::Inherit => serializer.serialize_str("inherit"), + } + } +} + impl From for AgentEditorMode { fn from(b: EditorMode) -> Self { AgentEditorMode::EditorModeOverride(b) From f7b946e5254831da7d3de14337b53876890708d7 Mon Sep 17 00:00:00 2001 From: Smit Barmase Date: Fri, 22 Aug 2025 16:09:45 +0530 Subject: [PATCH 10/15] on agent setting change Co-authored-by: Oleksiy Syvokon --- crates/agent_ui/src/acp/message_editor.rs | 22 ++++++++---- crates/agent_ui/src/message_editor.rs | 14 +++++++- .../src/session/running/console.rs | 2 +- crates/editor/src/editor.rs | 25 +++++++++---- crates/repl/src/repl_sessions_ui.rs | 2 +- crates/rules_library/src/rules_library.rs | 2 +- crates/vim/src/vim.rs | 36 +++++++++---------- 7 files changed, 66 insertions(+), 37 deletions(-) diff --git a/crates/agent_ui/src/acp/message_editor.rs b/crates/agent_ui/src/acp/message_editor.rs index 887346a14c..123315170b 100644 --- a/crates/agent_ui/src/acp/message_editor.rs +++ b/crates/agent_ui/src/acp/message_editor.rs @@ -5,6 +5,7 @@ use crate::{ use acp_thread::{MentionUri, selection_name}; use agent_client_protocol as acp; use agent_servers::AgentServer; +use agent_settings::{AgentEditorMode, AgentSettings}; use agent2::HistoryStore; use anyhow::{Context as _, Result, anyhow}; use assistant_slash_commands::codeblock_fence_for_path; @@ -113,12 +114,10 @@ impl MessageEditor { }); let mention_set = MentionSet::default(); - let settings = agent_settings::AgentSettings::get_global(cx); + let settings = AgentSettings::get_global(cx); let editor_mode = match settings.editor_mode { - agent_settings::AgentEditorMode::EditorModeOverride(mode) => mode, - agent_settings::AgentEditorMode::Inherit => { - vim_mode_setting::EditorModeSetting::get_global(cx).0 - } + AgentEditorMode::EditorModeOverride(mode) => mode, + AgentEditorMode::Inherit => vim_mode_setting::EditorModeSetting::get_global(cx).0, }; let editor = cx.new(|cx| { @@ -129,7 +128,7 @@ impl MessageEditor { editor.set_placeholder_text(placeholder, cx); editor.set_show_indent_guides(false, cx); editor.set_soft_wrap(); - editor.set_default_editor_mode(editor_mode); + editor.set_editor_mode(editor_mode, cx); editor.set_completion_provider(Some(Rc::new(completion_provider))); editor.set_context_menu_options(ContextMenuOptions { min_entries_visible: 12, @@ -168,6 +167,17 @@ impl MessageEditor { } })); + subscriptions.push(cx.observe_global::(move |this, cx| { + let settings = AgentSettings::get_global(cx); + let editor_mode = match settings.editor_mode { + AgentEditorMode::EditorModeOverride(mode) => mode, + AgentEditorMode::Inherit => vim_mode_setting::EditorModeSetting::get_global(cx).0, + }; + this.editor.update(cx, |editor, cx| { + editor.set_editor_mode(editor_mode, cx); + }); + })); + Self { editor, project, diff --git a/crates/agent_ui/src/message_editor.rs b/crates/agent_ui/src/message_editor.rs index a5f1830e97..f066b75dee 100644 --- a/crates/agent_ui/src/message_editor.rs +++ b/crates/agent_ui/src/message_editor.rs @@ -136,7 +136,7 @@ pub(crate) fn create_editor( editor.set_placeholder_text("Message the agent – @ to include context", cx); editor.set_show_indent_guides(false, cx); editor.set_soft_wrap(); - editor.set_default_editor_mode(editor_mode); + editor.set_editor_mode(editor_mode, cx); editor.set_context_menu_options(ContextMenuOptions { min_entries_visible: 12, max_entries_visible: 12, @@ -236,6 +236,18 @@ impl MessageEditor { cx.observe(&thread.read(cx).action_log().clone(), |_, _, cx| { cx.notify() }), + cx.observe_global::(move |this, cx| { + 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 => { + vim_mode_setting::EditorModeSetting::get_global(cx).0 + } + }; + this.editor.update(cx, |editor, cx| { + editor.set_editor_mode(editor_mode, cx); + }); + }), ]; let model_selector = cx.new(|cx| { diff --git a/crates/debugger_ui/src/session/running/console.rs b/crates/debugger_ui/src/session/running/console.rs index 04f3cb7af5..239641c34c 100644 --- a/crates/debugger_ui/src/session/running/console.rs +++ b/crates/debugger_ui/src/session/running/console.rs @@ -75,7 +75,7 @@ impl Console { editor.set_show_wrap_guides(false, cx); editor.set_show_indent_guides(false, cx); editor.set_show_edit_predictions(Some(false), window, cx); - editor.set_default_editor_mode(EditorMode::Default); + editor.set_editor_mode(EditorMode::Default, cx); editor.set_soft_wrap_mode(language::language_settings::SoftWrap::EditorWidth, cx); editor }); diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index 29e8d26ac7..3fd8037984 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -201,6 +201,7 @@ use ui::{ IconSize, Indicator, Key, Tooltip, h_flex, prelude::*, }; use util::{RangeExt, ResultExt, TryFutureExt, maybe, post_inc}; +use vim_mode_setting::EditorMode; use workspace::{ CollaboratorId, Item as WorkspaceItem, ItemId, ItemNavHistory, OpenInTerminal, OpenTerminal, RestoreOnStartupBehavior, SERIALIZATION_THROTTLE_TIME, SplitDirection, TabBarSettings, Toast, @@ -1179,7 +1180,7 @@ pub struct Editor { next_color_inlay_id: usize, colors: Option, folding_newlines: Task<()>, - default_editor_mode: vim_mode_setting::EditorMode, + editor_mode: vim_mode_setting::EditorMode, // editor_mode: EditorMode, <-- while init define which editor, // agenty subscribe to agen settings @@ -2293,7 +2294,7 @@ impl Editor { display_mode: mode, selection_drag_state: SelectionDragState::None, folding_newlines: Task::ready(()), - default_editor_mode: vim_mode_setting::EditorMode::default(), + editor_mode: vim_mode_setting::EditorMode::default(), }; if is_minimap { @@ -3030,12 +3031,19 @@ impl Editor { }) } - pub fn set_default_editor_mode(&mut self, to: vim_mode_setting::EditorMode) { - self.default_editor_mode = to; + pub fn set_editor_mode(&mut self, to: vim_mode_setting::EditorMode, cx: &mut Context) { + let from = self.editor_mode; + if from != to { + self.editor_mode = to; + cx.emit(EditorEvent::EditorModeChanged { + old_mode: from, + new_mode: to, + }); + } } - pub fn default_editor_mode(&self) -> vim_mode_setting::EditorMode { - self.default_editor_mode + pub fn editor_mode(&self) -> vim_mode_setting::EditorMode { + self.editor_mode } fn selections_did_change( @@ -22937,7 +22945,10 @@ pub enum EditorEvent { anchor: Anchor, is_deactivate: bool, }, - EditorModeChanged, + EditorModeChanged { + new_mode: EditorMode, + old_mode: EditorMode, + }, } impl EventEmitter for Editor {} diff --git a/crates/repl/src/repl_sessions_ui.rs b/crates/repl/src/repl_sessions_ui.rs index de7cbf2b0e..8d86ee6568 100644 --- a/crates/repl/src/repl_sessions_ui.rs +++ b/crates/repl/src/repl_sessions_ui.rs @@ -75,7 +75,7 @@ pub fn init(cx: &mut App) { return; }; - if !editor.default_editor_mode().is_modal() || !editor.buffer().read(cx).is_singleton() + if !editor.editor_mode().is_modal() || !editor.buffer().read(cx).is_singleton() { return; } diff --git a/crates/rules_library/src/rules_library.rs b/crates/rules_library/src/rules_library.rs index 32c151fab7..fb273c65ee 100644 --- a/crates/rules_library/src/rules_library.rs +++ b/crates/rules_library/src/rules_library.rs @@ -638,7 +638,7 @@ impl RulesLibrary { editor.set_show_gutter(false, cx); editor.set_show_wrap_guides(false, cx); editor.set_show_indent_guides(false, cx); - editor.set_default_editor_mode(EditorMode::Default); + editor.set_editor_mode(EditorMode::Default, cx); editor.set_current_line_highlight(Some(CurrentLineHighlight::None)); editor.set_completion_provider(Some(make_completion_provider())); if focus { diff --git a/crates/vim/src/vim.rs b/crates/vim/src/vim.rs index 1681735c55..cbbb5ce56e 100644 --- a/crates/vim/src/vim.rs +++ b/crates/vim/src/vim.rs @@ -443,7 +443,7 @@ impl Vim { return; }; - if !editor.default_editor_mode().is_modal() { + if !editor.editor_mode().is_modal() { return; } @@ -471,7 +471,7 @@ impl Vim { let vim = Vim::new(window, cx); vim.update(cx, |vim, _| { - let initial_mode = match editor.default_editor_mode() { + let initial_mode = match editor.editor_mode() { EditorMode::Default => return, EditorMode::Vim(modal_mode) => modal_mode, EditorMode::Helix(modal_mode) => modal_mode, @@ -483,7 +483,7 @@ impl Vim { entity: vim.clone(), }); - let default_editor_mode = editor.default_editor_mode(); + let default_editor_mode = editor.editor_mode(); vim.update(cx, move |_, cx| { Vim::action( editor, @@ -914,23 +914,19 @@ impl Vim { vim.set_mark(mark, vec![*anchor], editor.buffer(), window, cx); }); } - EditorEvent::EditorModeChanged => { - 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) - // } - // + EditorEvent::EditorModeChanged { new_mode, old_mode } => { + self.update_editor(cx, |_vim, editor, cx| { + let enabled = new_mode.is_modal(); + let was_enabled = old_mode.is_modal(); + if was_enabled == enabled { + return; + } + if enabled { + Self::activate(editor, window, cx) + } else { + editor.set_relative_line_number(None, cx); + Self::deactivate(editor, cx) + } }); } _ => {} From d3e1730b724671aa9c4aa77dc974502240913eca Mon Sep 17 00:00:00 2001 From: Smit Barmase Date: Fri, 22 Aug 2025 16:52:28 +0530 Subject: [PATCH 11/15] debug stuff Co-authored-by: Oleksiy Syvokon --- crates/agent_settings/src/agent_settings.rs | 29 +++++++++- crates/agent_ui/src/acp/message_editor.rs | 3 + crates/agent_ui/src/message_editor.rs | 2 + crates/editor/src/editor.rs | 40 ++----------- crates/vim/src/state.rs | 2 +- crates/vim/src/vim.rs | 8 +-- .../vim_mode_setting/src/vim_mode_setting.rs | 56 ++++++++++++++++++- 7 files changed, 97 insertions(+), 43 deletions(-) diff --git a/crates/agent_settings/src/agent_settings.rs b/crates/agent_settings/src/agent_settings.rs index c7772a6a1b..9a02a77939 100644 --- a/crates/agent_settings/src/agent_settings.rs +++ b/crates/agent_settings/src/agent_settings.rs @@ -49,7 +49,7 @@ pub enum NotifyWhenAgentWaiting { Never, } -#[derive(Copy, Clone, Debug, PartialEq, Eq, JsonSchema, Default)] +#[derive(Copy, Clone, Debug, PartialEq, Eq, Default)] pub enum AgentEditorMode { EditorModeOverride(EditorMode), #[default] @@ -62,10 +62,12 @@ impl<'de> Deserialize<'de> for AgentEditorMode { D: Deserializer<'de>, { let s = String::deserialize(deserializer)?; + dbg!(&s); if s == "inherit" { Ok(AgentEditorMode::Inherit) } else { let mode = EditorMode::deserialize(serde::de::value::StringDeserializer::new(s))?; + dbg!(&mode); Ok(AgentEditorMode::EditorModeOverride(mode)) } } @@ -83,6 +85,31 @@ impl Serialize for AgentEditorMode { } } +impl JsonSchema for AgentEditorMode { + fn schema_name() -> Cow<'static, str> { + "AgentEditorMode".into() + } + + fn json_schema(schema_gen: &mut schemars::SchemaGenerator) -> schemars::Schema { + let editor_mode_schema = EditorMode::json_schema(schema_gen); + + // TODO: This schema is incorrect. Need to extend editor_mode_schema with `inherit` + let result = json_schema!({ + "oneOf": [ + { + "const": "inherit", + "description": "Inherit editor mode from global settings" + }, + editor_mode_schema + ], + "description": "Agent editor mode - either inherit from global settings or override with a specific mode" + }); + + dbg!(&result); + result + } +} + impl From for AgentEditorMode { fn from(b: EditorMode) -> Self { AgentEditorMode::EditorModeOverride(b) diff --git a/crates/agent_ui/src/acp/message_editor.rs b/crates/agent_ui/src/acp/message_editor.rs index 123315170b..659b6e3cf1 100644 --- a/crates/agent_ui/src/acp/message_editor.rs +++ b/crates/agent_ui/src/acp/message_editor.rs @@ -115,6 +115,7 @@ impl MessageEditor { let mention_set = MentionSet::default(); let settings = AgentSettings::get_global(cx); + dbg!(&settings); let editor_mode = match settings.editor_mode { AgentEditorMode::EditorModeOverride(mode) => mode, AgentEditorMode::Inherit => vim_mode_setting::EditorModeSetting::get_global(cx).0, @@ -128,6 +129,8 @@ impl MessageEditor { editor.set_placeholder_text(placeholder, cx); editor.set_show_indent_guides(false, cx); editor.set_soft_wrap(); + println!("editor mode in agent acp"); + dbg!(&editor_mode); editor.set_editor_mode(editor_mode, cx); editor.set_completion_provider(Some(Rc::new(completion_provider))); editor.set_context_menu_options(ContextMenuOptions { diff --git a/crates/agent_ui/src/message_editor.rs b/crates/agent_ui/src/message_editor.rs index f066b75dee..3a94d31a73 100644 --- a/crates/agent_ui/src/message_editor.rs +++ b/crates/agent_ui/src/message_editor.rs @@ -136,6 +136,8 @@ pub(crate) fn create_editor( editor.set_placeholder_text("Message the agent – @ to include context", cx); editor.set_show_indent_guides(false, cx); editor.set_soft_wrap(); + println!("editor mode in agent"); + dbg!(&editor_mode); editor.set_editor_mode(editor_mode, cx); editor.set_context_menu_options(ContextMenuOptions { min_entries_visible: 12, diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index 3fd8037984..a9e6ef6dec 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -201,7 +201,7 @@ use ui::{ IconSize, Indicator, Key, Tooltip, h_flex, prelude::*, }; use util::{RangeExt, ResultExt, TryFutureExt, maybe, post_inc}; -use vim_mode_setting::EditorMode; +use vim_mode_setting::{EditorMode, EditorModeSetting}; use workspace::{ CollaboratorId, Item as WorkspaceItem, ItemId, ItemNavHistory, OpenInTerminal, OpenTerminal, RestoreOnStartupBehavior, SERIALIZATION_THROTTLE_TIME, SplitDirection, TabBarSettings, Toast, @@ -1181,38 +1181,6 @@ pub struct Editor { colors: Option, folding_newlines: Task<()>, editor_mode: vim_mode_setting::EditorMode, - // editor_mode: EditorMode, <-- while init define which editor, - - // agenty subscribe to agen settings - // - // editor <- agent - // - // settings listent to event emitted by editor, - // - - // agent will set_editor_mode(AgentPanelSettings::read("editor_mode")) on init - // vim.rs will get_editor_mode() on init / activate / register - // - // match editor_mode { - // // which setting to use - // } - // - // - - // editor_mode: EditorMode, <-- while init define which editor, - // pros -> jsut set enum - // cons -> actual setting check lives in either editor.rs or vim.rs?? - // - // set_edutr(); - // - // Fn () -> weather mode this editor is, and what;s the default value? - // pros -> all setting lives in agent, git. - // cons -> if someone wants to use agent setting in their editor, they need to copy paste code - // - // // agent.rs - // set_vim_setting_fn(|| { - // // edito seting agnet - // }); } #[derive(Copy, Clone, Debug, PartialEq, Eq, Default)] @@ -2294,7 +2262,11 @@ impl Editor { display_mode: mode, selection_drag_state: SelectionDragState::None, folding_newlines: Task::ready(()), - editor_mode: vim_mode_setting::EditorMode::default(), + editor_mode: if full_mode { + EditorModeSetting::get_global(cx).0 + } else { + vim_mode_setting::EditorMode::default() + }, }; if is_minimap { diff --git a/crates/vim/src/state.rs b/crates/vim/src/state.rs index c0d48ab142..290f0af9ee 100644 --- a/crates/vim/src/state.rs +++ b/crates/vim/src/state.rs @@ -652,7 +652,7 @@ impl VimGlobals { let mut was_enabled = None; cx.observe_global::(move |cx| { - let is_enabled = Vim::enabled(cx); + let is_enabled = Vim::global_enabled(cx); if was_enabled == Some(is_enabled) { return; } diff --git a/crates/vim/src/vim.rs b/crates/vim/src/vim.rs index cbbb5ce56e..f3d4b746f3 100644 --- a/crates/vim/src/vim.rs +++ b/crates/vim/src/vim.rs @@ -244,7 +244,7 @@ pub fn init(cx: &mut App) { cx.observe_new(|workspace: &mut Workspace, _, _| { workspace.register_action(|workspace, _: &ToggleVimMode, _, cx| { let fs = workspace.app_state().fs.clone(); - let currently_enabled = Vim::enabled(cx); + let currently_enabled = Vim::global_enabled(cx); update_settings_file::(fs, cx, move |setting, _| { *setting = Some(if currently_enabled { EditorMode::Default @@ -812,13 +812,11 @@ impl Vim { .map(|workspace| workspace.read(cx).focused_pane(window, cx)) } - pub fn enabled(cx: &mut App) -> bool { + pub fn global_enabled(cx: &mut App) -> bool { + dbg!(&EditorModeSetting::get_global(cx).0); if EditorModeSetting::get_global(cx).0 == EditorMode::Default { return false; } - - // check for agent.editor_mode - // return true; } diff --git a/crates/vim_mode_setting/src/vim_mode_setting.rs b/crates/vim_mode_setting/src/vim_mode_setting.rs index a7f7ecf127..46f67cb870 100644 --- a/crates/vim_mode_setting/src/vim_mode_setting.rs +++ b/crates/vim_mode_setting/src/vim_mode_setting.rs @@ -6,10 +6,12 @@ use anyhow::Result; use gpui::App; -use schemars::JsonSchema; +use schemars::{JsonSchema, Schema, json_schema}; + use serde::de::Error; use serde::{Deserialize, Deserializer, Serialize, Serializer}; use settings::{Settings, SettingsSources}; +use std::borrow::Cow; use std::fmt::Display; /// Initializes the `vim_mode_setting` crate. @@ -22,7 +24,7 @@ pub fn init(cx: &mut App) { /// Default: `EditMode::Default` pub struct EditorModeSetting(pub EditorMode); -#[derive(Copy, Clone, Debug, PartialEq, Eq, JsonSchema, Default)] +#[derive(Copy, Clone, Debug, PartialEq, Eq, Default)] pub enum EditorMode { #[default] Default, @@ -30,6 +32,56 @@ pub enum EditorMode { Helix(ModalMode), } +impl JsonSchema for EditorMode { + fn schema_name() -> Cow<'static, str> { + "EditorMode".into() + } + + fn json_schema(_gen: &mut schemars::SchemaGenerator) -> Schema { + json_schema!({ + "oneOf": [ + { + "const": "default", + "description": "Standard editing mode" + }, + { + "const": "vim", + "description": "Vim normal mode" + }, + { + "const": "vim_normal", + "description": "Vim normal mode" + }, + { + "const": "vim_insert", + "description": "Vim insert mode" + }, + { + "const": "vim_replace", + "description": "Vim replace mode" + }, + { + "const": "vim_visual", + "description": "Vim visual mode" + }, + { + "const": "vim_visual_line", + "description": "Vim visual line mode" + }, + { + "const": "vim_visual_block", + "description": "Vim visual block mode" + }, + { + "const": "helix_experimental", + "description": "Helix mode (experimental)" + } + ], + "description": "Editor mode" + }) + } +} + impl<'de> Deserialize<'de> for EditorMode { fn deserialize(deserializer: D) -> Result where From 96523f0d77f0243321b2bc9dcd13bfa61314c52c Mon Sep 17 00:00:00 2001 From: Smit Barmase Date: Fri, 22 Aug 2025 17:21:48 +0530 Subject: [PATCH 12/15] schema for agent mode --- Cargo.lock | 1 + crates/agent_settings/Cargo.toml | 1 + crates/agent_settings/src/agent_settings.rs | 26 +++--- crates/vim_mode_setting/Cargo.toml | 1 + .../vim_mode_setting/src/vim_mode_setting.rs | 81 ++++++++++--------- 5 files changed, 57 insertions(+), 53 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 789642ec07..7da54587d0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -18000,6 +18000,7 @@ dependencies = [ "gpui", "schemars", "serde", + "serde_json", "settings", "workspace-hack", ] diff --git a/crates/agent_settings/Cargo.toml b/crates/agent_settings/Cargo.toml index e0df5af0aa..07fbd74b4e 100644 --- a/crates/agent_settings/Cargo.toml +++ b/crates/agent_settings/Cargo.toml @@ -19,6 +19,7 @@ gpui.workspace = true language_model.workspace = true schemars.workspace = true serde.workspace = true +serde_json.workspace = true settings.workspace = true workspace-hack.workspace = true vim_mode_setting.workspace = true diff --git a/crates/agent_settings/src/agent_settings.rs b/crates/agent_settings/src/agent_settings.rs index 9a02a77939..d4d1cd9dc0 100644 --- a/crates/agent_settings/src/agent_settings.rs +++ b/crates/agent_settings/src/agent_settings.rs @@ -90,23 +90,19 @@ impl JsonSchema for AgentEditorMode { "AgentEditorMode".into() } - fn json_schema(schema_gen: &mut schemars::SchemaGenerator) -> schemars::Schema { - let editor_mode_schema = EditorMode::json_schema(schema_gen); + fn json_schema(_gen: &mut schemars::SchemaGenerator) -> schemars::Schema { + use vim_mode_setting::EditorMode; - // TODO: This schema is incorrect. Need to extend editor_mode_schema with `inherit` - let result = json_schema!({ - "oneOf": [ - { - "const": "inherit", - "description": "Inherit editor mode from global settings" - }, - editor_mode_schema - ], + let mut options = vec![serde_json::json!({ + "const": "inherit", + "description": "Inherit editor mode from global settings" + })]; + options.extend(EditorMode::get_schema_options()); + + json_schema!({ + "oneOf": options, "description": "Agent editor mode - either inherit from global settings or override with a specific mode" - }); - - dbg!(&result); - result + }) } } diff --git a/crates/vim_mode_setting/Cargo.toml b/crates/vim_mode_setting/Cargo.toml index ef4fde738f..562632d1db 100644 --- a/crates/vim_mode_setting/Cargo.toml +++ b/crates/vim_mode_setting/Cargo.toml @@ -18,3 +18,4 @@ schemars.workspace = true settings.workspace = true workspace-hack.workspace = true serde.workspace = true +serde_json.workspace = true diff --git a/crates/vim_mode_setting/src/vim_mode_setting.rs b/crates/vim_mode_setting/src/vim_mode_setting.rs index 46f67cb870..663b198bd0 100644 --- a/crates/vim_mode_setting/src/vim_mode_setting.rs +++ b/crates/vim_mode_setting/src/vim_mode_setting.rs @@ -38,45 +38,9 @@ impl JsonSchema for EditorMode { } fn json_schema(_gen: &mut schemars::SchemaGenerator) -> Schema { + let options = Self::get_schema_options(); json_schema!({ - "oneOf": [ - { - "const": "default", - "description": "Standard editing mode" - }, - { - "const": "vim", - "description": "Vim normal mode" - }, - { - "const": "vim_normal", - "description": "Vim normal mode" - }, - { - "const": "vim_insert", - "description": "Vim insert mode" - }, - { - "const": "vim_replace", - "description": "Vim replace mode" - }, - { - "const": "vim_visual", - "description": "Vim visual mode" - }, - { - "const": "vim_visual_line", - "description": "Vim visual line mode" - }, - { - "const": "vim_visual_block", - "description": "Vim visual block mode" - }, - { - "const": "helix_experimental", - "description": "Helix mode (experimental)" - } - ], + "oneOf": options, "description": "Editor mode" }) } @@ -192,4 +156,45 @@ impl EditorMode { pub fn vim() -> EditorMode { EditorMode::Vim(ModalMode::default()) } + + pub fn get_schema_options() -> Vec { + vec![ + serde_json::json!({ + "const": "default", + "description": "Standard editing mode" + }), + serde_json::json!({ + "const": "vim", + "description": "Vim normal mode" + }), + serde_json::json!({ + "const": "vim_normal", + "description": "Vim normal mode" + }), + serde_json::json!({ + "const": "vim_insert", + "description": "Vim insert mode" + }), + serde_json::json!({ + "const": "vim_replace", + "description": "Vim replace mode" + }), + serde_json::json!({ + "const": "vim_visual", + "description": "Vim visual mode" + }), + serde_json::json!({ + "const": "vim_visual_line", + "description": "Vim visual line mode" + }), + serde_json::json!({ + "const": "vim_visual_block", + "description": "Vim visual block mode" + }), + serde_json::json!({ + "const": "helix_experimental", + "description": "Helix mode (experimental)" + }), + ] + } } From ea5425f8181644acc3136062ba1b49a558109bb6 Mon Sep 17 00:00:00 2001 From: Smit Barmase Date: Fri, 22 Aug 2025 17:54:17 +0530 Subject: [PATCH 13/15] editor mode merge --- crates/agent_settings/src/agent_settings.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/crates/agent_settings/src/agent_settings.rs b/crates/agent_settings/src/agent_settings.rs index d4d1cd9dc0..388f414075 100644 --- a/crates/agent_settings/src/agent_settings.rs +++ b/crates/agent_settings/src/agent_settings.rs @@ -539,6 +539,7 @@ impl Settings for AgentSettings { &mut settings.use_modifier_to_send, value.use_modifier_to_send, ); + merge(&mut settings.editor_mode, value.editor_mode); settings .model_parameters From 1e4614f9a06c1a53332d89dc4795fe84d13e0c03 Mon Sep 17 00:00:00 2001 From: Smit Barmase Date: Fri, 22 Aug 2025 17:59:37 +0530 Subject: [PATCH 14/15] vim_mode_setting -> editor_mode_setting --- Cargo.lock | 44 +++++++++---------- Cargo.toml | 4 +- crates/agent_settings/Cargo.toml | 2 +- crates/agent_settings/src/agent_settings.rs | 6 +-- crates/agent_ui/Cargo.toml | 2 +- crates/agent_ui/src/acp/message_editor.rs | 9 ++-- crates/agent_ui/src/message_editor.rs | 6 +-- crates/debugger_ui/Cargo.toml | 2 +- .../src/session/running/console.rs | 2 +- crates/editor/Cargo.toml | 2 +- crates/editor/src/editor.rs | 10 ++--- .../Cargo.toml | 4 +- .../LICENSE-GPL | 0 .../src/editor_mode_setting.rs} | 2 +- crates/extensions_ui/Cargo.toml | 2 +- crates/extensions_ui/src/extensions_ui.rs | 2 +- crates/onboarding/Cargo.toml | 2 +- crates/onboarding/src/basics_page.rs | 2 +- crates/rules_library/Cargo.toml | 2 +- crates/rules_library/src/rules_library.rs | 2 +- crates/vim/Cargo.toml | 2 +- crates/vim/src/insert.rs | 2 +- crates/vim/src/normal/paste.rs | 2 +- crates/vim/src/state.rs | 2 +- crates/vim/src/test/vim_test_context.rs | 4 +- crates/vim/src/vim.rs | 5 +-- crates/zed/Cargo.toml | 2 +- crates/zed/src/zed.rs | 6 +-- crates/zed/src/zed/quick_action_bar.rs | 2 +- 29 files changed, 64 insertions(+), 70 deletions(-) rename crates/{vim_mode_setting => editor_mode_setting}/Cargo.toml (83%) rename crates/{vim_mode_setting => editor_mode_setting}/LICENSE-GPL (100%) rename crates/{vim_mode_setting/src/vim_mode_setting.rs => editor_mode_setting/src/editor_mode_setting.rs} (99%) diff --git a/Cargo.lock b/Cargo.lock index 7da54587d0..5c7a0aba3f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -313,6 +313,7 @@ dependencies = [ "anyhow", "cloud_llm_client", "collections", + "editor_mode_setting", "fs", "gpui", "language_model", @@ -322,7 +323,6 @@ dependencies = [ "serde_json", "serde_json_lenient", "settings", - "vim_mode_setting", "workspace-hack", ] @@ -355,6 +355,7 @@ dependencies = [ "context_server", "db", "editor", + "editor_mode_setting", "extension", "extension_host", "feature_flags", @@ -416,7 +417,6 @@ dependencies = [ "urlencoding", "util", "uuid", - "vim_mode_setting", "watch", "workspace", "workspace-hack", @@ -4549,6 +4549,7 @@ dependencies = [ "db", "debugger_tools", "editor", + "editor_mode_setting", "file_icons", "futures 0.3.31", "fuzzy", @@ -4586,7 +4587,6 @@ dependencies = [ "ui", "unindent", "util", - "vim_mode_setting", "workspace", "workspace-hack", "zed_actions", @@ -5064,6 +5064,7 @@ dependencies = [ "dap", "db", "edit_prediction", + "editor_mode_setting", "emojis", "file_icons", "fs", @@ -5118,13 +5119,25 @@ dependencies = [ "url", "util", "uuid", - "vim_mode_setting", "workspace", "workspace-hack", "zed_actions", "zlog", ] +[[package]] +name = "editor_mode_setting" +version = "0.1.0" +dependencies = [ + "anyhow", + "gpui", + "schemars", + "serde", + "serde_json", + "settings", + "workspace-hack", +] + [[package]] name = "either" version = "1.15.0" @@ -5616,6 +5629,7 @@ dependencies = [ "collections", "db", "editor", + "editor_mode_setting", "extension", "extension_host", "fs", @@ -5636,7 +5650,6 @@ dependencies = [ "theme", "ui", "util", - "vim_mode_setting", "workspace", "workspace-hack", "zed_actions", @@ -11105,6 +11118,7 @@ dependencies = [ "db", "documented", "editor", + "editor_mode_setting", "fs", "fuzzy", "git", @@ -11123,7 +11137,6 @@ dependencies = [ "theme", "ui", "util", - "vim_mode_setting", "workspace", "workspace-hack", "zed_actions", @@ -13966,6 +13979,7 @@ dependencies = [ "anyhow", "collections", "editor", + "editor_mode_setting", "gpui", "language", "language_model", @@ -13981,7 +13995,6 @@ dependencies = [ "title_bar", "ui", "util", - "vim_mode_setting", "workspace", "workspace-hack", "zed_actions", @@ -17957,6 +17970,7 @@ dependencies = [ "command_palette_hooks", "db", "editor", + "editor_mode_setting", "env_logger 0.11.8", "futures 0.3.31", "git_ui", @@ -17986,25 +18000,11 @@ dependencies = [ "tokio", "ui", "util", - "vim_mode_setting", "workspace", "workspace-hack", "zed_actions", ] -[[package]] -name = "vim_mode_setting" -version = "0.1.0" -dependencies = [ - "anyhow", - "gpui", - "schemars", - "serde", - "serde_json", - "settings", - "workspace-hack", -] - [[package]] name = "vscode_theme" version = "0.2.0" @@ -20463,6 +20463,7 @@ dependencies = [ "diagnostics", "edit_prediction_button", "editor", + "editor_mode_setting", "env_logger 0.11.8", "extension", "extension_host", @@ -20562,7 +20563,6 @@ dependencies = [ "util", "uuid", "vim", - "vim_mode_setting", "watch", "web_search", "web_search_providers", diff --git a/Cargo.toml b/Cargo.toml index 84de9b30ad..468dfd67b2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -181,7 +181,7 @@ members = [ "crates/util_macros", "crates/vercel", "crates/vim", - "crates/vim_mode_setting", + "crates/editor_mode_setting", "crates/watch", "crates/web_search", "crates/web_search_providers", @@ -406,7 +406,7 @@ util = { path = "crates/util" } util_macros = { path = "crates/util_macros" } vercel = { path = "crates/vercel" } vim = { path = "crates/vim" } -vim_mode_setting = { path = "crates/vim_mode_setting" } +editor_mode_setting = { path = "crates/editor_mode_setting" } watch = { path = "crates/watch" } web_search = { path = "crates/web_search" } diff --git a/crates/agent_settings/Cargo.toml b/crates/agent_settings/Cargo.toml index 07fbd74b4e..0791898001 100644 --- a/crates/agent_settings/Cargo.toml +++ b/crates/agent_settings/Cargo.toml @@ -22,7 +22,7 @@ serde.workspace = true serde_json.workspace = true settings.workspace = true workspace-hack.workspace = true -vim_mode_setting.workspace = true +editor_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 388f414075..af220bd535 100644 --- a/crates/agent_settings/src/agent_settings.rs +++ b/crates/agent_settings/src/agent_settings.rs @@ -4,13 +4,13 @@ use std::sync::Arc; use anyhow::{Result, bail}; use collections::IndexMap; +use editor_mode_setting::EditorMode; use gpui::{App, Pixels, SharedString}; use language_model::LanguageModel; use schemars::{JsonSchema, json_schema}; use serde::{Deserialize, Deserializer, Serialize, Serializer}; use settings::{Settings, SettingsSources}; use std::borrow::Cow; -use vim_mode_setting::EditorMode; pub use crate::agent_profile::*; @@ -62,12 +62,10 @@ impl<'de> Deserialize<'de> for AgentEditorMode { D: Deserializer<'de>, { let s = String::deserialize(deserializer)?; - dbg!(&s); if s == "inherit" { Ok(AgentEditorMode::Inherit) } else { let mode = EditorMode::deserialize(serde::de::value::StringDeserializer::new(s))?; - dbg!(&mode); Ok(AgentEditorMode::EditorModeOverride(mode)) } } @@ -91,7 +89,7 @@ impl JsonSchema for AgentEditorMode { } fn json_schema(_gen: &mut schemars::SchemaGenerator) -> schemars::Schema { - use vim_mode_setting::EditorMode; + use editor_mode_setting::EditorMode; let mut options = vec![serde_json::json!({ "const": "inherit", diff --git a/crates/agent_ui/Cargo.toml b/crates/agent_ui/Cargo.toml index 52ee0f600a..2c9967ea31 100644 --- a/crates/agent_ui/Cargo.toml +++ b/crates/agent_ui/Cargo.toml @@ -100,7 +100,7 @@ watch.workspace = true workspace-hack.workspace = true workspace.workspace = true zed_actions.workspace = true -vim_mode_setting.workspace = true +editor_mode_setting.workspace = true [dev-dependencies] acp_thread = { workspace = true, features = ["test-support"] } diff --git a/crates/agent_ui/src/acp/message_editor.rs b/crates/agent_ui/src/acp/message_editor.rs index 659b6e3cf1..4a9f0c8cd0 100644 --- a/crates/agent_ui/src/acp/message_editor.rs +++ b/crates/agent_ui/src/acp/message_editor.rs @@ -115,10 +115,9 @@ impl MessageEditor { let mention_set = MentionSet::default(); let settings = AgentSettings::get_global(cx); - dbg!(&settings); let editor_mode = match settings.editor_mode { AgentEditorMode::EditorModeOverride(mode) => mode, - AgentEditorMode::Inherit => vim_mode_setting::EditorModeSetting::get_global(cx).0, + AgentEditorMode::Inherit => editor_mode_setting::EditorModeSetting::get_global(cx).0, }; let editor = cx.new(|cx| { @@ -129,8 +128,6 @@ impl MessageEditor { editor.set_placeholder_text(placeholder, cx); editor.set_show_indent_guides(false, cx); editor.set_soft_wrap(); - println!("editor mode in agent acp"); - dbg!(&editor_mode); editor.set_editor_mode(editor_mode, cx); editor.set_completion_provider(Some(Rc::new(completion_provider))); editor.set_context_menu_options(ContextMenuOptions { @@ -174,7 +171,9 @@ impl MessageEditor { let settings = AgentSettings::get_global(cx); let editor_mode = match settings.editor_mode { AgentEditorMode::EditorModeOverride(mode) => mode, - AgentEditorMode::Inherit => vim_mode_setting::EditorModeSetting::get_global(cx).0, + AgentEditorMode::Inherit => { + editor_mode_setting::EditorModeSetting::get_global(cx).0 + } }; this.editor.update(cx, |editor, cx| { editor.set_editor_mode(editor_mode, cx); diff --git a/crates/agent_ui/src/message_editor.rs b/crates/agent_ui/src/message_editor.rs index 3a94d31a73..f94205491f 100644 --- a/crates/agent_ui/src/message_editor.rs +++ b/crates/agent_ui/src/message_editor.rs @@ -119,7 +119,7 @@ pub(crate) fn create_editor( let editor_mode = match settings.editor_mode { agent_settings::AgentEditorMode::EditorModeOverride(mode) => mode, agent_settings::AgentEditorMode::Inherit => { - vim_mode_setting::EditorModeSetting::get_global(cx).0 + editor_mode_setting::EditorModeSetting::get_global(cx).0 } }; @@ -136,8 +136,6 @@ pub(crate) fn create_editor( editor.set_placeholder_text("Message the agent – @ to include context", cx); editor.set_show_indent_guides(false, cx); editor.set_soft_wrap(); - println!("editor mode in agent"); - dbg!(&editor_mode); editor.set_editor_mode(editor_mode, cx); editor.set_context_menu_options(ContextMenuOptions { min_entries_visible: 12, @@ -243,7 +241,7 @@ impl MessageEditor { let editor_mode = match settings.editor_mode { agent_settings::AgentEditorMode::EditorModeOverride(mode) => mode, agent_settings::AgentEditorMode::Inherit => { - vim_mode_setting::EditorModeSetting::get_global(cx).0 + editor_mode_setting::EditorModeSetting::get_global(cx).0 } }; this.editor.update(cx, |editor, cx| { diff --git a/crates/debugger_ui/Cargo.toml b/crates/debugger_ui/Cargo.toml index 4ea0ddf95c..a7a9fdf61c 100644 --- a/crates/debugger_ui/Cargo.toml +++ b/crates/debugger_ui/Cargo.toml @@ -76,7 +76,7 @@ util.workspace = true workspace-hack.workspace = true workspace.workspace = true zed_actions.workspace = true -vim_mode_setting.workspace = true +editor_mode_setting.workspace = true [dev-dependencies] dap = { workspace = true, features = ["test-support"] } diff --git a/crates/debugger_ui/src/session/running/console.rs b/crates/debugger_ui/src/session/running/console.rs index 239641c34c..f4b43aeacd 100644 --- a/crates/debugger_ui/src/session/running/console.rs +++ b/crates/debugger_ui/src/session/running/console.rs @@ -7,6 +7,7 @@ use anyhow::Result; use collections::HashMap; use dap::{CompletionItem, CompletionItemType, OutputEvent}; use editor::{Bias, CompletionProvider, Editor, EditorElement, EditorStyle, ExcerptId}; +use editor_mode_setting::EditorMode; use fuzzy::StringMatchCandidate; use gpui::{ Action as _, AppContext, Context, Corner, Entity, FocusHandle, Focusable, HighlightStyle, Hsla, @@ -26,7 +27,6 @@ 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_setting::EditorMode; actions!( console, diff --git a/crates/editor/Cargo.toml b/crates/editor/Cargo.toml index c3a9f0f3c7..90346a65d5 100644 --- a/crates/editor/Cargo.toml +++ b/crates/editor/Cargo.toml @@ -92,7 +92,7 @@ uuid.workspace = true workspace.workspace = true zed_actions.workspace = true workspace-hack.workspace = true -vim_mode_setting.workspace = true +editor_mode_setting.workspace = true [dev-dependencies] ctor.workspace = true diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index a9e6ef6dec..8fbbe78f73 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -94,6 +94,7 @@ use convert_case::{Case, Casing}; use dap::TelemetrySpawnLocation; use display_map::*; use edit_prediction::{EditPredictionProvider, EditPredictionProviderHandle}; +use editor_mode_setting::{EditorMode, EditorModeSetting}; use editor_settings::{GoToDefinitionFallback, Minimap as MinimapSettings}; use element::{AcceptEditPredictionBinding, LineWithInvisibles, PositionMap, layout_line}; use futures::{ @@ -201,7 +202,6 @@ use ui::{ IconSize, Indicator, Key, Tooltip, h_flex, prelude::*, }; use util::{RangeExt, ResultExt, TryFutureExt, maybe, post_inc}; -use vim_mode_setting::{EditorMode, EditorModeSetting}; use workspace::{ CollaboratorId, Item as WorkspaceItem, ItemId, ItemNavHistory, OpenInTerminal, OpenTerminal, RestoreOnStartupBehavior, SERIALIZATION_THROTTLE_TIME, SplitDirection, TabBarSettings, Toast, @@ -1180,7 +1180,7 @@ pub struct Editor { next_color_inlay_id: usize, colors: Option, folding_newlines: Task<()>, - editor_mode: vim_mode_setting::EditorMode, + editor_mode: editor_mode_setting::EditorMode, } #[derive(Copy, Clone, Debug, PartialEq, Eq, Default)] @@ -2265,7 +2265,7 @@ impl Editor { editor_mode: if full_mode { EditorModeSetting::get_global(cx).0 } else { - vim_mode_setting::EditorMode::default() + editor_mode_setting::EditorMode::default() }, }; @@ -3003,7 +3003,7 @@ impl Editor { }) } - pub fn set_editor_mode(&mut self, to: vim_mode_setting::EditorMode, cx: &mut Context) { + pub fn set_editor_mode(&mut self, to: editor_mode_setting::EditorMode, cx: &mut Context) { let from = self.editor_mode; if from != to { self.editor_mode = to; @@ -3014,7 +3014,7 @@ impl Editor { } } - pub fn editor_mode(&self) -> vim_mode_setting::EditorMode { + pub fn editor_mode(&self) -> editor_mode_setting::EditorMode { self.editor_mode } diff --git a/crates/vim_mode_setting/Cargo.toml b/crates/editor_mode_setting/Cargo.toml similarity index 83% rename from crates/vim_mode_setting/Cargo.toml rename to crates/editor_mode_setting/Cargo.toml index 562632d1db..701f053da8 100644 --- a/crates/vim_mode_setting/Cargo.toml +++ b/crates/editor_mode_setting/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "vim_mode_setting" +name = "editor_mode_setting" version = "0.1.0" edition.workspace = true publish.workspace = true @@ -9,7 +9,7 @@ license = "GPL-3.0-or-later" workspace = true [lib] -path = "src/vim_mode_setting.rs" +path = "src/editor_mode_setting.rs" [dependencies] anyhow.workspace = true diff --git a/crates/vim_mode_setting/LICENSE-GPL b/crates/editor_mode_setting/LICENSE-GPL similarity index 100% rename from crates/vim_mode_setting/LICENSE-GPL rename to crates/editor_mode_setting/LICENSE-GPL diff --git a/crates/vim_mode_setting/src/vim_mode_setting.rs b/crates/editor_mode_setting/src/editor_mode_setting.rs similarity index 99% rename from crates/vim_mode_setting/src/vim_mode_setting.rs rename to crates/editor_mode_setting/src/editor_mode_setting.rs index 663b198bd0..7f714bff55 100644 --- a/crates/vim_mode_setting/src/vim_mode_setting.rs +++ b/crates/editor_mode_setting/src/editor_mode_setting.rs @@ -14,7 +14,7 @@ use settings::{Settings, SettingsSources}; use std::borrow::Cow; use std::fmt::Display; -/// Initializes the `vim_mode_setting` crate. +/// Initializes the `editor_mode_setting` crate. pub fn init(cx: &mut App) { EditorModeSetting::register(cx); } diff --git a/crates/extensions_ui/Cargo.toml b/crates/extensions_ui/Cargo.toml index c31483d763..21c09d3b1a 100644 --- a/crates/extensions_ui/Cargo.toml +++ b/crates/extensions_ui/Cargo.toml @@ -37,7 +37,7 @@ telemetry.workspace = true theme.workspace = true ui.workspace = true util.workspace = true -vim_mode_setting.workspace = true +editor_mode_setting.workspace = true workspace-hack.workspace = true workspace.workspace = true zed_actions.workspace = true diff --git a/crates/extensions_ui/src/extensions_ui.rs b/crates/extensions_ui/src/extensions_ui.rs index 58d975800d..408fc556bf 100644 --- a/crates/extensions_ui/src/extensions_ui.rs +++ b/crates/extensions_ui/src/extensions_ui.rs @@ -10,6 +10,7 @@ use anyhow::Context as _; use client::{ExtensionMetadata, ExtensionProvides}; use collections::{BTreeMap, BTreeSet}; use editor::{Editor, EditorElement, EditorStyle}; +use editor_mode_setting::{EditorMode, EditorModeSetting}; use extension_host::{ExtensionManifest, ExtensionOperation, ExtensionStore}; use fuzzy::{StringMatchCandidate, match_strings}; use gpui::{ @@ -27,7 +28,6 @@ use ui::{ CheckboxWithLabel, Chip, ContextMenu, PopoverMenu, ScrollableHandle, Scrollbar, ScrollbarState, ToggleButton, Tooltip, prelude::*, }; -use vim_mode_setting::{EditorMode, EditorModeSetting}; use workspace::{ Workspace, WorkspaceId, item::{Item, ItemEvent}, diff --git a/crates/onboarding/Cargo.toml b/crates/onboarding/Cargo.toml index 4157be3172..04ab861fa0 100644 --- a/crates/onboarding/Cargo.toml +++ b/crates/onboarding/Cargo.toml @@ -40,7 +40,7 @@ telemetry.workspace = true theme.workspace = true ui.workspace = true util.workspace = true -vim_mode_setting.workspace = true +editor_mode_setting.workspace = true workspace-hack.workspace = true workspace.workspace = true zed_actions.workspace = true diff --git a/crates/onboarding/src/basics_page.rs b/crates/onboarding/src/basics_page.rs index d679009220..afcee30f1c 100644 --- a/crates/onboarding/src/basics_page.rs +++ b/crates/onboarding/src/basics_page.rs @@ -1,6 +1,7 @@ use std::sync::Arc; use client::TelemetrySettings; +use editor_mode_setting::{EditorMode, EditorModeSetting}; use fs::Fs; use gpui::{App, IntoElement}; use settings::{BaseKeymap, Settings, update_settings_file}; @@ -12,7 +13,6 @@ use ui::{ ParentElement as _, StatefulInteractiveElement, SwitchField, ToggleButtonGroup, ToggleButtonSimple, ToggleButtonWithIcon, prelude::*, rems_from_px, }; -use vim_mode_setting::{EditorMode, EditorModeSetting}; use crate::theme_preview::{ThemePreviewStyle, ThemePreviewTile}; diff --git a/crates/rules_library/Cargo.toml b/crates/rules_library/Cargo.toml index 06d7ff9d40..a6fa0b28d1 100644 --- a/crates/rules_library/Cargo.toml +++ b/crates/rules_library/Cargo.toml @@ -33,4 +33,4 @@ util.workspace = true workspace-hack.workspace = true workspace.workspace = true zed_actions.workspace = true -vim_mode_setting.workspace = true +editor_mode_setting.workspace = true diff --git a/crates/rules_library/src/rules_library.rs b/crates/rules_library/src/rules_library.rs index fb273c65ee..3302b71028 100644 --- a/crates/rules_library/src/rules_library.rs +++ b/crates/rules_library/src/rules_library.rs @@ -2,6 +2,7 @@ use anyhow::Result; use collections::{HashMap, HashSet}; use editor::{CompletionProvider, SelectionEffects}; use editor::{CurrentLineHighlight, Editor, EditorElement, EditorEvent, EditorStyle, actions::Tab}; +use editor_mode_setting::EditorMode; use gpui::{ Action, App, Bounds, Entity, EventEmitter, Focusable, PromptLevel, Subscription, Task, TextStyle, TitlebarOptions, WindowBounds, WindowHandle, WindowOptions, actions, point, size, @@ -26,7 +27,6 @@ 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/Cargo.toml b/crates/vim/Cargo.toml index 434b14b07c..c9f4e71f49 100644 --- a/crates/vim/Cargo.toml +++ b/crates/vim/Cargo.toml @@ -47,7 +47,7 @@ theme.workspace = true tokio = { version = "1.15", features = ["full"], optional = true } ui.workspace = true util.workspace = true -vim_mode_setting.workspace = true +editor_mode_setting.workspace = true workspace.workspace = true zed_actions.workspace = true workspace-hack.workspace = true diff --git a/crates/vim/src/insert.rs b/crates/vim/src/insert.rs index 9bc6c1c951..fd0c591bdd 100644 --- a/crates/vim/src/insert.rs +++ b/crates/vim/src/insert.rs @@ -1,10 +1,10 @@ use crate::{Vim, state::Mode}; use editor::{Bias, Editor}; +use editor_mode_setting::{EditorMode, EditorModeSetting}; use gpui::{Action, Context, Window, actions}; use language::SelectionGoal; use settings::Settings; use text::Point; -use vim_mode_setting::{EditorMode, EditorModeSetting}; use workspace::searchable::Direction; actions!( diff --git a/crates/vim/src/normal/paste.rs b/crates/vim/src/normal/paste.rs index 460aac8075..a32961f7d7 100644 --- a/crates/vim/src/normal/paste.rs +++ b/crates/vim/src/normal/paste.rs @@ -1,11 +1,11 @@ use editor::{DisplayPoint, RowExt, SelectionEffects, display_map::ToDisplayPoint, movement}; +use editor_mode_setting::{EditorMode, EditorModeSetting}; use gpui::{Action, Context, Window}; use language::{Bias, SelectionGoal}; use schemars::JsonSchema; use serde::Deserialize; use settings::Settings; use std::cmp; -use vim_mode_setting::{EditorMode, EditorModeSetting}; use crate::{ Vim, diff --git a/crates/vim/src/state.rs b/crates/vim/src/state.rs index 290f0af9ee..5c7271dfbd 100644 --- a/crates/vim/src/state.rs +++ b/crates/vim/src/state.rs @@ -11,6 +11,7 @@ use db::define_connection; use db::sqlez_macros::sql; use editor::display_map::{is_invisible, replacement}; use editor::{Anchor, ClipboardSelection, Editor, MultiBuffer, ToPoint as EditorToPoint}; +pub use editor_mode_setting::ModalMode as Mode; use gpui::{ Action, App, AppContext, BorrowAppContext, ClipboardEntry, ClipboardItem, DismissEvent, Entity, EntityId, Global, HighlightStyle, StyledText, Subscription, Task, TextStyle, WeakEntity, @@ -31,7 +32,6 @@ use ui::{ StyledTypography, Window, h_flex, rems, }; use util::ResultExt; -pub use vim_mode_setting::ModalMode as Mode; use workspace::searchable::Direction; use workspace::{Workspace, WorkspaceDb, WorkspaceId}; diff --git a/crates/vim/src/test/vim_test_context.rs b/crates/vim/src/test/vim_test_context.rs index b4c309c2c5..6ac282fbe8 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, state::Mode, *}; +use crate::{state::Mode, state::Operator, *}; pub struct VimTestContext { cx: EditorLspTestContext, @@ -156,7 +156,7 @@ impl VimTestContext { pub fn enable_helix(&mut self) { self.cx.update(|_, cx| { SettingsStore::update_global(cx, |store, cx| { - store.update_user_settings::(cx, |s| { + store.update_user_settings::(cx, |s| { *s = Some(EditorMode::Helix(ModalMode::HelixNormal)) }); }); diff --git a/crates/vim/src/vim.rs b/crates/vim/src/vim.rs index f3d4b746f3..3ea8a275fe 100644 --- a/crates/vim/src/vim.rs +++ b/crates/vim/src/vim.rs @@ -26,6 +26,7 @@ use editor::{ ToPoint, movement::{self, FindRange}, }; +use editor_mode_setting::{EditorMode, EditorModeSetting, ModalMode}; use gpui::{ Action, App, AppContext, Axis, Context, Entity, EventEmitter, KeyContext, KeystrokeEvent, Render, Subscription, Task, WeakEntity, Window, actions, @@ -45,7 +46,6 @@ use std::{mem, ops::Range, sync::Arc}; use surrounds::SurroundsType; use theme::ThemeSettings; use ui::{IntoElement, SharedString, px}; -use vim_mode_setting::{EditorMode, EditorModeSetting, ModalMode}; use workspace::{self, Pane, Workspace}; use crate::state::ReplayableAction; @@ -235,7 +235,7 @@ actions!( /// Initializes the `vim` crate. pub fn init(cx: &mut App) { - vim_mode_setting::init(cx); + editor_mode_setting::init(cx); VimSettings::register(cx); VimGlobals::register(cx); @@ -813,7 +813,6 @@ impl Vim { } pub fn global_enabled(cx: &mut App) -> bool { - dbg!(&EditorModeSetting::get_global(cx).0); if EditorModeSetting::get_global(cx).0 == EditorMode::Default { return false; } diff --git a/crates/zed/Cargo.toml b/crates/zed/Cargo.toml index c61e23f0a1..67b54e58ea 100644 --- a/crates/zed/Cargo.toml +++ b/crates/zed/Cargo.toml @@ -156,7 +156,7 @@ urlencoding.workspace = true util.workspace = true uuid.workspace = true vim.workspace = true -vim_mode_setting.workspace = true +editor_mode_setting.workspace = true watch.workspace = true web_search.workspace = true web_search_providers.workspace = true diff --git a/crates/zed/src/zed.rs b/crates/zed/src/zed.rs index 2d47c07ad6..647c45631f 100644 --- a/crates/zed/src/zed.rs +++ b/crates/zed/src/zed.rs @@ -19,6 +19,7 @@ use collections::VecDeque; use debugger_ui::debugger_panel::DebugPanel; use editor::ProposedChangesEditorToolbar; use editor::{Editor, MultiBuffer}; +use editor_mode_setting::EditorModeSetting; use feature_flags::{FeatureFlagAppExt, PanicFeatureFlag}; use futures::future::Either; use futures::{StreamExt, channel::mpsc, select_biased}; @@ -70,7 +71,6 @@ use ui::{PopoverMenuHandle, prelude::*}; use util::markdown::MarkdownString; use util::{ResultExt, asset_str}; use uuid::Uuid; -use vim_mode_setting::EditorModeSetting; use workspace::notifications::{ NotificationId, SuppressEvent, dismiss_app_notification, show_app_notification, }; @@ -1282,7 +1282,7 @@ pub fn handle_keymap_file_changes( cx: &mut App, ) { BaseKeymap::register(cx); - vim_mode_setting::init(cx); + editor_mode_setting::init(cx); let (base_keymap_tx, mut base_keymap_rx) = mpsc::unbounded(); let (keyboard_layout_tx, mut keyboard_layout_rx) = mpsc::unbounded(); @@ -4616,7 +4616,7 @@ mod tests { app_state.languages.add(markdown_language()); gpui_tokio::init(cx); - vim_mode_setting::init(cx); + editor_mode_setting::init(cx); theme::init(theme::LoadThemes::JustBase, cx); audio::init(cx); channel::init(&app_state.client, app_state.user_store.clone(), cx); diff --git a/crates/zed/src/zed/quick_action_bar.rs b/crates/zed/src/zed/quick_action_bar.rs index 34eac520f2..b13c78d411 100644 --- a/crates/zed/src/zed/quick_action_bar.rs +++ b/crates/zed/src/zed/quick_action_bar.rs @@ -10,6 +10,7 @@ use editor::actions::{ }; use editor::code_context_menus::{CodeContextMenu, ContextMenuOrigin}; use editor::{Editor, EditorSettings}; +use editor_mode_setting::{EditorMode, EditorModeSetting}; use gpui::{ Action, AnchoredPositionMode, ClickEvent, Context, Corner, ElementId, Entity, EventEmitter, FocusHandle, Focusable, InteractiveElement, ParentElement, Render, Styled, Subscription, @@ -23,7 +24,6 @@ use ui::{ ButtonStyle, ContextMenu, ContextMenuEntry, DocumentationSide, IconButton, IconName, IconSize, PopoverMenu, PopoverMenuHandle, Tooltip, prelude::*, }; -use vim_mode_setting::{EditorMode, EditorModeSetting}; use workspace::{ ToolbarItemEvent, ToolbarItemLocation, ToolbarItemView, Workspace, item::ItemHandle, }; From bd886e423c356c03755e0bf22d4bb479097ee5ab Mon Sep 17 00:00:00 2001 From: Oleksiy Syvokon Date: Fri, 22 Aug 2025 15:39:23 +0300 Subject: [PATCH 15/15] Don't read global vim mode setting + mode->display_mode --- crates/editor/src/editor.rs | 39 +++++++++++++++---------------------- 1 file changed, 16 insertions(+), 23 deletions(-) diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index 8fbbe78f73..efc071a61e 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -1763,17 +1763,17 @@ impl Editor { } pub fn new( - mode: EditorDisplayMode, + display_mode: EditorDisplayMode, buffer: Entity, project: Option>, window: &mut Window, cx: &mut Context, ) -> Self { - Editor::new_internal(mode, buffer, project, None, window, cx) + Editor::new_internal(display_mode, buffer, project, None, window, cx) } fn new_internal( - mode: EditorDisplayMode, + display_mode: EditorDisplayMode, buffer: Entity, project: Option>, display_map: Option>, @@ -1781,12 +1781,12 @@ impl Editor { cx: &mut Context, ) -> Self { debug_assert!( - display_map.is_none() || mode.is_minimap(), + display_map.is_none() || display_mode.is_minimap(), "Providing a display map for a new editor is only intended for the minimap and might have unintended side effects otherwise!" ); - let full_mode = mode.is_full(); - let is_minimap = mode.is_minimap(); + let full_mode = display_mode.is_full(); + let is_minimap = display_mode.is_minimap(); let diagnostics_max_severity = if full_mode { EditorSettings::get_global(cx) .diagnostics_max_severity @@ -1855,7 +1855,7 @@ impl Editor { blink_manager }); - let soft_wrap_mode_override = matches!(mode, EditorDisplayMode::SingleLine) + let soft_wrap_mode_override = matches!(display_mode, EditorDisplayMode::SingleLine) .then(|| language_settings::SoftWrap::None); let mut project_subscriptions = Vec::new(); @@ -2036,7 +2036,7 @@ impl Editor { } let show_indent_guides = if matches!( - mode, + display_mode, EditorDisplayMode::SingleLine | EditorDisplayMode::Minimap { .. } ) { Some(false) @@ -2044,7 +2044,7 @@ impl Editor { None }; - let breakpoint_store = match (&mode, project.as_ref()) { + let breakpoint_store = match (&display_mode, project.as_ref()) { (EditorDisplayMode::Full { .. }, Some(project)) => { Some(project.read(cx).breakpoint_store()) } @@ -2103,8 +2103,8 @@ impl Editor { horizontal: full_mode, vertical: full_mode, }, - minimap_visibility: MinimapVisibility::for_display_mode(&mode, cx), - offset_content: !matches!(mode, EditorDisplayMode::SingleLine), + minimap_visibility: MinimapVisibility::for_display_mode(&display_mode, cx), + offset_content: !matches!(display_mode, EditorDisplayMode::SingleLine), show_breadcrumbs: EditorSettings::get_global(cx).toolbar.breadcrumbs, show_gutter: full_mode, show_line_numbers: (!full_mode).then_some(false), @@ -2259,7 +2259,7 @@ impl Editor { .hide_mouse .unwrap_or_default(), change_list: ChangeList::new(), - display_mode: mode, + display_mode, selection_drag_state: SelectionDragState::None, folding_newlines: Task::ready(()), editor_mode: if full_mode { @@ -2302,7 +2302,7 @@ impl Editor { } } EditorEvent::Edited { .. } => { - if !vim_enabled(cx) { + if !editor.editor_mode().is_modal() { let (map, selections) = editor.selections.all_adjusted_display(cx); let pop_state = editor .change_list @@ -2461,7 +2461,7 @@ impl Editor { ) -> KeyContext { let mut key_context = KeyContext::new_with_defaults(); key_context.add("Editor"); - let mode = match self.display_mode { + let display_mode = match self.display_mode { EditorDisplayMode::SingleLine => "single_line", EditorDisplayMode::AutoHeight { .. } => "auto_height", EditorDisplayMode::Minimap { .. } => "minimap", @@ -2472,7 +2472,7 @@ impl Editor { key_context.add("jupyter"); } - key_context.set("mode", mode); + key_context.set("mode", display_mode); if self.pending_rename.is_some() { key_context.add("renaming"); } @@ -20663,7 +20663,7 @@ impl Editor { .and_then(|e| e.to_str()) .map(|a| a.to_string())); - let vim_mode = vim_enabled(cx); + let vim_mode = self.editor_mode.is_modal(); let edit_predictions_provider = all_language_settings(file, cx).edit_predictions.provider; let copilot_enabled = edit_predictions_provider @@ -21254,13 +21254,6 @@ impl Editor { } } -fn vim_enabled(cx: &App) -> bool { - cx.global::() - .raw_user_settings() - .get("vim_mode") - == Some(&serde_json::Value::Bool(true)) -} - fn process_completion_for_edit( completion: &Completion, intent: CompletionIntent,