diff --git a/crates/diagnostics/src/diagnostics.rs b/crates/diagnostics/src/diagnostics.rs index 4b54ad9352..806703a544 100644 --- a/crates/diagnostics/src/diagnostics.rs +++ b/crates/diagnostics/src/diagnostics.rs @@ -1003,7 +1003,7 @@ mod tests { // Diagnostics are added for another earlier path. project.update(cx, |project, cx| { - project.disk_based_diagnostics_started(cx); + project.disk_based_diagnostics_started(0, cx); project .update_diagnostic_entries( 0, @@ -1103,7 +1103,7 @@ mod tests { // Diagnostics are added to the first path project.update(cx, |project, cx| { - project.disk_based_diagnostics_started(cx); + project.disk_based_diagnostics_started(0, cx); project .update_diagnostic_entries( 0, diff --git a/crates/diagnostics/src/items.rs b/crates/diagnostics/src/items.rs index f7d831eeca..4a402522bd 100644 --- a/crates/diagnostics/src/items.rs +++ b/crates/diagnostics/src/items.rs @@ -1,3 +1,4 @@ +use collections::HashSet; use editor::{Editor, GoToNextDiagnostic}; use gpui::{ elements::*, platform::CursorStyle, serde_json, Entity, ModelHandle, MutableAppContext, @@ -12,7 +13,7 @@ pub struct DiagnosticIndicator { summary: project::DiagnosticSummary, active_editor: Option>, current_diagnostic: Option, - check_in_progress: bool, + in_progress_checks: HashSet, _observe_active_editor: Option, } @@ -23,16 +24,13 @@ pub fn init(cx: &mut MutableAppContext) { impl DiagnosticIndicator { pub fn new(project: &ModelHandle, cx: &mut ViewContext) -> Self { cx.subscribe(project, |this, project, event, cx| match event { - project::Event::DiskBasedDiagnosticsUpdated => { + project::Event::DiskBasedDiagnosticsStarted { language_server_id } => { + this.in_progress_checks.insert(*language_server_id); cx.notify(); } - project::Event::DiskBasedDiagnosticsStarted => { - this.check_in_progress = true; - cx.notify(); - } - project::Event::DiskBasedDiagnosticsFinished { .. } => { + project::Event::DiskBasedDiagnosticsFinished { language_server_id } => { this.summary = project.read(cx).diagnostic_summary(cx); - this.check_in_progress = false; + this.in_progress_checks.remove(language_server_id); cx.notify(); } _ => {} @@ -40,7 +38,10 @@ impl DiagnosticIndicator { .detach(); Self { summary: project.read(cx).diagnostic_summary(cx), - check_in_progress: project.read(cx).is_running_disk_based_diagnostics(), + in_progress_checks: project + .read(cx) + .language_servers_running_disk_based_diagnostics() + .collect(), active_editor: None, current_diagnostic: None, _observe_active_editor: None, @@ -85,7 +86,7 @@ impl View for DiagnosticIndicator { enum Summary {} enum Message {} - let in_progress = self.check_in_progress; + let in_progress = !self.in_progress_checks.is_empty(); let mut element = Flex::row().with_child( MouseEventHandler::new::(0, cx, |state, cx| { let style = &cx diff --git a/crates/project/src/project.rs b/crates/project/src/project.rs index 3857264f34..1e622f71a0 100644 --- a/crates/project/src/project.rs +++ b/crates/project/src/project.rs @@ -154,8 +154,9 @@ pub enum Event { ActiveEntryChanged(Option), WorktreeAdded, WorktreeRemoved(WorktreeId), - DiskBasedDiagnosticsStarted, - DiskBasedDiagnosticsUpdated, + DiskBasedDiagnosticsStarted { + language_server_id: usize, + }, DiskBasedDiagnosticsFinished { language_server_id: usize, }, @@ -2126,7 +2127,7 @@ impl Project { if Some(token.as_str()) == disk_based_diagnostics_progress_token { language_server_status.pending_diagnostic_updates += 1; if language_server_status.pending_diagnostic_updates == 1 { - self.disk_based_diagnostics_started(cx); + self.disk_based_diagnostics_started(server_id, cx); self.broadcast_language_server_update( server_id, proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating( @@ -3997,10 +3998,18 @@ impl Project { } } - pub fn is_running_disk_based_diagnostics(&self) -> bool { + pub fn language_servers_running_disk_based_diagnostics<'a>( + &'a self, + ) -> impl 'a + Iterator { self.language_server_statuses - .values() - .any(|status| status.pending_diagnostic_updates > 0) + .iter() + .filter_map(|(id, status)| { + if status.pending_diagnostic_updates > 0 { + Some(*id) + } else { + None + } + }) } pub fn diagnostic_summary(&self, cx: &AppContext) -> DiagnosticSummary { @@ -4025,16 +4034,12 @@ impl Project { }) } - pub fn disk_based_diagnostics_started(&mut self, cx: &mut ModelContext) { - if self - .language_server_statuses - .values() - .map(|status| status.pending_diagnostic_updates) - .sum::() - == 1 - { - cx.emit(Event::DiskBasedDiagnosticsStarted); - } + pub fn disk_based_diagnostics_started( + &mut self, + language_server_id: usize, + cx: &mut ModelContext, + ) { + cx.emit(Event::DiskBasedDiagnosticsStarted { language_server_id }); } pub fn disk_based_diagnostics_finished( @@ -4042,7 +4047,6 @@ impl Project { language_server_id: usize, cx: &mut ModelContext, ) { - cx.emit(Event::DiskBasedDiagnosticsUpdated); cx.emit(Event::DiskBasedDiagnosticsFinished { language_server_id }); } @@ -4446,7 +4450,7 @@ impl Project { } proto::update_language_server::Variant::DiskBasedDiagnosticsUpdating(_) => { this.update(&mut cx, |this, cx| { - this.disk_based_diagnostics_started(cx); + this.disk_based_diagnostics_started(language_server_id, cx); }) } proto::update_language_server::Variant::DiskBasedDiagnosticsUpdated(_) => { @@ -6208,7 +6212,9 @@ mod tests { fake_server.start_progress(progress_token).await; assert_eq!( events.next().await.unwrap(), - Event::DiskBasedDiagnosticsStarted + Event::DiskBasedDiagnosticsStarted { + language_server_id: 0, + } ); fake_server.start_progress(progress_token).await; @@ -6237,10 +6243,6 @@ mod tests { fake_server.end_progress(progress_token).await; fake_server.end_progress(progress_token).await; - assert_eq!( - events.next().await.unwrap(), - Event::DiskBasedDiagnosticsUpdated - ); assert_eq!( events.next().await.unwrap(), Event::DiskBasedDiagnosticsFinished { @@ -6344,22 +6346,35 @@ mod tests { fake_server.start_progress(progress_token).await; assert_eq!( events.next().await.unwrap(), - Event::DiskBasedDiagnosticsStarted + Event::DiskBasedDiagnosticsStarted { + language_server_id: 1 + } ); + project.read_with(cx, |project, _| { + assert_eq!( + project + .language_servers_running_disk_based_diagnostics() + .collect::>(), + [1] + ); + }); // All diagnostics are considered done, despite the old server's diagnostic // task never completing. fake_server.end_progress(progress_token).await; assert_eq!( events.next().await.unwrap(), - Event::DiskBasedDiagnosticsUpdated + Event::DiskBasedDiagnosticsFinished { + language_server_id: 1 + } ); - assert!(matches!( - events.next().await.unwrap(), - Event::DiskBasedDiagnosticsFinished { .. } - )); project.read_with(cx, |project, _| { - assert!(!project.is_running_disk_based_diagnostics()); + assert_eq!( + project + .language_servers_running_disk_based_diagnostics() + .collect::>(), + [0; 0] + ); }); }