From e12ae58c07a5fab6f2f51c0c748ce6721ed36d73 Mon Sep 17 00:00:00 2001 From: Conrad Ludgate Date: Mon, 10 Apr 2023 23:25:22 +0100 Subject: [PATCH] speed up latency --- src/command/client/search/history_list.rs | 2 +- src/command/client/search/interactive.rs | 29 ++++++++++++++++--- .../client/search/search_syntect/mod.rs | 2 +- 3 files changed, 27 insertions(+), 6 deletions(-) diff --git a/src/command/client/search/history_list.rs b/src/command/client/search/history_list.rs index 15057088..f9cd9c8b 100644 --- a/src/command/client/search/history_list.rs +++ b/src/command/client/search/history_list.rs @@ -180,7 +180,7 @@ impl DrawState<'_> { if let Some(parsed) = parsed { theme.highlight(&h.command, parsed, &mut |t, style| { - if t.is_empty() { + if t == "\n" { self.x += 1; } else { self.draw(t, with_select(style)); diff --git a/src/command/client/search/interactive.rs b/src/command/client/search/interactive.rs index d9ffc39d..f5a45a8a 100644 --- a/src/command/client/search/interactive.rs +++ b/src/command/client/search/interactive.rs @@ -1,7 +1,7 @@ use std::{ collections::HashMap, io::{stdout, Write}, - time::Duration, + time::{Duration, Instant}, }; use crossterm::{ @@ -58,12 +58,20 @@ impl State { async fn query_results(&mut self, db: &mut dyn Database) -> Result> { let results = self.engine.query(&self.search, db).await?; self.results_state.select(0); - for h in &results { + Ok(results) + } + + fn highlight_results(&mut self, results: &[History]) -> bool { + let start = Instant::now(); + for h in results { + if start.elapsed() > Duration::from_millis(10) { + return true; + } self.results_parsed .entry(h.id.clone()) .or_insert_with(|| self.syntax.parse_shell(&h.command)); } - Ok(results) + false } fn handle_input(&mut self, settings: &Settings, input: &Event, len: usize) -> Option { @@ -566,7 +574,20 @@ pub async fn history( let initial_filter_mode = app.search.filter_mode; let initial_search_mode = app.search_mode; - let event_ready = tokio::task::spawn_blocking(|| event::poll(Duration::from_millis(250))); + // highlight any new results found. + // this uses a cache internally so it is quick at skipping + // previously seen commands + let highlight_interrupted = app.highlight_results(&results); + + // if we didn't get around to highlighting all the results, we should consider + // triggering a re-draw sooner. + let wait = if highlight_interrupted { + Duration::from_millis(10) + } else { + Duration::from_millis(250) + }; + + let event_ready = tokio::task::spawn_blocking(move || event::poll(wait)); tokio::select! { event_ready = event_ready => { diff --git a/src/command/client/search/search_syntect/mod.rs b/src/command/client/search/search_syntect/mod.rs index 451e5d7f..40f55f03 100644 --- a/src/command/client/search/search_syntect/mod.rs +++ b/src/command/client/search/search_syntect/mod.rs @@ -19,7 +19,7 @@ impl Theme { let mut stack = ScopeStack::default(); let mut styles: Vec<(f64, Style)> = vec![]; for (line, parsed_line) in h.lines().zip(parsed) { - draw("", Style::default()); + draw("\n", Style::default()); let mut last = 0; for &(index, ref op) in parsed_line {