From 0949ee84d8aa72872455f1c7f38c468b1e83646b Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Mon, 5 Jun 2023 15:02:29 -0700 Subject: [PATCH 1/4] :art: Move OpenSettings action back to the zed crate --- crates/workspace/src/workspace.rs | 16 +--------------- crates/zed/src/main.rs | 6 ++---- crates/zed/src/menus.rs | 2 +- crates/zed/src/zed.rs | 11 +++++++++++ 4 files changed, 15 insertions(+), 20 deletions(-) diff --git a/crates/workspace/src/workspace.rs b/crates/workspace/src/workspace.rs index a429a30a39..278b02d74e 100644 --- a/crates/workspace/src/workspace.rs +++ b/crates/workspace/src/workspace.rs @@ -15,7 +15,6 @@ mod toolbar; mod workspace_settings; use anyhow::{anyhow, Context, Result}; -use assets::Assets; use call::ActiveCall; use client::{ proto::{self, PeerId}, @@ -83,7 +82,7 @@ use status_bar::StatusBar; pub use status_bar::StatusItemView; use theme::{Theme, ThemeSettings}; pub use toolbar::{ToolbarItemLocation, ToolbarItemView}; -use util::{async_iife, paths, ResultExt}; +use util::{async_iife, ResultExt}; pub use workspace_settings::{AutosaveSetting, GitGutterSetting, WorkspaceSettings}; lazy_static! { @@ -133,8 +132,6 @@ actions!( ] ); -actions!(zed, [OpenSettings]); - #[derive(Clone, PartialEq)] pub struct OpenPaths { pub paths: Vec, @@ -295,17 +292,6 @@ pub fn init(app_state: Arc, cx: &mut AppContext) { .detach(); }); - cx.add_action( - move |_: &mut Workspace, _: &OpenSettings, cx: &mut ViewContext| { - create_and_open_local_file(&paths::SETTINGS, cx, || { - settings::initial_user_settings_content(&Assets) - .as_ref() - .into() - }) - .detach_and_log_err(cx); - }, - ); - let client = &app_state.client; client.add_view_request_handler(Workspace::handle_follow); client.add_view_message_handler(Workspace::handle_unfollow); diff --git a/crates/zed/src/main.rs b/crates/zed/src/main.rs index 59072cc9f4..f5031beb2e 100644 --- a/crates/zed/src/main.rs +++ b/crates/zed/src/main.rs @@ -56,9 +56,7 @@ use fs::RealFs; #[cfg(debug_assertions)] use staff_mode::StaffMode; use util::{channel::RELEASE_CHANNEL, paths, ResultExt, TryFutureExt}; -use workspace::{ - item::ItemHandle, notifications::NotifyResultExt, AppState, OpenSettings, Workspace, -}; +use workspace::{item::ItemHandle, notifications::NotifyResultExt, AppState, Workspace}; use zed::{ self, build_window_options, handle_keymap_file_changes, initialize_workspace, languages, menus, }; @@ -877,6 +875,6 @@ pub fn background_actions() -> &'static [(&'static str, &'static dyn Action)] { ("Go to file", &file_finder::Toggle), ("Open command palette", &command_palette::Toggle), ("Open recent projects", &recent_projects::OpenRecent), - ("Change your settings", &OpenSettings), + ("Change your settings", &zed::OpenSettings), ] } diff --git a/crates/zed/src/menus.rs b/crates/zed/src/menus.rs index 76e88325f5..83af92e264 100644 --- a/crates/zed/src/menus.rs +++ b/crates/zed/src/menus.rs @@ -12,7 +12,7 @@ pub fn menus() -> Vec> { MenuItem::submenu(Menu { name: "Preferences", items: vec![ - MenuItem::action("Open Settings", workspace::OpenSettings), + MenuItem::action("Open Settings", super::OpenSettings), MenuItem::action("Open Key Bindings", super::OpenKeymap), MenuItem::action("Open Default Settings", super::OpenDefaultSettings), MenuItem::action("Open Default Key Bindings", super::OpenDefaultKeymap), diff --git a/crates/zed/src/zed.rs b/crates/zed/src/zed.rs index 6dbddae2ad..7472500d39 100644 --- a/crates/zed/src/zed.rs +++ b/crates/zed/src/zed.rs @@ -65,6 +65,7 @@ actions!( OpenLicenses, OpenTelemetryLog, OpenKeymap, + OpenSettings, OpenDefaultSettings, OpenDefaultKeymap, IncreaseBufferFontSize, @@ -157,6 +158,16 @@ pub fn init(app_state: &Arc, cx: &mut gpui::AppContext) { create_and_open_local_file(&paths::KEYMAP, cx, Default::default).detach_and_log_err(cx); }, ); + cx.add_action( + move |_: &mut Workspace, _: &OpenSettings, cx: &mut ViewContext| { + create_and_open_local_file(&paths::SETTINGS, cx, || { + settings::initial_user_settings_content(&Assets) + .as_ref() + .into() + }) + .detach_and_log_err(cx); + }, + ); cx.add_action( move |workspace: &mut Workspace, _: &OpenDefaultKeymap, cx: &mut ViewContext| { open_bundled_file( From cb975f125255713bc07b60c1d21d531f1c4e0011 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Mon, 5 Jun 2023 17:45:42 -0700 Subject: [PATCH 2/4] Add Zed > Preferences > Local Settings to application menu --- crates/zed/src/menus.rs | 1 + crates/zed/src/zed.rs | 55 ++++++++++++++++++++++++++++++++++++++++- 2 files changed, 55 insertions(+), 1 deletion(-) diff --git a/crates/zed/src/menus.rs b/crates/zed/src/menus.rs index 83af92e264..9112cd207b 100644 --- a/crates/zed/src/menus.rs +++ b/crates/zed/src/menus.rs @@ -16,6 +16,7 @@ pub fn menus() -> Vec> { MenuItem::action("Open Key Bindings", super::OpenKeymap), MenuItem::action("Open Default Settings", super::OpenDefaultSettings), MenuItem::action("Open Default Key Bindings", super::OpenDefaultKeymap), + MenuItem::action("Open Local Settings", super::OpenLocalSettings), MenuItem::action("Select Theme", theme_selector::Toggle), ], }), diff --git a/crates/zed/src/zed.rs b/crates/zed/src/zed.rs index 7472500d39..ae9370384a 100644 --- a/crates/zed/src/zed.rs +++ b/crates/zed/src/zed.rs @@ -33,7 +33,11 @@ use serde_json::to_string_pretty; use settings::{KeymapFileContent, SettingsStore, DEFAULT_SETTINGS_ASSET_PATH}; use std::{borrow::Cow, str, sync::Arc}; use terminal_view::terminal_panel::{self, TerminalPanel}; -use util::{channel::ReleaseChannel, paths, ResultExt}; +use util::{ + channel::ReleaseChannel, + paths::{self, LOCAL_SETTINGS_RELATIVE_PATH}, + ResultExt, +}; use uuid::Uuid; use welcome::BaseKeymap; pub use workspace; @@ -66,6 +70,7 @@ actions!( OpenTelemetryLog, OpenKeymap, OpenSettings, + OpenLocalSettings, OpenDefaultSettings, OpenDefaultKeymap, IncreaseBufferFontSize, @@ -168,6 +173,7 @@ pub fn init(app_state: &Arc, cx: &mut gpui::AppContext) { .detach_and_log_err(cx); }, ); + cx.add_action(open_local_settings_file); cx.add_action( move |workspace: &mut Workspace, _: &OpenDefaultKeymap, cx: &mut ViewContext| { open_bundled_file( @@ -555,6 +561,53 @@ pub fn handle_keymap_file_changes( .detach(); } +fn open_local_settings_file( + workspace: &mut Workspace, + _: &OpenLocalSettings, + cx: &mut ViewContext, +) { + let project = workspace.project().clone(); + let worktree = project + .read(cx) + .visible_worktrees(cx) + .find_map(|tree| tree.read(cx).root_entry()?.is_dir().then_some(tree)); + if let Some(worktree) = worktree { + let tree_id = worktree.read(cx).id(); + cx.spawn(|workspace, mut cx| async move { + let file_path = &*LOCAL_SETTINGS_RELATIVE_PATH; + + if let Some(dir_path) = file_path.parent() { + if worktree.read_with(&cx, |tree, _| tree.entry_for_path(dir_path).is_none()) { + project + .update(&mut cx, |project, cx| { + project.create_entry((tree_id, dir_path), true, cx) + }) + .ok_or_else(|| anyhow!("worktree was removed"))? + .await?; + } + } + + if worktree.read_with(&cx, |tree, _| tree.entry_for_path(file_path).is_none()) { + project + .update(&mut cx, |project, cx| { + project.create_entry((tree_id, file_path), false, cx) + }) + .ok_or_else(|| anyhow!("worktree was removed"))? + .await?; + } + + workspace + .update(&mut cx, |workspace, cx| { + workspace.open_path((tree_id, file_path), None, true, cx) + })? + .await?; + + anyhow::Ok(()) + }) + .detach(); + } +} + fn open_telemetry_log_file(workspace: &mut Workspace, cx: &mut ViewContext) { workspace.with_local_workspace(cx, move |workspace, cx| { let app_state = workspace.app_state().clone(); From 296a0bf51060eab6c8eaf1b530f529ee62bce04a Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Mon, 5 Jun 2023 18:09:42 -0700 Subject: [PATCH 3/4] Populate created local settings file with an empty JSON object and comments --- assets/settings/initial_local_settings.json | 11 +++++++++ crates/collab/src/rpc.rs | 4 +-- crates/settings/src/settings.rs | 19 ++++++++++++--- crates/settings/src/settings_file.rs | 14 +++-------- crates/zed/src/zed.rs | 27 ++++++++++++++++++--- 5 files changed, 55 insertions(+), 20 deletions(-) create mode 100644 assets/settings/initial_local_settings.json diff --git a/assets/settings/initial_local_settings.json b/assets/settings/initial_local_settings.json new file mode 100644 index 0000000000..69be683aa8 --- /dev/null +++ b/assets/settings/initial_local_settings.json @@ -0,0 +1,11 @@ +// Folder-specific Zed settings +// +// A subset of Zed's settings can be configured on a per-folder basis. +// +// For information on how to configure Zed, see the Zed +// documentation: https://zed.dev/docs/configuring-zed +// +// To see all of Zed's default settings without changing your +// custom settings, run the `open default settings` command +// from the command palette or from `Zed` application menu. +{} diff --git a/crates/collab/src/rpc.rs b/crates/collab/src/rpc.rs index 61c6123a82..8d210513c2 100644 --- a/crates/collab/src/rpc.rs +++ b/crates/collab/src/rpc.rs @@ -1424,7 +1424,7 @@ async fn join_project( )?; } - for settings_file in dbg!(worktree.settings_files) { + for settings_file in worktree.settings_files { session.peer.send( session.connection_id, proto::UpdateWorktreeSettings { @@ -1554,8 +1554,6 @@ async fn update_worktree_settings( message: proto::UpdateWorktreeSettings, session: Session, ) -> Result<()> { - dbg!(&message); - let guest_connection_ids = session .db() .await diff --git a/crates/settings/src/settings.rs b/crates/settings/src/settings.rs index 840797c6ad..1c131e5916 100644 --- a/crates/settings/src/settings.rs +++ b/crates/settings/src/settings.rs @@ -9,10 +9,23 @@ pub use settings_store::{Setting, SettingsJsonSchemaParams, SettingsStore}; use std::{borrow::Cow, str}; pub const DEFAULT_SETTINGS_ASSET_PATH: &str = "settings/default.json"; -pub const INITIAL_USER_SETTINGS_ASSET_PATH: &str = "settings/initial_user_settings.json"; +const INITIAL_USER_SETTINGS_ASSET_PATH: &str = "settings/initial_user_settings.json"; +const INITIAL_LOCAL_SETTINGS_ASSET_PATH: &str = "settings/initial_local_settings.json"; -pub fn initial_user_settings_content(assets: &'static impl AssetSource) -> Cow<'static, str> { - match assets.load(INITIAL_USER_SETTINGS_ASSET_PATH).unwrap() { +pub fn default_settings() -> Cow<'static, str> { + asset_str(&assets::Assets, DEFAULT_SETTINGS_ASSET_PATH) +} + +pub fn initial_user_settings_content(assets: &dyn AssetSource) -> Cow<'_, str> { + asset_str(assets, INITIAL_USER_SETTINGS_ASSET_PATH) +} + +pub fn initial_local_settings_content(assets: &dyn AssetSource) -> Cow<'_, str> { + asset_str(assets, INITIAL_LOCAL_SETTINGS_ASSET_PATH) +} + +fn asset_str<'a>(assets: &'a dyn AssetSource, path: &str) -> Cow<'a, str> { + match assets.load(path).unwrap() { Cow::Borrowed(s) => Cow::Borrowed(str::from_utf8(s).unwrap()), Cow::Owned(s) => Cow::Owned(String::from_utf8(s).unwrap()), } diff --git a/crates/settings/src/settings_file.rs b/crates/settings/src/settings_file.rs index 3505330eda..edd4fe0d9d 100644 --- a/crates/settings/src/settings_file.rs +++ b/crates/settings/src/settings_file.rs @@ -1,11 +1,10 @@ -use crate::{settings_store::SettingsStore, Setting, DEFAULT_SETTINGS_ASSET_PATH}; +use crate::{settings_store::SettingsStore, Setting}; use anyhow::Result; use assets::Assets; use fs::Fs; use futures::{channel::mpsc, StreamExt}; -use gpui::{executor::Background, AppContext, AssetSource}; +use gpui::{executor::Background, AppContext}; use std::{ - borrow::Cow, io::ErrorKind, path::{Path, PathBuf}, str, @@ -28,19 +27,12 @@ pub fn get_local<'a, T: Setting>(location: Option<(usize, &Path)>, cx: &'a AppCo cx.global::().get(location) } -pub fn default_settings() -> Cow<'static, str> { - match Assets.load(DEFAULT_SETTINGS_ASSET_PATH).unwrap() { - Cow::Borrowed(s) => Cow::Borrowed(str::from_utf8(s).unwrap()), - Cow::Owned(s) => Cow::Owned(String::from_utf8(s).unwrap()), - } -} - pub const EMPTY_THEME_NAME: &'static str = "empty-theme"; #[cfg(any(test, feature = "test-support"))] pub fn test_settings() -> String { let mut value = crate::settings_store::parse_json_with_comments::( - default_settings().as_ref(), + crate::default_settings().as_ref(), ) .unwrap(); util::merge_non_null_json_value_into( diff --git a/crates/zed/src/zed.rs b/crates/zed/src/zed.rs index ae9370384a..f0e88133f3 100644 --- a/crates/zed/src/zed.rs +++ b/crates/zed/src/zed.rs @@ -30,7 +30,9 @@ use project_panel::ProjectPanel; use search::{BufferSearchBar, ProjectSearchBar}; use serde::Deserialize; use serde_json::to_string_pretty; -use settings::{KeymapFileContent, SettingsStore, DEFAULT_SETTINGS_ASSET_PATH}; +use settings::{ + initial_local_settings_content, KeymapFileContent, SettingsStore, DEFAULT_SETTINGS_ASSET_PATH, +}; use std::{borrow::Cow, str, sync::Arc}; use terminal_view::terminal_panel::{self, TerminalPanel}; use util::{ @@ -596,11 +598,30 @@ fn open_local_settings_file( .await?; } - workspace + let editor = workspace .update(&mut cx, |workspace, cx| { workspace.open_path((tree_id, file_path), None, true, cx) })? - .await?; + .await? + .downcast::() + .ok_or_else(|| anyhow!("unexpected item type"))?; + + editor + .downgrade() + .update(&mut cx, |editor, cx| { + if let Some(buffer) = editor.buffer().read(cx).as_singleton() { + if buffer.read(cx).is_empty() { + buffer.update(cx, |buffer, cx| { + buffer.edit( + [(0..0, initial_local_settings_content(&Assets))], + None, + cx, + ) + }); + } + } + }) + .ok(); anyhow::Ok(()) }) From cfcfc3bf6b1493e7668ed6a0c433f198690d6358 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Tue, 6 Jun 2023 09:03:57 -0700 Subject: [PATCH 4/4] Show notification when attempting to open local settings in a project w/ no folders --- crates/zed/src/zed.rs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/crates/zed/src/zed.rs b/crates/zed/src/zed.rs index f0e88133f3..8d27a378c5 100644 --- a/crates/zed/src/zed.rs +++ b/crates/zed/src/zed.rs @@ -44,8 +44,9 @@ use uuid::Uuid; use welcome::BaseKeymap; pub use workspace; use workspace::{ - create_and_open_local_file, dock::PanelHandle, open_new, AppState, NewFile, NewWindow, - Workspace, WorkspaceSettings, + create_and_open_local_file, dock::PanelHandle, + notifications::simple_message_notification::MessageNotification, open_new, AppState, NewFile, + NewWindow, Workspace, WorkspaceSettings, }; #[derive(Deserialize, Clone, PartialEq)] @@ -626,6 +627,10 @@ fn open_local_settings_file( anyhow::Ok(()) }) .detach(); + } else { + workspace.show_notification(0, cx, |cx| { + cx.add_view(|_| MessageNotification::new("This project has no folders open.")) + }) } }