@@ -15,7 +15,7 @@ use project::{Project, WorktreeId};
use release_channel::ReleaseChannel;
use schemars::JsonSchema;
use serde::Deserialize;
-use settings::{Settings, SettingsContent, SettingsStore};
+use settings::{Settings, SettingsContent, SettingsStore, initial_project_settings_content};
use std::{
any::{Any, TypeId, type_name},
cell::RefCell,
@@ -35,7 +35,7 @@ use ui::{
use ui_input::{NumberField, NumberFieldType};
use util::{ResultExt as _, paths::PathStyle, rel_path::RelPath};
use workspace::{AppState, OpenOptions, OpenVisible, Workspace, client_side_decorations};
-use zed_actions::{OpenSettings, OpenSettingsAt};
+use zed_actions::{OpenProjectSettings, OpenSettings, OpenSettingsAt};
use crate::components::{
EnumVariantDropdown, SettingsInputField, font_picker, icon_theme_picker, theme_picker,
@@ -379,26 +379,30 @@ pub fn init(cx: &mut App) {
init_renderers(cx);
cx.observe_new(|workspace: &mut workspace::Workspace, _, _| {
- workspace.register_action(
- |workspace, OpenSettingsAt { path }: &OpenSettingsAt, window, cx| {
+ workspace
+ .register_action(
+ |workspace, OpenSettingsAt { path }: &OpenSettingsAt, window, cx| {
+ let window_handle = window
+ .window_handle()
+ .downcast::<Workspace>()
+ .expect("Workspaces are root Windows");
+ open_settings_editor(workspace, Some(&path), false, window_handle, cx);
+ },
+ )
+ .register_action(|workspace, _: &OpenSettings, window, cx| {
let window_handle = window
.window_handle()
.downcast::<Workspace>()
.expect("Workspaces are root Windows");
- open_settings_editor(workspace, Some(&path), window_handle, cx);
- },
- );
- })
- .detach();
-
- cx.observe_new(|workspace: &mut workspace::Workspace, _, _| {
- workspace.register_action(|workspace, _: &OpenSettings, window, cx| {
- let window_handle = window
- .window_handle()
- .downcast::<Workspace>()
- .expect("Workspaces are root Windows");
- open_settings_editor(workspace, None, window_handle, cx);
- });
+ open_settings_editor(workspace, None, false, window_handle, cx);
+ })
+ .register_action(|workspace, _: &OpenProjectSettings, window, cx| {
+ let window_handle = window
+ .window_handle()
+ .downcast::<Workspace>()
+ .expect("Workspaces are root Windows");
+ open_settings_editor(workspace, None, true, window_handle, cx);
+ });
})
.detach();
}
@@ -506,6 +510,7 @@ fn init_renderers(cx: &mut App) {
pub fn open_settings_editor(
_workspace: &mut Workspace,
path: Option<&str>,
+ open_project_settings: bool,
workspace_handle: WindowHandle<Workspace>,
cx: &mut App,
) {
@@ -514,6 +519,8 @@ pub fn open_settings_editor(
/// Assumes a settings GUI window is already open
fn open_path(
path: &str,
+ // Note: This option is unsupported right now
+ _open_project_settings: bool,
settings_window: &mut SettingsWindow,
window: &mut Window,
cx: &mut Context<SettingsWindow>,
@@ -540,7 +547,17 @@ pub fn open_settings_editor(
settings_window.original_window = Some(workspace_handle);
window.activate_window();
if let Some(path) = path {
- open_path(path, settings_window, window, cx);
+ open_path(path, open_project_settings, settings_window, window, cx);
+ } else if open_project_settings {
+ if let Some(file_index) = settings_window
+ .files
+ .iter()
+ .position(|(file, _)| file.worktree_id().is_some())
+ {
+ settings_window.change_file(file_index, window, cx);
+ }
+
+ cx.notify();
}
})
.ok();
@@ -588,7 +605,17 @@ pub fn open_settings_editor(
cx.new(|cx| SettingsWindow::new(Some(workspace_handle), window, cx));
settings_window.update(cx, |settings_window, cx| {
if let Some(path) = path {
- open_path(&path, settings_window, window, cx);
+ open_path(&path, open_project_settings, settings_window, window, cx);
+ } else if open_project_settings {
+ if let Some(file_index) = settings_window
+ .files
+ .iter()
+ .position(|(file, _)| file.worktree_id().is_some())
+ {
+ settings_window.change_file(file_index, window, cx);
+ }
+
+ settings_window.fetch_files(window, cx);
}
});
@@ -1159,7 +1186,7 @@ fn all_language_names(cx: &App) -> Vec<SharedString> {
}
#[allow(unused)]
-#[derive(Clone, PartialEq)]
+#[derive(Clone, PartialEq, Debug)]
enum SettingsUiFile {
User, // Uses all settings.
Project((WorktreeId, Arc<RelPath>)), // Has a special name, and special set of settings
@@ -1283,15 +1310,34 @@ impl SettingsWindow {
})
.collect::<Vec<_>>()
{
+ cx.observe_release_in(&project, window, |this, _, window, cx| {
+ this.fetch_files(window, cx)
+ })
+ .detach();
cx.subscribe_in(&project, window, Self::handle_project_event)
.detach();
}
+
+ for workspace in app_state
+ .workspace_store
+ .read(cx)
+ .workspaces()
+ .iter()
+ .filter_map(|space| space.entity(cx).ok())
+ {
+ cx.observe_release_in(&workspace, window, |this, _, window, cx| {
+ this.fetch_files(window, cx)
+ })
+ .detach();
+ }
} else {
log::error!("App state doesn't exist when creating a new settings window");
}
let this_weak = cx.weak_entity();
cx.observe_new::<Project>({
+ let this_weak = this_weak.clone();
+
move |_, window, cx| {
let project = cx.entity();
let Some(window) = window else {
@@ -1299,7 +1345,13 @@ impl SettingsWindow {
};
this_weak
- .update(cx, |_, cx| {
+ .update(cx, |this, cx| {
+ this.fetch_files(window, cx);
+ cx.observe_release_in(&project, window, |_, _, window, cx| {
+ cx.defer_in(window, |this, window, cx| this.fetch_files(window, cx));
+ })
+ .detach();
+
cx.subscribe_in(&project, window, Self::handle_project_event)
.detach();
})
@@ -1308,6 +1360,24 @@ impl SettingsWindow {
})
.detach();
+ cx.observe_new::<Workspace>(move |_, window, cx| {
+ let workspace = cx.entity();
+ let Some(window) = window else {
+ return;
+ };
+
+ this_weak
+ .update(cx, |this, cx| {
+ this.fetch_files(window, cx);
+ cx.observe_release_in(&workspace, window, |this, _, window, cx| {
+ this.fetch_files(window, cx)
+ })
+ .detach();
+ })
+ .ok();
+ })
+ .detach();
+
let title_bar = if !cfg!(target_os = "macos") {
Some(cx.new(|cx| PlatformTitleBar::new("settings-title-bar", cx)))
} else {
@@ -1818,6 +1888,7 @@ impl SettingsWindow {
cx.notify();
}
+ #[track_caller]
fn fetch_files(&mut self, window: &mut Window, cx: &mut Context<SettingsWindow>) {
self.worktree_root_dirs.clear();
let prev_files = self.files.clone();
@@ -1870,7 +1941,7 @@ impl SettingsWindow {
let mut missing_worktrees = Vec::new();
for worktree in all_projects(cx)
- .flat_map(|project| project.read(cx).worktrees(cx))
+ .flat_map(|project| project.read(cx).visible_worktrees(cx))
.filter(|tree| !self.worktree_root_dirs.contains_key(&tree.read(cx).id()))
{
let worktree = worktree.read(cx);
@@ -3028,7 +3099,7 @@ impl SettingsWindow {
tree.create_entry(
settings_path.clone(),
false,
- Some("{\n\n}".as_bytes().to_vec()),
+ Some(initial_project_settings_content().as_bytes().to_vec()),
cx,
)
}))