From 6780e80bf7b5550371f23378aa8254cb39036a18 Mon Sep 17 00:00:00 2001 From: Kirill Bulatov Date: Fri, 3 Nov 2023 22:03:05 +0200 Subject: [PATCH] Refresh diagnostics inside the tab (#3225) r-a now has 2 different types of diagnostics: * "disk-based" ones that come from `cargo check` and related, that emit `project::Event::DiskBasedDiagnosticsStarted` and `DiskBasedDiagnosticsFinished` * "flycheck" diagnostics from r-a itself, that it tries to dynamically apply to every buffer open, that come with `DiagnosticsUpdated` event. Latter diagnostics update frequently, on every file close and open, but `diagnostics.rs` logic had never polled for new diagnostics after registering the `DiagnosticsUpdated` event, so the only way we could have newer diagnostics was to re-open the whole panel. The PR fixes that, and also adds more debug logging to the module. The logic of the fix looks very familiar to previous related fix: https://github.com/zed-industries/zed/pull/3128 One notable thing after the fix: "flycheck" diagnostics stay forever if the diagnostics panel is opened: excerpts in that panel do not allow the buffer to get dropped (hence, closed in terms of r-a) and get the updated, zero diagnostics. If the diagnostics panel is opened and closed multiple times, those errors gradually disappear. Release Notes: - Fixed diagnostics panel not refreshing its contents properly --- Cargo.lock | 1 + crates/diagnostics/Cargo.toml | 1 + crates/diagnostics/src/diagnostics.rs | 43 +++++++++++++++------------ crates/editor/src/items.rs | 4 +-- 4 files changed, 28 insertions(+), 21 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7440ca5a97f82865a9f33ed276174952920c1aa0..65b4175999cbd9251d09307c9d42ca0a579a1b51 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2426,6 +2426,7 @@ dependencies = [ "editor", "gpui", "language", + "log", "lsp", "postage", "project", diff --git a/crates/diagnostics/Cargo.toml b/crates/diagnostics/Cargo.toml index b0b2450f053fb9c8925b4bfe0131af24d5d24fa7..26a2a82999d2374e65ce5e061ee23ab91c366455 100644 --- a/crates/diagnostics/Cargo.toml +++ b/crates/diagnostics/Cargo.toml @@ -20,6 +20,7 @@ theme = { path = "../theme" } util = { path = "../util" } workspace = { path = "../workspace" } +log.workspace = true anyhow.workspace = true schemars.workspace = true serde.workspace = true diff --git a/crates/diagnostics/src/diagnostics.rs b/crates/diagnostics/src/diagnostics.rs index 0b1c6f8470369cbe18538e15b362258756d1aaeb..a3d779531b5690be0dc60808085bc099768df6bd 100644 --- a/crates/diagnostics/src/diagnostics.rs +++ b/crates/diagnostics/src/diagnostics.rs @@ -151,6 +151,7 @@ impl ProjectDiagnosticsEditor { ) -> Self { cx.subscribe(&project_handle, |this, _, event, cx| match event { project::Event::DiskBasedDiagnosticsFinished { language_server_id } => { + log::debug!("Disk based diagnostics finished for server {language_server_id}"); this.update_excerpts(Some(*language_server_id), cx); this.update_title(cx); } @@ -158,8 +159,11 @@ impl ProjectDiagnosticsEditor { language_server_id, path, } => { + log::debug!("Adding path {path:?} to update for server {language_server_id}"); this.paths_to_update .insert((path.clone(), *language_server_id)); + this.update_excerpts(Some(*language_server_id), cx); + this.update_title(cx); } _ => {} }) @@ -229,6 +233,7 @@ impl ProjectDiagnosticsEditor { language_server_id: Option, cx: &mut ViewContext, ) { + log::debug!("Updating excerpts for server {language_server_id:?}"); let mut paths = Vec::new(); self.paths_to_update.retain(|(path, server_id)| { if language_server_id @@ -1301,25 +1306,6 @@ mod tests { cx, ) .unwrap(); - project - .update_diagnostic_entries( - server_id_2, - PathBuf::from("/test/main.js"), - None, - vec![DiagnosticEntry { - range: Unclipped(PointUtf16::new(1, 0))..Unclipped(PointUtf16::new(1, 1)), - diagnostic: Diagnostic { - message: "warning 1".to_string(), - severity: DiagnosticSeverity::ERROR, - is_primary: true, - is_disk_based: true, - group_id: 2, - ..Default::default() - }, - }], - cx, - ) - .unwrap(); }); // The first language server finishes @@ -1353,6 +1339,25 @@ mod tests { // The second language server finishes project.update(cx, |project, cx| { + project + .update_diagnostic_entries( + server_id_2, + PathBuf::from("/test/main.js"), + None, + vec![DiagnosticEntry { + range: Unclipped(PointUtf16::new(1, 0))..Unclipped(PointUtf16::new(1, 1)), + diagnostic: Diagnostic { + message: "warning 1".to_string(), + severity: DiagnosticSeverity::ERROR, + is_primary: true, + is_disk_based: true, + group_id: 2, + ..Default::default() + }, + }], + cx, + ) + .unwrap(); project.disk_based_diagnostics_finished(server_id_2, cx); }); diff --git a/crates/editor/src/items.rs b/crates/editor/src/items.rs index c87606070e5660c90a7e53962098b4da923a2f1e..1b922848e061b8b162fc5c1f25babf5c3ce96c0e 100644 --- a/crates/editor/src/items.rs +++ b/crates/editor/src/items.rs @@ -33,9 +33,9 @@ use util::{ paths::{PathExt, FILE_ROW_COLUMN_DELIMITER}, ResultExt, TryFutureExt, }; -use workspace::item::{BreadcrumbText, FollowableItemHandle}; +use workspace::item::{BreadcrumbText, FollowableItemHandle, ItemHandle}; use workspace::{ - item::{FollowableItem, Item, ItemEvent, ItemHandle, ProjectItem}, + item::{FollowableItem, Item, ItemEvent, ProjectItem}, searchable::{Direction, SearchEvent, SearchableItem, SearchableItemHandle}, ItemId, ItemNavHistory, Pane, StatusItemView, ToolbarItemLocation, ViewId, Workspace, WorkspaceId,