From 08951258e537edf50234645a54dbc8b765d2e100 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=B4=80=E1=B4=8D=E1=B4=9B=E1=B4=8F=E1=B4=80=E1=B4=87?= =?UTF-8?q?=CA=80?= Date: Tue, 17 Mar 2026 15:36:37 +0800 Subject: [PATCH] lsp: Display readable gopls version in UI (#49835) Closes #49757 |Before|After| |--|--| |CleanShot 2026-02-22 at 17 43
16@2x|CleanShot 2026-02-22 at 17 42
21@2x| Before you mark this PR as ready for review, make sure that you have: - [x] Added a solid test coverage and/or screenshots from doing manual testing - [x] Done a self-review taking into account security and performance aspects - [x] Aligned any UI changes with the [UI checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist) Release Notes: - Fixed gopls version display showing raw JSON instead of readable version number --- crates/language_tools/src/lsp_button.rs | 2 +- crates/language_tools/src/lsp_log_view.rs | 1 + crates/lsp/src/lsp.rs | 23 +++++++++++++++++++++++ crates/project/src/lsp_store.rs | 4 ++++ 4 files changed, 29 insertions(+), 1 deletion(-) diff --git a/crates/language_tools/src/lsp_button.rs b/crates/language_tools/src/lsp_button.rs index 781c18eb84cbc9ad7a1b666c089a7b65460c327b..59b14d470003f3a8a4f45b7b2b3e51505f562e56 100644 --- a/crates/language_tools/src/lsp_button.rs +++ b/crates/language_tools/src/lsp_button.rs @@ -230,7 +230,7 @@ impl LanguageServerState { ( server_id, ( - status.server_version.clone(), + status.server_readable_version.clone(), status.binary.as_ref().map(|b| b.path.clone()), status.process_id, ), diff --git a/crates/language_tools/src/lsp_log_view.rs b/crates/language_tools/src/lsp_log_view.rs index 47c840ea4e2f22e1b64cfc5b78bb7f983255dcba..ff1ec56b41ccf12ce6e497c21439aea5c97c3d39 100644 --- a/crates/language_tools/src/lsp_log_view.rs +++ b/crates/language_tools/src/lsp_log_view.rs @@ -1355,6 +1355,7 @@ impl ServerInfo { status: LanguageServerStatus { name: server.name(), server_version: server.version(), + server_readable_version: server.readable_version(), pending_work: Default::default(), has_pending_diagnostic_updates: false, progress_tokens: Default::default(), diff --git a/crates/lsp/src/lsp.rs b/crates/lsp/src/lsp.rs index 2e2318065292ffdc2ac39b577afc7a264d36473d..00fe0f59f1c71cd0c36e7f579b058191eff8f898 100644 --- a/crates/lsp/src/lsp.rs +++ b/crates/lsp/src/lsp.rs @@ -1306,6 +1306,29 @@ impl LanguageServer { self.version.clone() } + /// Get the readable version of the running language server. + pub fn readable_version(&self) -> Option { + match self.name().as_ref() { + "gopls" => { + // Gopls returns a detailed JSON object as its version string; we must parse it to extract the semantic version. + // Example: `{"GoVersion":"go1.26.0","Path":"golang.org/x/tools/gopls","Main":{},"Deps":[],"Settings":[],"Version":"v0.21.1"}` + self.version + .as_ref() + .and_then(|obj| { + #[derive(Deserialize)] + struct GoplsVersion<'a> { + #[serde(rename = "Version")] + version: &'a str, + } + let parsed: GoplsVersion = serde_json::from_str(obj.as_str()).ok()?; + Some(parsed.version.trim_start_matches("v").to_owned().into()) + }) + .or_else(|| self.version.clone()) + } + _ => self.version.clone(), + } + } + /// Get the process name of the running language server. pub fn process_name(&self) -> &str { &self.process_name diff --git a/crates/project/src/lsp_store.rs b/crates/project/src/lsp_store.rs index 25a614052789c85b8c418086e803b9b5cb9e6fae..4673bc1df19b72a60be7197af9ae364acd0933c2 100644 --- a/crates/project/src/lsp_store.rs +++ b/crates/project/src/lsp_store.rs @@ -4028,6 +4028,7 @@ pub enum LspStoreEvent { pub struct LanguageServerStatus { pub name: LanguageServerName, pub server_version: Option, + pub server_readable_version: Option, pub pending_work: BTreeMap, pub has_pending_diagnostic_updates: bool, pub progress_tokens: HashSet, @@ -8201,6 +8202,7 @@ impl LspStore { LanguageServerStatus { name, server_version: None, + server_readable_version: None, pending_work: Default::default(), has_pending_diagnostic_updates: false, progress_tokens: Default::default(), @@ -9391,6 +9393,7 @@ impl LspStore { LanguageServerStatus { name: server_name.clone(), server_version: None, + server_readable_version: None, pending_work: Default::default(), has_pending_diagnostic_updates: false, progress_tokens: Default::default(), @@ -11354,6 +11357,7 @@ impl LspStore { LanguageServerStatus { name: language_server.name(), server_version: language_server.version(), + server_readable_version: language_server.readable_version(), pending_work: Default::default(), has_pending_diagnostic_updates: false, progress_tokens: Default::default(),