summaryrefslogtreecommitdiffstats
path: root/src/command/client/search.rs
diff options
context:
space:
mode:
authorFrank Hamand <frank.hamand@coinbase.com>2022-06-13 09:33:05 +0100
committerGitHub <noreply@github.com>2022-06-13 09:33:05 +0100
commitab994e3c827c65966ebc9cd2ac1d3a6048f042bc (patch)
tree5b0cd9d58b5f41caca9e6d758abb99fb372c5a28 /src/command/client/search.rs
parent23b9d34e162a9cf27b519c1fe075785be25c46e5 (diff)
Batch key handling (#448)
* Batch input events and only query once they are finished This simplifies the code a lot (no more bounded channel) and yields the same performance improvement with scroll wheel spam while fixing copy/paste * Clippy * fmt * Use blocking wait before emptying events channel This was causing a busy loop * Update query on filter mode change
Diffstat (limited to 'src/command/client/search.rs')
-rw-r--r--src/command/client/search.rs33
1 files changed, 18 insertions, 15 deletions
diff --git a/src/command/client/search.rs b/src/command/client/search.rs
index 4e0de6838..c50c492c3 100644
--- a/src/command/client/search.rs
+++ b/src/command/client/search.rs
@@ -307,12 +307,7 @@ fn remove_char_from_input(app: &mut State, i: usize) -> char {
}
#[allow(clippy::too_many_lines)]
-async fn key_handler(
- input: TermEvent,
- search_mode: SearchMode,
- db: &mut impl Database,
- app: &mut State,
-) -> Option<String> {
+fn key_handler(input: &TermEvent, app: &mut State) -> Option<String> {
match input {
TermEvent::Key(Key::Esc | Key::Ctrl('c' | 'd' | 'g')) => return Some(String::from("")),
TermEvent::Key(Key::Char('\n')) => {
@@ -324,7 +319,7 @@ async fn key_handler(
.map_or(app.input.clone(), |h| h.command.clone()),
);
}
- TermEvent::Key(Key::Alt(c)) if ('1'..='9').contains(&c) => {
+ TermEvent::Key(Key::Alt(c)) if ('1'..='9').contains(c) => {
let c = c.to_digit(10)? as usize;
let i = app.results_state.selected()? + c;
@@ -351,9 +346,8 @@ async fn key_handler(
app.cursor_index = app.input.chars().count();
}
TermEvent::Key(Key::Char(c)) => {
- insert_char_into_input(app, app.cursor_index, c);
+ insert_char_into_input(app, app.cursor_index, *c);
app.cursor_index += 1;
- query_results(app, search_mode, db).await.unwrap();
}
TermEvent::Key(Key::Backspace) => {
if app.cursor_index == 0 {
@@ -361,7 +355,6 @@ async fn key_handler(
}
remove_char_from_input(app, app.cursor_index);
app.cursor_index -= 1;
- query_results(app, search_mode, db).await.unwrap();
}
TermEvent::Key(Key::Ctrl('w')) => {
let mut stop_on_next_whitespace = false;
@@ -379,12 +372,10 @@ async fn key_handler(
}
app.cursor_index -= 1;
}
- query_results(app, search_mode, db).await.unwrap();
}
TermEvent::Key(Key::Ctrl('u')) => {
app.input = String::from("");
app.cursor_index = 0;
- query_results(app, search_mode, db).await.unwrap();
}
TermEvent::Key(Key::Ctrl('r')) => {
app.filter_mode = match app.filter_mode {
@@ -393,8 +384,6 @@ async fn key_handler(
FilterMode::Session => FilterMode::Directory,
FilterMode::Directory => FilterMode::Global,
};
-
- query_results(app, search_mode, db).await.unwrap();
}
TermEvent::Key(Key::Down | Key::Ctrl('n' | 'j'))
| TermEvent::Mouse(MouseEvent::Press(MouseButton::WheelDown, _, _)) => {
@@ -632,13 +621,27 @@ async fn select_history(
loop {
let history_count = db.history_count().await?;
+ let initial_input = app.input.clone();
+ let initial_filter_mode = app.filter_mode;
+
// Handle input
if let Event::Input(input) = events.next()? {
- if let Some(output) = key_handler(input, search_mode, db, &mut app).await {
+ if let Some(output) = key_handler(&input, &mut app) {
return Ok(output);
}
}
+ // After we receive input process the whole event channel before query/render.
+ while let Ok(Event::Input(input)) = events.try_next() {
+ if let Some(output) = key_handler(&input, &mut app) {
+ return Ok(output);
+ }
+ }
+
+ if initial_input != app.input || initial_filter_mode != app.filter_mode {
+ query_results(&mut app, search_mode, db).await?;
+ }
+
let compact = match style {
atuin_client::settings::Style::Auto => {
terminal.size().map(|size| size.height < 14).unwrap_or(true)