Add --user-data-dir CLI flag and propose renaming support_dir to data_dir (#26886)
This PR introduces support for a `--user-data-dir` CLI flag to override Zed's data directory and proposes renaming `support_dir` to `data_dir` for better cross-platform clarity. It builds on the discussion in #25349 about custom data directories, aiming to provide a flexible cross-platform solution. ### Changes The PR is split into two commits: 1. **[feat(cli): add --user-data-dir to override data directory](28e8889105
)** 2. **[refactor(paths): rename support_dir to data_dir for cross-platform clarity](affd2fc606
)** ### Context Inspired by the need for custom data directories discussed in #25349, this PR provides an immediate implementation in the first commit, while the second commit suggests a naming improvement for broader appeal. @mikayla-maki, I’d appreciate your feedback, especially on the rename proposal, given your involvement in the original discussion! ### Testing - `cargo build ` - `./target/debug/zed --user-data-dir ~/custom-data-dir` Release Notes: - Added --user-data-dir CLI flag --------- Signed-off-by: Marko Kungla <marko.kungla@gmail.com>
This commit is contained in:
parent
d88694f8da
commit
384868e597
@ -491,7 +491,7 @@ impl ThreadsDatabase {
|
||||
let database_future = executor
|
||||
.spawn({
|
||||
let executor = executor.clone();
|
||||
let database_path = paths::support_dir().join("threads/threads-db.1.mdb");
|
||||
let database_path = paths::data_dir().join("threads/threads-db.1.mdb");
|
||||
async move { ThreadsDatabase::new(database_path, executor) }
|
||||
})
|
||||
.then(|result| future::ready(result.map(Arc::new).map_err(Arc::new)))
|
||||
|
@ -16,6 +16,7 @@ pub enum CliRequest {
|
||||
wait: bool,
|
||||
open_new_workspace: Option<bool>,
|
||||
env: Option<HashMap<String, String>>,
|
||||
user_data_dir: Option<String>,
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -26,7 +26,11 @@ struct Detect;
|
||||
trait InstalledApp {
|
||||
fn zed_version_string(&self) -> String;
|
||||
fn launch(&self, ipc_url: String) -> anyhow::Result<()>;
|
||||
fn run_foreground(&self, ipc_url: String) -> io::Result<ExitStatus>;
|
||||
fn run_foreground(
|
||||
&self,
|
||||
ipc_url: String,
|
||||
user_data_dir: Option<&str>,
|
||||
) -> io::Result<ExitStatus>;
|
||||
fn path(&self) -> PathBuf;
|
||||
}
|
||||
|
||||
@ -58,6 +62,13 @@ struct Args {
|
||||
/// Create a new workspace
|
||||
#[arg(short, long, overrides_with = "add")]
|
||||
new: bool,
|
||||
/// Sets a custom directory for all user data (e.g., database, extensions, logs).
|
||||
/// This overrides the default platform-specific data directory location.
|
||||
/// On macOS, the default is `~/Library/Application Support/Zed`.
|
||||
/// On Linux/FreeBSD, the default is `$XDG_DATA_HOME/zed`.
|
||||
/// On Windows, the default is `%LOCALAPPDATA%\Zed`.
|
||||
#[arg(long, value_name = "DIR")]
|
||||
user_data_dir: Option<String>,
|
||||
/// The paths to open in Zed (space-separated).
|
||||
///
|
||||
/// Use `path:line:column` syntax to open a file at the given line and column.
|
||||
@ -135,6 +146,12 @@ fn main() -> Result<()> {
|
||||
}
|
||||
let args = Args::parse();
|
||||
|
||||
// Set custom data directory before any path operations
|
||||
let user_data_dir = args.user_data_dir.clone();
|
||||
if let Some(dir) = &user_data_dir {
|
||||
paths::set_custom_data_dir(dir);
|
||||
}
|
||||
|
||||
#[cfg(any(target_os = "linux", target_os = "freebsd"))]
|
||||
let args = flatpak::set_bin_if_no_escape(args);
|
||||
|
||||
@ -246,6 +263,7 @@ fn main() -> Result<()> {
|
||||
|
||||
let sender: JoinHandle<anyhow::Result<()>> = thread::spawn({
|
||||
let exit_status = exit_status.clone();
|
||||
let user_data_dir_for_thread = user_data_dir.clone();
|
||||
move || {
|
||||
let (_, handshake) = server.accept().context("Handshake after Zed spawn")?;
|
||||
let (tx, rx) = (handshake.requests, handshake.responses);
|
||||
@ -256,6 +274,7 @@ fn main() -> Result<()> {
|
||||
wait: args.wait,
|
||||
open_new_workspace,
|
||||
env,
|
||||
user_data_dir: user_data_dir_for_thread,
|
||||
})?;
|
||||
|
||||
while let Ok(response) = rx.recv() {
|
||||
@ -291,7 +310,7 @@ fn main() -> Result<()> {
|
||||
.collect();
|
||||
|
||||
if args.foreground {
|
||||
app.run_foreground(url)?;
|
||||
app.run_foreground(url, user_data_dir.as_deref())?;
|
||||
} else {
|
||||
app.launch(url)?;
|
||||
sender.join().unwrap()?;
|
||||
@ -437,7 +456,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::data_dir().join(format!("zed-{}.sock", *RELEASE_CHANNEL));
|
||||
let sock = UnixDatagram::unbound()?;
|
||||
if sock.connect(&sock_path).is_err() {
|
||||
self.boot_background(ipc_url)?;
|
||||
@ -447,10 +466,17 @@ mod linux {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn run_foreground(&self, ipc_url: String) -> io::Result<ExitStatus> {
|
||||
std::process::Command::new(self.0.clone())
|
||||
.arg(ipc_url)
|
||||
.status()
|
||||
fn run_foreground(
|
||||
&self,
|
||||
ipc_url: String,
|
||||
user_data_dir: Option<&str>,
|
||||
) -> io::Result<ExitStatus> {
|
||||
let mut cmd = std::process::Command::new(self.0.clone());
|
||||
cmd.arg(ipc_url);
|
||||
if let Some(dir) = user_data_dir {
|
||||
cmd.arg("--user-data-dir").arg(dir);
|
||||
}
|
||||
cmd.status()
|
||||
}
|
||||
|
||||
fn path(&self) -> PathBuf {
|
||||
@ -688,12 +714,17 @@ mod windows {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn run_foreground(&self, ipc_url: String) -> io::Result<ExitStatus> {
|
||||
std::process::Command::new(self.0.clone())
|
||||
.arg(ipc_url)
|
||||
.arg("--foreground")
|
||||
.spawn()?
|
||||
.wait()
|
||||
fn run_foreground(
|
||||
&self,
|
||||
ipc_url: String,
|
||||
user_data_dir: Option<&str>,
|
||||
) -> io::Result<ExitStatus> {
|
||||
let mut cmd = std::process::Command::new(self.0.clone());
|
||||
cmd.arg(ipc_url).arg("--foreground");
|
||||
if let Some(dir) = user_data_dir {
|
||||
cmd.arg("--user-data-dir").arg(dir);
|
||||
}
|
||||
cmd.spawn()?.wait()
|
||||
}
|
||||
|
||||
fn path(&self) -> PathBuf {
|
||||
@ -875,13 +906,22 @@ mod mac_os {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn run_foreground(&self, ipc_url: String) -> io::Result<ExitStatus> {
|
||||
fn run_foreground(
|
||||
&self,
|
||||
ipc_url: String,
|
||||
user_data_dir: Option<&str>,
|
||||
) -> io::Result<ExitStatus> {
|
||||
let path = match self {
|
||||
Bundle::App { app_bundle, .. } => app_bundle.join("Contents/MacOS/zed"),
|
||||
Bundle::LocalPath { executable, .. } => executable.clone(),
|
||||
};
|
||||
|
||||
std::process::Command::new(path).arg(ipc_url).status()
|
||||
let mut cmd = std::process::Command::new(path);
|
||||
cmd.arg(ipc_url);
|
||||
if let Some(dir) = user_data_dir {
|
||||
cmd.arg("--user-data-dir").arg(dir);
|
||||
}
|
||||
cmd.status()
|
||||
}
|
||||
|
||||
fn path(&self) -> PathBuf {
|
||||
|
@ -53,7 +53,7 @@ impl IndexedDocsProvider for LocalRustdocProvider {
|
||||
}
|
||||
|
||||
fn database_path(&self) -> PathBuf {
|
||||
paths::support_dir().join("docs/rust/rustdoc-db.1.mdb")
|
||||
paths::data_dir().join("docs/rust/rustdoc-db.1.mdb")
|
||||
}
|
||||
|
||||
async fn suggest_packages(&self) -> Result<Vec<PackageName>> {
|
||||
@ -144,7 +144,7 @@ impl IndexedDocsProvider for DocsDotRsProvider {
|
||||
}
|
||||
|
||||
fn database_path(&self) -> PathBuf {
|
||||
paths::support_dir().join("docs/rust/docs-rs-db.1.mdb")
|
||||
paths::data_dir().join("docs/rust/docs-rs-db.1.mdb")
|
||||
}
|
||||
|
||||
async fn suggest_packages(&self) -> Result<Vec<PackageName>> {
|
||||
|
@ -312,7 +312,7 @@ impl ManagedNodeRuntime {
|
||||
|
||||
let version = Self::VERSION;
|
||||
let folder_name = format!("node-{version}-{os}-{arch}");
|
||||
let node_containing_dir = paths::support_dir().join("node");
|
||||
let node_containing_dir = paths::data_dir().join("node");
|
||||
let node_dir = node_containing_dir.join(folder_name);
|
||||
let node_binary = node_dir.join(Self::NODE_PATH);
|
||||
let npm_file = node_dir.join(Self::NPM_PATH);
|
||||
@ -498,7 +498,7 @@ impl SystemNodeRuntime {
|
||||
)
|
||||
}
|
||||
|
||||
let scratch_dir = paths::support_dir().join("node");
|
||||
let scratch_dir = paths::data_dir().join("node");
|
||||
fs::create_dir(&scratch_dir).await.ok();
|
||||
fs::create_dir(scratch_dir.join("cache")).await.ok();
|
||||
|
||||
|
@ -5,61 +5,109 @@ use std::sync::OnceLock;
|
||||
|
||||
pub use util::paths::home_dir;
|
||||
|
||||
/// A default editorconfig file name to use when resolving project settings.
|
||||
pub const EDITORCONFIG_NAME: &str = ".editorconfig";
|
||||
|
||||
/// A custom data directory override, set only by `set_custom_data_dir`.
|
||||
/// This is used to override the default data directory location.
|
||||
/// The directory will be created if it doesn't exist when set.
|
||||
static CUSTOM_DATA_DIR: OnceLock<PathBuf> = OnceLock::new();
|
||||
|
||||
/// The resolved data directory, combining custom override or platform defaults.
|
||||
/// This is set once and cached for subsequent calls.
|
||||
/// On macOS, this is `~/Library/Application Support/Zed`.
|
||||
/// On Linux/FreeBSD, this is `$XDG_DATA_HOME/zed`.
|
||||
/// On Windows, this is `%LOCALAPPDATA%\Zed`.
|
||||
static CURRENT_DATA_DIR: OnceLock<PathBuf> = OnceLock::new();
|
||||
|
||||
/// The resolved config directory, combining custom override or platform defaults.
|
||||
/// This is set once and cached for subsequent calls.
|
||||
/// On macOS, this is `~/.config/zed`.
|
||||
/// On Linux/FreeBSD, this is `$XDG_CONFIG_HOME/zed`.
|
||||
/// On Windows, this is `%APPDATA%\Zed`.
|
||||
static CONFIG_DIR: OnceLock<PathBuf> = OnceLock::new();
|
||||
|
||||
/// Returns the relative path to the zed_server directory on the ssh host.
|
||||
pub fn remote_server_dir_relative() -> &'static Path {
|
||||
Path::new(".zed_server")
|
||||
}
|
||||
|
||||
/// Sets a custom directory for all user data, overriding the default data directory.
|
||||
/// This function must be called before any other path operations that depend on the data directory.
|
||||
/// The directory will be created if it doesn't exist.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `dir` - The path to use as the custom data directory. This will be used as the base
|
||||
/// directory for all user data, including databases, extensions, and logs.
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// A reference to the static `PathBuf` containing the custom data directory path.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if:
|
||||
/// * Called after the data directory has been initialized (e.g., via `data_dir` or `config_dir`)
|
||||
/// * The directory cannot be created
|
||||
pub fn set_custom_data_dir(dir: &str) -> &'static PathBuf {
|
||||
if CURRENT_DATA_DIR.get().is_some() || CONFIG_DIR.get().is_some() {
|
||||
panic!("set_custom_data_dir called after data_dir or config_dir was initialized");
|
||||
}
|
||||
CUSTOM_DATA_DIR.get_or_init(|| {
|
||||
let path = PathBuf::from(dir);
|
||||
std::fs::create_dir_all(&path).expect("failed to create custom data directory");
|
||||
path
|
||||
})
|
||||
}
|
||||
|
||||
/// Returns the path to the configuration directory used by Zed.
|
||||
pub fn config_dir() -> &'static PathBuf {
|
||||
static CONFIG_DIR: OnceLock<PathBuf> = OnceLock::new();
|
||||
CONFIG_DIR.get_or_init(|| {
|
||||
if cfg!(target_os = "windows") {
|
||||
return dirs::config_dir()
|
||||
if let Some(custom_dir) = CUSTOM_DATA_DIR.get() {
|
||||
custom_dir.join("config")
|
||||
} else if cfg!(target_os = "windows") {
|
||||
dirs::config_dir()
|
||||
.expect("failed to determine RoamingAppData directory")
|
||||
.join("Zed");
|
||||
}
|
||||
|
||||
if cfg!(any(target_os = "linux", target_os = "freebsd")) {
|
||||
return if let Ok(flatpak_xdg_config) = std::env::var("FLATPAK_XDG_CONFIG_HOME") {
|
||||
.join("Zed")
|
||||
} else if cfg!(any(target_os = "linux", target_os = "freebsd")) {
|
||||
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")
|
||||
dirs::config_dir()
|
||||
.expect("failed to determine XDG_CONFIG_HOME directory")
|
||||
.join("zed")
|
||||
}
|
||||
.join("zed");
|
||||
} else {
|
||||
home_dir().join(".config").join("zed")
|
||||
}
|
||||
|
||||
home_dir().join(".config").join("zed")
|
||||
})
|
||||
}
|
||||
|
||||
/// Returns the path to the support directory used by Zed.
|
||||
pub fn support_dir() -> &'static PathBuf {
|
||||
static SUPPORT_DIR: OnceLock<PathBuf> = OnceLock::new();
|
||||
SUPPORT_DIR.get_or_init(|| {
|
||||
if cfg!(target_os = "macos") {
|
||||
return home_dir().join("Library/Application Support/Zed");
|
||||
}
|
||||
|
||||
if cfg!(any(target_os = "linux", target_os = "freebsd")) {
|
||||
return if let Ok(flatpak_xdg_data) = std::env::var("FLATPAK_XDG_DATA_HOME") {
|
||||
/// Returns the path to the data directory used by Zed.
|
||||
pub fn data_dir() -> &'static PathBuf {
|
||||
CURRENT_DATA_DIR.get_or_init(|| {
|
||||
if let Some(custom_dir) = CUSTOM_DATA_DIR.get() {
|
||||
custom_dir.clone()
|
||||
} else if cfg!(target_os = "macos") {
|
||||
home_dir().join("Library/Application Support/Zed")
|
||||
} else if cfg!(any(target_os = "linux", target_os = "freebsd")) {
|
||||
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")
|
||||
dirs::data_local_dir()
|
||||
.expect("failed to determine XDG_DATA_HOME directory")
|
||||
.join("zed")
|
||||
}
|
||||
.join("zed");
|
||||
}
|
||||
|
||||
if cfg!(target_os = "windows") {
|
||||
return dirs::data_local_dir()
|
||||
} else if cfg!(target_os = "windows") {
|
||||
dirs::data_local_dir()
|
||||
.expect("failed to determine LocalAppData directory")
|
||||
.join("Zed");
|
||||
.join("Zed")
|
||||
} else {
|
||||
config_dir().clone() // Fallback
|
||||
}
|
||||
|
||||
config_dir().clone()
|
||||
})
|
||||
}
|
||||
|
||||
/// Returns the path to the temp directory used by Zed.
|
||||
pub fn temp_dir() -> &'static PathBuf {
|
||||
static TEMP_DIR: OnceLock<PathBuf> = OnceLock::new();
|
||||
@ -96,7 +144,7 @@ pub fn logs_dir() -> &'static PathBuf {
|
||||
if cfg!(target_os = "macos") {
|
||||
home_dir().join("Library/Logs/Zed")
|
||||
} else {
|
||||
support_dir().join("logs")
|
||||
data_dir().join("logs")
|
||||
}
|
||||
})
|
||||
}
|
||||
@ -104,7 +152,7 @@ pub fn logs_dir() -> &'static PathBuf {
|
||||
/// Returns the path to the Zed server directory on this SSH host.
|
||||
pub fn remote_server_state_dir() -> &'static PathBuf {
|
||||
static REMOTE_SERVER_STATE: OnceLock<PathBuf> = OnceLock::new();
|
||||
REMOTE_SERVER_STATE.get_or_init(|| support_dir().join("server_state"))
|
||||
REMOTE_SERVER_STATE.get_or_init(|| data_dir().join("server_state"))
|
||||
}
|
||||
|
||||
/// Returns the path to the `Zed.log` file.
|
||||
@ -122,7 +170,7 @@ pub fn old_log_file() -> &'static PathBuf {
|
||||
/// Returns the path to the database directory.
|
||||
pub fn database_dir() -> &'static PathBuf {
|
||||
static DATABASE_DIR: OnceLock<PathBuf> = OnceLock::new();
|
||||
DATABASE_DIR.get_or_init(|| support_dir().join("db"))
|
||||
DATABASE_DIR.get_or_init(|| data_dir().join("db"))
|
||||
}
|
||||
|
||||
/// Returns the path to the crashes directory, if it exists for the current platform.
|
||||
@ -180,7 +228,7 @@ pub fn debug_tasks_file() -> &'static PathBuf {
|
||||
/// This is where installed extensions are stored.
|
||||
pub fn extensions_dir() -> &'static PathBuf {
|
||||
static EXTENSIONS_DIR: OnceLock<PathBuf> = OnceLock::new();
|
||||
EXTENSIONS_DIR.get_or_init(|| support_dir().join("extensions"))
|
||||
EXTENSIONS_DIR.get_or_init(|| data_dir().join("extensions"))
|
||||
}
|
||||
|
||||
/// Returns the path to the extensions directory.
|
||||
@ -188,7 +236,7 @@ pub fn extensions_dir() -> &'static PathBuf {
|
||||
/// This is where installed extensions are stored on a remote.
|
||||
pub fn remote_extensions_dir() -> &'static PathBuf {
|
||||
static EXTENSIONS_DIR: OnceLock<PathBuf> = OnceLock::new();
|
||||
EXTENSIONS_DIR.get_or_init(|| support_dir().join("remote_extensions"))
|
||||
EXTENSIONS_DIR.get_or_init(|| data_dir().join("remote_extensions"))
|
||||
}
|
||||
|
||||
/// Returns the path to the extensions directory.
|
||||
@ -222,7 +270,7 @@ pub fn contexts_dir() -> &'static PathBuf {
|
||||
if cfg!(target_os = "macos") {
|
||||
config_dir().join("conversations")
|
||||
} else {
|
||||
support_dir().join("conversations")
|
||||
data_dir().join("conversations")
|
||||
}
|
||||
})
|
||||
}
|
||||
@ -236,7 +284,7 @@ pub fn prompts_dir() -> &'static PathBuf {
|
||||
if cfg!(target_os = "macos") {
|
||||
config_dir().join("prompts")
|
||||
} else {
|
||||
support_dir().join("prompts")
|
||||
data_dir().join("prompts")
|
||||
}
|
||||
})
|
||||
}
|
||||
@ -262,7 +310,7 @@ pub fn prompt_overrides_dir(repo_path: Option<&Path>) -> PathBuf {
|
||||
if cfg!(target_os = "macos") {
|
||||
config_dir().join("prompt_overrides")
|
||||
} else {
|
||||
support_dir().join("prompt_overrides")
|
||||
data_dir().join("prompt_overrides")
|
||||
}
|
||||
})
|
||||
.clone()
|
||||
@ -277,7 +325,7 @@ pub fn embeddings_dir() -> &'static PathBuf {
|
||||
if cfg!(target_os = "macos") {
|
||||
config_dir().join("embeddings")
|
||||
} else {
|
||||
support_dir().join("embeddings")
|
||||
data_dir().join("embeddings")
|
||||
}
|
||||
})
|
||||
}
|
||||
@ -287,7 +335,7 @@ pub fn embeddings_dir() -> &'static PathBuf {
|
||||
/// This is where language servers are downloaded to for languages built-in to Zed.
|
||||
pub fn languages_dir() -> &'static PathBuf {
|
||||
static LANGUAGES_DIR: OnceLock<PathBuf> = OnceLock::new();
|
||||
LANGUAGES_DIR.get_or_init(|| support_dir().join("languages"))
|
||||
LANGUAGES_DIR.get_or_init(|| data_dir().join("languages"))
|
||||
}
|
||||
|
||||
/// Returns the path to the debug adapters directory
|
||||
@ -295,31 +343,31 @@ pub fn languages_dir() -> &'static PathBuf {
|
||||
/// This is where debug adapters are downloaded to for DAPs that are built-in to Zed.
|
||||
pub fn debug_adapters_dir() -> &'static PathBuf {
|
||||
static DEBUG_ADAPTERS_DIR: OnceLock<PathBuf> = OnceLock::new();
|
||||
DEBUG_ADAPTERS_DIR.get_or_init(|| support_dir().join("debug_adapters"))
|
||||
DEBUG_ADAPTERS_DIR.get_or_init(|| data_dir().join("debug_adapters"))
|
||||
}
|
||||
|
||||
/// Returns the path to the Copilot directory.
|
||||
pub fn copilot_dir() -> &'static PathBuf {
|
||||
static COPILOT_DIR: OnceLock<PathBuf> = OnceLock::new();
|
||||
COPILOT_DIR.get_or_init(|| support_dir().join("copilot"))
|
||||
COPILOT_DIR.get_or_init(|| data_dir().join("copilot"))
|
||||
}
|
||||
|
||||
/// Returns the path to the Supermaven directory.
|
||||
pub fn supermaven_dir() -> &'static PathBuf {
|
||||
static SUPERMAVEN_DIR: OnceLock<PathBuf> = OnceLock::new();
|
||||
SUPERMAVEN_DIR.get_or_init(|| support_dir().join("supermaven"))
|
||||
SUPERMAVEN_DIR.get_or_init(|| data_dir().join("supermaven"))
|
||||
}
|
||||
|
||||
/// Returns the path to the default Prettier directory.
|
||||
pub fn default_prettier_dir() -> &'static PathBuf {
|
||||
static DEFAULT_PRETTIER_DIR: OnceLock<PathBuf> = OnceLock::new();
|
||||
DEFAULT_PRETTIER_DIR.get_or_init(|| support_dir().join("prettier"))
|
||||
DEFAULT_PRETTIER_DIR.get_or_init(|| data_dir().join("prettier"))
|
||||
}
|
||||
|
||||
/// Returns the path to the remote server binaries directory.
|
||||
pub fn remote_servers_dir() -> &'static PathBuf {
|
||||
static REMOTE_SERVERS_DIR: OnceLock<PathBuf> = OnceLock::new();
|
||||
REMOTE_SERVERS_DIR.get_or_init(|| support_dir().join("remote_servers"))
|
||||
REMOTE_SERVERS_DIR.get_or_init(|| data_dir().join("remote_servers"))
|
||||
}
|
||||
|
||||
/// Returns the relative path to a `.zed` folder within a project.
|
||||
@ -359,6 +407,3 @@ pub fn local_debug_file_relative_path() -> &'static Path {
|
||||
pub fn local_vscode_launch_file_relative_path() -> &'static Path {
|
||||
Path::new(".vscode/launch.json")
|
||||
}
|
||||
|
||||
/// A default editorconfig file name to use when resolving project settings.
|
||||
pub const EDITORCONFIG_NAME: &str = ".editorconfig";
|
||||
|
@ -172,6 +172,11 @@ fn fail_to_open_window(e: anyhow::Error, _cx: &mut App) {
|
||||
fn main() {
|
||||
let args = Args::parse();
|
||||
|
||||
// Set custom data directory.
|
||||
if let Some(dir) = &args.user_data_dir {
|
||||
paths::set_custom_data_dir(dir);
|
||||
}
|
||||
|
||||
#[cfg(all(not(debug_assertions), target_os = "windows"))]
|
||||
unsafe {
|
||||
use windows::Win32::System::Console::{ATTACH_PARENT_PROCESS, AttachConsole};
|
||||
@ -962,6 +967,14 @@ struct Args {
|
||||
/// URLs can either be `file://` or `zed://` scheme, or relative to <https://zed.dev>.
|
||||
paths_or_urls: Vec<String>,
|
||||
|
||||
/// Sets a custom directory for all user data (e.g., database, extensions, logs).
|
||||
/// This overrides the default platform-specific data directory location.
|
||||
/// On macOS, the default is `~/Library/Application Support/Zed`.
|
||||
/// On Linux/FreeBSD, the default is `$XDG_DATA_HOME/zed`.
|
||||
/// On Windows, the default is `%LOCALAPPDATA%\Zed`.
|
||||
#[arg(long, value_name = "DIR")]
|
||||
user_data_dir: Option<String>,
|
||||
|
||||
/// Instructs zed to run as a dev server on this machine. (not implemented)
|
||||
#[arg(long)]
|
||||
dev_server_token: Option<String>,
|
||||
|
@ -151,7 +151,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::data_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 {
|
||||
@ -261,6 +261,7 @@ pub async fn handle_cli_connection(
|
||||
wait,
|
||||
open_new_workspace,
|
||||
env,
|
||||
user_data_dir: _, // Ignore user_data_dir
|
||||
} => {
|
||||
if !urls.is_empty() {
|
||||
cx.update(|cx| {
|
||||
|
@ -130,6 +130,7 @@ fn send_args_to_instance(args: &Args) -> anyhow::Result<()> {
|
||||
wait: false,
|
||||
open_new_workspace: None,
|
||||
env: None,
|
||||
user_data_dir: args.user_data_dir.clone(),
|
||||
}
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user