Show language server path in language server menu (#47037)

<img width="779" height="210" alt="SCR-20260116-qrif"
src="https://github.com/user-attachments/assets/13c84f20-8fe1-4e3a-9de6-8df1024c2c6c"
/>

In most languages, Zed will check 2-3 locations for language servers.
For instance, when opening a python file, zed looks for ruff in:

- project venv
- user's PATH
- location that zed installs language servers

The language server menu surfaces information that makes it easier to
gather data about your language server, I think offering a path for the
one being ran makes things more clear to the user.

That being said, Idk the best way to surface this. (@danilo-leal?)

Release Notes:

- Add language server path to a tooltip that is produced when hovering
on its status in the language server menu
This commit is contained in:
Joseph T. Lyons authored and GitHub committed 2026-01-18 23:13:25 +00:00
1 parent 23c7d60f1e
commit b1325f2623
1 file changed
+24 -5
+24 -5
View File
@@ -20,7 +20,7 @@ use ui::{
ContextMenu, ContextMenuEntry, Indicator, PopoverMenu, PopoverMenuHandle, Tooltip, prelude::*,
};
use util::{ResultExt, rel_path::RelPath};
use util::{ResultExt, paths::PathExt, rel_path::RelPath};
use workspace::{StatusItemView, Workspace};
use crate::lsp_log_view;
@@ -132,12 +132,20 @@ impl LanguageServerState {
return menu;
};
let server_versions = self
let server_metadata = self
.lsp_store
.update(cx, |lsp_store, _| {
lsp_store
.language_server_statuses()
.map(|(server_id, status)| (server_id, status.server_version.clone()))
.map(|(server_id, status)| {
(
server_id,
(
status.server_version.clone(),
status.binary.as_ref().map(|b| b.path.clone()),
),
)
})
.collect::<HashMap<_, _>>()
})
.unwrap_or_default();
@@ -266,9 +274,16 @@ impl LanguageServerState {
.or_else(|| server_info.binary_status.as_ref()?.message.as_ref())
.cloned();
let server_version = server_versions
let (server_version, binary_path) = server_metadata
.get(&server_info.id)
.and_then(|version| version.clone());
.map(|(version, path)| {
(
version.clone(),
path.as_ref()
.map(|p| SharedString::from(p.compact().to_string_lossy().to_string())),
)
})
.unwrap_or((None, None));
let truncated_message = message.as_ref().and_then(|message| {
message
@@ -495,6 +510,7 @@ impl LanguageServerState {
submenu = submenu.separator().custom_row({
let metadata_label = metadata_label.clone();
let binary_path = binary_path.clone();
move |_, _| {
h_flex()
.id("metadata-container")
@@ -525,6 +541,9 @@ impl LanguageServerState {
.truncate(),
)
})
.when_some(binary_path.clone(), |el, path| {
el.tooltip(Tooltip::text(path))
})
.into_any_element()
}
});