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(