lsp: Fix workspace diagnostics lag & add streaming support (#34022)
Closes https://github.com/zed-industries/zed/issues/33980 Closes https://github.com/zed-industries/zed/discussions/33979 - Switches to the debounce task pattern for diagnostic summary computations, which most importantly lets us do them only once when a large number of DiagnosticUpdated events are received at once. - Makes workspace diagnostic requests not time out if a partial result is received. - Makes diagnostics from workspace diagnostic partial results get merged. There might be some related areas where we're not fully complying with the LSP spec but they may be outside the scope of what this PR should include. Release Notes: - Added support for streaming LSP workspace diagnostics. - Fixed editor freeze from large LSP workspace diagnostic responses.
This commit is contained in:
parent
5f3e7a5f91
commit
d7bb1c1d0e
9 changed files with 460 additions and 114 deletions
|
@ -80,6 +80,7 @@ pub(crate) struct ProjectDiagnosticsEditor {
|
|||
include_warnings: bool,
|
||||
update_excerpts_task: Option<Task<Result<()>>>,
|
||||
cargo_diagnostics_fetch: CargoDiagnosticsFetchState,
|
||||
diagnostic_summary_update: Task<()>,
|
||||
_subscription: Subscription,
|
||||
}
|
||||
|
||||
|
@ -179,7 +180,16 @@ impl ProjectDiagnosticsEditor {
|
|||
path,
|
||||
} => {
|
||||
this.paths_to_update.insert(path.clone());
|
||||
this.summary = project.read(cx).diagnostic_summary(false, cx);
|
||||
let project = project.clone();
|
||||
this.diagnostic_summary_update = cx.spawn(async move |this, cx| {
|
||||
cx.background_executor()
|
||||
.timer(Duration::from_millis(30))
|
||||
.await;
|
||||
this.update(cx, |this, cx| {
|
||||
this.summary = project.read(cx).diagnostic_summary(false, cx);
|
||||
})
|
||||
.log_err();
|
||||
});
|
||||
cx.emit(EditorEvent::TitleChanged);
|
||||
|
||||
if this.editor.focus_handle(cx).contains_focused(window, cx) || this.focus_handle.contains_focused(window, cx) {
|
||||
|
@ -276,6 +286,7 @@ impl ProjectDiagnosticsEditor {
|
|||
cancel_task: None,
|
||||
diagnostic_sources: Arc::new(Vec::new()),
|
||||
},
|
||||
diagnostic_summary_update: Task::ready(()),
|
||||
_subscription: project_event_subscription,
|
||||
};
|
||||
this.update_all_diagnostics(true, window, cx);
|
||||
|
|
|
@ -9,6 +9,7 @@ use language::Diagnostic;
|
|||
use project::project_settings::{GoToDiagnosticSeverityFilter, ProjectSettings};
|
||||
use settings::Settings;
|
||||
use ui::{Button, ButtonLike, Color, Icon, IconName, Label, Tooltip, h_flex, prelude::*};
|
||||
use util::ResultExt;
|
||||
use workspace::{StatusItemView, ToolbarItemEvent, Workspace, item::ItemHandle};
|
||||
|
||||
use crate::{Deploy, IncludeWarnings, ProjectDiagnosticsEditor};
|
||||
|
@ -20,6 +21,7 @@ pub struct DiagnosticIndicator {
|
|||
current_diagnostic: Option<Diagnostic>,
|
||||
_observe_active_editor: Option<Subscription>,
|
||||
diagnostics_update: Task<()>,
|
||||
diagnostic_summary_update: Task<()>,
|
||||
}
|
||||
|
||||
impl Render for DiagnosticIndicator {
|
||||
|
@ -135,8 +137,16 @@ impl DiagnosticIndicator {
|
|||
}
|
||||
|
||||
project::Event::DiagnosticsUpdated { .. } => {
|
||||
this.summary = project.read(cx).diagnostic_summary(false, cx);
|
||||
cx.notify();
|
||||
this.diagnostic_summary_update = cx.spawn(async move |this, cx| {
|
||||
cx.background_executor()
|
||||
.timer(Duration::from_millis(30))
|
||||
.await;
|
||||
this.update(cx, |this, cx| {
|
||||
this.summary = project.read(cx).diagnostic_summary(false, cx);
|
||||
cx.notify();
|
||||
})
|
||||
.log_err();
|
||||
});
|
||||
}
|
||||
|
||||
_ => {}
|
||||
|
@ -150,6 +160,7 @@ impl DiagnosticIndicator {
|
|||
current_diagnostic: None,
|
||||
_observe_active_editor: None,
|
||||
diagnostics_update: Task::ready(()),
|
||||
diagnostic_summary_update: Task::ready(()),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue