diff options
| author | Conrad Ludgate <conradludgate@gmail.com> | 2022-09-11 16:24:16 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-09-11 16:24:16 +0100 |
| commit | 702a644f68c687142c9a03b48cf451665ed41b62 (patch) | |
| tree | 5621dc20001662f556532745d800ed5dc3607673 /src/command/client/search/event.rs | |
| parent | Add index for interactive search (#493) (diff) | |
| download | atuin-702a644f68c687142c9a03b48cf451665ed41b62.zip | |
better cursor search (#473)
* improve cursor code
* proper unicode support
* refactor and test
* fmt
* clippy
* move methods to state
* refactor search modules
Diffstat (limited to 'src/command/client/search/event.rs')
| -rw-r--r-- | src/command/client/search/event.rs | 70 |
1 files changed, 70 insertions, 0 deletions
diff --git a/src/command/client/search/event.rs b/src/command/client/search/event.rs new file mode 100644 index 00000000..8044e278 --- /dev/null +++ b/src/command/client/search/event.rs @@ -0,0 +1,70 @@ +use std::{thread, time::Duration}; + +use crossbeam_channel::unbounded; +use termion::{event::Event as TermEvent, event::Key, input::TermRead}; + +pub enum Event<I> { + Input(I), + Tick, +} + +/// A small event handler that wrap termion input and tick events. Each event +/// type is handled in its own thread and returned to a common `Receiver` +pub struct Events { + rx: crossbeam_channel::Receiver<Event<TermEvent>>, +} + +#[derive(Debug, Clone, Copy)] +pub struct Config { + pub exit_key: Key, + pub tick_rate: Duration, +} + +impl Default for Config { + fn default() -> Config { + Config { + exit_key: Key::Char('q'), + tick_rate: Duration::from_millis(250), + } + } +} + +impl Events { + pub fn new() -> Events { + Events::with_config(Config::default()) + } + + pub fn with_config(config: Config) -> Events { + 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.send(Event::Input(event)) { + eprintln!("{}", err); + return; + } + } + }) + }; + + thread::spawn(move || loop { + if tx.send(Event::Tick).is_err() { + break; + } + thread::sleep(config.tick_rate); + }); + + Events { rx } + } + + 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() + } +} |
