Skip to content

Commit

Permalink
Asynchronous processing of keyboard events…
Browse files Browse the repository at this point in the history
…to pave the way for async handling of initial traversal and events,
that is, processing both at the same time.
  • Loading branch information
Byron committed Mar 29, 2020
1 parent 9824585 commit 7f32fb9
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 43 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
108 changes: 65 additions & 43 deletions src/interactive/app/eventloop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -73,61 +78,78 @@ 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,
{
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,
Expand Down

0 comments on commit 7f32fb9

Please sign in to comment.