From 81475ac4cde2d7481d620ef22e1d9c3148b38ec2 Mon Sep 17 00:00:00 2001 From: Marshall Bowers Date: Tue, 18 Jun 2024 12:22:37 -0400 Subject: [PATCH] paths: Replace `lazy_static!` with `OnceLock` (#13213) This PR replaces the `lazy_static!` usages in the `paths` crate with `OnceLock` from the standard library. This allows us to drop the `lazy_static` dependency from this crate. The paths are now exposed as accessor functions that reference a private static value. Release Notes: - N/A --- Cargo.lock | 1 - crates/assistant/src/assistant.rs | 3 +- crates/assistant/src/assistant_panel.rs | 6 +- crates/assistant/src/context_store.rs | 8 +- crates/assistant/src/prompt_library.rs | 3 +- crates/cli/src/main.rs | 2 +- crates/client/src/client.rs | 2 +- crates/client/src/telemetry.rs | 2 +- crates/copilot/src/copilot.rs | 8 +- crates/db/src/db.rs | 6 +- crates/extension/src/extension_store.rs | 3 +- crates/fs/src/fs.rs | 2 +- .../src/inline_completion_button.rs | 2 +- crates/languages/src/json.rs | 10 +- crates/node_runtime/src/node_runtime.rs | 2 +- crates/paths/Cargo.toml | 1 - crates/paths/src/paths.rs | 319 +++++++++++++----- crates/prettier/src/prettier.rs | 8 +- crates/project/src/prettier_support.rs | 12 +- crates/project/src/project.rs | 11 +- crates/rustdoc/src/store.rs | 6 +- crates/settings/src/settings_file.rs | 4 +- crates/supermaven_api/src/supermaven_api.rs | 10 +- crates/zed/src/main.rs | 29 +- crates/zed/src/reliability.rs | 10 +- crates/zed/src/zed.rs | 22 +- crates/zed/src/zed/open_listener.rs | 2 +- 27 files changed, 322 insertions(+), 172 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8b62a30a10..64034c3f51 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7399,7 +7399,6 @@ name = "paths" version = "0.1.0" dependencies = [ "dirs 4.0.0", - "lazy_static", "util", ] diff --git a/crates/assistant/src/assistant.rs b/crates/assistant/src/assistant.rs index 543e03421d..dcdb4546bd 100644 --- a/crates/assistant/src/assistant.rs +++ b/crates/assistant/src/assistant.rs @@ -21,7 +21,6 @@ pub(crate) use context_store::*; use gpui::{actions, AppContext, Global, SharedString, UpdateGlobal}; pub(crate) use inline_assistant::*; pub(crate) use model_selector::*; -use paths::EMBEDDINGS_DIR; use rustdoc::RustdocStore; use semantic_index::{CloudEmbeddingProvider, SemanticIndex}; use serde::{Deserialize, Serialize}; @@ -271,7 +270,7 @@ pub fn init(client: Arc, cx: &mut AppContext) { async move { let embedding_provider = CloudEmbeddingProvider::new(client.clone()); let semantic_index = SemanticIndex::new( - EMBEDDINGS_DIR.join("semantic-index-db.0.mdb"), + paths::embeddings_dir().join("semantic-index-db.0.mdb"), Arc::new(embedding_provider), &mut cx, ) diff --git a/crates/assistant/src/assistant_panel.rs b/crates/assistant/src/assistant_panel.rs index 10f50c91bd..3d8775efaf 100644 --- a/crates/assistant/src/assistant_panel.rs +++ b/crates/assistant/src/assistant_panel.rs @@ -39,7 +39,7 @@ use language::{ LspAdapterDelegate, OffsetRangeExt as _, Point, ToOffset as _, }; use multi_buffer::MultiBufferRow; -use paths::CONTEXTS_DIR; +use paths::contexts_dir; use picker::{Picker, PickerDelegate}; use project::{Project, ProjectLspAdapterDelegate, ProjectTransaction}; use rustdoc::{CrateName, RustdocStore}; @@ -2042,7 +2042,7 @@ impl Context { let mut discriminant = 1; let mut new_path; loop { - new_path = CONTEXTS_DIR.join(&format!( + new_path = contexts_dir().join(&format!( "{} - {}.zed.json", summary.trim(), discriminant @@ -2056,7 +2056,7 @@ impl Context { new_path }; - fs.create_dir(CONTEXTS_DIR.as_ref()).await?; + fs.create_dir(contexts_dir().as_ref()).await?; fs.atomic_write(path.clone(), serde_json::to_string(&context).unwrap()) .await?; this.update(&mut cx, |this, _| this.path = Some(path))?; diff --git a/crates/assistant/src/context_store.rs b/crates/assistant/src/context_store.rs index f418b61173..9e76caea15 100644 --- a/crates/assistant/src/context_store.rs +++ b/crates/assistant/src/context_store.rs @@ -6,7 +6,7 @@ use fs::Fs; use futures::StreamExt; use fuzzy::StringMatchCandidate; use gpui::{AppContext, Model, ModelContext, Task}; -use paths::CONTEXTS_DIR; +use paths::contexts_dir; use regex::Regex; use serde::{Deserialize, Serialize}; use std::{cmp::Reverse, ffi::OsStr, path::PathBuf, sync::Arc, time::Duration}; @@ -76,7 +76,7 @@ impl ContextStore { pub fn new(fs: Arc, cx: &mut AppContext) -> Task>> { cx.spawn(|mut cx| async move { const CONTEXT_WATCH_DURATION: Duration = Duration::from_millis(100); - let (mut events, _) = fs.watch(&CONTEXTS_DIR, CONTEXT_WATCH_DURATION).await; + let (mut events, _) = fs.watch(contexts_dir(), CONTEXT_WATCH_DURATION).await; let this = cx.new_model(|cx: &mut ModelContext| Self { contexts_metadata: Vec::new(), @@ -181,9 +181,9 @@ impl ContextStore { fn reload(&mut self, cx: &mut ModelContext) -> Task> { let fs = self.fs.clone(); cx.spawn(|this, mut cx| async move { - fs.create_dir(&CONTEXTS_DIR).await?; + fs.create_dir(contexts_dir()).await?; - let mut paths = fs.read_dir(&CONTEXTS_DIR).await?; + let mut paths = fs.read_dir(contexts_dir()).await?; let mut contexts = Vec::::new(); while let Some(path) = paths.next().await { let path = path?; diff --git a/crates/assistant/src/prompt_library.rs b/crates/assistant/src/prompt_library.rs index fa693d77e8..0a4a408891 100644 --- a/crates/assistant/src/prompt_library.rs +++ b/crates/assistant/src/prompt_library.rs @@ -20,7 +20,6 @@ use gpui::{ use heed::{types::SerdeBincode, Database, RoTxn}; use language::{language_settings::SoftWrap, Buffer, LanguageRegistry}; use parking_lot::RwLock; -use paths::PROMPTS_DIR; use picker::{Picker, PickerDelegate}; use rope::Rope; use serde::{Deserialize, Serialize}; @@ -49,7 +48,7 @@ actions!( /// Init starts loading the PromptStore in the background and assigns /// a shared future to a global. pub fn init(cx: &mut AppContext) { - let db_path = PROMPTS_DIR.join("prompts-library-db.0.mdb"); + let db_path = paths::prompts_dir().join("prompts-library-db.0.mdb"); let prompt_store_future = PromptStore::new(db_path, cx.background_executor().clone()) .then(|result| future::ready(result.map(Arc::new).map_err(Arc::new))) .boxed() diff --git a/crates/cli/src/main.rs b/crates/cli/src/main.rs index 52fb700ad2..69f90f395e 100644 --- a/crates/cli/src/main.rs +++ b/crates/cli/src/main.rs @@ -220,7 +220,7 @@ mod linux { } fn launch(&self, ipc_url: String) -> anyhow::Result<()> { - let sock_path = paths::SUPPORT_DIR.join(format!("zed-{}.sock", *RELEASE_CHANNEL)); + let sock_path = paths::support_dir().join(format!("zed-{}.sock", *RELEASE_CHANNEL)); let sock = UnixDatagram::unbound()?; if sock.connect(&sock_path).is_err() { self.boot_background(ipc_url)?; diff --git a/crates/client/src/client.rs b/crates/client/src/client.rs index 71653bc914..a33bffd2b0 100644 --- a/crates/client/src/client.rs +++ b/crates/client/src/client.rs @@ -509,7 +509,7 @@ impl Client { let credentials_provider: Arc = if use_zed_development_auth { Arc::new(DevelopmentCredentialsProvider { - path: paths::CONFIG_DIR.join("development_auth"), + path: paths::config_dir().join("development_auth"), }) } else { Arc::new(KeychainCredentialsProvider) diff --git a/crates/client/src/telemetry.rs b/crates/client/src/telemetry.rs index ae230a8a02..c09a44c430 100644 --- a/crates/client/src/telemetry.rs +++ b/crates/client/src/telemetry.rs @@ -223,7 +223,7 @@ impl Telemetry { let state = state.clone(); async move { if let Some(tempfile) = - NamedTempFile::new_in(paths::CONFIG_DIR.as_path()).log_err() + NamedTempFile::new_in(paths::config_dir().as_path()).log_err() { state.lock().log_file = Some(tempfile); } diff --git a/crates/copilot/src/copilot.rs b/crates/copilot/src/copilot.rs index 8cbe9af6ef..5d034d150d 100644 --- a/crates/copilot/src/copilot.rs +++ b/crates/copilot/src/copilot.rs @@ -968,7 +968,7 @@ fn uri_for_buffer(buffer: &Model, cx: &AppContext) -> lsp::Url { } async fn clear_copilot_dir() { - remove_matching(&paths::COPILOT_DIR, |_| true).await + remove_matching(paths::copilot_dir(), |_| true).await } async fn get_copilot_lsp(http: Arc) -> anyhow::Result { @@ -979,7 +979,7 @@ async fn get_copilot_lsp(http: Arc) -> anyhow::Result { let release = latest_github_release("zed-industries/copilot", true, false, http.clone()).await?; - let version_dir = &*paths::COPILOT_DIR.join(format!("copilot-{}", release.tag_name)); + let version_dir = &paths::copilot_dir().join(format!("copilot-{}", release.tag_name)); fs::create_dir_all(version_dir).await?; let server_path = version_dir.join(SERVER_PATH); @@ -1003,7 +1003,7 @@ async fn get_copilot_lsp(http: Arc) -> anyhow::Result { let archive = Archive::new(decompressed_bytes); archive.unpack(dist_dir).await?; - remove_matching(&paths::COPILOT_DIR, |entry| entry != version_dir).await; + remove_matching(paths::copilot_dir(), |entry| entry != version_dir).await; } Ok(server_path) @@ -1016,7 +1016,7 @@ async fn get_copilot_lsp(http: Arc) -> anyhow::Result { // Fetch a cached binary, if it exists maybe!(async { let mut last_version_dir = None; - let mut entries = fs::read_dir(paths::COPILOT_DIR.as_path()).await?; + let mut entries = fs::read_dir(paths::copilot_dir()).await?; while let Some(entry) = entries.next().await { let entry = entry?; if entry.file_type().await?.is_dir() { diff --git a/crates/db/src/db.rs b/crates/db/src/db.rs index 56aaba245a..3d65549fef 100644 --- a/crates/db/src/db.rs +++ b/crates/db/src/db.rs @@ -7,7 +7,7 @@ use anyhow::Context; use gpui::AppContext; pub use indoc::indoc; pub use lazy_static; -pub use paths::DB_DIR; +pub use paths::database_dir; pub use smol; pub use sqlez; pub use sqlez_macros; @@ -145,7 +145,7 @@ macro_rules! define_connection { #[cfg(not(any(test, feature = "test-support")))] $crate::lazy_static::lazy_static! { - pub static ref $id: $t = $t($crate::smol::block_on($crate::open_db(&$crate::DB_DIR, &$crate::RELEASE_CHANNEL))); + pub static ref $id: $t = $t($crate::smol::block_on($crate::open_db($crate::database_dir(), &$crate::RELEASE_CHANNEL))); } }; (pub static ref $id:ident: $t:ident<$($d:ty),+> = $migrations:expr;) => { @@ -176,7 +176,7 @@ macro_rules! define_connection { #[cfg(not(any(test, feature = "test-support")))] $crate::lazy_static::lazy_static! { - pub static ref $id: $t = $t($crate::smol::block_on($crate::open_db(&$crate::DB_DIR, &$crate::RELEASE_CHANNEL))); + pub static ref $id: $t = $t($crate::smol::block_on($crate::open_db($crate::database_dir(), &$crate::RELEASE_CHANNEL))); } }; } diff --git a/crates/extension/src/extension_store.rs b/crates/extension/src/extension_store.rs index 894aeee9fa..6b912412ef 100644 --- a/crates/extension/src/extension_store.rs +++ b/crates/extension/src/extension_store.rs @@ -36,7 +36,6 @@ use language::{ LanguageConfig, LanguageMatcher, LanguageQueries, LanguageRegistry, QUERY_FILENAME_PREFIXES, }; use node_runtime::NodeRuntime; -use paths::EXTENSIONS_DIR; use project::ContextProviderWithTasks; use release_channel::ReleaseChannel; use semantic_version::SemanticVersion; @@ -180,7 +179,7 @@ pub fn init( let store = cx.new_model(move |cx| { ExtensionStore::new( - EXTENSIONS_DIR.clone(), + paths::extensions_dir().clone(), None, fs, client.http_client().clone(), diff --git a/crates/fs/src/fs.rs b/crates/fs/src/fs.rs index 6a5f97c94d..a268ed6503 100644 --- a/crates/fs/src/fs.rs +++ b/crates/fs/src/fs.rs @@ -325,7 +325,7 @@ impl Fs for RealFs { // Use the directory of the destination as temp dir to avoid // invalid cross-device link error, and XDG_CACHE_DIR for fallback. // See https://github.com/zed-industries/zed/pull/8437 for more details. - NamedTempFile::new_in(path.parent().unwrap_or(&paths::TEMP_DIR)) + NamedTempFile::new_in(path.parent().unwrap_or(&paths::temp_dir())) } else { NamedTempFile::new() }?; diff --git a/crates/inline_completion_button/src/inline_completion_button.rs b/crates/inline_completion_button/src/inline_completion_button.rs index 0ecabb33cb..d500b223e3 100644 --- a/crates/inline_completion_button/src/inline_completion_button.rs +++ b/crates/inline_completion_button/src/inline_completion_button.rs @@ -369,7 +369,7 @@ async fn configure_disabled_globs( ) -> Result<()> { let settings_editor = workspace .update(&mut cx, |_, cx| { - create_and_open_local_file(&paths::SETTINGS, cx, || { + create_and_open_local_file(paths::settings_file(), cx, || { settings::initial_user_settings_content().as_ref().into() }) })? diff --git a/crates/languages/src/json.rs b/crates/languages/src/json.rs index 658d3b1a21..5c7d3c6fc3 100644 --- a/crates/languages/src/json.rs +++ b/crates/languages/src/json.rs @@ -98,19 +98,19 @@ impl JsonLspAdapter { }, { "fileMatch": [ - schema_file_match(&paths::SETTINGS), - &*paths::LOCAL_SETTINGS_RELATIVE_PATH, + schema_file_match(paths::settings_file()), + paths::local_settings_file_relative_path() ], "schema": settings_schema, }, { - "fileMatch": [schema_file_match(&paths::KEYMAP)], + "fileMatch": [schema_file_match(paths::keymap_file())], "schema": KeymapFile::generate_json_schema(&action_names), }, { "fileMatch": [ - schema_file_match(&paths::TASKS), - &*paths::LOCAL_TASKS_RELATIVE_PATH, + schema_file_match(paths::tasks_file()), + paths::local_tasks_file_relative_path() ], "schema": tasks_schema, } diff --git a/crates/node_runtime/src/node_runtime.rs b/crates/node_runtime/src/node_runtime.rs index 766c8237d1..6ec7f95f4a 100644 --- a/crates/node_runtime/src/node_runtime.rs +++ b/crates/node_runtime/src/node_runtime.rs @@ -138,7 +138,7 @@ impl RealNodeRuntime { }; let folder_name = format!("node-{VERSION}-{os}-{arch}"); - let node_containing_dir = paths::SUPPORT_DIR.join("node"); + let node_containing_dir = paths::support_dir().join("node"); let node_dir = node_containing_dir.join(folder_name); let node_binary = node_dir.join(NODE_PATH); let npm_file = node_dir.join(NPM_PATH); diff --git a/crates/paths/Cargo.toml b/crates/paths/Cargo.toml index 5947721bd1..1f465a482f 100644 --- a/crates/paths/Cargo.toml +++ b/crates/paths/Cargo.toml @@ -13,5 +13,4 @@ path = "src/paths.rs" [dependencies] dirs.workspace = true -lazy_static.workspace = true util.workspace = true diff --git a/crates/paths/src/paths.rs b/crates/paths/src/paths.rs index 558709651f..0711d1a56b 100644 --- a/crates/paths/src/paths.rs +++ b/crates/paths/src/paths.rs @@ -1,92 +1,243 @@ //! Paths to locations used by Zed. use std::path::{Path, PathBuf}; +use std::sync::OnceLock; use util::paths::HOME; -lazy_static::lazy_static! { - pub static ref CONFIG_DIR: PathBuf = if cfg!(target_os = "windows") { - dirs::config_dir() - .expect("failed to determine RoamingAppData directory") - .join("Zed") - } else if cfg!(target_os = "linux") { - if let Ok(flatpak_xdg_config) = std::env::var("FLATPAK_XDG_CONFIG_HOME") { - flatpak_xdg_config.into() - } else { - dirs::config_dir().expect("failed to determine XDG_CONFIG_HOME directory") - }.join("zed") - } else { +/// Returns the path to the configuration directory used by Zed. +pub fn config_dir() -> &'static PathBuf { + static CONFIG_DIR: OnceLock = OnceLock::new(); + CONFIG_DIR.get_or_init(|| { + if cfg!(target_os = "windows") { + return dirs::config_dir() + .expect("failed to determine RoamingAppData directory") + .join("Zed"); + } + + if cfg!(target_os = "linux") { + return if let Ok(flatpak_xdg_config) = std::env::var("FLATPAK_XDG_CONFIG_HOME") { + flatpak_xdg_config.into() + } else { + dirs::config_dir().expect("failed to determine XDG_CONFIG_HOME directory") + } + .join("zed"); + } + HOME.join(".config").join("zed") - }; - pub static ref CONTEXTS_DIR: PathBuf = if cfg!(target_os = "macos") { - CONFIG_DIR.join("conversations") - } else { - SUPPORT_DIR.join("conversations") - }; - pub static ref PROMPTS_DIR: PathBuf = if cfg!(target_os = "macos") { - CONFIG_DIR.join("prompts") - } else { - SUPPORT_DIR.join("prompts") - }; - pub static ref EMBEDDINGS_DIR: PathBuf = if cfg!(target_os = "macos") { - CONFIG_DIR.join("embeddings") - } else { - SUPPORT_DIR.join("embeddings") - }; - pub static ref THEMES_DIR: PathBuf = CONFIG_DIR.join("themes"); - - pub static ref SUPPORT_DIR: PathBuf = if cfg!(target_os = "macos") { - HOME.join("Library/Application Support/Zed") - } else if cfg!(target_os = "linux") { - if let Ok(flatpak_xdg_data) = std::env::var("FLATPAK_XDG_DATA_HOME") { - flatpak_xdg_data.into() - } else { - dirs::data_local_dir().expect("failed to determine XDG_DATA_HOME directory") - }.join("zed") - } else if cfg!(target_os = "windows") { - dirs::data_local_dir() - .expect("failed to determine LocalAppData directory") - .join("Zed") - } else { - CONFIG_DIR.clone() - }; - pub static ref LOGS_DIR: PathBuf = if cfg!(target_os = "macos") { - HOME.join("Library/Logs/Zed") - } else { - SUPPORT_DIR.join("logs") - }; - pub static ref EXTENSIONS_DIR: PathBuf = SUPPORT_DIR.join("extensions"); - pub static ref LANGUAGES_DIR: PathBuf = SUPPORT_DIR.join("languages"); - pub static ref COPILOT_DIR: PathBuf = SUPPORT_DIR.join("copilot"); - pub static ref SUPERMAVEN_DIR: PathBuf = SUPPORT_DIR.join("supermaven"); - pub static ref DEFAULT_PRETTIER_DIR: PathBuf = SUPPORT_DIR.join("prettier"); - pub static ref DB_DIR: PathBuf = SUPPORT_DIR.join("db"); - pub static ref CRASHES_DIR: Option = cfg!(target_os = "macos") - .then_some(HOME.join("Library/Logs/DiagnosticReports")); - pub static ref CRASHES_RETIRED_DIR: Option = CRASHES_DIR - .as_ref() - .map(|dir| dir.join("Retired")); - - pub static ref SETTINGS: PathBuf = CONFIG_DIR.join("settings.json"); - pub static ref KEYMAP: PathBuf = CONFIG_DIR.join("keymap.json"); - pub static ref TASKS: PathBuf = CONFIG_DIR.join("tasks.json"); - pub static ref LAST_USERNAME: PathBuf = CONFIG_DIR.join("last-username.txt"); - pub static ref LOG: PathBuf = LOGS_DIR.join("Zed.log"); - pub static ref OLD_LOG: PathBuf = LOGS_DIR.join("Zed.log.old"); - pub static ref LOCAL_SETTINGS_RELATIVE_PATH: &'static Path = Path::new(".zed/settings.json"); - pub static ref LOCAL_TASKS_RELATIVE_PATH: &'static Path = Path::new(".zed/tasks.json"); - pub static ref LOCAL_VSCODE_TASKS_RELATIVE_PATH: &'static Path = Path::new(".vscode/tasks.json"); - pub static ref TEMP_DIR: PathBuf = if cfg!(target_os = "windows") { - dirs::cache_dir() - .expect("failed to determine LocalAppData directory") - .join("Zed") - } else if cfg!(target_os = "linux") { - if let Ok(flatpak_xdg_cache) = std::env::var("FLATPAK_XDG_CACHE_HOME") { - flatpak_xdg_cache.into() - } else { - dirs::cache_dir().expect("failed to determine XDG_CACHE_HOME directory") - }.join("zed") - } else { - HOME.join(".cache").join("zed") - }; + }) +} + +/// Returns the path to the support directory used by Zed. +pub fn support_dir() -> &'static PathBuf { + static SUPPORT_DIR: OnceLock = OnceLock::new(); + SUPPORT_DIR.get_or_init(|| { + if cfg!(target_os = "macos") { + return HOME.join("Library/Application Support/Zed"); + } + + if cfg!(target_os = "linux") { + return if let Ok(flatpak_xdg_data) = std::env::var("FLATPAK_XDG_DATA_HOME") { + flatpak_xdg_data.into() + } else { + dirs::data_local_dir().expect("failed to determine XDG_DATA_HOME directory") + } + .join("zed"); + } + + if cfg!(target_os = "windows") { + return dirs::data_local_dir() + .expect("failed to determine LocalAppData directory") + .join("Zed"); + } + + config_dir().clone() + }) +} + +/// Returns the path to the temp directory used by Zed. +pub fn temp_dir() -> &'static PathBuf { + static TEMP_DIR: OnceLock = OnceLock::new(); + TEMP_DIR.get_or_init(|| { + if cfg!(target_os = "windows") { + return dirs::cache_dir() + .expect("failed to determine LocalAppData directory") + .join("Zed"); + } + + if cfg!(target_os = "linux") { + return if let Ok(flatpak_xdg_cache) = std::env::var("FLATPAK_XDG_CACHE_HOME") { + flatpak_xdg_cache.into() + } else { + dirs::cache_dir().expect("failed to determine XDG_CACHE_HOME directory") + } + .join("zed"); + } + + HOME.join(".cache").join("zed") + }) +} + +/// Returns the path to the logs directory. +pub fn logs_dir() -> &'static PathBuf { + static LOGS_DIR: OnceLock = OnceLock::new(); + LOGS_DIR.get_or_init(|| { + if cfg!(target_os = "macos") { + HOME.join("Library/Logs/Zed") + } else { + support_dir().join("logs") + } + }) +} + +/// Returns the path to the `Zed.log` file. +pub fn log_file() -> &'static PathBuf { + static LOG_FILE: OnceLock = OnceLock::new(); + LOG_FILE.get_or_init(|| logs_dir().join("Zed.log")) +} + +/// Returns the path to the `Zed.log.old` file. +pub fn old_log_file() -> &'static PathBuf { + static OLD_LOG_FILE: OnceLock = OnceLock::new(); + OLD_LOG_FILE.get_or_init(|| logs_dir().join("Zed.log.old")) +} + +/// Returns the path to the database directory. +pub fn database_dir() -> &'static PathBuf { + static DATABASE_DIR: OnceLock = OnceLock::new(); + DATABASE_DIR.get_or_init(|| support_dir().join("db")) +} + +/// Returns the path to the crashes directory, if it exists for the current platform. +pub fn crashes_dir() -> &'static Option { + static CRASHES_DIR: OnceLock> = OnceLock::new(); + CRASHES_DIR.get_or_init(|| { + cfg!(target_os = "macos").then_some(HOME.join("Library/Logs/DiagnosticReports")) + }) +} + +/// Returns the path to the retired crashes directory, if it exists for the current platform. +pub fn crashes_retired_dir() -> &'static Option { + static CRASHES_RETIRED_DIR: OnceLock> = OnceLock::new(); + CRASHES_RETIRED_DIR.get_or_init(|| crashes_dir().as_ref().map(|dir| dir.join("Retired"))) +} + +/// Returns the path to the `settings.json` file. +pub fn settings_file() -> &'static PathBuf { + static SETTINGS_FILE: OnceLock = OnceLock::new(); + SETTINGS_FILE.get_or_init(|| config_dir().join("settings.json")) +} + +/// Returns the path to the `keymap.json` file. +pub fn keymap_file() -> &'static PathBuf { + static KEYMAP_FILE: OnceLock = OnceLock::new(); + KEYMAP_FILE.get_or_init(|| config_dir().join("keymap.json")) +} + +/// Returns the path to the `tasks.json` file. +pub fn tasks_file() -> &'static PathBuf { + static TASKS_FILE: OnceLock = OnceLock::new(); + TASKS_FILE.get_or_init(|| config_dir().join("tasks.json")) +} + +/// Returns the path to the extensions directory. +/// +/// This is where installed extensions are stored. +pub fn extensions_dir() -> &'static PathBuf { + static EXTENSIONS_DIR: OnceLock = OnceLock::new(); + EXTENSIONS_DIR.get_or_init(|| support_dir().join("extensions")) +} + +/// Returns the path to the themes directory. +/// +/// This is where themes that are not provided by extensions are stored. +pub fn themes_dir() -> &'static PathBuf { + static THEMES_DIR: OnceLock = OnceLock::new(); + THEMES_DIR.get_or_init(|| config_dir().join("themes")) +} + +/// Returns the path to the contexts directory. +/// +/// This is where the saved contexts from the Assistant are stored. +pub fn contexts_dir() -> &'static PathBuf { + static CONTEXTS_DIR: OnceLock = OnceLock::new(); + CONTEXTS_DIR.get_or_init(|| { + if cfg!(target_os = "macos") { + config_dir().join("conversations") + } else { + support_dir().join("conversations") + } + }) +} + +/// Returns the path to the contexts directory. +/// +/// This is where the prompts for use with the Assistant are stored. +pub fn prompts_dir() -> &'static PathBuf { + static PROMPTS_DIR: OnceLock = OnceLock::new(); + PROMPTS_DIR.get_or_init(|| { + if cfg!(target_os = "macos") { + config_dir().join("prompts") + } else { + support_dir().join("prompts") + } + }) +} + +/// Returns the path to the semantic search's embeddings directory. +/// +/// This is where the embeddings used to power semantic search are stored. +pub fn embeddings_dir() -> &'static PathBuf { + static EMBEDDINGS_DIR: OnceLock = OnceLock::new(); + EMBEDDINGS_DIR.get_or_init(|| { + if cfg!(target_os = "macos") { + config_dir().join("embeddings") + } else { + support_dir().join("embeddings") + } + }) +} + +/// Returns the path to the languages directory. +/// +/// This is where language servers are downloaded to for languages built-in to Zed. +pub fn languages_dir() -> &'static PathBuf { + static LANGUAGES_DIR: OnceLock = OnceLock::new(); + LANGUAGES_DIR.get_or_init(|| support_dir().join("languages")) +} + +/// Returns the path to the Copilot directory. +pub fn copilot_dir() -> &'static PathBuf { + static COPILOT_DIR: OnceLock = OnceLock::new(); + COPILOT_DIR.get_or_init(|| support_dir().join("copilot")) +} + +/// Returns the path to the Supermaven directory. +pub fn supermaven_dir() -> &'static PathBuf { + static SUPERMAVEN_DIR: OnceLock = OnceLock::new(); + SUPERMAVEN_DIR.get_or_init(|| support_dir().join("supermaven")) +} + +/// Returns the path to the default Prettier directory. +pub fn default_prettier_dir() -> &'static PathBuf { + static DEFAULT_PRETTIER_DIR: OnceLock = OnceLock::new(); + DEFAULT_PRETTIER_DIR.get_or_init(|| support_dir().join("prettier")) +} + +/// Returns the relative path to a `settings.json` file within a project. +pub fn local_settings_file_relative_path() -> &'static Path { + static LOCAL_SETTINGS_FILE_RELATIVE_PATH: OnceLock<&Path> = OnceLock::new(); + LOCAL_SETTINGS_FILE_RELATIVE_PATH.get_or_init(|| Path::new(".zed/settings.json")) +} + +/// Returns the relative path to a `tasks.json` file within a project. +pub fn local_tasks_file_relative_path() -> &'static Path { + static LOCAL_TASKS_FILE_RELATIVE_PATH: OnceLock<&Path> = OnceLock::new(); + LOCAL_TASKS_FILE_RELATIVE_PATH.get_or_init(|| Path::new(".zed/tasks.json")) +} + +/// Returns the relative path to a `.vscode/tasks.json` file within a project. +pub fn local_vscode_tasks_file_relative_path() -> &'static Path { + static LOCAL_VSCODE_TASKS_FILE_RELATIVE_PATH: OnceLock<&Path> = OnceLock::new(); + LOCAL_VSCODE_TASKS_FILE_RELATIVE_PATH.get_or_init(|| Path::new(".vscode/tasks.json")) } diff --git a/crates/prettier/src/prettier.rs b/crates/prettier/src/prettier.rs index d1691f9d01..214ef48d3f 100644 --- a/crates/prettier/src/prettier.rs +++ b/crates/prettier/src/prettier.rs @@ -5,7 +5,7 @@ use gpui::{AsyncAppContext, Model}; use language::{language_settings::language_settings, Buffer, Diff}; use lsp::{LanguageServer, LanguageServerId}; use node_runtime::NodeRuntime; -use paths::DEFAULT_PRETTIER_DIR; +use paths::default_prettier_dir; use serde::{Deserialize, Serialize}; use std::{ ops::ControlFlow, @@ -159,7 +159,7 @@ impl Prettier { _: AsyncAppContext, ) -> anyhow::Result { Ok(Self::Test(TestPrettier { - default: prettier_dir == DEFAULT_PRETTIER_DIR.as_path(), + default: prettier_dir == default_prettier_dir().as_path(), prettier_dir, })) } @@ -178,7 +178,7 @@ impl Prettier { prettier_dir.is_dir(), "Prettier dir {prettier_dir:?} is not a directory" ); - let prettier_server = DEFAULT_PRETTIER_DIR.join(PRETTIER_SERVER_FILE); + let prettier_server = default_prettier_dir().join(PRETTIER_SERVER_FILE); anyhow::ensure!( prettier_server.is_file(), "no prettier server package found at {prettier_server:?}" @@ -206,7 +206,7 @@ impl Prettier { .context("prettier server initialization")?; Ok(Self::Real(RealPrettier { server, - default: prettier_dir == DEFAULT_PRETTIER_DIR.as_path(), + default: prettier_dir == default_prettier_dir().as_path(), prettier_dir, })) } diff --git a/crates/project/src/prettier_support.rs b/crates/project/src/prettier_support.rs index 73ae697101..f94ba558b0 100644 --- a/crates/project/src/prettier_support.rs +++ b/crates/project/src/prettier_support.rs @@ -18,7 +18,7 @@ use language::{ }; use lsp::{LanguageServer, LanguageServerId}; use node_runtime::NodeRuntime; -use paths::DEFAULT_PRETTIER_DIR; +use paths::default_prettier_dir; use prettier::Prettier; use util::{ResultExt, TryFutureExt}; @@ -252,7 +252,7 @@ fn start_default_prettier( } let new_default_prettier = project.update(&mut cx, |project, cx| { let new_default_prettier = - start_prettier(node, DEFAULT_PRETTIER_DIR.clone(), worktree_id, cx); + start_prettier(node, default_prettier_dir().clone(), worktree_id, cx); project.default_prettier.prettier = PrettierInstallation::Installed(PrettierInstance { attempt: 0, @@ -267,7 +267,7 @@ fn start_default_prettier( None => { let new_default_prettier = project.update(&mut cx, |project, cx| { let new_default_prettier = - start_prettier(node, DEFAULT_PRETTIER_DIR.clone(), worktree_id, cx); + start_prettier(node, default_prettier_dir().clone(), worktree_id, cx); project.default_prettier.prettier = PrettierInstallation::Installed(PrettierInstance { attempt: instance.attempt + 1, @@ -380,7 +380,7 @@ async fn install_prettier_packages( .await .context("fetching latest npm versions")?; - let default_prettier_dir = DEFAULT_PRETTIER_DIR.as_path(); + let default_prettier_dir = default_prettier_dir().as_path(); match fs.metadata(default_prettier_dir).await.with_context(|| { format!("fetching FS metadata for default prettier dir {default_prettier_dir:?}") })? { @@ -406,7 +406,7 @@ async fn install_prettier_packages( } async fn save_prettier_server_file(fs: &dyn Fs) -> anyhow::Result<()> { - let prettier_wrapper_path = DEFAULT_PRETTIER_DIR.join(prettier::PRETTIER_SERVER_FILE); + let prettier_wrapper_path = default_prettier_dir().join(prettier::PRETTIER_SERVER_FILE); fs.save( &prettier_wrapper_path, &text::Rope::from(prettier::PRETTIER_SERVER_JS), @@ -423,7 +423,7 @@ async fn save_prettier_server_file(fs: &dyn Fs) -> anyhow::Result<()> { } async fn should_write_prettier_server_file(fs: &dyn Fs) -> bool { - let prettier_wrapper_path = DEFAULT_PRETTIER_DIR.join(prettier::PRETTIER_SERVER_FILE); + let prettier_wrapper_path = default_prettier_dir().join(prettier::PRETTIER_SERVER_FILE); if !fs.is_file(&prettier_wrapper_path).await { return true; } diff --git a/crates/project/src/project.rs b/crates/project/src/project.rs index ff3b30ef1f..7c1c6bbdbd 100644 --- a/crates/project/src/project.rs +++ b/crates/project/src/project.rs @@ -67,7 +67,8 @@ use lsp_command::*; use node_runtime::NodeRuntime; use parking_lot::{Mutex, RwLock}; use paths::{ - LOCAL_SETTINGS_RELATIVE_PATH, LOCAL_TASKS_RELATIVE_PATH, LOCAL_VSCODE_TASKS_RELATIVE_PATH, + local_settings_file_relative_path, local_tasks_file_relative_path, + local_vscode_tasks_file_relative_path, }; use postage::watch; use prettier_support::{DefaultPrettier, PrettierInstance}; @@ -8176,10 +8177,10 @@ impl Project { } }; - if abs_path.ends_with(&*LOCAL_SETTINGS_RELATIVE_PATH) { + if abs_path.ends_with(local_settings_file_relative_path()) { let settings_dir = Arc::from( path.ancestors() - .nth(LOCAL_SETTINGS_RELATIVE_PATH.components().count()) + .nth(local_settings_file_relative_path().components().count()) .unwrap(), ); let fs = self.fs.clone(); @@ -8193,7 +8194,7 @@ impl Project { }, ) }); - } else if abs_path.ends_with(&*LOCAL_TASKS_RELATIVE_PATH) { + } else if abs_path.ends_with(local_tasks_file_relative_path()) { self.task_inventory().update(cx, |task_inventory, cx| { if removed { task_inventory.remove_local_static_source(&abs_path); @@ -8213,7 +8214,7 @@ impl Project { ); } }) - } else if abs_path.ends_with(&*LOCAL_VSCODE_TASKS_RELATIVE_PATH) { + } else if abs_path.ends_with(local_vscode_tasks_file_relative_path()) { self.task_inventory().update(cx, |task_inventory, cx| { if removed { task_inventory.remove_local_static_source(&abs_path); diff --git a/crates/rustdoc/src/store.rs b/crates/rustdoc/src/store.rs index 7abd5cc858..8a8a2fd9f7 100644 --- a/crates/rustdoc/src/store.rs +++ b/crates/rustdoc/src/store.rs @@ -12,7 +12,6 @@ use gpui::{AppContext, BackgroundExecutor, Global, ReadGlobal, Task, UpdateGloba use heed::types::SerdeBincode; use heed::Database; use parking_lot::RwLock; -use paths::SUPPORT_DIR; use serde::{Deserialize, Serialize}; use util::ResultExt; @@ -57,7 +56,10 @@ impl RustdocStore { .spawn({ let executor = executor.clone(); async move { - RustdocDatabase::new(SUPPORT_DIR.join("docs/rust/rustdoc-db.0.mdb"), executor) + RustdocDatabase::new( + paths::support_dir().join("docs/rust/rustdoc-db.0.mdb"), + executor, + ) } }) .then(|result| future::ready(result.map(Arc::new).map_err(Arc::new))) diff --git a/crates/settings/src/settings_file.rs b/crates/settings/src/settings_file.rs index ac4c8f1adc..ff6927a787 100644 --- a/crates/settings/src/settings_file.rs +++ b/crates/settings/src/settings_file.rs @@ -92,7 +92,7 @@ pub fn handle_settings_file_changes( } async fn load_settings(fs: &Arc) -> Result { - match fs.load(&paths::SETTINGS).await { + match fs.load(paths::settings_file()).await { result @ Ok(_) => result, Err(err) => { if let Some(e) = err.downcast_ref::() { @@ -115,7 +115,7 @@ pub fn update_settings_file( let new_text = cx.read_global(|store: &SettingsStore, _cx| { store.new_text_for_update::(old_text, update) })?; - let initial_path = paths::SETTINGS.as_path(); + let initial_path = paths::settings_file().as_path(); if fs.is_file(initial_path).await { let resolved_path = fs.canonicalize(initial_path).await.with_context(|| { format!("Failed to canonicalize settings path {:?}", initial_path) diff --git a/crates/supermaven_api/src/supermaven_api.rs b/crates/supermaven_api/src/supermaven_api.rs index 75c39d314e..09f64b1215 100644 --- a/crates/supermaven_api/src/supermaven_api.rs +++ b/crates/supermaven_api/src/supermaven_api.rs @@ -2,7 +2,7 @@ use anyhow::{anyhow, Context, Result}; use futures::io::BufReader; use futures::{AsyncReadExt, Future}; use http::{AsyncBody, HttpClient, Request as HttpRequest}; -use paths::SUPERMAVEN_DIR; +use paths::supermaven_dir; use serde::{Deserialize, Serialize}; use smol::fs::{self, File}; use smol::stream::StreamExt; @@ -212,7 +212,7 @@ pub async fn latest_release( } pub fn version_path(version: u64) -> PathBuf { - SUPERMAVEN_DIR.join(format!("sm-agent-{}", version)) + supermaven_dir().join(format!("sm-agent-{}", version)) } pub async fn has_version(version_path: &Path) -> bool { @@ -225,12 +225,12 @@ pub fn get_supermaven_agent_path( client: Arc, ) -> impl Future> { async move { - fs::create_dir_all(&*SUPERMAVEN_DIR) + fs::create_dir_all(supermaven_dir()) .await .with_context(|| { format!( "Could not create Supermaven Agent Directory at {:?}", - &*SUPERMAVEN_DIR + supermaven_dir() ) })?; @@ -278,7 +278,7 @@ pub fn get_supermaven_agent_path( .await?; } - let mut old_binary_paths = fs::read_dir(&*SUPERMAVEN_DIR).await?; + let mut old_binary_paths = fs::read_dir(supermaven_dir()).await?; while let Some(old_binary_path) = old_binary_paths.next().await { let old_binary_path = old_binary_path?; if old_binary_path.path() != binary_path { diff --git a/crates/zed/src/main.rs b/crates/zed/src/main.rs index 3ba31064c3..ac93ed1a1d 100644 --- a/crates/zed/src/main.rs +++ b/crates/zed/src/main.rs @@ -343,12 +343,12 @@ fn main() { let user_settings_file_rx = watch_config_file( &app.background_executor(), fs.clone(), - paths::SETTINGS.clone(), + paths::settings_file().clone(), ); let user_keymap_file_rx = watch_config_file( &app.background_executor(), fs.clone(), - paths::KEYMAP.clone(), + paths::keymap_file().clone(), ); let login_shell_env_loaded = if stdout_is_a_pty() { @@ -399,7 +399,7 @@ fn main() { cx.update_http_client(client.http_client().clone()); let mut languages = LanguageRegistry::new(login_shell_env_loaded, cx.background_executor().clone()); - languages.set_language_server_download_dir(paths::LANGUAGES_DIR.clone()); + languages.set_language_server_download_dir(paths::languages_dir().clone()); let languages = Arc::new(languages); let node_runtime = RealNodeRuntime::new(client.http_client()); @@ -668,12 +668,12 @@ async fn restore_or_create_workspace( fn init_paths() -> anyhow::Result<()> { for path in [ - &*paths::CONFIG_DIR, - &*paths::EXTENSIONS_DIR, - &*paths::LANGUAGES_DIR, - &*paths::DB_DIR, - &*paths::LOGS_DIR, - &*paths::TEMP_DIR, + paths::config_dir(), + paths::extensions_dir(), + paths::languages_dir(), + paths::database_dir(), + paths::logs_dir(), + paths::temp_dir(), ] .iter() { @@ -693,15 +693,16 @@ fn init_logger() { const KIB: u64 = 1024; const MIB: u64 = 1024 * KIB; const MAX_LOG_BYTES: u64 = MIB; - if std::fs::metadata(&*paths::LOG).map_or(false, |metadata| metadata.len() > MAX_LOG_BYTES) + if std::fs::metadata(paths::log_file()) + .map_or(false, |metadata| metadata.len() > MAX_LOG_BYTES) { - let _ = std::fs::rename(&*paths::LOG, &*paths::OLD_LOG); + let _ = std::fs::rename(paths::log_file(), paths::old_log_file()); } match OpenOptions::new() .create(true) .append(true) - .open(&*paths::LOG) + .open(paths::log_file()) { Ok(log_file) => { let config = ConfigBuilder::new() @@ -918,7 +919,7 @@ fn load_user_themes_in_background(fs: Arc, cx: &mut AppContext) { if let Some(theme_registry) = cx.update(|cx| ThemeRegistry::global(cx).clone()).log_err() { - let themes_dir = paths::THEMES_DIR.as_ref(); + let themes_dir = paths::themes_dir().as_ref(); match fs .metadata(themes_dir) .await @@ -949,7 +950,7 @@ fn watch_themes(fs: Arc, cx: &mut AppContext) { use std::time::Duration; cx.spawn(|cx| async move { let (mut events, _) = fs - .watch(&paths::THEMES_DIR.clone(), Duration::from_millis(100)) + .watch(paths::themes_dir(), Duration::from_millis(100)) .await; while let Some(paths) = events.next().await { diff --git a/crates/zed/src/reliability.rs b/crates/zed/src/reliability.rs index 0c73bb08e4..a784765898 100644 --- a/crates/zed/src/reliability.rs +++ b/crates/zed/src/reliability.rs @@ -8,7 +8,7 @@ use http::Method; use isahc::config::Configurable; use http::{self, HttpClient, HttpClientWithUrl}; -use paths::{CRASHES_DIR, CRASHES_RETIRED_DIR}; +use paths::{crashes_dir, crashes_retired_dir}; use release_channel::ReleaseChannel; use release_channel::RELEASE_CHANNEL; use settings::Settings; @@ -113,7 +113,7 @@ pub fn init_panic_hook( if !is_pty { if let Some(panic_data_json) = serde_json::to_string(&panic_data).log_err() { let timestamp = chrono::Utc::now().format("%Y_%m_%d %H_%M_%S").to_string(); - let panic_file_path = paths::LOGS_DIR.join(format!("zed-{}.panic", timestamp)); + let panic_file_path = paths::logs_dir().join(format!("zed-{}.panic", timestamp)); let panic_file = std::fs::OpenOptions::new() .append(true) .create(true) @@ -368,7 +368,7 @@ async fn upload_previous_panics( telemetry_settings: client::TelemetrySettings, ) -> Result> { let panic_report_url = http.build_zed_api_url("/telemetry/panics", &[])?; - let mut children = smol::fs::read_dir(&*paths::LOGS_DIR).await?; + let mut children = smol::fs::read_dir(paths::logs_dir()).await?; let mut most_recent_panic = None; @@ -460,8 +460,8 @@ async fn upload_previous_crashes( let crash_report_url = http.build_zed_api_url("/telemetry/crashes", &[])?; - // crash directories are only set on MacOS - for dir in [&*CRASHES_DIR, &*CRASHES_RETIRED_DIR] + // Crash directories are only set on macOS. + for dir in [crashes_dir(), crashes_retired_dir()] .iter() .filter_map(|d| d.as_deref()) { diff --git a/crates/zed/src/zed.rs b/crates/zed/src/zed.rs index b7ab71ab93..e02c0e1244 100644 --- a/crates/zed/src/zed.rs +++ b/crates/zed/src/zed.rs @@ -36,7 +36,7 @@ use task::static_source::{StaticSource, TrackedFile}; use theme::ActiveTheme; use workspace::notifications::NotificationId; -use paths::{LOCAL_SETTINGS_RELATIVE_PATH, LOCAL_TASKS_RELATIVE_PATH}; +use paths::{local_settings_file_relative_path, local_tasks_file_relative_path}; use terminal_view::terminal_panel::{self, TerminalPanel}; use util::{asset_str, ResultExt}; use uuid::Uuid; @@ -178,11 +178,11 @@ pub fn initialize_workspace(app_state: Arc, cx: &mut AppContext) { let fs = app_state.fs.clone(); project.task_inventory().update(cx, |inventory, cx| { let tasks_file_rx = - watch_config_file(&cx.background_executor(), fs, paths::TASKS.clone()); + watch_config_file(&cx.background_executor(), fs, paths::tasks_file().clone()); inventory.add_source( TaskSourceKind::AbsPath { id_base: "global_tasks".into(), - abs_path: paths::TASKS.clone(), + abs_path: paths::tasks_file().clone(), }, |tx, cx| StaticSource::new(TrackedFile::new(tasks_file_rx, tx, cx)), cx, @@ -341,13 +341,13 @@ pub fn initialize_workspace(app_state: Arc, cx: &mut AppContext) { ) .register_action( move |_: &mut Workspace, _: &OpenKeymap, cx: &mut ViewContext| { - open_settings_file(&paths::KEYMAP, Rope::default, cx); + open_settings_file(paths::keymap_file(), Rope::default, cx); }, ) .register_action( move |_: &mut Workspace, _: &OpenSettings, cx: &mut ViewContext| { open_settings_file( - &paths::SETTINGS, + paths::settings_file(), || settings::initial_user_settings_content().as_ref().into(), cx, ); @@ -356,7 +356,7 @@ pub fn initialize_workspace(app_state: Arc, cx: &mut AppContext) { .register_action( move |_: &mut Workspace, _: &OpenTasks, cx: &mut ViewContext| { open_settings_file( - &paths::TASKS, + paths::tasks_file(), || settings::initial_tasks_content().as_ref().into(), cx, ); @@ -566,7 +566,7 @@ fn open_log_file(workspace: &mut Workspace, cx: &mut ViewContext) { let fs = workspace.app_state().fs.clone(); cx.spawn(|workspace, mut cx| async move { let (old_log, new_log) = - futures::join!(fs.load(&paths::OLD_LOG), fs.load(&paths::LOG)); + futures::join!(fs.load(paths::old_log_file()), fs.load(paths::log_file())); let log = match (old_log, new_log) { (Err(_), Err(_)) => None, (old_log, new_log) => { @@ -602,7 +602,7 @@ fn open_log_file(workspace: &mut Workspace, cx: &mut ViewContext) { cx.new_view(|_| { MessageNotification::new(format!( "Unable to access/open log file at path {:?}", - paths::LOG.as_path() + paths::log_file().as_path() )) }) }, @@ -715,7 +715,7 @@ fn open_local_settings_file( ) { open_local_file( workspace, - &LOCAL_SETTINGS_RELATIVE_PATH, + local_settings_file_relative_path(), initial_local_settings_content(), cx, ) @@ -728,7 +728,7 @@ fn open_local_tasks_file( ) { open_local_file( workspace, - &LOCAL_TASKS_RELATIVE_PATH, + local_tasks_file_relative_path(), initial_tasks_content(), cx, ) @@ -904,7 +904,7 @@ fn open_settings_file( let worktree_creation_task = workspace.project().update(cx, |project, cx| { // Set up a dedicated worktree for settings, since otherwise we're dropping and re-starting LSP servers for each file inside on every settings file close/open // TODO: Do note that all other external files (e.g. drag and drop from OS) still have their worktrees released on file close, causing LSP servers' restarts. - project.find_or_create_local_worktree(paths::CONFIG_DIR.as_path(), false, cx) + project.find_or_create_local_worktree(paths::config_dir().as_path(), false, cx) }); let settings_open_task = create_and_open_local_file(&abs_path, cx, default_content); (worktree_creation_task, settings_open_task) diff --git a/crates/zed/src/zed/open_listener.rs b/crates/zed/src/zed/open_listener.rs index d5e49351ff..b94d7b50df 100644 --- a/crates/zed/src/zed/open_listener.rs +++ b/crates/zed/src/zed/open_listener.rs @@ -114,7 +114,7 @@ pub fn listen_for_cli_connections(opener: OpenListener) -> Result<()> { use release_channel::RELEASE_CHANNEL_NAME; use std::os::unix::net::UnixDatagram; - let sock_path = paths::SUPPORT_DIR.join(format!("zed-{}.sock", *RELEASE_CHANNEL_NAME)); + let sock_path = paths::support_dir().join(format!("zed-{}.sock", *RELEASE_CHANNEL_NAME)); // remove the socket if the process listening on it has died if let Err(e) = UnixDatagram::unbound()?.connect(&sock_path) { if e.kind() == std::io::ErrorKind::ConnectionRefused {