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:
@@ -7,12 +7,15 @@ use gpui::{
|
||||
};
|
||||
use language::{LanguageServerId, language_settings::SoftWrap};
|
||||
use lsp::{
|
||||
LanguageServer, LanguageServerBinary, LanguageServerName, LanguageServerSelector, MessageType,
|
||||
SetTraceParams, TraceValue, notification::SetTrace,
|
||||
LanguageServer, LanguageServerName, LanguageServerSelector, MessageType, SetTraceParams,
|
||||
TraceValue, notification::SetTrace,
|
||||
};
|
||||
use project::{
|
||||
Project,
|
||||
lsp_store::log_store::{self, Event, LanguageServerKind, LogKind, LogStore, Message},
|
||||
LanguageServerStatus, Project,
|
||||
lsp_store::{
|
||||
LanguageServerBinaryInfo,
|
||||
log_store::{self, Event, LanguageServerKind, LogKind, LogStore, Message},
|
||||
},
|
||||
search::SearchQuery,
|
||||
};
|
||||
use proto::toggle_lsp_logs::LogType;
|
||||
@@ -337,16 +340,28 @@ impl LspLogView {
|
||||
* Capabilities: {CAPABILITIES}
|
||||
|
||||
* Configuration: {CONFIGURATION}",
|
||||
NAME = info.name,
|
||||
NAME = info.status.name,
|
||||
ID = info.id,
|
||||
BINARY = info
|
||||
.binary
|
||||
.as_ref()
|
||||
.map_or_else(|| "Unknown".to_string(), |binary| format!("{binary:#?}")),
|
||||
WORKSPACE_FOLDERS = info.workspace_folders.join(", "),
|
||||
BINARY = info.status.binary.as_ref().map_or_else(
|
||||
|| "Unknown".to_string(),
|
||||
|binary| serde_json::to_string_pretty(binary)
|
||||
.unwrap_or_else(|e| format!("Failed to serialize binary info: {e:#}"))
|
||||
),
|
||||
WORKSPACE_FOLDERS = info
|
||||
.status
|
||||
.workspace_folders
|
||||
.iter()
|
||||
.filter_map(|uri| {
|
||||
uri.to_file_path()
|
||||
.ok()
|
||||
.map(|path| path.to_string_lossy().into_owned())
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
.join(", "),
|
||||
CAPABILITIES = serde_json::to_string_pretty(&info.capabilities)
|
||||
.unwrap_or_else(|e| format!("Failed to serialize capabilities: {e}")),
|
||||
CONFIGURATION = info
|
||||
.status
|
||||
.configuration
|
||||
.map(|configuration| serde_json::to_string_pretty(&configuration))
|
||||
.transpose()
|
||||
@@ -633,17 +648,12 @@ impl LspLogView {
|
||||
.or_else(move || {
|
||||
let capabilities =
|
||||
lsp_store.lsp_server_capabilities.get(&server_id)?.clone();
|
||||
let name = lsp_store
|
||||
.language_server_statuses
|
||||
.get(&server_id)
|
||||
.map(|status| status.name.clone())?;
|
||||
let status = lsp_store.language_server_statuses.get(&server_id)?.clone();
|
||||
|
||||
Some(ServerInfo {
|
||||
id: server_id,
|
||||
capabilities,
|
||||
binary: None,
|
||||
name,
|
||||
workspace_folders: Vec::new(),
|
||||
configuration: None,
|
||||
status,
|
||||
})
|
||||
})
|
||||
})
|
||||
@@ -1314,10 +1324,7 @@ impl LspLogToolbarItemView {
|
||||
struct ServerInfo {
|
||||
id: LanguageServerId,
|
||||
capabilities: lsp::ServerCapabilities,
|
||||
binary: Option<LanguageServerBinary>,
|
||||
name: LanguageServerName,
|
||||
workspace_folders: Vec<String>,
|
||||
configuration: Option<serde_json::Value>,
|
||||
status: LanguageServerStatus,
|
||||
}
|
||||
|
||||
impl ServerInfo {
|
||||
@@ -1325,18 +1332,25 @@ impl ServerInfo {
|
||||
Self {
|
||||
id: server.server_id(),
|
||||
capabilities: server.capabilities(),
|
||||
binary: Some(server.binary().clone()),
|
||||
name: server.name(),
|
||||
workspace_folders: server
|
||||
.workspace_folders()
|
||||
.into_iter()
|
||||
.filter_map(|path| {
|
||||
path.to_file_path()
|
||||
.ok()
|
||||
.map(|path| path.to_string_lossy().into_owned())
|
||||
})
|
||||
.collect::<Vec<_>>(),
|
||||
configuration: Some(server.configuration().clone()),
|
||||
status: LanguageServerStatus {
|
||||
name: server.name(),
|
||||
pending_work: Default::default(),
|
||||
has_pending_diagnostic_updates: false,
|
||||
progress_tokens: Default::default(),
|
||||
worktree: None,
|
||||
binary: Some(LanguageServerBinaryInfo {
|
||||
path: server.binary().path.to_string_lossy().into_owned(),
|
||||
arguments: server
|
||||
.binary()
|
||||
.arguments
|
||||
.iter()
|
||||
.map(|arg| arg.to_string_lossy().into_owned())
|
||||
.collect(),
|
||||
env: server.binary().env.clone(),
|
||||
}),
|
||||
configuration: Some(server.configuration().clone()),
|
||||
workspace_folders: server.workspace_folders(),
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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(),
|
||||
},
|
||||
);
|
||||
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -615,8 +615,16 @@ message RegisteredForBuffer {
|
||||
uint64 buffer_id = 2;
|
||||
}
|
||||
|
||||
message LanguageServerBinaryInfo {
|
||||
string path = 1;
|
||||
repeated string arguments = 2;
|
||||
}
|
||||
|
||||
message ServerMetadataUpdated {
|
||||
optional string capabilities = 1;
|
||||
optional LanguageServerBinaryInfo binary = 2;
|
||||
optional string configuration = 3;
|
||||
repeated string workspace_folders = 4;
|
||||
}
|
||||
|
||||
message LanguageServerLog {
|
||||
|
||||
Reference in New Issue
Block a user