Compare commits
15 commits
main
...
editor-mod
Author | SHA1 | Date | |
---|---|---|---|
![]() |
bd886e423c | ||
![]() |
1e4614f9a0 | ||
![]() |
ea5425f818 | ||
![]() |
96523f0d77 | ||
![]() |
d3e1730b72 | ||
![]() |
f7b946e525 | ||
![]() |
dfa7cd431a | ||
![]() |
bbbc168f50 | ||
![]() |
66fac38cf8 | ||
![]() |
1ecb2ff30b | ||
![]() |
fd0316f7d1 | ||
![]() |
c6d0d75711 | ||
![]() |
57a0bb327d | ||
![]() |
854b7e104e | ||
![]() |
0d5becfadf |
61 changed files with 879 additions and 599 deletions
36
Cargo.lock
generated
36
Cargo.lock
generated
|
@ -313,6 +313,7 @@ dependencies = [
|
|||
"anyhow",
|
||||
"cloud_llm_client",
|
||||
"collections",
|
||||
"editor_mode_setting",
|
||||
"fs",
|
||||
"gpui",
|
||||
"language_model",
|
||||
|
@ -354,6 +355,7 @@ dependencies = [
|
|||
"context_server",
|
||||
"db",
|
||||
"editor",
|
||||
"editor_mode_setting",
|
||||
"extension",
|
||||
"extension_host",
|
||||
"feature_flags",
|
||||
|
@ -4547,6 +4549,7 @@ dependencies = [
|
|||
"db",
|
||||
"debugger_tools",
|
||||
"editor",
|
||||
"editor_mode_setting",
|
||||
"file_icons",
|
||||
"futures 0.3.31",
|
||||
"fuzzy",
|
||||
|
@ -5061,6 +5064,7 @@ dependencies = [
|
|||
"dap",
|
||||
"db",
|
||||
"edit_prediction",
|
||||
"editor_mode_setting",
|
||||
"emojis",
|
||||
"file_icons",
|
||||
"fs",
|
||||
|
@ -5121,6 +5125,19 @@ dependencies = [
|
|||
"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"
|
||||
|
@ -5612,6 +5629,7 @@ dependencies = [
|
|||
"collections",
|
||||
"db",
|
||||
"editor",
|
||||
"editor_mode_setting",
|
||||
"extension",
|
||||
"extension_host",
|
||||
"fs",
|
||||
|
@ -5632,7 +5650,6 @@ dependencies = [
|
|||
"theme",
|
||||
"ui",
|
||||
"util",
|
||||
"vim_mode_setting",
|
||||
"workspace",
|
||||
"workspace-hack",
|
||||
"zed_actions",
|
||||
|
@ -11101,6 +11118,7 @@ dependencies = [
|
|||
"db",
|
||||
"documented",
|
||||
"editor",
|
||||
"editor_mode_setting",
|
||||
"fs",
|
||||
"fuzzy",
|
||||
"git",
|
||||
|
@ -11119,7 +11137,6 @@ dependencies = [
|
|||
"theme",
|
||||
"ui",
|
||||
"util",
|
||||
"vim_mode_setting",
|
||||
"workspace",
|
||||
"workspace-hack",
|
||||
"zed_actions",
|
||||
|
@ -13962,6 +13979,7 @@ dependencies = [
|
|||
"anyhow",
|
||||
"collections",
|
||||
"editor",
|
||||
"editor_mode_setting",
|
||||
"gpui",
|
||||
"language",
|
||||
"language_model",
|
||||
|
@ -17952,6 +17970,7 @@ dependencies = [
|
|||
"command_palette_hooks",
|
||||
"db",
|
||||
"editor",
|
||||
"editor_mode_setting",
|
||||
"env_logger 0.11.8",
|
||||
"futures 0.3.31",
|
||||
"git_ui",
|
||||
|
@ -17981,22 +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",
|
||||
"settings",
|
||||
"workspace-hack",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "vscode_theme"
|
||||
version = "0.2.0"
|
||||
|
@ -20455,6 +20463,7 @@ dependencies = [
|
|||
"diagnostics",
|
||||
"edit_prediction_button",
|
||||
"editor",
|
||||
"editor_mode_setting",
|
||||
"env_logger 0.11.8",
|
||||
"extension",
|
||||
"extension_host",
|
||||
|
@ -20554,7 +20563,6 @@ dependencies = [
|
|||
"util",
|
||||
"uuid",
|
||||
"vim",
|
||||
"vim_mode_setting",
|
||||
"watch",
|
||||
"web_search",
|
||||
"web_search_providers",
|
||||
|
|
|
@ -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" }
|
||||
|
|
|
@ -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.
|
||||
|
@ -885,7 +889,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": {
|
||||
|
|
|
@ -19,8 +19,10 @@ gpui.workspace = true
|
|||
language_model.workspace = true
|
||||
schemars.workspace = true
|
||||
serde.workspace = true
|
||||
serde_json.workspace = true
|
||||
settings.workspace = true
|
||||
workspace-hack.workspace = true
|
||||
editor_mode_setting.workspace = true
|
||||
|
||||
[dev-dependencies]
|
||||
fs.workspace = true
|
||||
|
|
|
@ -4,10 +4,11 @@ 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, Serialize};
|
||||
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
||||
use settings::{Settings, SettingsSources};
|
||||
use std::borrow::Cow;
|
||||
|
||||
|
@ -48,6 +49,67 @@ pub enum NotifyWhenAgentWaiting {
|
|||
Never,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Default)]
|
||||
pub enum AgentEditorMode {
|
||||
EditorModeOverride(EditorMode),
|
||||
#[default]
|
||||
Inherit,
|
||||
}
|
||||
|
||||
impl<'de> Deserialize<'de> for AgentEditorMode {
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
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<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: Serializer,
|
||||
{
|
||||
match self {
|
||||
AgentEditorMode::EditorModeOverride(mode) => mode.serialize(serializer),
|
||||
AgentEditorMode::Inherit => serializer.serialize_str("inherit"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl JsonSchema for AgentEditorMode {
|
||||
fn schema_name() -> Cow<'static, str> {
|
||||
"AgentEditorMode".into()
|
||||
}
|
||||
|
||||
fn json_schema(_gen: &mut schemars::SchemaGenerator) -> schemars::Schema {
|
||||
use editor_mode_setting::EditorMode;
|
||||
|
||||
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"
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl From<EditorMode> for AgentEditorMode {
|
||||
fn from(b: EditorMode) -> Self {
|
||||
AgentEditorMode::EditorModeOverride(b)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default, Clone, Debug)]
|
||||
pub struct AgentSettings {
|
||||
pub enabled: bool,
|
||||
|
@ -75,6 +137,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 +378,10 @@ pub struct AgentSettingsContent {
|
|||
///
|
||||
/// Default: false
|
||||
use_modifier_to_send: Option<bool>,
|
||||
/// Weather to inherit or override the editor mode for the agent panel.
|
||||
///
|
||||
/// Default: inherit
|
||||
editor_mode: Option<AgentEditorMode>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Default)]
|
||||
|
@ -470,6 +537,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
|
||||
|
|
|
@ -100,6 +100,7 @@ watch.workspace = true
|
|||
workspace-hack.workspace = true
|
||||
workspace.workspace = true
|
||||
zed_actions.workspace = true
|
||||
editor_mode_setting.workspace = true
|
||||
|
||||
[dev-dependencies]
|
||||
acp_thread = { workspace = true, features = ["test-support"] }
|
||||
|
|
|
@ -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<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,
|
||||
|
|
|
@ -5,14 +5,15 @@ 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;
|
||||
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 +91,7 @@ impl MessageEditor {
|
|||
prompt_capabilities: Rc<Cell<acp::PromptCapabilities>>,
|
||||
placeholder: impl Into<Arc<str>>,
|
||||
prevent_slash_commands: bool,
|
||||
mode: EditorMode,
|
||||
mode: EditorDisplayMode,
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) -> Self {
|
||||
|
@ -112,6 +113,13 @@ impl MessageEditor {
|
|||
range: Cell::new(None),
|
||||
});
|
||||
let mention_set = MentionSet::default();
|
||||
|
||||
let settings = AgentSettings::get_global(cx);
|
||||
let editor_mode = match settings.editor_mode {
|
||||
AgentEditorMode::EditorModeOverride(mode) => mode,
|
||||
AgentEditorMode::Inherit => editor_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_editor_mode(editor_mode, cx);
|
||||
editor.set_completion_provider(Some(Rc::new(completion_provider)));
|
||||
editor.set_context_menu_options(ContextMenuOptions {
|
||||
min_entries_visible: 12,
|
||||
|
@ -159,6 +167,19 @@ impl MessageEditor {
|
|||
}
|
||||
}));
|
||||
|
||||
subscriptions.push(cx.observe_global::<AgentSettings>(move |this, cx| {
|
||||
let settings = AgentSettings::get_global(cx);
|
||||
let editor_mode = match settings.editor_mode {
|
||||
AgentEditorMode::EditorModeOverride(mode) => mode,
|
||||
AgentEditorMode::Inherit => {
|
||||
editor_mode_setting::EditorModeSetting::get_global(cx).0
|
||||
}
|
||||
};
|
||||
this.editor.update(cx, |editor, cx| {
|
||||
editor.set_editor_mode(editor_mode, cx);
|
||||
});
|
||||
}));
|
||||
|
||||
Self {
|
||||
editor,
|
||||
project,
|
||||
|
@ -1056,9 +1077,9 @@ impl MessageEditor {
|
|||
})
|
||||
}
|
||||
|
||||
pub fn set_mode(&mut self, mode: EditorMode, cx: &mut Context<Self>) {
|
||||
pub fn set_display_mode(&mut self, mode: EditorDisplayMode, cx: &mut Context<Self>) {
|
||||
self.editor.update(cx, |editor, cx| {
|
||||
editor.set_mode(mode);
|
||||
editor.set_display_mode(mode);
|
||||
cx.notify()
|
||||
});
|
||||
}
|
||||
|
@ -1858,7 +1879,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 +1922,7 @@ mod tests {
|
|||
Default::default(),
|
||||
"Test",
|
||||
false,
|
||||
EditorMode::AutoHeight {
|
||||
EditorDisplayMode::AutoHeight {
|
||||
min_lines: 1,
|
||||
max_lines: None,
|
||||
},
|
||||
|
@ -2102,7 +2123,7 @@ mod tests {
|
|||
prompt_capabilities.clone(),
|
||||
"Test",
|
||||
false,
|
||||
EditorMode::AutoHeight {
|
||||
EditorDisplayMode::AutoHeight {
|
||||
max_lines: None,
|
||||
min_lines: 1,
|
||||
},
|
||||
|
|
|
@ -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),
|
||||
},
|
||||
|
|
|
@ -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),
|
||||
},
|
||||
|
|
|
@ -1046,7 +1046,7 @@ impl ToolbarItemView for AgentDiffToolbar {
|
|||
}
|
||||
|
||||
if let Some(editor) = item.act_as::<Editor>(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<WeakEntity<Buffer>> {
|
||||
if editor.mode().is_full() {
|
||||
if editor.display_mode().is_full() {
|
||||
editor
|
||||
.buffer()
|
||||
.read(cx)
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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<BufferCodegen> {
|
|||
|
||||
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<TerminalCodegen> {
|
|||
|
||||
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),
|
||||
},
|
||||
|
|
|
@ -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;
|
||||
|
@ -114,8 +114,17 @@ 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::EditorModeOverride(mode) => mode,
|
||||
agent_settings::AgentEditorMode::Inherit => {
|
||||
editor_mode_setting::EditorModeSetting::get_global(cx).0
|
||||
}
|
||||
};
|
||||
|
||||
let mut editor = Editor::new(
|
||||
editor::EditorMode::AutoHeight {
|
||||
editor::EditorDisplayMode::AutoHeight {
|
||||
min_lines,
|
||||
max_lines,
|
||||
},
|
||||
|
@ -127,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_use_modal_editing(true);
|
||||
editor.set_editor_mode(editor_mode, cx);
|
||||
editor.set_context_menu_options(ContextMenuOptions {
|
||||
min_entries_visible: 12,
|
||||
max_entries_visible: 12,
|
||||
|
@ -227,6 +236,18 @@ impl MessageEditor {
|
|||
cx.observe(&thread.read(cx).action_log().clone(), |_, _, cx| {
|
||||
cx.notify()
|
||||
}),
|
||||
cx.observe_global::<AgentSettings>(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 => {
|
||||
editor_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| {
|
||||
|
@ -299,13 +320,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),
|
||||
})
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -76,6 +76,7 @@ util.workspace = true
|
|||
workspace-hack.workspace = true
|
||||
workspace.workspace = true
|
||||
zed_actions.workspace = true
|
||||
editor_mode_setting.workspace = true
|
||||
|
||||
[dev-dependencies]
|
||||
dap = { workspace = true, features = ["test-support"] }
|
||||
|
|
|
@ -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,
|
||||
|
@ -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_editor_mode(EditorMode::Default, cx);
|
||||
editor.set_soft_wrap_mode(language::language_settings::SoftWrap::EditorWidth, cx);
|
||||
editor
|
||||
});
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -92,6 +92,7 @@ uuid.workspace = true
|
|||
workspace.workspace = true
|
||||
zed_actions.workspace = true
|
||||
workspace-hack.workspace = true
|
||||
editor_mode_setting.workspace = true
|
||||
|
||||
[dev-dependencies]
|
||||
ctor.workspace = true
|
||||
|
|
|
@ -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::{
|
||||
|
@ -494,7 +495,7 @@ pub enum SelectMode {
|
|||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, Debug)]
|
||||
pub enum EditorMode {
|
||||
pub enum EditorDisplayMode {
|
||||
SingleLine,
|
||||
AutoHeight {
|
||||
min_lines: usize,
|
||||
|
@ -513,7 +514,7 @@ pub enum EditorMode {
|
|||
},
|
||||
}
|
||||
|
||||
impl EditorMode {
|
||||
impl EditorDisplayMode {
|
||||
pub fn full() -> Self {
|
||||
Self::Full {
|
||||
scale_ui_elements_with_buffer_font_size: true,
|
||||
|
@ -757,7 +758,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(),
|
||||
|
@ -1044,7 +1045,7 @@ pub struct Editor {
|
|||
show_cursor_names: bool,
|
||||
hovered_cursors: HashMap<HoveredCursor, Task<()>>,
|
||||
pub show_local_selections: bool,
|
||||
mode: EditorMode,
|
||||
display_mode: EditorDisplayMode,
|
||||
show_breadcrumbs: bool,
|
||||
show_gutter: bool,
|
||||
show_scrollbars: ScrollbarAxes,
|
||||
|
@ -1092,7 +1093,6 @@ pub struct Editor {
|
|||
autoindent_mode: Option<AutoindentMode>,
|
||||
workspace: Option<(WeakEntity<Workspace>, Option<WorkspaceId>)>,
|
||||
input_enabled: bool,
|
||||
use_modal_editing: bool,
|
||||
read_only: bool,
|
||||
leader_id: Option<CollaboratorId>,
|
||||
remote_id: Option<ViewId>,
|
||||
|
@ -1180,6 +1180,7 @@ pub struct Editor {
|
|||
next_color_inlay_id: usize,
|
||||
colors: Option<LspColorData>,
|
||||
folding_newlines: Task<()>,
|
||||
editor_mode: editor_mode_setting::EditorMode,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Default)]
|
||||
|
@ -1202,7 +1203,7 @@ impl NextScrollCursorCenterTopBottom {
|
|||
|
||||
#[derive(Clone)]
|
||||
pub struct EditorSnapshot {
|
||||
pub mode: EditorMode,
|
||||
pub display_mode: EditorDisplayMode,
|
||||
show_gutter: bool,
|
||||
show_line_numbers: Option<bool>,
|
||||
show_git_diff_gutter: Option<bool>,
|
||||
|
@ -1670,13 +1671,13 @@ impl Editor {
|
|||
pub fn single_line(window: &mut Window, cx: &mut Context<Self>) -> 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>) -> 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(
|
||||
|
@ -1688,7 +1689,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),
|
||||
},
|
||||
|
@ -1709,7 +1710,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,
|
||||
},
|
||||
|
@ -1727,7 +1728,7 @@ impl Editor {
|
|||
cx: &mut Context<Self>,
|
||||
) -> 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(
|
||||
|
@ -1736,12 +1737,12 @@ impl Editor {
|
|||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) -> 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>) -> Self {
|
||||
let mut clone = Self::new(
|
||||
self.mode.clone(),
|
||||
self.display_mode.clone(),
|
||||
self.buffer.clone(),
|
||||
self.project.clone(),
|
||||
window,
|
||||
|
@ -1762,17 +1763,17 @@ impl Editor {
|
|||
}
|
||||
|
||||
pub fn new(
|
||||
mode: EditorMode,
|
||||
display_mode: EditorDisplayMode,
|
||||
buffer: Entity<MultiBuffer>,
|
||||
project: Option<Entity<Project>>,
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) -> Self {
|
||||
Editor::new_internal(mode, buffer, project, None, window, cx)
|
||||
Editor::new_internal(display_mode, buffer, project, None, window, cx)
|
||||
}
|
||||
|
||||
fn new_internal(
|
||||
mode: EditorMode,
|
||||
display_mode: EditorDisplayMode,
|
||||
buffer: Entity<MultiBuffer>,
|
||||
project: Option<Entity<Project>>,
|
||||
display_map: Option<Entity<DisplayMap>>,
|
||||
|
@ -1780,12 +1781,12 @@ impl Editor {
|
|||
cx: &mut Context<Self>,
|
||||
) -> 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
|
||||
|
@ -1854,8 +1855,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!(display_mode, EditorDisplayMode::SingleLine)
|
||||
.then(|| language_settings::SoftWrap::None);
|
||||
|
||||
let mut project_subscriptions = Vec::new();
|
||||
if full_mode && let Some(project) = project.as_ref() {
|
||||
|
@ -2034,15 +2035,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!(
|
||||
display_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()),
|
||||
let breakpoint_store = match (&display_mode, project.as_ref()) {
|
||||
(EditorDisplayMode::Full { .. }, Some(project)) => {
|
||||
Some(project.read(cx).breakpoint_store())
|
||||
}
|
||||
_ => None,
|
||||
};
|
||||
|
||||
|
@ -2098,8 +2103,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(&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),
|
||||
|
@ -2147,7 +2152,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,
|
||||
|
@ -2255,9 +2259,14 @@ impl Editor {
|
|||
.hide_mouse
|
||||
.unwrap_or_default(),
|
||||
change_list: ChangeList::new(),
|
||||
mode,
|
||||
display_mode,
|
||||
selection_drag_state: SelectionDragState::None,
|
||||
folding_newlines: Task::ready(()),
|
||||
editor_mode: if full_mode {
|
||||
EditorModeSetting::get_global(cx).0
|
||||
} else {
|
||||
editor_mode_setting::EditorMode::default()
|
||||
},
|
||||
};
|
||||
|
||||
if is_minimap {
|
||||
|
@ -2293,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
|
||||
|
@ -2383,7 +2392,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);
|
||||
}
|
||||
|
||||
|
@ -2452,18 +2461,18 @@ 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 display_mode = match self.display_mode {
|
||||
EditorDisplayMode::SingleLine => "single_line",
|
||||
EditorDisplayMode::AutoHeight { .. } => "auto_height",
|
||||
EditorDisplayMode::Minimap { .. } => "minimap",
|
||||
EditorDisplayMode::Full { .. } => "full",
|
||||
};
|
||||
|
||||
if EditorSettings::jupyter_enabled(cx) {
|
||||
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");
|
||||
}
|
||||
|
@ -2720,7 +2729,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,
|
||||
|
@ -2757,12 +2766,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> {
|
||||
|
@ -2994,12 +3003,19 @@ impl Editor {
|
|||
})
|
||||
}
|
||||
|
||||
pub fn set_use_modal_editing(&mut self, to: bool) {
|
||||
self.use_modal_editing = to;
|
||||
pub fn set_editor_mode(&mut self, to: editor_mode_setting::EditorMode, cx: &mut Context<Self>) {
|
||||
let from = self.editor_mode;
|
||||
if from != to {
|
||||
self.editor_mode = to;
|
||||
cx.emit(EditorEvent::EditorModeChanged {
|
||||
old_mode: from,
|
||||
new_mode: to,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
pub fn use_modal_editing(&self) -> bool {
|
||||
self.use_modal_editing
|
||||
pub fn editor_mode(&self) -> editor_mode_setting::EditorMode {
|
||||
self.editor_mode
|
||||
}
|
||||
|
||||
fn selections_did_change(
|
||||
|
@ -3202,7 +3218,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;
|
||||
|
@ -3885,7 +3901,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;
|
||||
|
@ -3928,7 +3944,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;
|
||||
}
|
||||
|
@ -5142,7 +5160,7 @@ impl Editor {
|
|||
}
|
||||
|
||||
fn refresh_inlay_hints(&mut self, reason: InlayHintRefreshReason, cx: &mut Context<Self>) {
|
||||
if self.semantics_provider.is_none() || !self.mode.is_full() {
|
||||
if self.semantics_provider.is_none() || !self.display_mode.is_full() {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -6819,7 +6837,7 @@ impl Editor {
|
|||
&mut self,
|
||||
cx: &mut Context<Editor>,
|
||||
) -> Option<(String, Range<Anchor>)> {
|
||||
if matches!(self.mode, EditorMode::SingleLine) {
|
||||
if matches!(self.display_mode, EditorDisplayMode::SingleLine) {
|
||||
return None;
|
||||
}
|
||||
if !EditorSettings::get_global(cx).selection_highlight {
|
||||
|
@ -6918,7 +6936,7 @@ impl Editor {
|
|||
fn refresh_single_line_folds(&mut self, window: &mut Window, cx: &mut Context<Editor>) {
|
||||
struct NewlineFold;
|
||||
let type_id = std::any::TypeId::of::<NewlineFold>();
|
||||
if !self.mode.is_single_line() {
|
||||
if !self.display_mode.is_single_line() {
|
||||
return;
|
||||
}
|
||||
let snapshot = self.snapshot(window, cx);
|
||||
|
@ -7144,7 +7162,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)
|
||||
{
|
||||
|
@ -8483,7 +8501,7 @@ impl Editor {
|
|||
window: &mut Window,
|
||||
cx: &mut App,
|
||||
) -> Option<(AnyElement, gpui::Point<Pixels>)> {
|
||||
if self.mode().is_minimap() {
|
||||
if self.display_mode().is_minimap() {
|
||||
return None;
|
||||
}
|
||||
let active_edit_prediction = self.active_edit_prediction.as_ref()?;
|
||||
|
@ -9920,7 +9938,7 @@ impl Editor {
|
|||
}
|
||||
|
||||
pub fn backtab(&mut self, _: &Backtab, window: &mut Window, cx: &mut Context<Self>) {
|
||||
if self.mode.is_single_line() {
|
||||
if self.display_mode.is_single_line() {
|
||||
cx.propagate();
|
||||
return;
|
||||
}
|
||||
|
@ -9933,7 +9951,7 @@ impl Editor {
|
|||
}
|
||||
|
||||
pub fn tab(&mut self, _: &Tab, window: &mut Window, cx: &mut Context<Self>) {
|
||||
if self.mode.is_single_line() {
|
||||
if self.display_mode.is_single_line() {
|
||||
cx.propagate();
|
||||
return;
|
||||
}
|
||||
|
@ -10056,7 +10074,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;
|
||||
}
|
||||
|
@ -10164,7 +10182,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;
|
||||
}
|
||||
|
@ -10241,7 +10259,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;
|
||||
}
|
||||
|
@ -11486,7 +11504,7 @@ impl Editor {
|
|||
|
||||
pub fn move_line_up(&mut self, _: &MoveLineUp, window: &mut Window, cx: &mut Context<Self>) {
|
||||
self.hide_mouse_cursor(HideMouseCursorOrigin::TypingAction, cx);
|
||||
if self.mode.is_single_line() {
|
||||
if self.display_mode.is_single_line() {
|
||||
cx.propagate();
|
||||
return;
|
||||
}
|
||||
|
@ -11597,7 +11615,7 @@ impl Editor {
|
|||
cx: &mut Context<Self>,
|
||||
) {
|
||||
self.hide_mouse_cursor(HideMouseCursorOrigin::TypingAction, cx);
|
||||
if self.mode.is_single_line() {
|
||||
if self.display_mode.is_single_line() {
|
||||
cx.propagate();
|
||||
return;
|
||||
}
|
||||
|
@ -11749,7 +11767,7 @@ impl Editor {
|
|||
|
||||
pub fn rewrap(&mut self, _: &Rewrap, _: &mut Window, cx: &mut Context<Self>) {
|
||||
self.hide_mouse_cursor(HideMouseCursorOrigin::TypingAction, cx);
|
||||
if self.mode.is_single_line() {
|
||||
if self.display_mode.is_single_line() {
|
||||
cx.propagate();
|
||||
return;
|
||||
}
|
||||
|
@ -12460,7 +12478,7 @@ impl Editor {
|
|||
return;
|
||||
}
|
||||
|
||||
if self.mode.is_single_line() {
|
||||
if self.display_mode.is_single_line() {
|
||||
cx.propagate();
|
||||
return;
|
||||
}
|
||||
|
@ -12503,7 +12521,7 @@ impl Editor {
|
|||
return;
|
||||
}
|
||||
|
||||
if self.mode.is_single_line() {
|
||||
if self.display_mode.is_single_line() {
|
||||
cx.propagate();
|
||||
return;
|
||||
}
|
||||
|
@ -12540,7 +12558,7 @@ impl Editor {
|
|||
return;
|
||||
}
|
||||
|
||||
if self.mode.is_single_line() {
|
||||
if self.display_mode.is_single_line() {
|
||||
cx.propagate();
|
||||
return;
|
||||
}
|
||||
|
@ -12638,7 +12656,7 @@ impl Editor {
|
|||
return;
|
||||
}
|
||||
|
||||
if matches!(self.mode, EditorMode::SingleLine) {
|
||||
if matches!(self.display_mode, EditorDisplayMode::SingleLine) {
|
||||
cx.propagate();
|
||||
return;
|
||||
}
|
||||
|
@ -12688,7 +12706,7 @@ impl Editor {
|
|||
pub fn move_down(&mut self, _: &MoveDown, window: &mut Window, cx: &mut Context<Self>) {
|
||||
self.take_rename(true, window, cx);
|
||||
|
||||
if self.mode.is_single_line() {
|
||||
if self.display_mode.is_single_line() {
|
||||
cx.propagate();
|
||||
return;
|
||||
}
|
||||
|
@ -12762,7 +12780,7 @@ impl Editor {
|
|||
return;
|
||||
}
|
||||
|
||||
if matches!(self.mode, EditorMode::SingleLine) {
|
||||
if matches!(self.display_mode, EditorDisplayMode::SingleLine) {
|
||||
cx.propagate();
|
||||
return;
|
||||
}
|
||||
|
@ -13246,7 +13264,7 @@ impl Editor {
|
|||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
if matches!(self.mode, EditorMode::SingleLine) {
|
||||
if matches!(self.display_mode, EditorDisplayMode::SingleLine) {
|
||||
cx.propagate();
|
||||
return;
|
||||
}
|
||||
|
@ -13267,7 +13285,7 @@ impl Editor {
|
|||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
if matches!(self.mode, EditorMode::SingleLine) {
|
||||
if matches!(self.display_mode, EditorDisplayMode::SingleLine) {
|
||||
cx.propagate();
|
||||
return;
|
||||
}
|
||||
|
@ -13288,7 +13306,7 @@ impl Editor {
|
|||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
if matches!(self.mode, EditorMode::SingleLine) {
|
||||
if matches!(self.display_mode, EditorDisplayMode::SingleLine) {
|
||||
cx.propagate();
|
||||
return;
|
||||
}
|
||||
|
@ -13309,7 +13327,7 @@ impl Editor {
|
|||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
if matches!(self.mode, EditorMode::SingleLine) {
|
||||
if matches!(self.display_mode, EditorDisplayMode::SingleLine) {
|
||||
cx.propagate();
|
||||
return;
|
||||
}
|
||||
|
@ -13330,7 +13348,7 @@ impl Editor {
|
|||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
if matches!(self.mode, EditorMode::SingleLine) {
|
||||
if matches!(self.display_mode, EditorDisplayMode::SingleLine) {
|
||||
cx.propagate();
|
||||
return;
|
||||
}
|
||||
|
@ -13355,7 +13373,7 @@ impl Editor {
|
|||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
if matches!(self.mode, EditorMode::SingleLine) {
|
||||
if matches!(self.display_mode, EditorDisplayMode::SingleLine) {
|
||||
cx.propagate();
|
||||
return;
|
||||
}
|
||||
|
@ -13380,7 +13398,7 @@ impl Editor {
|
|||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
if matches!(self.mode, EditorMode::SingleLine) {
|
||||
if matches!(self.display_mode, EditorDisplayMode::SingleLine) {
|
||||
cx.propagate();
|
||||
return;
|
||||
}
|
||||
|
@ -13405,7 +13423,7 @@ impl Editor {
|
|||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
if matches!(self.mode, EditorMode::SingleLine) {
|
||||
if matches!(self.display_mode, EditorDisplayMode::SingleLine) {
|
||||
cx.propagate();
|
||||
return;
|
||||
}
|
||||
|
@ -13430,7 +13448,7 @@ impl Editor {
|
|||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
if matches!(self.mode, EditorMode::SingleLine) {
|
||||
if matches!(self.display_mode, EditorDisplayMode::SingleLine) {
|
||||
cx.propagate();
|
||||
return;
|
||||
}
|
||||
|
@ -13451,7 +13469,7 @@ impl Editor {
|
|||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
if matches!(self.mode, EditorMode::SingleLine) {
|
||||
if matches!(self.display_mode, EditorDisplayMode::SingleLine) {
|
||||
cx.propagate();
|
||||
return;
|
||||
}
|
||||
|
@ -13472,7 +13490,7 @@ impl Editor {
|
|||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
if matches!(self.mode, EditorMode::SingleLine) {
|
||||
if matches!(self.display_mode, EditorDisplayMode::SingleLine) {
|
||||
cx.propagate();
|
||||
return;
|
||||
}
|
||||
|
@ -13493,7 +13511,7 @@ impl Editor {
|
|||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
if matches!(self.mode, EditorMode::SingleLine) {
|
||||
if matches!(self.display_mode, EditorDisplayMode::SingleLine) {
|
||||
cx.propagate();
|
||||
return;
|
||||
}
|
||||
|
@ -13514,7 +13532,7 @@ impl Editor {
|
|||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
if matches!(self.mode, EditorMode::SingleLine) {
|
||||
if matches!(self.display_mode, EditorDisplayMode::SingleLine) {
|
||||
cx.propagate();
|
||||
return;
|
||||
}
|
||||
|
@ -13539,7 +13557,7 @@ impl Editor {
|
|||
}
|
||||
|
||||
pub fn move_to_end(&mut self, _: &MoveToEnd, window: &mut Window, cx: &mut Context<Self>) {
|
||||
if matches!(self.mode, EditorMode::SingleLine) {
|
||||
if matches!(self.display_mode, EditorDisplayMode::SingleLine) {
|
||||
cx.propagate();
|
||||
return;
|
||||
}
|
||||
|
@ -14588,7 +14606,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);
|
||||
|
@ -16913,7 +16931,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 {
|
||||
|
@ -17073,7 +17091,7 @@ impl Editor {
|
|||
window: &Window,
|
||||
cx: &mut Context<Self>,
|
||||
) -> Option<()> {
|
||||
if !self.mode().is_full() {
|
||||
if !self.display_mode().is_full() {
|
||||
return None;
|
||||
}
|
||||
let pull_diagnostics_settings = ProjectSettings::get_global(cx)
|
||||
|
@ -18355,7 +18373,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(),
|
||||
|
@ -18457,7 +18475,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(
|
||||
|
@ -19003,7 +19021,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 {
|
||||
|
@ -20274,9 +20294,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 {
|
||||
|
@ -20294,7 +20314,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,
|
||||
);
|
||||
|
@ -20643,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
|
||||
|
@ -21127,7 +21147,7 @@ impl Editor {
|
|||
}
|
||||
|
||||
pub fn register_addon<T: Addon>(&mut self, instance: T) {
|
||||
if self.mode.is_minimap() {
|
||||
if self.display_mode.is_minimap() {
|
||||
return;
|
||||
}
|
||||
self.addons
|
||||
|
@ -21180,7 +21200,7 @@ impl Editor {
|
|||
cx: &mut Context<Editor>,
|
||||
) {
|
||||
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();
|
||||
|
@ -21234,13 +21254,6 @@ impl Editor {
|
|||
}
|
||||
}
|
||||
|
||||
fn vim_enabled(cx: &App) -> bool {
|
||||
cx.global::<SettingsStore>()
|
||||
.raw_user_settings()
|
||||
.get("vim_mode")
|
||||
== Some(&serde_json::Value::Bool(true))
|
||||
}
|
||||
|
||||
fn process_completion_for_edit(
|
||||
completion: &Completion,
|
||||
intent: CompletionIntent,
|
||||
|
@ -22897,6 +22910,10 @@ pub enum EditorEvent {
|
|||
anchor: Anchor,
|
||||
is_deactivate: bool,
|
||||
},
|
||||
EditorModeChanged {
|
||||
new_mode: EditorMode,
|
||||
old_mode: EditorMode,
|
||||
},
|
||||
}
|
||||
|
||||
impl EventEmitter<EditorEvent> for Editor {}
|
||||
|
@ -22911,8 +22928,8 @@ impl Render for Editor {
|
|||
fn render(&mut self, _: &mut Window, cx: &mut Context<Self>) -> 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(),
|
||||
|
@ -22922,7 +22939,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(),
|
||||
|
@ -22937,11 +22954,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(
|
||||
|
@ -23626,7 +23643,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),
|
||||
},
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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<Option<AnyElement>> {
|
||||
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<Pixels> {
|
||||
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<Entity<Editor>> {
|
||||
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<Pixels>,
|
||||
scrollbars_layout: Option<EditorScrollbars>,
|
||||
minimap: Option<MinimapLayout>,
|
||||
mode: EditorMode,
|
||||
mode: EditorDisplayMode,
|
||||
wrap_guides: SmallVec<[(Pixels, bool); 2]>,
|
||||
indent_guides: Option<Vec<IndentGuideLayout>>,
|
||||
visible_display_row_range: Range<DisplayRow>,
|
||||
|
@ -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,
|
||||
|
|
|
@ -1267,7 +1267,7 @@ impl SerializableItem for Editor {
|
|||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) -> Option<Task<Result<()>>> {
|
||||
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<Self>,
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -150,7 +150,7 @@ impl Editor {
|
|||
_: &Window,
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
if !self.mode().is_full() {
|
||||
if !self.display_mode().is_full() {
|
||||
return;
|
||||
}
|
||||
let Some(project) = self.project.clone() else {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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<Self>,
|
||||
) {
|
||||
if matches!(self.mode, EditorMode::SingleLine) {
|
||||
if matches!(self.display_mode, EditorDisplayMode::SingleLine) {
|
||||
cx.propagate();
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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 {
|
||||
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 {
|
||||
Editor::new(EditorMode::full(), buffer, Some(project), window, cx)
|
||||
Editor::new(EditorDisplayMode::full(), buffer, Some(project), window, cx)
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
[package]
|
||||
name = "vim_mode_setting"
|
||||
name = "editor_mode_setting"
|
||||
version = "0.1.0"
|
||||
edition.workspace = true
|
||||
publish.workspace = true
|
||||
|
@ -9,10 +9,13 @@ 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
|
||||
gpui.workspace = true
|
||||
schemars.workspace = true
|
||||
settings.workspace = true
|
||||
workspace-hack.workspace = true
|
||||
serde.workspace = true
|
||||
serde_json.workspace = true
|
200
crates/editor_mode_setting/src/editor_mode_setting.rs
Normal file
200
crates/editor_mode_setting/src/editor_mode_setting.rs
Normal file
|
@ -0,0 +1,200 @@
|
|||
//! Contains the [`VimModeSetting`] and [`HelixModeSetting`] used to enable/disable Vim and Helix modes.
|
||||
//!
|
||||
//! This is in its own crate as we want other crates to be able to enable or
|
||||
//! disable Vim/Helix modes without having to depend on the `vim` crate in its
|
||||
//! entirety.
|
||||
|
||||
use anyhow::Result;
|
||||
use gpui::App;
|
||||
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 `editor_mode_setting` crate.
|
||||
pub fn init(cx: &mut App) {
|
||||
EditorModeSetting::register(cx);
|
||||
}
|
||||
|
||||
/// Whether or not to enable Vim mode.
|
||||
///
|
||||
/// Default: `EditMode::Default`
|
||||
pub struct EditorModeSetting(pub EditorMode);
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Default)]
|
||||
pub enum EditorMode {
|
||||
#[default]
|
||||
Default,
|
||||
Vim(ModalMode),
|
||||
Helix(ModalMode),
|
||||
}
|
||||
|
||||
impl JsonSchema for EditorMode {
|
||||
fn schema_name() -> Cow<'static, str> {
|
||||
"EditorMode".into()
|
||||
}
|
||||
|
||||
fn json_schema(_gen: &mut schemars::SchemaGenerator) -> Schema {
|
||||
let options = Self::get_schema_options();
|
||||
json_schema!({
|
||||
"oneOf": options,
|
||||
"description": "Editor mode"
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de> Deserialize<'de> for EditorMode {
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
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<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
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::HelixNormal) => "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 {
|
||||
const KEY: Option<&'static str> = Some("editor_mode");
|
||||
|
||||
type FileContent = Option<EditorMode>;
|
||||
|
||||
fn load(sources: SettingsSources<Self::FileContent>, _: &mut App) -> Result<Self> {
|
||||
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 `vim.<foo>` keys are set?
|
||||
}
|
||||
}
|
||||
|
||||
impl EditorMode {
|
||||
pub fn is_modal(&self) -> bool {
|
||||
matches!(self, EditorMode::Vim(_) | EditorMode::Helix(_))
|
||||
}
|
||||
|
||||
pub fn vim() -> EditorMode {
|
||||
EditorMode::Vim(ModalMode::default())
|
||||
}
|
||||
|
||||
pub fn get_schema_options() -> Vec<serde_json::Value> {
|
||||
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)"
|
||||
}),
|
||||
]
|
||||
}
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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::VimModeSetting;
|
||||
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 editor_mode.is_modal() {
|
||||
ui::ToggleState::Selected
|
||||
} else {
|
||||
ui::ToggleState::Unselected
|
||||
}
|
||||
},
|
||||
cx.listener(move |this, selection, _, cx| {
|
||||
telemetry::event!("Vim Mode Toggled", source = "Feature Upsell");
|
||||
this.update_settings::<VimModeSetting>(
|
||||
this.update_settings::<EditorModeSetting>(
|
||||
selection,
|
||||
cx,
|
||||
|setting, value| *setting = Some(value),
|
||||
|setting, value| {
|
||||
*setting = Some(if value {
|
||||
EditorMode::vim()
|
||||
} else {
|
||||
EditorMode::default()
|
||||
});
|
||||
},
|
||||
);
|
||||
}),
|
||||
)),
|
||||
|
|
|
@ -44,7 +44,7 @@ impl editor::Addon for ConflictAddon {
|
|||
|
||||
pub fn register_editor(editor: &mut Editor, buffer: Entity<MultiBuffer>, cx: &mut Context<Editor>) {
|
||||
// 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())
|
||||
{
|
||||
|
|
|
@ -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),
|
||||
},
|
||||
|
@ -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());
|
||||
|
|
|
@ -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::<Selection<Point>>;
|
||||
let snapshot = editor.buffer().read(cx).snapshot(cx);
|
||||
if snapshot.excerpts().count() > 0 {
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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::VimModeSetting;
|
||||
|
||||
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 editor_mode.is_modal() {
|
||||
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 = <dyn Fs>::global(cx);
|
||||
move |&selection, _, cx| {
|
||||
update_settings_file::<VimModeSetting>(fs.clone(), cx, move |setting, _| {
|
||||
update_settings_file::<EditorModeSetting>(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,
|
||||
}
|
||||
});
|
||||
|
|
|
@ -88,7 +88,7 @@ impl Render for OutlineView {
|
|||
|
||||
impl OutlineView {
|
||||
fn register(editor: &mut Editor, _: Option<&mut Window>, cx: &mut Context<Editor>) {
|
||||
if editor.mode().is_full() {
|
||||
if editor.display_mode().is_full() {
|
||||
let handle = cx.entity().downgrade();
|
||||
editor
|
||||
.register_action(move |action, window, cx| {
|
||||
|
|
|
@ -4949,7 +4949,7 @@ fn workspace_active_editor(
|
|||
let active_item = workspace.active_item(cx)?;
|
||||
let active_editor = active_item
|
||||
.act_as::<Editor>(cx)
|
||||
.filter(|editor| editor.read(cx).mode().is_full())?;
|
||||
.filter(|editor| editor.read(cx).display_mode().is_full())?;
|
||||
Some((active_item, active_editor))
|
||||
}
|
||||
|
||||
|
|
|
@ -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),
|
||||
},
|
||||
|
|
|
@ -75,7 +75,8 @@ pub fn init(cx: &mut App) {
|
|||
return;
|
||||
};
|
||||
|
||||
if !editor.use_modal_editing() || !editor.buffer().read(cx).is_singleton() {
|
||||
if !editor.editor_mode().is_modal() || !editor.buffer().read(cx).is_singleton()
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -33,3 +33,4 @@ util.workspace = true
|
|||
workspace-hack.workspace = true
|
||||
workspace.workspace = true
|
||||
zed_actions.workspace = true
|
||||
editor_mode_setting.workspace = true
|
||||
|
|
|
@ -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,
|
||||
|
@ -637,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_use_modal_editing(false);
|
||||
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 {
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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::HelixModeSetting;
|
||||
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 !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 HelixModeSetting::get_global(cx).0 {
|
||||
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);
|
||||
|
|
|
@ -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::HelixModeSetting;
|
||||
|
||||
use crate::{
|
||||
Vim,
|
||||
|
@ -220,7 +220,7 @@ impl Vim {
|
|||
});
|
||||
});
|
||||
|
||||
if HelixModeSetting::get_global(cx).0 {
|
||||
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);
|
||||
|
|
|
@ -3,8 +3,9 @@ use gpui::{Context, Window, actions};
|
|||
use language::Point;
|
||||
|
||||
use crate::{
|
||||
Mode, Vim,
|
||||
Vim,
|
||||
motion::{Motion, MotionKind},
|
||||
state::Mode,
|
||||
};
|
||||
|
||||
actions!(
|
||||
|
|
|
@ -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,
|
||||
|
@ -19,12 +20,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::{
|
||||
|
@ -35,46 +35,6 @@ use util::ResultExt;
|
|||
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,
|
||||
|
@ -692,7 +652,7 @@ impl VimGlobals {
|
|||
let mut was_enabled = None;
|
||||
|
||||
cx.observe_global::<SettingsStore>(move |cx| {
|
||||
let is_enabled = Vim::enabled(cx);
|
||||
let is_enabled = Vim::global_enabled(cx);
|
||||
if was_enabled == Some(is_enabled) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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::Mode, state::Operator, *};
|
||||
|
||||
pub struct VimTestContext {
|
||||
cx: EditorLspTestContext,
|
||||
|
@ -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::<VimModeSetting>(cx, |s| *s = Some(enabled));
|
||||
store.update_user_settings::<EditorModeSetting>(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,9 @@ impl VimTestContext {
|
|||
pub fn enable_vim(&mut self) {
|
||||
self.cx.update(|_, cx| {
|
||||
SettingsStore::update_global(cx, |store, cx| {
|
||||
store.update_user_settings::<VimModeSetting>(cx, |s| *s = Some(true));
|
||||
store.update_user_settings::<EditorModeSetting>(cx, |s| {
|
||||
*s = Some(EditorMode::vim())
|
||||
});
|
||||
});
|
||||
})
|
||||
}
|
||||
|
@ -138,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::<VimModeSetting>(cx, |s| *s = Some(false));
|
||||
store.update_user_settings::<EditorModeSetting>(cx, |s| {
|
||||
*s = Some(EditorMode::vim())
|
||||
});
|
||||
});
|
||||
})
|
||||
}
|
||||
|
@ -146,8 +156,8 @@ impl VimTestContext {
|
|||
pub fn enable_helix(&mut self) {
|
||||
self.cx.update(|_, cx| {
|
||||
SettingsStore::update_global(cx, |store, cx| {
|
||||
store.update_user_settings::<vim_mode_setting::HelixModeSetting>(cx, |s| {
|
||||
*s = Some(true)
|
||||
store.update_user_settings::<editor_mode_setting::EditorModeSetting>(cx, |s| {
|
||||
*s = Some(EditorMode::Helix(ModalMode::HelixNormal))
|
||||
});
|
||||
});
|
||||
})
|
||||
|
|
|
@ -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,
|
||||
|
@ -40,13 +41,11 @@ 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;
|
||||
use ui::{IntoElement, SharedString, px};
|
||||
use vim_mode_setting::HelixModeSetting;
|
||||
use vim_mode_setting::VimModeSetting;
|
||||
use workspace::{self, Pane, Workspace};
|
||||
|
||||
use crate::state::ReplayableAction;
|
||||
|
@ -236,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);
|
||||
|
||||
|
@ -245,9 +244,13 @@ 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);
|
||||
update_settings_file::<VimModeSetting>(fs, cx, move |setting, _| {
|
||||
*setting = Some(!currently_enabled)
|
||||
let currently_enabled = Vim::global_enabled(cx);
|
||||
update_settings_file::<EditorModeSetting>(fs, cx, move |setting, _| {
|
||||
*setting = Some(if currently_enabled {
|
||||
EditorMode::Default
|
||||
} else {
|
||||
EditorMode::vim()
|
||||
});
|
||||
})
|
||||
});
|
||||
|
||||
|
@ -357,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<SharedString>,
|
||||
pub exit_temporary_mode: bool,
|
||||
|
@ -366,11 +369,11 @@ pub(crate) struct Vim {
|
|||
operator_stack: Vec<Operator>,
|
||||
pub(crate) replacements: Vec<(Range<editor::Anchor>, String)>,
|
||||
|
||||
pub(crate) stored_visual_mode: Option<(Mode, Vec<bool>)>,
|
||||
pub(crate) stored_visual_mode: Option<(ModalMode, Vec<bool>)>,
|
||||
|
||||
pub(crate) current_tx: Option<TransactionId>,
|
||||
pub(crate) current_anchor: Option<Selection<Anchor>>,
|
||||
pub(crate) undo_modes: HashMap<TransactionId, Mode>,
|
||||
pub(crate) undo_modes: HashMap<TransactionId, ModalMode>,
|
||||
pub(crate) undo_last_line_tx: Option<TransactionId>,
|
||||
|
||||
selected_register: Option<char>,
|
||||
|
@ -404,14 +407,9 @@ impl Vim {
|
|||
pub fn new(window: &mut Window, cx: &mut Context<Editor>) -> Entity<Self> {
|
||||
let editor = cx.entity();
|
||||
|
||||
let mut initial_mode = VimSettings::get_global(cx).default_mode;
|
||||
if initial_mode == Mode::Normal && HelixModeSetting::get_global(cx).0 {
|
||||
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(),
|
||||
|
@ -445,85 +443,81 @@ impl Vim {
|
|||
return;
|
||||
};
|
||||
|
||||
if !editor.use_modal_editing() {
|
||||
if !editor.editor_mode().is_modal() {
|
||||
return;
|
||||
}
|
||||
|
||||
let mut was_enabled = Vim::enabled(cx);
|
||||
let mut was_toggle = VimSettings::get_global(cx).toggle_relative_line_numbers;
|
||||
cx.observe_global_in::<SettingsStore>(window, move |editor, window, cx| {
|
||||
let enabled = Vim::enabled(cx);
|
||||
cx.observe_global_in::<SettingsStore>(window, move |editor, _window, 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::<VimAddon>()
|
||||
.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)
|
||||
}
|
||||
|
||||
Self::activate(editor, window, cx)
|
||||
}
|
||||
|
||||
fn activate(editor: &mut Editor, window: &mut Window, cx: &mut Context<Editor>) {
|
||||
let vim = Vim::new(window, cx);
|
||||
|
||||
if !editor.mode().is_full() {
|
||||
vim.update(cx, |vim, _| {
|
||||
vim.mode = Mode::Insert;
|
||||
});
|
||||
}
|
||||
vim.update(cx, |vim, _| {
|
||||
let initial_mode = match editor.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(),
|
||||
});
|
||||
|
||||
vim.update(cx, |_, cx| {
|
||||
Vim::action(editor, cx, |vim, _: &SwitchToNormalMode, window, cx| {
|
||||
if HelixModeSetting::get_global(cx).0 {
|
||||
vim.switch_mode(Mode::HelixNormal, false, window, cx)
|
||||
} else {
|
||||
vim.switch_mode(Mode::Normal, false, window, cx)
|
||||
}
|
||||
});
|
||||
let default_editor_mode = editor.editor_mode();
|
||||
vim.update(cx, move |_, cx| {
|
||||
Vim::action(
|
||||
editor,
|
||||
cx,
|
||||
move |vim, _: &SwitchToNormalMode, window, cx| {
|
||||
if matches!(default_editor_mode, EditorMode::Helix(_)) {
|
||||
vim.switch_mode(ModalMode::HelixNormal, false, window, cx)
|
||||
} else {
|
||||
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)
|
||||
},
|
||||
);
|
||||
|
||||
|
@ -531,7 +525,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| {
|
||||
|
@ -751,8 +745,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),
|
||||
};
|
||||
},
|
||||
);
|
||||
|
@ -818,8 +812,11 @@ impl Vim {
|
|||
.map(|workspace| workspace.read(cx).focused_pane(window, cx))
|
||||
}
|
||||
|
||||
pub fn enabled(cx: &mut App) -> bool {
|
||||
VimModeSetting::get_global(cx).0 || HelixModeSetting::get_global(cx).0
|
||||
pub fn global_enabled(cx: &mut App) -> bool {
|
||||
if EditorModeSetting::get_global(cx).0 == EditorMode::Default {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Called whenever an keystroke is typed so vim can observe all actions
|
||||
|
@ -838,7 +835,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
|
||||
|
@ -914,6 +911,21 @@ impl Vim {
|
|||
vim.set_mark(mark, vec![*anchor], editor.buffer(), window, 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)
|
||||
}
|
||||
});
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
@ -940,18 +952,21 @@ impl Vim {
|
|||
|
||||
pub fn switch_mode(
|
||||
&mut self,
|
||||
mode: Mode,
|
||||
mode: ModalMode,
|
||||
leave_selections: bool,
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
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;
|
||||
}
|
||||
|
@ -965,7 +980,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, _| {
|
||||
|
@ -973,7 +988,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);
|
||||
}
|
||||
|
||||
|
@ -982,10 +997,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)
|
||||
});
|
||||
}
|
||||
|
@ -1000,13 +1015,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)
|
||||
|
@ -1016,15 +1033,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])
|
||||
|
@ -1089,7 +1106,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
|
||||
|
@ -1108,12 +1125,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()
|
||||
}),
|
||||
|
@ -1122,45 +1139,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();
|
||||
|
||||
|
@ -1201,16 +1218,16 @@ impl Vim {
|
|||
editor.selections.newest::<usize>(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
|
||||
&& 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);
|
||||
|
@ -1236,13 +1253,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)
|
||||
});
|
||||
}
|
||||
|
@ -1330,19 +1347,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),
|
||||
},
|
||||
|
@ -1459,9 +1476,9 @@ impl Vim {
|
|||
_window: &mut Window,
|
||||
_: &mut Context<Self>,
|
||||
) {
|
||||
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);
|
||||
|
@ -1469,7 +1486,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);
|
||||
}
|
||||
}
|
||||
|
@ -1481,12 +1498,12 @@ impl Vim {
|
|||
cx: &mut Context<Self>,
|
||||
) {
|
||||
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,
|
||||
|
@ -1494,7 +1511,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]);
|
||||
|
@ -1510,9 +1527,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| {
|
||||
|
@ -1522,7 +1539,7 @@ impl Vim {
|
|||
})
|
||||
});
|
||||
}
|
||||
Mode::Insert | Mode::Replace | Mode::HelixNormal => {}
|
||||
ModalMode::Insert | ModalMode::Replace | ModalMode::HelixNormal => {}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1535,7 +1552,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
|
||||
|
@ -1545,17 +1562,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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1628,11 +1650,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 }) => {
|
||||
|
@ -1650,20 +1672,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);
|
||||
|
@ -1672,7 +1694,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);
|
||||
}
|
||||
|
@ -1686,7 +1708,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)
|
||||
|
@ -1708,11 +1730,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 {},
|
||||
|
@ -1732,9 +1754,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()
|
||||
|
@ -1776,7 +1798,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,
|
||||
|
@ -1787,7 +1808,6 @@ struct VimSettings {
|
|||
|
||||
#[derive(Clone, Default, Serialize, Deserialize, JsonSchema)]
|
||||
struct VimSettingsContent {
|
||||
pub default_mode: Option<ModeContent>,
|
||||
pub toggle_relative_line_numbers: Option<bool>,
|
||||
pub use_system_clipboard: Option<UseSystemClipboard>,
|
||||
pub use_smartcase_find: Option<bool>,
|
||||
|
@ -1796,33 +1816,6 @@ struct VimSettingsContent {
|
|||
pub cursor_shape: Option<CursorShapeSettings>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Default, Serialize, Deserialize, JsonSchema)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum ModeContent {
|
||||
#[default]
|
||||
Normal,
|
||||
Insert,
|
||||
Replace,
|
||||
Visual,
|
||||
VisualLine,
|
||||
VisualBlock,
|
||||
HelixNormal,
|
||||
}
|
||||
|
||||
impl From<ModeContent> 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");
|
||||
|
||||
|
@ -1832,10 +1825,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)?,
|
||||
|
|
|
@ -1,67 +0,0 @@
|
|||
//! Contains the [`VimModeSetting`] and [`HelixModeSetting`] used to enable/disable Vim and Helix modes.
|
||||
//!
|
||||
//! This is in its own crate as we want other crates to be able to enable or
|
||||
//! disable Vim/Helix modes without having to depend on the `vim` crate in its
|
||||
//! entirety.
|
||||
|
||||
use anyhow::Result;
|
||||
use gpui::App;
|
||||
use settings::{Settings, SettingsSources};
|
||||
|
||||
/// Initializes the `vim_mode_setting` crate.
|
||||
pub fn init(cx: &mut App) {
|
||||
VimModeSetting::register(cx);
|
||||
HelixModeSetting::register(cx);
|
||||
}
|
||||
|
||||
/// Whether or not to enable Vim mode.
|
||||
///
|
||||
/// Default: false
|
||||
pub struct VimModeSetting(pub bool);
|
||||
|
||||
impl Settings for VimModeSetting {
|
||||
const KEY: Option<&'static str> = Some("vim_mode");
|
||||
|
||||
type FileContent = Option<bool>;
|
||||
|
||||
fn load(sources: SettingsSources<Self::FileContent>, _: &mut App) -> Result<Self> {
|
||||
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 `vim.<foo>` 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<bool>;
|
||||
|
||||
fn load(sources: SettingsSources<Self::FileContent>, _: &mut App) -> Result<Self> {
|
||||
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.<foo>` keys are set?
|
||||
}
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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::VimModeSetting;
|
||||
use workspace::notifications::{
|
||||
NotificationId, SuppressEvent, dismiss_app_notification, show_app_notification,
|
||||
};
|
||||
|
@ -1282,26 +1282,20 @@ 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();
|
||||
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::<SettingsStore>(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();
|
||||
}
|
||||
|
@ -1498,8 +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 VimModeSetting::get_global(cx).0 || vim_mode_setting::HelixModeSetting::get_global(cx).0 {
|
||||
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(),
|
||||
);
|
||||
|
@ -4622,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);
|
||||
|
|
|
@ -18,7 +18,7 @@ pub fn init(client: Arc<Client>, user_store: Entity<UserStore>, cx: &mut App) {
|
|||
let client = client.clone();
|
||||
let user_store = user_store.clone();
|
||||
move |editor: &mut Editor, window, cx: &mut Context<Editor>| {
|
||||
if !editor.mode().is_full() {
|
||||
if !editor.display_mode().is_full() {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -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::VimModeSetting;
|
||||
use workspace::{
|
||||
ToolbarItemEvent, ToolbarItemLocation, ToolbarItemView, Workspace, item::ItemHandle,
|
||||
};
|
||||
|
@ -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();
|
||||
|
@ -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 = editor_mode.is_modal();
|
||||
|
||||
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();
|
||||
}
|
||||
},
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue