From da0d968a2cd558bf4957d837ed147b97bac06e1d Mon Sep 17 00:00:00 2001 From: Thorsten Ball Date: Mon, 15 Apr 2024 17:39:07 +0200 Subject: [PATCH] zig: Use env if using `zls` from shell env (#10559) This fixes the problem of the Zig extension picking up `zls` from the shell env but `zls` then failing to launch because it cannot find `zig`. Scenario in which this happens: - `.envrc` in a project that sets `$PATH` up - in that `$PATH` there's `zls` and `zig` - Zed is started from Dock - Project is opened - Shell env from project directory is loaded and used to get to `zls` - `zls` is then started, without that environment set on the process - `zls` cannot find `zig` Release Notes: - N/A Co-authored-by: Marshall --- extensions/zig/src/zig.rs | 42 +++++++++++++++++++++++++++------------ 1 file changed, 29 insertions(+), 13 deletions(-) diff --git a/extensions/zig/src/zig.rs b/extensions/zig/src/zig.rs index d982f7b0a6c99f6f057f3214348225364824176c..e10ff55c44d01477501ceef0776db65eab125c40 100644 --- a/extensions/zig/src/zig.rs +++ b/extensions/zig/src/zig.rs @@ -3,24 +3,35 @@ use zed::LanguageServerId; use zed_extension_api::{self as zed, Result}; struct ZigExtension { - cached_binary_path: Option, + cached_binary: Option, +} + +#[derive(Clone)] +struct ZlsBinary { + path: String, + environment: Option>, } impl ZigExtension { - fn language_server_binary_path( + fn language_server_binary( &mut self, language_server_id: &LanguageServerId, worktree: &zed::Worktree, - ) -> Result { - if let Some(path) = &self.cached_binary_path { - if fs::metadata(path).map_or(false, |stat| stat.is_file()) { - return Ok(path.clone()); + ) -> Result { + if let Some(zls_binary) = &self.cached_binary { + if fs::metadata(&zls_binary.path).map_or(false, |stat| stat.is_file()) { + return Ok(zls_binary.clone()); } } if let Some(path) = worktree.which("zls") { - self.cached_binary_path = Some(path.clone()); - return Ok(path); + let environment = worktree.shell_env(); + let zls_binary = ZlsBinary { + path, + environment: Some(environment), + }; + self.cached_binary = Some(zls_binary.clone()); + return Ok(zls_binary); } zed::set_language_server_installation_status( @@ -91,15 +102,19 @@ impl ZigExtension { } } - self.cached_binary_path = Some(binary_path.clone()); - Ok(binary_path) + let zls_binary = ZlsBinary { + path: binary_path, + environment: None, + }; + self.cached_binary = Some(zls_binary.clone()); + Ok(zls_binary) } } impl zed::Extension for ZigExtension { fn new() -> Self { Self { - cached_binary_path: None, + cached_binary: None, } } @@ -108,10 +123,11 @@ impl zed::Extension for ZigExtension { language_server_id: &LanguageServerId, worktree: &zed::Worktree, ) -> Result { + let zls_binary = self.language_server_binary(language_server_id, worktree)?; Ok(zed::Command { - command: self.language_server_binary_path(language_server_id, worktree)?, + command: zls_binary.path, args: vec![], - env: Default::default(), + env: zls_binary.environment.unwrap_or_default(), }) } }