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
This commit is contained in:
Kirill Bulatov 2023-11-03 22:03:05 +02:00 committed by GitHub
commit edacffab58
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 28 additions and 21 deletions

1
Cargo.lock generated
View File

@ -2461,6 +2461,7 @@ dependencies = [
"editor",
"gpui",
"language",
"log",
"lsp",
"postage",
"project",

View File

@ -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

View File

@ -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<LanguageServerId>,
cx: &mut ViewContext<Self>,
) {
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);
});

View File

@ -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,