Fix --user-data-dir (#44235)

Closes #40067

Release Notes:

- The `--user-data-dir` flag now works on Windows and Linux, as well as
macOS if you pass `--foreground`.

---------

Co-authored-by: Lukas Wirth <me@lukaswirth.dev>
This commit is contained in:
Julia Ryan
2025-12-09 16:42:19 -08:00
committed by GitHub
parent 736a712387
commit 4353b8ecd5
2 changed files with 35 additions and 16 deletions

View File

@@ -32,7 +32,7 @@ struct Detect;
trait InstalledApp {
fn zed_version_string(&self) -> String;
fn launch(&self, ipc_url: String) -> anyhow::Result<()>;
fn launch(&self, ipc_url: String, user_data_dir: Option<&str>) -> anyhow::Result<()>;
fn run_foreground(
&self,
ipc_url: String,
@@ -588,7 +588,7 @@ fn main() -> Result<()> {
if args.foreground {
app.run_foreground(url, user_data_dir.as_deref())?;
} else {
app.launch(url)?;
app.launch(url, user_data_dir.as_deref())?;
sender.join().unwrap()?;
if let Some(handle) = stdin_pipe_handle {
handle.join().unwrap()?;
@@ -709,14 +709,18 @@ mod linux {
)
}
fn launch(&self, ipc_url: String) -> anyhow::Result<()> {
let sock_path = paths::data_dir().join(format!(
fn launch(&self, ipc_url: String, user_data_dir: Option<&str>) -> anyhow::Result<()> {
let data_dir = user_data_dir
.map(PathBuf::from)
.unwrap_or_else(|| paths::data_dir().clone());
let sock_path = data_dir.join(format!(
"zed-{}.sock",
*release_channel::RELEASE_CHANNEL_NAME
));
let sock = UnixDatagram::unbound()?;
if sock.connect(&sock_path).is_err() {
self.boot_background(ipc_url)?;
self.boot_background(ipc_url, user_data_dir)?;
} else {
sock.send(ipc_url.as_bytes())?;
}
@@ -742,7 +746,11 @@ mod linux {
}
impl App {
fn boot_background(&self, ipc_url: String) -> anyhow::Result<()> {
fn boot_background(
&self,
ipc_url: String,
user_data_dir: Option<&str>,
) -> anyhow::Result<()> {
let path = &self.0;
match fork::fork() {
@@ -756,8 +764,13 @@ mod linux {
if fork::close_fd().is_err() {
eprintln!("failed to close_fd: {}", std::io::Error::last_os_error());
}
let error =
exec::execvp(path.clone(), &[path.as_os_str(), &OsString::from(ipc_url)]);
let mut args: Vec<OsString> =
vec![path.as_os_str().to_owned(), OsString::from(ipc_url)];
if let Some(dir) = user_data_dir {
args.push(OsString::from("--user-data-dir"));
args.push(OsString::from(dir));
}
let error = exec::execvp(path.clone(), &args);
// if exec succeeded, we never get here.
eprintln!("failed to exec {:?}: {}", path, error);
process::exit(1)
@@ -943,11 +956,14 @@ mod windows {
)
}
fn launch(&self, ipc_url: String) -> anyhow::Result<()> {
fn launch(&self, ipc_url: String, user_data_dir: Option<&str>) -> anyhow::Result<()> {
if check_single_instance() {
std::process::Command::new(self.0.clone())
.arg(ipc_url)
.spawn()?;
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.spawn()?;
} else {
unsafe {
let pipe = CreateFileW(
@@ -1096,7 +1112,7 @@ mod mac_os {
format!("Zed {} {}", self.version(), self.path().display(),)
}
fn launch(&self, url: String) -> anyhow::Result<()> {
fn launch(&self, url: String, user_data_dir: Option<&str>) -> anyhow::Result<()> {
match self {
Self::App { app_bundle, .. } => {
let app_path = app_bundle;
@@ -1146,8 +1162,11 @@ mod mac_os {
format!("Cloning descriptor for file {subprocess_stdout_file:?}")
})?;
let mut command = std::process::Command::new(executable);
let command = command
.env(FORCE_CLI_MODE_ENV_VAR_NAME, "")
command.env(FORCE_CLI_MODE_ENV_VAR_NAME, "");
if let Some(dir) = user_data_dir {
command.arg("--user-data-dir").arg(dir);
}
command
.stderr(subprocess_stdout_file)
.stdout(subprocess_stdin_file)
.arg(url);

View File

@@ -3,7 +3,7 @@ mod zed;
use agent_ui::AgentPanel;
use anyhow::{Context as _, Error, Result};
use clap::{Parser, command};
use clap::Parser;
use cli::FORCE_CLI_MODE_ENV_VAR_NAME;
use client::{Client, ProxySettings, UserStore, parse_zed_link};
use collab_ui::channel_view::ChannelView;