From 7cf0696c89fc73fc964c4610a4e8e6003e7a20c5 Mon Sep 17 00:00:00 2001 From: Thorsten Ball Date: Fri, 23 Feb 2024 15:20:31 +0100 Subject: [PATCH] Pick up more home dir shell env when spawning (#8273) Release Notes: - Improved how Zed picks up shell environment when spawned. --- crates/project/src/project.rs | 4 +++- crates/zed/src/main.rs | 23 ++++++++++++++++++++++- 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/crates/project/src/project.rs b/crates/project/src/project.rs index 5b11c7622d..4b136b1169 100644 --- a/crates/project/src/project.rs +++ b/crates/project/src/project.rs @@ -9345,7 +9345,9 @@ impl LspAdapterDelegate for ProjectLspAdapterDelegate { Ok(command_path) => Some((command_path, shell_env)), Err(error) => { log::warn!( - "failed to determine path for command {:?} in env {shell_env:?}: {error}", command.to_string_lossy() + "failed to determine path for command {:?} in shell PATH {:?}: {error}", + command.to_string_lossy(), + shell_path.map(String::as_str).unwrap_or("") ); None } diff --git a/crates/zed/src/main.rs b/crates/zed/src/main.rs index 25e0980f90..e0a5d3eff8 100644 --- a/crates/zed/src/main.rs +++ b/crates/zed/src/main.rs @@ -839,8 +839,29 @@ async fn load_login_shell_environment() -> Result<()> { let shell = env::var("SHELL").context( "SHELL environment variable is not assigned so we can't source login environment variables", )?; + + // If possible, we want to `cd` in the user's `$HOME` to trigger programs + // such as direnv, asdf, mise, ... to adjust the PATH. These tools often hook + // into shell's `cd` command (and hooks) to manipulate env. + // We do this so that we get the env a user would have when spawning a shell + // in home directory. + let shell_cmd_prefix = std::env::var_os("HOME") + .and_then(|home| home.into_string().ok()) + .map(|home| format!("cd {home};")); + + // The `exit 0` is the result of hours of debugging, trying to find out + // why running this command here, without `exit 0`, would mess + // up signal process for our process so that `ctrl-c` doesn't work + // anymore. + // We still don't know why `$SHELL -l -i -c '/usr/bin/env -0'` would + // do that, but it does, and `exit 0` helps. + let shell_cmd = format!( + "{}echo {marker}; /usr/bin/env -0; exit 0;", + shell_cmd_prefix.as_deref().unwrap_or("") + ); + let output = Command::new(&shell) - .args(["-l", "-i", "-c", &format!("echo {marker}; /usr/bin/env -0")]) + .args(["-l", "-i", "-c", &shell_cmd]) .output() .await .context("failed to spawn login shell to source login environment variables")?;