summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSebastian Thiel <sebastian.thiel@icloud.com>2020-03-29 11:30:18 +0800
committerSebastian Thiel <sebastian.thiel@icloud.com>2020-03-29 11:30:18 +0800
commit7f32fb9a70dd9b7078ae4db8e465d6762336048a (patch)
treea84913ea9447e0108e577c0d33e0238db376605b
parent9824585960f09729c5547d60edaea5d97fdb595f (diff)
Asynchronous processing of keyboard events…
…to pave the way for async handling of initial traversal and events, that is, processing both at the same time.
-rw-r--r--Cargo.lock1
-rw-r--r--Cargo.toml1
-rw-r--r--src/interactive/app/eventloop.rs108
3 files changed, 67 insertions, 43 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 0ce69b2..631a529 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -186,6 +186,7 @@ version = "2.3.9"
dependencies = [
"atty",
"byte-unit",
+ "crossbeam-channel",
"failure",
"failure-tools",
"filesize",
diff --git a/Cargo.toml b/Cargo.toml
index 4bfa1c4..11ab704 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -26,6 +26,7 @@ tui-react = { path = "./tui-react", version = "0.2" }
num_cpus = "1.10.0"
unicode-segmentation = "1.3.0"
filesize = "0.2.0"
+crossbeam-channel = "0.4.2"
[[bin]]
name="dua"
diff --git a/src/interactive/app/eventloop.rs b/src/interactive/app/eventloop.rs
index 88f2c11..db6014e 100644
--- a/src/interactive/app/eventloop.rs
+++ b/src/interactive/app/eventloop.rs
@@ -45,6 +45,11 @@ pub struct TerminalApp {
pub window: MainWindow,
}
+/// A set of events that multiple kinds of input sources
+enum Event {
+ Key(Key),
+}
+
impl TerminalApp {
pub fn draw_window<B>(
window: &mut MainWindow,
@@ -73,7 +78,7 @@ impl TerminalApp {
pub fn process_events<B>(
&mut self,
mut terminal: Terminal<B>,
- keys: impl Iterator<Item = Result<Key, io::Error>>,
+ keys: impl Iterator<Item = Result<Key, io::Error>> + Send + 'static,
) -> Result<WalkResult, Error>
where
B: Backend,
@@ -81,53 +86,70 @@ impl TerminalApp {
use termion::event::Key::*;
use FocussedPane::*;
+ let (keys_tx, keys_rx) = crossbeam_channel::bounded(1);
+ std::thread::spawn(move || {
+ for key in keys.filter_map(Result::ok) {
+ if keys_tx.send(Event::Key(key)).is_err() {
+ break;
+ }
+ }
+ });
+
self.draw(&mut terminal)?;
- for key in keys.filter_map(Result::ok) {
+ for event in keys_rx {
self.update_message();
- match key {
- Char('?') => self.toggle_help_pane(),
- Char('\t') => {
- self.cycle_focus();
- }
- Ctrl('c') => break,
- Char('q') | Esc => match self.state.focussed {
- Main => {
- drop(terminal);
- io::stdout().flush().ok();
- // Exit 'quickly' to avoid having to wait for all memory to be freed by us.
- // Let the OS do it - we have nothing to lose, literally.
- std::process::exit(0);
- }
- Mark => self.state.focussed = Main,
- Help => {
- self.state.focussed = Main;
- self.window.help_pane = None
+ match event {
+ Event::Key(key) => {
+ match key {
+ Char('?') => self.toggle_help_pane(),
+ Char('\t') => {
+ self.cycle_focus();
+ }
+ Ctrl('c') => break,
+ Char('q') | Esc => match self.state.focussed {
+ Main => {
+ drop(terminal);
+ io::stdout().flush().ok();
+ // Exit 'quickly' to avoid having to wait for all memory to be freed by us.
+ // Let the OS do it - we have nothing to lose, literally.
+ std::process::exit(0);
+ }
+ Mark => self.state.focussed = Main,
+ Help => {
+ self.state.focussed = Main;
+ self.window.help_pane = None
+ }
+ },
+ _ => {}
}
- },
- _ => {}
- }
- match self.state.focussed {
- FocussedPane::Mark => self.dispatch_to_mark_pane(key, &mut terminal),
- FocussedPane::Help => {
- self.window.help_pane.as_mut().expect("help pane").key(key);
+ match self.state.focussed {
+ FocussedPane::Mark => self.dispatch_to_mark_pane(key, &mut terminal),
+ FocussedPane::Help => {
+ self.window.help_pane.as_mut().expect("help pane").key(key);
+ }
+ FocussedPane::Main => match key {
+ Char('O') => self.open_that(),
+ Char(' ') => self.mark_entry(false),
+ Char('d') => self.mark_entry(true),
+ Char('u') | Char('h') | Backspace | Left => self.exit_node(),
+ Char('o') | Char('l') | Char('\n') | Right => self.enter_node(),
+ Ctrl('u') | PageUp => {
+ self.change_entry_selection(CursorDirection::PageUp)
+ }
+ Char('k') | Up => self.change_entry_selection(CursorDirection::Up),
+ Char('j') | Down => self.change_entry_selection(CursorDirection::Down),
+ Ctrl('d') | PageDown => {
+ self.change_entry_selection(CursorDirection::PageDown)
+ }
+ Char('s') => self.cycle_sorting(),
+ Char('g') => self.display.byte_vis.cycle(),
+ _ => {}
+ },
+ };
+ self.draw(&mut terminal)?;
}
- FocussedPane::Main => match key {
- Char('O') => self.open_that(),
- Char(' ') => self.mark_entry(false),
- Char('d') => self.mark_entry(true),
- Char('u') | Char('h') | Backspace | Left => self.exit_node(),
- Char('o') | Char('l') | Char('\n') | Right => self.enter_node(),
- Ctrl('u') | PageUp => self.change_entry_selection(CursorDirection::PageUp),
- Char('k') | Up => self.change_entry_selection(CursorDirection::Up),
- Char('j') | Down => self.change_entry_selection(CursorDirection::Down),
- Ctrl('d') | PageDown => self.change_entry_selection(CursorDirection::PageDown),
- Char('s') => self.cycle_sorting(),
- Char('g') => self.display.byte_vis.cycle(),
- _ => {}
- },
- };
- self.draw(&mut terminal)?;
+ }
}
Ok(WalkResult {
num_errors: self.traversal.io_errors,