aboutsummaryrefslogtreecommitdiffstats
path: root/src/command/client/search/event.rs
diff options
context:
space:
mode:
authorConrad Ludgate <conradludgate@gmail.com>2022-09-11 16:24:16 +0100
committerGitHub <noreply@github.com>2022-09-11 16:24:16 +0100
commit702a644f68c687142c9a03b48cf451665ed41b62 (patch)
tree5621dc20001662f556532745d800ed5dc3607673 /src/command/client/search/event.rs
parentAdd index for interactive search (#493) (diff)
downloadatuin-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.rs70
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()
+ }
+}