aboutsummaryrefslogtreecommitdiffstats
path: root/src/command
diff options
context:
space:
mode:
Diffstat (limited to 'src/command')
-rw-r--r--src/command/client/event.rs20
-rw-r--r--src/command/client/search.rs33
2 files changed, 27 insertions, 26 deletions
diff --git a/src/command/client/event.rs b/src/command/client/event.rs
index f818d728..8044e278 100644
--- a/src/command/client/event.rs
+++ b/src/command/client/event.rs
@@ -1,6 +1,6 @@
use std::{thread, time::Duration};
-use crossbeam_channel::{bounded, TrySendError};
+use crossbeam_channel::unbounded;
use termion::{event::Event as TermEvent, event::Key, input::TermRead};
pub enum Event<I> {
@@ -35,22 +35,16 @@ impl Events {
}
pub fn with_config(config: Config) -> Events {
- // Keep channel small so scroll events don't stack for ages.
- let (tx, rx) = bounded(1);
+ let (tx, rx) = unbounded();
{
let tx = tx.clone();
thread::spawn(move || {
let tty = termion::get_tty().expect("Could not find tty");
for event in tty.events().flatten() {
- if let Err(err) = tx.try_send(Event::Input(event)) {
- if let TrySendError::Full(_) = err {
- // Silently ignore send fails when buffer is full.
- // This will most likely be scroll wheel spam and we can drop some events.
- } else {
- eprintln!("{}", err);
- return;
- }
+ if let Err(err) = tx.send(Event::Input(event)) {
+ eprintln!("{}", err);
+ return;
}
}
})
@@ -69,4 +63,8 @@ impl Events {
pub fn next(&self) -> Result<Event<TermEvent>, crossbeam_channel::RecvError> {
self.rx.recv()
}
+
+ pub fn try_next(&self) -> Result<Event<TermEvent>, crossbeam_channel::TryRecvError> {
+ self.rx.try_recv()
+ }
}
diff --git a/src/command/client/search.rs b/src/command/client/search.rs
index 4e0de683..c50c492c 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)