From c16f2a1a29325969c0f2e39903f89e0de2dbb4e3 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Thu, 23 Oct 2025 00:47:16 +0200 Subject: [PATCH] project: Normalize `Path` env var to `PATH` in shell env on windows (#40720) Release Notes: - N/A *or* Added/Fixed/Improved ... --- crates/languages/src/python.rs | 10 +++++++--- crates/project/src/environment.rs | 7 ++++++- crates/project/src/lsp_store.rs | 7 +------ 3 files changed, 14 insertions(+), 10 deletions(-) diff --git a/crates/languages/src/python.rs b/crates/languages/src/python.rs index a9300dbb5ddca610e8d946b0cec211a7d9aa28df..c255ed3f09f733321c1066520b12355f76941931 100644 --- a/crates/languages/src/python.rs +++ b/crates/languages/src/python.rs @@ -1344,9 +1344,13 @@ impl pet_core::os_environment::Environment for EnvironmentApi<'_> { fn get_know_global_search_locations(&self) -> Vec { if self.global_search_locations.lock().is_empty() { - let mut paths = - std::env::split_paths(&self.get_env_var("PATH".to_string()).unwrap_or_default()) - .collect::>(); + let mut paths = std::env::split_paths( + &self + .get_env_var("PATH".to_string()) + .or_else(|| self.get_env_var("Path".to_string())) + .unwrap_or_default(), + ) + .collect::>(); log::trace!("Env PATH: {:?}", paths); for p in self.pet_env.get_know_global_search_locations() { diff --git a/crates/project/src/environment.rs b/crates/project/src/environment.rs index 3d42bb217faae7645301aa0b7f9e3a857d418a7b..c888cdd11f18a4c118665eac7dbbb6037e70bba4 100644 --- a/crates/project/src/environment.rs +++ b/crates/project/src/environment.rs @@ -265,7 +265,7 @@ async fn load_shell_environment( (Some(fake_env), None) } else if cfg!(target_os = "windows") { let (shell, args) = shell.program_and_args(); - let envs = match shell_env::capture(shell, args, dir).await { + let mut envs = match shell_env::capture(shell, args, dir).await { Ok(envs) => envs, Err(err) => { util::log_err(&err); @@ -278,6 +278,11 @@ async fn load_shell_environment( ); } }; + if let Some(path) = envs.remove("Path") { + // windows env vars are case-insensitive, so normalize the path var + // so we can just assume `PATH` in other places + envs.insert("PATH".into(), path); + } // Note: direnv is not available on Windows, so we skip direnv processing // and just return the shell environment diff --git a/crates/project/src/lsp_store.rs b/crates/project/src/lsp_store.rs index dc082453fd74d9d6e046e99e1e75de0f7e4c544e..f33d7af8b6ede6f1ae62109f1390acee51975693 100644 --- a/crates/project/src/lsp_store.rs +++ b/crates/project/src/lsp_store.rs @@ -13271,12 +13271,7 @@ impl LspAdapterDelegate for LocalLspAdapterDelegate { let env = self.shell_env().await; - // On Windows, PATH might be "Path" instead of "PATH" - let shell_path = env - .get("PATH") - .or_else(|| env.get("Path")) - .or_else(|| env.get("path")) - .cloned(); + let shell_path = env.get("PATH").cloned(); which::which_in(command, shell_path.as_ref(), worktree_abs_path).ok() }