Define editor settings in editor crate

This commit is contained in:
Max Brunsfeld 2023-05-16 17:29:21 -07:00
parent 39618ae32d
commit 65e3713d4d
13 changed files with 93 additions and 54 deletions

1
Cargo.lock generated
View file

@ -4873,6 +4873,7 @@ dependencies = [
name = "project_panel" name = "project_panel"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"client",
"context_menu", "context_menu",
"drag_and_drop", "drag_and_drop",
"editor", "editor",

View file

@ -70,10 +70,14 @@ pub const CONNECTION_TIMEOUT: Duration = Duration::from_secs(5);
actions!(client, [SignIn, SignOut]); actions!(client, [SignIn, SignOut]);
pub fn init(client: &Arc<Client>, cx: &mut AppContext) { pub fn init_settings(cx: &mut AppContext) {
let client = Arc::downgrade(client);
settings::register_setting::<TelemetrySettings>(cx); settings::register_setting::<TelemetrySettings>(cx);
}
pub fn init(client: &Arc<Client>, cx: &mut AppContext) {
init_settings(cx);
let client = Arc::downgrade(client);
cx.add_global_action({ cx.add_global_action({
let client = client.clone(); let client = client.clone();
move |_: &SignIn, cx| { move |_: &SignIn, cx| {

View file

@ -186,11 +186,6 @@ impl TestServer {
}) })
}); });
cx.update(|cx| {
client::init(&client, cx);
language::init(cx);
});
let fs = FakeFs::new(cx.background()); let fs = FakeFs::new(cx.background());
let user_store = cx.add_model(|cx| UserStore::new(client.clone(), http, cx)); let user_store = cx.add_model(|cx| UserStore::new(client.clone(), http, cx));
let app_state = Arc::new(workspace::AppState { let app_state = Arc::new(workspace::AppState {
@ -205,8 +200,11 @@ impl TestServer {
background_actions: || &[], background_actions: || &[],
}); });
Project::init(&client);
cx.update(|cx| { cx.update(|cx| {
Project::init(&client);
client::init(&client, cx);
language::init(cx);
editor::init_settings(cx);
workspace::init(app_state.clone(), cx); workspace::init(app_state.clone(), cx);
call::init(client.clone(), user_store.clone(), cx); call::init(client.clone(), user_store.clone(), cx);
}); });

View file

@ -27,7 +27,7 @@ use lsp::LanguageServerId;
use project::{search::SearchQuery, DiagnosticSummary, HoverBlockKind, Project, ProjectPath}; use project::{search::SearchQuery, DiagnosticSummary, HoverBlockKind, Project, ProjectPath};
use rand::prelude::*; use rand::prelude::*;
use serde_json::json; use serde_json::json;
use settings::{SettingsStore}; use settings::SettingsStore;
use std::{ use std::{
cell::{Cell, RefCell}, cell::{Cell, RefCell},
env, future, mem, env, future, mem,
@ -1439,7 +1439,6 @@ async fn test_host_disconnect(
cx_b: &mut TestAppContext, cx_b: &mut TestAppContext,
cx_c: &mut TestAppContext, cx_c: &mut TestAppContext,
) { ) {
cx_b.update(editor::init);
deterministic.forbid_parking(); deterministic.forbid_parking();
let mut server = TestServer::start(&deterministic).await; let mut server = TestServer::start(&deterministic).await;
let client_a = server.create_client(cx_a, "user_a").await; let client_a = server.create_client(cx_a, "user_a").await;
@ -1449,6 +1448,8 @@ async fn test_host_disconnect(
.create_room(&mut [(&client_a, cx_a), (&client_b, cx_b), (&client_c, cx_c)]) .create_room(&mut [(&client_a, cx_a), (&client_b, cx_b), (&client_c, cx_c)])
.await; .await;
cx_b.update(editor::init);
client_a client_a
.fs .fs
.insert_tree( .insert_tree(
@ -1546,7 +1547,6 @@ async fn test_project_reconnect(
cx_a: &mut TestAppContext, cx_a: &mut TestAppContext,
cx_b: &mut TestAppContext, cx_b: &mut TestAppContext,
) { ) {
cx_b.update(editor::init);
deterministic.forbid_parking(); deterministic.forbid_parking();
let mut server = TestServer::start(&deterministic).await; let mut server = TestServer::start(&deterministic).await;
let client_a = server.create_client(cx_a, "user_a").await; let client_a = server.create_client(cx_a, "user_a").await;
@ -1555,6 +1555,8 @@ async fn test_project_reconnect(
.create_room(&mut [(&client_a, cx_a), (&client_b, cx_b)]) .create_room(&mut [(&client_a, cx_a), (&client_b, cx_b)])
.await; .await;
cx_b.update(editor::init);
client_a client_a
.fs .fs
.insert_tree( .insert_tree(
@ -4992,7 +4994,6 @@ async fn test_collaborating_with_code_actions(
cx_b: &mut TestAppContext, cx_b: &mut TestAppContext,
) { ) {
deterministic.forbid_parking(); deterministic.forbid_parking();
cx_b.update(editor::init);
let mut server = TestServer::start(&deterministic).await; let mut server = TestServer::start(&deterministic).await;
let client_a = server.create_client(cx_a, "user_a").await; let client_a = server.create_client(cx_a, "user_a").await;
let client_b = server.create_client(cx_b, "user_b").await; let client_b = server.create_client(cx_b, "user_b").await;
@ -5001,6 +5002,8 @@ async fn test_collaborating_with_code_actions(
.await; .await;
let active_call_a = cx_a.read(ActiveCall::global); let active_call_a = cx_a.read(ActiveCall::global);
cx_b.update(editor::init);
// Set up a fake language server. // Set up a fake language server.
let mut language = Language::new( let mut language = Language::new(
LanguageConfig { LanguageConfig {
@ -5205,7 +5208,6 @@ async fn test_collaborating_with_renames(
cx_b: &mut TestAppContext, cx_b: &mut TestAppContext,
) { ) {
deterministic.forbid_parking(); deterministic.forbid_parking();
cx_b.update(editor::init);
let mut server = TestServer::start(&deterministic).await; let mut server = TestServer::start(&deterministic).await;
let client_a = server.create_client(cx_a, "user_a").await; let client_a = server.create_client(cx_a, "user_a").await;
let client_b = server.create_client(cx_b, "user_b").await; let client_b = server.create_client(cx_b, "user_b").await;
@ -5214,6 +5216,8 @@ async fn test_collaborating_with_renames(
.await; .await;
let active_call_a = cx_a.read(ActiveCall::global); let active_call_a = cx_a.read(ActiveCall::global);
cx_b.update(editor::init);
// Set up a fake language server. // Set up a fake language server.
let mut language = Language::new( let mut language = Language::new(
LanguageConfig { LanguageConfig {
@ -5395,8 +5399,6 @@ async fn test_language_server_statuses(
cx_b: &mut TestAppContext, cx_b: &mut TestAppContext,
) { ) {
deterministic.forbid_parking(); deterministic.forbid_parking();
cx_b.update(editor::init);
let mut server = TestServer::start(&deterministic).await; let mut server = TestServer::start(&deterministic).await;
let client_a = server.create_client(cx_a, "user_a").await; let client_a = server.create_client(cx_a, "user_a").await;
let client_b = server.create_client(cx_b, "user_b").await; let client_b = server.create_client(cx_b, "user_b").await;
@ -5405,6 +5407,8 @@ async fn test_language_server_statuses(
.await; .await;
let active_call_a = cx_a.read(ActiveCall::global); let active_call_a = cx_a.read(ActiveCall::global);
cx_b.update(editor::init);
// Set up a fake language server. // Set up a fake language server.
let mut language = Language::new( let mut language = Language::new(
LanguageConfig { LanguageConfig {
@ -6112,8 +6116,6 @@ async fn test_basic_following(
cx_d: &mut TestAppContext, cx_d: &mut TestAppContext,
) { ) {
deterministic.forbid_parking(); deterministic.forbid_parking();
cx_a.update(editor::init);
cx_b.update(editor::init);
let mut server = TestServer::start(&deterministic).await; let mut server = TestServer::start(&deterministic).await;
let client_a = server.create_client(cx_a, "user_a").await; let client_a = server.create_client(cx_a, "user_a").await;
@ -6131,6 +6133,9 @@ async fn test_basic_following(
let active_call_a = cx_a.read(ActiveCall::global); let active_call_a = cx_a.read(ActiveCall::global);
let active_call_b = cx_b.read(ActiveCall::global); let active_call_b = cx_b.read(ActiveCall::global);
cx_a.update(editor::init);
cx_b.update(editor::init);
client_a client_a
.fs .fs
.insert_tree( .insert_tree(
@ -6709,9 +6714,6 @@ async fn test_following_tab_order(
cx_a: &mut TestAppContext, cx_a: &mut TestAppContext,
cx_b: &mut TestAppContext, cx_b: &mut TestAppContext,
) { ) {
cx_a.update(editor::init);
cx_b.update(editor::init);
let mut server = TestServer::start(&deterministic).await; let mut server = TestServer::start(&deterministic).await;
let client_a = server.create_client(cx_a, "user_a").await; let client_a = server.create_client(cx_a, "user_a").await;
let client_b = server.create_client(cx_b, "user_b").await; let client_b = server.create_client(cx_b, "user_b").await;
@ -6721,6 +6723,9 @@ async fn test_following_tab_order(
let active_call_a = cx_a.read(ActiveCall::global); let active_call_a = cx_a.read(ActiveCall::global);
let active_call_b = cx_b.read(ActiveCall::global); let active_call_b = cx_b.read(ActiveCall::global);
cx_a.update(editor::init);
cx_b.update(editor::init);
client_a client_a
.fs .fs
.insert_tree( .insert_tree(
@ -6831,9 +6836,6 @@ async fn test_peers_following_each_other(
cx_b: &mut TestAppContext, cx_b: &mut TestAppContext,
) { ) {
deterministic.forbid_parking(); deterministic.forbid_parking();
cx_a.update(editor::init);
cx_b.update(editor::init);
let mut server = TestServer::start(&deterministic).await; let mut server = TestServer::start(&deterministic).await;
let client_a = server.create_client(cx_a, "user_a").await; let client_a = server.create_client(cx_a, "user_a").await;
let client_b = server.create_client(cx_b, "user_b").await; let client_b = server.create_client(cx_b, "user_b").await;
@ -6843,6 +6845,9 @@ async fn test_peers_following_each_other(
let active_call_a = cx_a.read(ActiveCall::global); let active_call_a = cx_a.read(ActiveCall::global);
let active_call_b = cx_b.read(ActiveCall::global); let active_call_b = cx_b.read(ActiveCall::global);
cx_a.update(editor::init);
cx_b.update(editor::init);
// Client A shares a project. // Client A shares a project.
client_a client_a
.fs .fs
@ -7002,8 +7007,6 @@ async fn test_auto_unfollowing(
cx_b: &mut TestAppContext, cx_b: &mut TestAppContext,
) { ) {
deterministic.forbid_parking(); deterministic.forbid_parking();
cx_a.update(editor::init);
cx_b.update(editor::init);
// 2 clients connect to a server. // 2 clients connect to a server.
let mut server = TestServer::start(&deterministic).await; let mut server = TestServer::start(&deterministic).await;
@ -7015,6 +7018,9 @@ async fn test_auto_unfollowing(
let active_call_a = cx_a.read(ActiveCall::global); let active_call_a = cx_a.read(ActiveCall::global);
let active_call_b = cx_b.read(ActiveCall::global); let active_call_b = cx_b.read(ActiveCall::global);
cx_a.update(editor::init);
cx_b.update(editor::init);
// Client A shares a project. // Client A shares a project.
client_a client_a
.fs .fs
@ -7169,8 +7175,6 @@ async fn test_peers_simultaneously_following_each_other(
cx_b: &mut TestAppContext, cx_b: &mut TestAppContext,
) { ) {
deterministic.forbid_parking(); deterministic.forbid_parking();
cx_a.update(editor::init);
cx_b.update(editor::init);
let mut server = TestServer::start(&deterministic).await; let mut server = TestServer::start(&deterministic).await;
let client_a = server.create_client(cx_a, "user_a").await; let client_a = server.create_client(cx_a, "user_a").await;
@ -7180,6 +7184,9 @@ async fn test_peers_simultaneously_following_each_other(
.await; .await;
let active_call_a = cx_a.read(ActiveCall::global); let active_call_a = cx_a.read(ActiveCall::global);
cx_a.update(editor::init);
cx_b.update(editor::init);
client_a.fs.insert_tree("/a", json!({})).await; client_a.fs.insert_tree("/a", json!({})).await;
let (project_a, _) = client_a.build_local_project("/a", cx_a).await; let (project_a, _) = client_a.build_local_project("/a", cx_a).await;
let workspace_a = client_a.build_workspace(&project_a, cx_a); let workspace_a = client_a.build_workspace(&project_a, cx_a);

View file

@ -1,8 +1,8 @@
use std::time::Duration; use crate::EditorSettings;
use gpui::{Entity, ModelContext}; use gpui::{Entity, ModelContext};
use settings::Settings; use settings::Settings;
use smol::Timer; use smol::Timer;
use std::time::Duration;
pub struct BlinkManager { pub struct BlinkManager {
blink_interval: Duration, blink_interval: Duration,
@ -64,7 +64,7 @@ impl BlinkManager {
} }
fn blink_cursors(&mut self, epoch: usize, cx: &mut ModelContext<Self>) { fn blink_cursors(&mut self, epoch: usize, cx: &mut ModelContext<Self>) {
if cx.global::<Settings>().cursor_blink { if settings::get_setting::<EditorSettings>(None, cx).cursor_blink {
if epoch == self.blink_epoch && self.enabled && !self.blinking_paused { if epoch == self.blink_epoch && self.enabled && !self.blinking_paused {
self.visible = !self.visible; self.visible = !self.visible;
cx.notify(); cx.notify();

View file

@ -1,5 +1,6 @@
mod blink_manager; mod blink_manager;
pub mod display_map; pub mod display_map;
mod editor_settings;
mod element; mod element;
mod git; mod git;
@ -28,6 +29,7 @@ use collections::{BTreeMap, Bound, HashMap, HashSet, VecDeque};
use copilot::Copilot; use copilot::Copilot;
pub use display_map::DisplayPoint; pub use display_map::DisplayPoint;
use display_map::*; use display_map::*;
pub use editor_settings::EditorSettings;
pub use element::*; pub use element::*;
use futures::FutureExt; use futures::FutureExt;
use fuzzy::{StringMatch, StringMatchCandidate}; use fuzzy::{StringMatch, StringMatchCandidate};
@ -287,7 +289,12 @@ pub enum Direction {
Next, Next,
} }
pub fn init_settings(cx: &mut AppContext) {
settings::register_setting::<EditorSettings>(cx);
}
pub fn init(cx: &mut AppContext) { pub fn init(cx: &mut AppContext) {
init_settings(cx);
cx.add_action(Editor::new_file); cx.add_action(Editor::new_file);
cx.add_action(Editor::cancel); cx.add_action(Editor::cancel);
cx.add_action(Editor::newline); cx.add_action(Editor::newline);
@ -2354,7 +2361,7 @@ impl Editor {
} }
fn trigger_completion_on_input(&mut self, text: &str, cx: &mut ViewContext<Self>) { fn trigger_completion_on_input(&mut self, text: &str, cx: &mut ViewContext<Self>) {
if !cx.global::<Settings>().show_completions_on_input { if !settings::get_setting::<EditorSettings>(None, cx).show_completions_on_input {
return; return;
} }

View file

@ -0,0 +1,34 @@
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use settings::Setting;
#[derive(Deserialize)]
pub struct EditorSettings {
pub cursor_blink: bool,
pub hover_popover_enabled: bool,
pub show_completions_on_input: bool,
}
#[derive(Clone, Serialize, Deserialize, JsonSchema)]
pub struct EditorSettingsContent {
pub cursor_blink: Option<bool>,
pub hover_popover_enabled: Option<bool>,
pub show_completions_on_input: Option<bool>,
}
impl Setting for EditorSettings {
const KEY: Option<&'static str> = None;
type FileContent = EditorSettingsContent;
fn load(
default_value: &Self::FileContent,
user_values: &[&Self::FileContent],
_: &gpui::AppContext,
) -> anyhow::Result<Self>
where
Self: Sized,
{
Self::load_via_json_merge(default_value, user_values)
}
}

View file

@ -4697,8 +4697,10 @@ async fn test_completion(cx: &mut gpui::TestAppContext) {
apply_additional_edits.await.unwrap(); apply_additional_edits.await.unwrap();
cx.update(|cx| { cx.update(|cx| {
cx.update_global::<Settings, _, _>(|settings, _| { cx.update_global::<SettingsStore, _, _>(|settings, cx| {
settings.show_completions_on_input = false; settings.update_user_settings::<EditorSettings>(cx, |settings| {
settings.show_completions_on_input = Some(false);
});
}) })
}); });
cx.set_state("editorˇ"); cx.set_state("editorˇ");

View file

@ -1,6 +1,6 @@
use crate::{ use crate::{
display_map::ToDisplayPoint, Anchor, AnchorRangeExt, DisplayPoint, Editor, EditorSnapshot, display_map::ToDisplayPoint, Anchor, AnchorRangeExt, DisplayPoint, Editor, EditorSettings,
EditorStyle, RangeToAnchorExt, EditorSnapshot, EditorStyle, RangeToAnchorExt,
}; };
use futures::FutureExt; use futures::FutureExt;
use gpui::{ use gpui::{
@ -38,7 +38,7 @@ pub fn hover(editor: &mut Editor, _: &Hover, cx: &mut ViewContext<Editor>) {
/// The internal hover action dispatches between `show_hover` or `hide_hover` /// The internal hover action dispatches between `show_hover` or `hide_hover`
/// depending on whether a point to hover over is provided. /// depending on whether a point to hover over is provided.
pub fn hover_at(editor: &mut Editor, point: Option<DisplayPoint>, cx: &mut ViewContext<Editor>) { pub fn hover_at(editor: &mut Editor, point: Option<DisplayPoint>, cx: &mut ViewContext<Editor>) {
if cx.global::<Settings>().hover_popover_enabled { if settings::get_setting::<EditorSettings>(None, cx).hover_popover_enabled {
if let Some(point) = point { if let Some(point) = point {
show_hover(editor, point, false, cx); show_hover(editor, point, false, cx);
} else { } else {

View file

@ -24,6 +24,7 @@ futures.workspace = true
unicase = "2.6" unicase = "2.6"
[dev-dependencies] [dev-dependencies]
client = { path = "../client", features = ["test-support"] }
language = { path = "../language", features = ["test-support"] } language = { path = "../language", features = ["test-support"] }
editor = { path = "../editor", features = ["test-support"] } editor = { path = "../editor", features = ["test-support"] }
gpui = { path = "../gpui", features = ["test-support"] } gpui = { path = "../gpui", features = ["test-support"] }

View file

@ -1935,6 +1935,7 @@ mod tests {
cx.update(|cx| { cx.update(|cx| {
cx.set_global(SettingsStore::test(cx)); cx.set_global(SettingsStore::test(cx));
language::init(cx); language::init(cx);
editor::init_settings(cx);
}); });
} }
} }

View file

@ -1281,11 +1281,13 @@ pub mod tests {
cx.update(|cx| { cx.update(|cx| {
cx.set_global(SettingsStore::test(cx)); cx.set_global(SettingsStore::test(cx));
cx.set_global(ActiveSearches::default()); cx.set_global(ActiveSearches::default());
let mut settings = Settings::test(cx); let mut settings = Settings::test(cx);
settings.theme = Arc::new(theme); settings.theme = Arc::new(theme);
cx.set_global(settings); cx.set_global(settings);
language::init(cx); language::init(cx);
editor::init_settings(cx);
}); });
} }
} }

View file

@ -38,10 +38,7 @@ pub struct Settings {
pub buffer_font_family: FamilyId, pub buffer_font_family: FamilyId,
pub buffer_font_size: f32, pub buffer_font_size: f32,
pub active_pane_magnification: f32, pub active_pane_magnification: f32,
pub cursor_blink: bool,
pub confirm_quit: bool, pub confirm_quit: bool,
pub hover_popover_enabled: bool,
pub show_completions_on_input: bool,
pub show_call_status_icon: bool, pub show_call_status_icon: bool,
pub autosave: Autosave, pub autosave: Autosave,
pub default_dock_anchor: DockAnchor, pub default_dock_anchor: DockAnchor,
@ -78,9 +75,6 @@ impl Setting for Settings {
buffer_font_size: defaults.buffer_font_size.unwrap(), buffer_font_size: defaults.buffer_font_size.unwrap(),
active_pane_magnification: defaults.active_pane_magnification.unwrap(), active_pane_magnification: defaults.active_pane_magnification.unwrap(),
confirm_quit: defaults.confirm_quit.unwrap(), confirm_quit: defaults.confirm_quit.unwrap(),
cursor_blink: defaults.cursor_blink.unwrap(),
hover_popover_enabled: defaults.hover_popover_enabled.unwrap(),
show_completions_on_input: defaults.show_completions_on_input.unwrap(),
show_call_status_icon: defaults.show_call_status_icon.unwrap(), show_call_status_icon: defaults.show_call_status_icon.unwrap(),
autosave: defaults.autosave.unwrap(), autosave: defaults.autosave.unwrap(),
default_dock_anchor: defaults.default_dock_anchor.unwrap(), default_dock_anchor: defaults.default_dock_anchor.unwrap(),
@ -341,9 +335,6 @@ impl Settings {
buffer_font_size: defaults.buffer_font_size.unwrap(), buffer_font_size: defaults.buffer_font_size.unwrap(),
active_pane_magnification: defaults.active_pane_magnification.unwrap(), active_pane_magnification: defaults.active_pane_magnification.unwrap(),
confirm_quit: defaults.confirm_quit.unwrap(), confirm_quit: defaults.confirm_quit.unwrap(),
cursor_blink: defaults.cursor_blink.unwrap(),
hover_popover_enabled: defaults.hover_popover_enabled.unwrap(),
show_completions_on_input: defaults.show_completions_on_input.unwrap(),
show_call_status_icon: defaults.show_call_status_icon.unwrap(), show_call_status_icon: defaults.show_call_status_icon.unwrap(),
autosave: defaults.autosave.unwrap(), autosave: defaults.autosave.unwrap(),
default_dock_anchor: defaults.default_dock_anchor.unwrap(), default_dock_anchor: defaults.default_dock_anchor.unwrap(),
@ -391,13 +382,7 @@ impl Settings {
&mut self.active_pane_magnification, &mut self.active_pane_magnification,
data.active_pane_magnification, data.active_pane_magnification,
); );
merge(&mut self.cursor_blink, data.cursor_blink);
merge(&mut self.confirm_quit, data.confirm_quit); merge(&mut self.confirm_quit, data.confirm_quit);
merge(&mut self.hover_popover_enabled, data.hover_popover_enabled);
merge(
&mut self.show_completions_on_input,
data.show_completions_on_input,
);
merge(&mut self.autosave, data.autosave); merge(&mut self.autosave, data.autosave);
merge(&mut self.default_dock_anchor, data.default_dock_anchor); merge(&mut self.default_dock_anchor, data.default_dock_anchor);
merge(&mut self.base_keymap, data.base_keymap); merge(&mut self.base_keymap, data.base_keymap);
@ -426,9 +411,6 @@ impl Settings {
buffer_font_size: 14., buffer_font_size: 14.,
active_pane_magnification: 1., active_pane_magnification: 1.,
confirm_quit: false, confirm_quit: false,
cursor_blink: true,
hover_popover_enabled: true,
show_completions_on_input: true,
show_call_status_icon: true, show_call_status_icon: true,
autosave: Autosave::Off, autosave: Autosave::Off,
default_dock_anchor: DockAnchor::Bottom, default_dock_anchor: DockAnchor::Bottom,