project: Send LSP metadata to remote ServerInfo (#42831)

Closes #39582

Release Notes:

- Added LSP metadata to remote ServerInfo

Here's the before/after:


https://github.com/user-attachments/assets/1057faa5-82af-4975-abad-5e10e139fac1

---------

Co-authored-by: Kirill Bulatov <mail4score@gmail.com>
This commit is contained in:
Mayank Verma
2025-11-24 23:16:35 +02:00
committed by GitHub
co-authored by Kirill Bulatov
parent bd2c1027fa
commit 342eba6f22
4 changed files with 136 additions and 45 deletions
+45 -1
View File
@@ -93,6 +93,7 @@ use rpc::{
proto::{LspRequestId, LspRequestMessage as _},
};
use serde::Serialize;
use serde_json::Value;
use settings::{Settings, SettingsLocation, SettingsStore};
use sha2::{Digest, Sha256};
use smol::channel::Sender;
@@ -3557,6 +3558,21 @@ fn notify_server_capabilities_updated(server: &LanguageServer, cx: &mut Context<
message: proto::update_language_server::Variant::MetadataUpdated(
proto::ServerMetadataUpdated {
capabilities: Some(capabilities),
binary: Some(proto::LanguageServerBinaryInfo {
path: server.binary().path.to_string_lossy().into_owned(),
arguments: server
.binary()
.arguments
.iter()
.map(|arg| arg.to_string_lossy().into_owned())
.collect(),
}),
configuration: serde_json::to_string(server.configuration()).ok(),
workspace_folders: server
.workspace_folders()
.iter()
.map(|uri| uri.to_string())
.collect(),
},
),
});
@@ -3713,13 +3729,23 @@ pub enum LspStoreEvent {
},
}
#[derive(Clone, Debug, Serialize)]
pub struct LanguageServerBinaryInfo {
pub path: String,
pub arguments: Vec<String>,
pub env: Option<HashMap<String, String>>,
}
#[derive(Clone, Debug, Serialize)]
pub struct LanguageServerStatus {
pub name: LanguageServerName,
pub pending_work: BTreeMap<ProgressToken, LanguageServerProgress>,
pub has_pending_diagnostic_updates: bool,
progress_tokens: HashSet<ProgressToken>,
pub progress_tokens: HashSet<ProgressToken>,
pub worktree: Option<WorktreeId>,
pub binary: Option<LanguageServerBinaryInfo>,
pub configuration: Option<Value>,
pub workspace_folders: BTreeSet<Uri>,
}
#[derive(Clone, Debug)]
@@ -8130,6 +8156,9 @@ impl LspStore {
has_pending_diagnostic_updates: false,
progress_tokens: Default::default(),
worktree,
binary: None,
configuration: None,
workspace_folders: BTreeSet::new(),
},
)
})
@@ -9139,6 +9168,9 @@ impl LspStore {
has_pending_diagnostic_updates: false,
progress_tokens: Default::default(),
worktree: server.worktree_id.map(WorktreeId::from_proto),
binary: None,
configuration: None,
workspace_folders: BTreeSet::new(),
},
);
cx.emit(LspStoreEvent::LanguageServerAdded(
@@ -11155,6 +11187,18 @@ impl LspStore {
has_pending_diagnostic_updates: false,
progress_tokens: Default::default(),
worktree: Some(key.worktree_id),
binary: Some(LanguageServerBinaryInfo {
path: language_server.binary().path.to_string_lossy().into_owned(),
arguments: language_server
.binary()
.arguments
.iter()
.map(|arg| arg.to_string_lossy().into_owned())
.collect(),
env: language_server.binary().env.clone(),
}),
configuration: Some(language_server.configuration().clone()),
workspace_folders: language_server.workspace_folders(),
},
);
+35 -10
View File
@@ -37,7 +37,7 @@ use dap::inline_value::{InlineValueLocation, VariableLookupKind, VariableScope};
use crate::{
git_store::GitStore,
lsp_store::{SymbolLocation, log_store::LogKind},
lsp_store::{LanguageServerBinaryInfo, SymbolLocation, log_store::LogKind},
project_search::SearchResultsHandle,
};
pub use agent_server_store::{AgentServerStore, AgentServersUpdated, ExternalAgentServerName};
@@ -114,7 +114,7 @@ use std::{
ops::{Not as _, Range},
path::{Path, PathBuf},
pin::pin,
str,
str::{self, FromStr},
sync::Arc,
time::Duration,
};
@@ -3111,17 +3111,42 @@ impl Project {
match message {
proto::update_language_server::Variant::MetadataUpdated(update) => {
if let Some(capabilities) = update
.capabilities
.as_ref()
.and_then(|capabilities| serde_json::from_str(capabilities).ok())
{
self.lsp_store.update(cx, |lsp_store, _| {
self.lsp_store.update(cx, |lsp_store, _| {
if let Some(capabilities) = update
.capabilities
.as_ref()
.and_then(|capabilities| serde_json::from_str(capabilities).ok())
{
lsp_store
.lsp_server_capabilities
.insert(*language_server_id, capabilities);
});
}
}
if let Some(language_server_status) = lsp_store
.language_server_statuses
.get_mut(language_server_id)
{
if let Some(binary) = &update.binary {
language_server_status.binary =
Some(LanguageServerBinaryInfo {
path: binary.path.clone(),
arguments: binary.arguments.clone(),
env: None,
});
}
language_server_status.configuration = update
.configuration
.as_ref()
.and_then(|config_str| serde_json::from_str(config_str).ok());
language_server_status.workspace_folders = update
.workspace_folders
.iter()
.filter_map(|uri_str| lsp::Uri::from_str(uri_str).ok())
.collect();
}
});
}
proto::update_language_server::Variant::RegisteredForBuffer(update) => {
if let Some(buffer_id) = BufferId::new(update.buffer_id).ok() {