diff --git a/crates/diagnostics/src/diagnostics.rs b/crates/diagnostics/src/diagnostics.rs index bd0af230ab0e67..be8da5c1302ee3 100644 --- a/crates/diagnostics/src/diagnostics.rs +++ b/crates/diagnostics/src/diagnostics.rs @@ -33,6 +33,7 @@ use std::{ mem, ops::Range, sync::Arc, + time::Duration, }; use theme::ActiveTheme; pub use toolbar_controls::ToolbarControls; @@ -82,6 +83,8 @@ struct DiagnosticGroupState { impl EventEmitter for ProjectDiagnosticsEditor {} +const DIAGNOSTICS_UPDATE_DEBOUNCE: Duration = Duration::from_millis(50); + impl Render for ProjectDiagnosticsEditor { fn render(&mut self, cx: &mut ViewContext) -> impl IntoElement { let child = if self.path_states.is_empty() { @@ -198,6 +201,9 @@ impl ProjectDiagnosticsEditor { } let project_handle = self.project.clone(); self.update_excerpts_task = Some(cx.spawn(|this, mut cx| async move { + cx.background_executor() + .timer(DIAGNOSTICS_UPDATE_DEBOUNCE) + .await; loop { let Some((path, language_server_id)) = this.update(&mut cx, |this, _| { let Some((path, language_server_id)) = this.paths_to_update.pop_first() else { diff --git a/crates/diagnostics/src/diagnostics_tests.rs b/crates/diagnostics/src/diagnostics_tests.rs index c5ae29ff2ed80e..ff305e45a2db27 100644 --- a/crates/diagnostics/src/diagnostics_tests.rs +++ b/crates/diagnostics/src/diagnostics_tests.rs @@ -155,7 +155,8 @@ async fn test_diagnostics(cx: &mut TestAppContext) { }); let editor = view.update(cx, |view, _| view.editor.clone()); - view.next_notification(cx).await; + view.next_notification(DIAGNOSTICS_UPDATE_DEBOUNCE + Duration::from_millis(10), cx) + .await; assert_eq!( editor_blocks(&editor, cx), [ @@ -240,7 +241,8 @@ async fn test_diagnostics(cx: &mut TestAppContext) { lsp_store.disk_based_diagnostics_finished(language_server_id, cx); }); - view.next_notification(cx).await; + view.next_notification(DIAGNOSTICS_UPDATE_DEBOUNCE + Duration::from_millis(10), cx) + .await; assert_eq!( editor_blocks(&editor, cx), [ @@ -352,7 +354,8 @@ async fn test_diagnostics(cx: &mut TestAppContext) { lsp_store.disk_based_diagnostics_finished(language_server_id, cx); }); - view.next_notification(cx).await; + view.next_notification(DIAGNOSTICS_UPDATE_DEBOUNCE + Duration::from_millis(10), cx) + .await; assert_eq!( editor_blocks(&editor, cx), [ @@ -491,6 +494,8 @@ async fn test_diagnostics_multiple_servers(cx: &mut TestAppContext) { }); // Only the first language server's diagnostics are shown. + cx.executor() + .advance_clock(DIAGNOSTICS_UPDATE_DEBOUNCE + Duration::from_millis(10)); cx.executor().run_until_parked(); assert_eq!( editor_blocks(&editor, cx), @@ -537,6 +542,8 @@ async fn test_diagnostics_multiple_servers(cx: &mut TestAppContext) { }); // Both language server's diagnostics are shown. + cx.executor() + .advance_clock(DIAGNOSTICS_UPDATE_DEBOUNCE + Duration::from_millis(10)); cx.executor().run_until_parked(); assert_eq!( editor_blocks(&editor, cx), @@ -603,6 +610,8 @@ async fn test_diagnostics_multiple_servers(cx: &mut TestAppContext) { }); // Only the first language server's diagnostics are updated. + cx.executor() + .advance_clock(DIAGNOSTICS_UPDATE_DEBOUNCE + Duration::from_millis(10)); cx.executor().run_until_parked(); assert_eq!( editor_blocks(&editor, cx), @@ -659,6 +668,8 @@ async fn test_diagnostics_multiple_servers(cx: &mut TestAppContext) { }); // Both language servers' diagnostics are updated. + cx.executor() + .advance_clock(DIAGNOSTICS_UPDATE_DEBOUNCE + Duration::from_millis(10)); cx.executor().run_until_parked(); assert_eq!( editor_blocks(&editor, cx), diff --git a/crates/gpui/src/app/test_context.rs b/crates/gpui/src/app/test_context.rs index 34449c91ec7328..2fea8043017926 100644 --- a/crates/gpui/src/app/test_context.rs +++ b/crates/gpui/src/app/test_context.rs @@ -538,12 +538,15 @@ impl Model { impl View { /// Returns a future that resolves when the view is next updated. - pub fn next_notification(&self, cx: &TestAppContext) -> impl Future { + pub fn next_notification( + &self, + advance_clock_by: Duration, + cx: &TestAppContext, + ) -> impl Future { use postage::prelude::{Sink as _, Stream as _}; let (mut tx, mut rx) = postage::mpsc::channel(1); - let mut cx = cx.app.app.borrow_mut(); - let subscription = cx.observe(self, move |_, _| { + let subscription = cx.app.app.borrow_mut().observe(self, move |_, _| { tx.try_send(()).ok(); }); @@ -553,6 +556,8 @@ impl View { Duration::from_secs(1) }; + cx.executor().advance_clock(advance_clock_by); + async move { let notification = crate::util::timeout(duration, rx.recv()) .await