diff --git a/helix-event/src/lib.rs b/helix-event/src/lib.rs index 894de5e8d..de018a79d 100644 --- a/helix-event/src/lib.rs +++ b/helix-event/src/lib.rs @@ -34,7 +34,9 @@ use anyhow::Result; pub use cancel::{cancelable_future, cancelation, CancelRx, CancelTx}; pub use debounce::{send_blocking, AsyncHook}; -pub use redraw::{lock_frame, redraw_requested, request_redraw, start_frame, RenderLockGuard}; +pub use redraw::{ + lock_frame, redraw_requested, request_redraw, start_frame, RenderLockGuard, RequestRedrawOnDrop, +}; pub use registry::Event; mod cancel; diff --git a/helix-event/src/redraw.rs b/helix-event/src/redraw.rs index 8fadb8aea..d1a188995 100644 --- a/helix-event/src/redraw.rs +++ b/helix-event/src/redraw.rs @@ -51,3 +51,12 @@ pub fn start_frame() { pub fn lock_frame() -> RenderLockGuard { RENDER_LOCK.read() } + +/// A zero sized type that requests a redraw via [request_redraw] when the type [Drop]s. +pub struct RequestRedrawOnDrop; + +impl Drop for RequestRedrawOnDrop { + fn drop(&mut self) { + request_redraw(); + } +} diff --git a/helix-term/src/ui/picker.rs b/helix-term/src/ui/picker.rs index 6394fb87f..1c47552d0 100644 --- a/helix-term/src/ui/picker.rs +++ b/helix-term/src/ui/picker.rs @@ -153,6 +153,12 @@ pub struct Injector { editor_data: Arc, version: usize, picker_version: Arc, + /// A marker that requests a redraw when the injector drops. + /// This marker causes the "running" indicator to disappear when a background job + /// providing items is finished and drops. This could be wrapped in an [Arc] to ensure + /// that the redraw is only requested when all Injectors drop for a Picker (which removes + /// the "running" indicator) but the redraw handle is debounced so this is unnecessary. + _redraw: helix_event::RequestRedrawOnDrop, } impl Clone for Injector { @@ -163,6 +169,7 @@ impl Clone for Injector { editor_data: self.editor_data.clone(), version: self.version, picker_version: self.picker_version.clone(), + _redraw: helix_event::RequestRedrawOnDrop, } } } @@ -284,6 +291,7 @@ impl Picker { editor_data: Arc::new(editor_data), version: 0, picker_version: Arc::new(AtomicUsize::new(0)), + _redraw: helix_event::RequestRedrawOnDrop, }; (matcher, streamer) } @@ -386,6 +394,7 @@ impl Picker { editor_data: self.editor_data.clone(), version: self.version.load(atomic::Ordering::Relaxed), picker_version: self.version.clone(), + _redraw: helix_event::RequestRedrawOnDrop, } } diff --git a/helix-term/src/ui/picker/handlers.rs b/helix-term/src/ui/picker/handlers.rs index e426adda7..4896ccbc6 100644 --- a/helix-term/src/ui/picker/handlers.rs +++ b/helix-term/src/ui/picker/handlers.rs @@ -174,11 +174,8 @@ impl AsyncHook for DynamicQu if let Err(err) = get_options.await { log::info!("Dynamic request failed: {err}"); } - // The picker's shows its running indicator when there are any active - // injectors. When we're done injecting new options, drop the injector - // and request a redraw to remove the running indicator. - drop(injector); - helix_event::request_redraw(); + // NOTE: the Drop implementation of Injector will request a redraw when the + // injector falls out of scope here, clearing the "running" indicator. }); }) }