mirror of
https://github.com/helix-editor/helix.git
synced 2024-11-22 01:16:18 +04:00
Picker: Skip dynamic query debounce for pastes (#11211)
Pastes are probably the last edit one means to make before the query should run so it doesn't need to be debounced. This makes global search much snappier for example when accepting the history suggestion from the '/' register or pasting a pattern from the clipboard or a register.
This commit is contained in:
parent
748a9cf022
commit
dbaa636683
@ -52,7 +52,7 @@
|
||||
Document, DocumentId, Editor,
|
||||
};
|
||||
|
||||
use self::handlers::{DynamicQueryHandler, PreviewHighlightHandler};
|
||||
use self::handlers::{DynamicQueryChange, DynamicQueryHandler, PreviewHighlightHandler};
|
||||
|
||||
pub const ID: &str = "picker";
|
||||
|
||||
@ -272,7 +272,7 @@ pub struct Picker<T: 'static + Send + Sync, D: 'static> {
|
||||
file_fn: Option<FileCallback<T>>,
|
||||
/// An event handler for syntax highlighting the currently previewed file.
|
||||
preview_highlight_handler: Sender<Arc<Path>>,
|
||||
dynamic_query_handler: Option<Sender<Arc<str>>>,
|
||||
dynamic_query_handler: Option<Sender<DynamicQueryChange>>,
|
||||
}
|
||||
|
||||
impl<T: 'static + Send + Sync, D: 'static + Send + Sync> Picker<T, D> {
|
||||
@ -435,7 +435,12 @@ pub fn with_dynamic_query(
|
||||
debounce_ms: Option<u64>,
|
||||
) -> Self {
|
||||
let handler = DynamicQueryHandler::new(callback, debounce_ms).spawn();
|
||||
helix_event::send_blocking(&handler, self.primary_query());
|
||||
let event = DynamicQueryChange {
|
||||
query: self.primary_query(),
|
||||
// Treat the initial query as a paste.
|
||||
is_paste: true,
|
||||
};
|
||||
helix_event::send_blocking(&handler, event);
|
||||
self.dynamic_query_handler = Some(handler);
|
||||
self
|
||||
}
|
||||
@ -511,12 +516,12 @@ pub fn toggle_preview(&mut self) {
|
||||
|
||||
fn prompt_handle_event(&mut self, event: &Event, cx: &mut Context) -> EventResult {
|
||||
if let EventResult::Consumed(_) = self.prompt.handle_event(event, cx) {
|
||||
self.handle_prompt_change();
|
||||
self.handle_prompt_change(matches!(event, Event::Paste(_)));
|
||||
}
|
||||
EventResult::Consumed(None)
|
||||
}
|
||||
|
||||
fn handle_prompt_change(&mut self) {
|
||||
fn handle_prompt_change(&mut self, is_paste: bool) {
|
||||
// TODO: better track how the pattern has changed
|
||||
let line = self.prompt.line();
|
||||
let old_query = self.query.parse(line);
|
||||
@ -557,7 +562,11 @@ fn handle_prompt_change(&mut self) {
|
||||
// If this is a dynamic picker, notify the query hook that the primary
|
||||
// query might have been updated.
|
||||
if let Some(handler) = &self.dynamic_query_handler {
|
||||
helix_event::send_blocking(handler, self.primary_query());
|
||||
let event = DynamicQueryChange {
|
||||
query: self.primary_query(),
|
||||
is_paste,
|
||||
};
|
||||
helix_event::send_blocking(handler, event);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1028,7 +1037,8 @@ fn handle_event(&mut self, event: &Event, ctx: &mut Context) -> EventResult {
|
||||
.filter(|_| self.prompt.line().is_empty())
|
||||
{
|
||||
self.prompt.set_line(completion.to_string(), ctx.editor);
|
||||
self.handle_prompt_change();
|
||||
// Inserting from the history register is a paste.
|
||||
self.handle_prompt_change(true);
|
||||
} else {
|
||||
if let Some(option) = self.selection() {
|
||||
(self.callback_fn)(ctx, option, Action::Replace);
|
||||
|
@ -115,6 +115,11 @@ fn finish_debounce(&mut self) {
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) struct DynamicQueryChange {
|
||||
pub query: Arc<str>,
|
||||
pub is_paste: bool,
|
||||
}
|
||||
|
||||
pub(super) struct DynamicQueryHandler<T: 'static + Send + Sync, D: 'static + Send + Sync> {
|
||||
callback: Arc<DynQueryCallback<T, D>>,
|
||||
// Duration used as a debounce.
|
||||
@ -137,9 +142,10 @@ pub(super) fn new(callback: DynQueryCallback<T, D>, duration_ms: Option<u64>) ->
|
||||
}
|
||||
|
||||
impl<T: 'static + Send + Sync, D: 'static + Send + Sync> AsyncHook for DynamicQueryHandler<T, D> {
|
||||
type Event = Arc<str>;
|
||||
type Event = DynamicQueryChange;
|
||||
|
||||
fn handle_event(&mut self, query: Self::Event, _timeout: Option<Instant>) -> Option<Instant> {
|
||||
fn handle_event(&mut self, change: Self::Event, _timeout: Option<Instant>) -> Option<Instant> {
|
||||
let DynamicQueryChange { query, is_paste } = change;
|
||||
if query == self.last_query {
|
||||
// If the search query reverts to the last one we requested, no need to
|
||||
// make a new request.
|
||||
@ -147,7 +153,12 @@ fn handle_event(&mut self, query: Self::Event, _timeout: Option<Instant>) -> Opt
|
||||
None
|
||||
} else {
|
||||
self.query = Some(query);
|
||||
Some(Instant::now() + self.debounce)
|
||||
if is_paste {
|
||||
self.finish_debounce();
|
||||
None
|
||||
} else {
|
||||
Some(Instant::now() + self.debounce)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user