lsp_log: Show messages before init and add filtering (#15893)

Allows language server logs to be published prior to the completion of
the initialize request. OmniSharp is one example of an LSP that
publishes (many) messages prior to the initialization response, and this
completely floods the Zed logs.

Also adds level filtering as demonstrated below. Again, this is due to
my experience with the massive amount of log messages that OmniSharp
publishes.

Release Notes:

- Added level filtering to language server logs

![Log Level
Filtering](https://github.com/user-attachments/assets/e3fcb7af-28cb-4787-9068-8e5e7eb3cf7d)

---------

Co-authored-by: Thorsten Ball <mrnugget@gmail.com>
This commit is contained in:
Jonathan Dickinson 2024-08-22 10:47:34 -04:00 committed by GitHub
parent 9245015d1a
commit 278864e19f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 332 additions and 111 deletions

View file

@ -62,8 +62,8 @@ use log::error;
use lsp::{
CompletionContext, DiagnosticSeverity, DiagnosticTag, DidChangeWatchedFilesRegistrationOptions,
DocumentHighlightKind, Edit, FileSystemWatcher, InsertTextFormat, LanguageServer,
LanguageServerBinary, LanguageServerId, LspRequestFuture, MessageActionItem, OneOf,
ServerHealthStatus, ServerStatus, TextEdit, WorkDoneProgressCancelParams,
LanguageServerBinary, LanguageServerId, LspRequestFuture, MessageActionItem, MessageType,
OneOf, ServerHealthStatus, ServerStatus, TextEdit, WorkDoneProgressCancelParams,
};
use lsp_command::*;
use node_runtime::NodeRuntime;
@ -308,11 +308,17 @@ impl PartialEq for LanguageServerPromptRequest {
}
}
#[derive(Clone, Debug, PartialEq)]
pub enum LanguageServerLogType {
Log(MessageType),
Trace(Option<String>),
}
#[derive(Clone, Debug, PartialEq)]
pub enum Event {
LanguageServerAdded(LanguageServerId),
LanguageServerRemoved(LanguageServerId),
LanguageServerLog(LanguageServerId, String),
LanguageServerLog(LanguageServerId, LanguageServerLogType, String),
Notification(String),
LanguageServerPrompt(LanguageServerPromptRequest),
LanguageNotFound(Model<Buffer>),
@ -3653,17 +3659,56 @@ impl Project {
})
.detach();
language_server
.on_notification::<lsp::notification::Progress, _>(move |params, mut cx| {
if let Some(this) = project.upgrade() {
this.update(&mut cx, |this, cx| {
this.on_lsp_progress(
params,
server_id,
disk_based_diagnostics_progress_token.clone(),
cx,
);
})
.ok();
.on_notification::<lsp::notification::Progress, _>({
let project = project.clone();
move |params, mut cx| {
if let Some(this) = project.upgrade() {
this.update(&mut cx, |this, cx| {
this.on_lsp_progress(
params,
server_id,
disk_based_diagnostics_progress_token.clone(),
cx,
);
})
.ok();
}
}
})
.detach();
language_server
.on_notification::<lsp::notification::LogMessage, _>({
let project = project.clone();
move |params, mut cx| {
if let Some(this) = project.upgrade() {
this.update(&mut cx, |_, cx| {
cx.emit(Event::LanguageServerLog(
server_id,
LanguageServerLogType::Log(params.typ),
params.message,
));
})
.ok();
}
}
})
.detach();
language_server
.on_notification::<lsp::notification::LogTrace, _>({
let project = project.clone();
move |params, mut cx| {
if let Some(this) = project.upgrade() {
this.update(&mut cx, |_, cx| {
cx.emit(Event::LanguageServerLog(
server_id,
LanguageServerLogType::Trace(params.verbose),
params.message,
));
})
.ok();
}
}
})
.detach();
@ -3675,9 +3720,16 @@ impl Project {
(None, override_options) => initialization_options = override_options,
_ => {}
}
let language_server = cx
.update(|cx| language_server.initialize(initialization_options, cx))?
.await?;
.await
.inspect_err(|_| {
if let Some(this) = project.upgrade() {
this.update(cx, |_, cx| cx.emit(Event::LanguageServerRemoved(server_id)))
.ok();
}
})?;
language_server
.notify::<lsp::notification::DidChangeConfiguration>(