Add Zed > Preferences > Local Settings to application menu

Max Brunsfeld created

Change summary

crates/zed/src/menus.rs |  1 
crates/zed/src/zed.rs   | 55 ++++++++++++++++++++++++++++++++++++++++++
2 files changed, 55 insertions(+), 1 deletion(-)

Detailed changes

crates/zed/src/menus.rs 🔗

@@ -16,6 +16,7 @@ pub fn menus() -> Vec<Menu<'static>> {
                         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),
                     ],
                 }),

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<AppState>, 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<Workspace>| {
             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<Workspace>,
+) {
+    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>) {
     workspace.with_local_workspace(cx, move |workspace, cx| {
         let app_state = workspace.app_state().clone();