Refactor code

This commit is contained in:
Dheepak Krishnamurthy 2020-10-12 03:42:09 -06:00
parent 0d97502e64
commit 199dbe1153
3 changed files with 247 additions and 448 deletions

View file

@ -29,6 +29,14 @@ use tui::{
use rustyline::error::ReadlineError;
use rustyline::line_buffer::LineBuffer;
use rustyline::Editor;
use rustyline::At;
use rustyline::Word;
use crate::util::Key;
use crate::util::Events;
use tui::{backend::CrosstermBackend, Terminal};
use std::io::{self};
const MAX_LINE: usize = 4096;
@ -1297,6 +1305,244 @@ impl TTApp {
}
}
}
pub fn handle_input(&mut self, input: Key, terminal: &mut Terminal<CrosstermBackend<io::Stdout>>, events: &Events) {
match self.mode {
AppMode::TaskReport => match input {
Key::Ctrl('c') | Key::Char('q') => self.should_quit = true,
Key::Char(']') => {
self.mode = AppMode::Calendar;
}
Key::Char('r') => self.update(),
Key::Down | Key::Char('j') => self.next(),
Key::Up | Key::Char('k') => self.previous(),
Key::Char('d') => match self.task_done() {
Ok(_) => self.update(),
Err(e) => {
self.mode = AppMode::TaskError;
self.error = e;
}
},
Key::Char('x') => match self.task_delete() {
Ok(_) => self.update(),
Err(e) => {
self.mode = AppMode::TaskError;
self.error = e;
}
},
Key::Char('s') => match self.task_start_or_stop() {
Ok(_) => self.update(),
Err(e) => {
self.mode = AppMode::TaskError;
self.error = e;
}
},
Key::Char('u') => match self.task_undo() {
Ok(_) => self.update(),
Err(e) => {
self.mode = AppMode::TaskError;
self.error = e;
}
},
Key::Char('e') => {
events.pause_event_loop(terminal);
let r = self.task_edit();
events.resume_event_loop(terminal);
match r {
Ok(_) => self.update(),
Err(e) => {
self.mode = AppMode::TaskError;
self.error = e;
}
}
}
Key::Char('m') => {
self.mode = AppMode::TaskModify;
match self.task_current() {
Some(t) => self.modify.update(t.description(), t.description().len()),
None => self.modify.update("", 0),
}
}
Key::Char('!') => {
self.mode = AppMode::TaskSubprocess;
}
Key::Char('l') => {
self.mode = AppMode::TaskLog;
}
Key::Char('a') => {
self.mode = AppMode::TaskAdd;
}
Key::Char('A') => {
self.mode = AppMode::TaskAnnotate;
}
Key::Char('?') => {
self.mode = AppMode::TaskHelpPopup;
}
Key::Char('/') => {
self.mode = AppMode::TaskFilter;
}
_ => {}
},
AppMode::TaskHelpPopup => match input {
Key::Esc => {
self.mode = AppMode::TaskReport;
}
_ => {}
},
AppMode::TaskModify => match input {
Key::Char('\n') => match self.task_modify() {
Ok(_) => {
self.mode = AppMode::TaskReport;
self.update();
}
Err(e) => {
self.mode = AppMode::TaskError;
self.error = e;
}
},
Key::Esc => {
self.modify.update("", 0);
self.mode = AppMode::TaskReport;
}
_ => handle_movement(&mut self.modify, input),
},
AppMode::TaskSubprocess => match input {
Key::Char('\n') => match self.task_subprocess() {
Ok(_) => {
self.mode = AppMode::TaskReport;
self.update();
}
Err(e) => {
self.mode = AppMode::TaskError;
self.error = e;
}
},
Key::Esc => {
self.command.update("", 0);
self.mode = AppMode::TaskReport;
}
_ => handle_movement(&mut self.command, input),
},
AppMode::TaskLog => match input {
Key::Char('\n') => match self.task_log() {
Ok(_) => {
self.mode = AppMode::TaskReport;
self.update();
}
Err(e) => {
self.mode = AppMode::TaskError;
self.error = e;
}
},
Key::Esc => {
self.command.update("", 0);
self.mode = AppMode::TaskReport;
}
_ => handle_movement(&mut self.command, input),
},
AppMode::TaskAnnotate => match input {
Key::Char('\n') => match self.task_annotate() {
Ok(_) => {
self.mode = AppMode::TaskReport;
self.update();
}
Err(e) => {
self.mode = AppMode::TaskError;
self.error = e;
}
},
Key::Esc => {
self.command.update("", 0);
self.mode = AppMode::TaskReport;
}
_ => handle_movement(&mut self.command, input),
},
AppMode::TaskAdd => match input {
Key::Char('\n') => match self.task_add() {
Ok(_) => {
self.mode = AppMode::TaskReport;
self.update();
}
Err(e) => {
self.mode = AppMode::TaskError;
self.error = e;
}
},
Key::Esc => {
self.command.update("", 0);
self.mode = AppMode::TaskReport;
}
_ => handle_movement(&mut self.command, input),
},
AppMode::TaskFilter => match input {
Key::Char('\n') | Key::Esc => {
self.mode = AppMode::TaskReport;
self.update();
}
_ => handle_movement(&mut self.command, input),
},
AppMode::TaskError => match input {
_ => {
self.mode = AppMode::TaskReport;
}
},
AppMode::Calendar => match input {
Key::Char('[') => {
self.mode = AppMode::TaskReport;
}
Key::Ctrl('c') | Key::Char('q') => self.should_quit = true,
_ => {}
},
}
}
}
pub fn handle_movement(linebuffer: &mut LineBuffer, input: Key) {
match input {
Key::Ctrl('f') | Key::Right => {
linebuffer.move_forward(1);
}
Key::Ctrl('b') | Key::Left => {
linebuffer.move_backward(1);
}
Key::Char(c) => {
linebuffer.insert(c, 1);
}
Key::Ctrl('h') | Key::Backspace => {
linebuffer.backspace(1);
}
Key::Ctrl('d') | Key::Delete => {
linebuffer.delete(1);
}
Key::Ctrl('a') | Key::Home => {
linebuffer.move_home();
}
Key::Ctrl('e') | Key::End => {
linebuffer.move_end();
}
Key::Ctrl('k') => {
linebuffer.kill_line();
}
Key::Ctrl('u') => {
linebuffer.discard_line();
}
Key::Ctrl('w') => {
linebuffer.delete_prev_word(Word::Emacs, 1);
}
Key::Alt('d') => {
linebuffer.delete_word(At::AfterEnd, Word::Emacs, 1);
}
Key::Alt('f') => {
linebuffer.move_to_next_word(At::AfterEnd, Word::Emacs, 1);
}
Key::Alt('b') => {
linebuffer.move_to_prev_word(Word::Emacs, 1);
}
Key::Alt('t') => {
linebuffer.transpose_words(1);
}
_ => {}
}
}
pub fn add_tag(task: &mut Task, tag: String) {

View file

@ -19,9 +19,6 @@ use app::{AppMode, TTApp};
const APP_VERSION: &str = env!("CARGO_PKG_VERSION");
const APP_NAME: &str = env!("CARGO_PKG_NAME");
use rustyline::At;
use rustyline::Word;
fn main() -> Result<(), Box<dyn Error>> {
let matches = App::new(APP_NAME)
.version(APP_VERSION)
@ -60,445 +57,7 @@ fn tui_main(_config: &str) -> Result<(), Box<dyn Error>> {
// Handle input
match events.next()? {
Event::Input(input) => match app.mode {
AppMode::TaskReport => match input {
Key::Ctrl('c') | Key::Char('q') => app.should_quit = true,
Key::Char(']') => {
app.mode = AppMode::Calendar;
}
Key::Char('r') => app.update(),
Key::Down | Key::Char('j') => app.next(),
Key::Up | Key::Char('k') => app.previous(),
Key::Char('d') => match app.task_done() {
Ok(_) => app.update(),
Err(e) => {
app.mode = AppMode::TaskError;
app.error = e;
}
},
Key::Char('x') => match app.task_delete() {
Ok(_) => app.update(),
Err(e) => {
app.mode = AppMode::TaskError;
app.error = e;
}
},
Key::Char('s') => match app.task_start_or_stop() {
Ok(_) => app.update(),
Err(e) => {
app.mode = AppMode::TaskError;
app.error = e;
}
},
Key::Char('u') => match app.task_undo() {
Ok(_) => app.update(),
Err(e) => {
app.mode = AppMode::TaskError;
app.error = e;
}
},
Key::Char('e') => {
events.pause_event_loop(&mut terminal);
let r = app.task_edit();
events.resume_event_loop(&mut terminal);
match r {
Ok(_) => app.update(),
Err(e) => {
app.mode = AppMode::TaskError;
app.error = e;
}
}
}
Key::Char('m') => {
app.mode = AppMode::TaskModify;
match app.task_current() {
Some(t) => app.modify.update(t.description(), t.description().len()),
None => app.modify.update("", 0),
}
}
Key::Char('!') => {
app.mode = AppMode::TaskSubprocess;
}
Key::Char('l') => {
app.mode = AppMode::TaskLog;
}
Key::Char('a') => {
app.mode = AppMode::TaskAdd;
}
Key::Char('A') => {
app.mode = AppMode::TaskAnnotate;
}
Key::Char('?') => {
app.mode = AppMode::TaskHelpPopup;
}
Key::Char('/') => {
app.mode = AppMode::TaskFilter;
}
_ => {}
},
AppMode::TaskHelpPopup => match input {
Key::Esc => {
app.mode = AppMode::TaskReport;
}
_ => {}
},
AppMode::TaskModify => match input {
Key::Char('\n') => match app.task_modify() {
Ok(_) => {
app.mode = AppMode::TaskReport;
app.update();
}
Err(e) => {
app.mode = AppMode::TaskError;
app.error = e;
}
},
Key::Esc => {
app.modify.update("", 0);
app.mode = AppMode::TaskReport;
}
Key::Ctrl('f') | Key::Right => {
app.modify.move_forward(1);
}
Key::Ctrl('b') | Key::Left => {
app.modify.move_backward(1);
}
Key::Char(c) => {
app.modify.insert(c, 1);
}
Key::Ctrl('h') | Key::Backspace => {
app.modify.backspace(1);
}
Key::Ctrl('d') | Key::Delete => {
app.modify.delete(1);
}
Key::Ctrl('a') | Key::Home => {
app.modify.move_home();
}
Key::Ctrl('e') | Key::End => {
app.modify.move_end();
}
Key::Ctrl('k') => {
app.modify.kill_line();
}
Key::Ctrl('u') => {
app.modify.discard_line();
}
Key::Ctrl('w') => {
app.modify.delete_prev_word(Word::Emacs, 1);
}
Key::Alt('d') => {
app.modify.delete_word(At::AfterEnd, Word::Emacs, 1);
}
Key::Alt('f') => {
app.modify.move_to_next_word(At::AfterEnd, Word::Emacs, 1);
}
Key::Alt('b') => {
app.modify.move_to_prev_word(Word::Emacs, 1);
}
Key::Alt('t') => {
app.modify.transpose_words(1);
}
_ => {}
},
AppMode::TaskSubprocess => match input {
Key::Char('\n') => match app.task_subprocess() {
Ok(_) => {
app.mode = AppMode::TaskReport;
app.update();
}
Err(e) => {
app.mode = AppMode::TaskError;
app.error = e;
}
},
Key::Esc => {
app.command.update("", 0);
app.mode = AppMode::TaskReport;
}
Key::Ctrl('f') | Key::Right => {
app.command.move_forward(1);
}
Key::Ctrl('b') | Key::Left => {
app.command.move_backward(1);
}
Key::Char(c) => {
app.command.insert(c, 1);
}
Key::Ctrl('h') | Key::Backspace => {
app.command.backspace(1);
}
Key::Ctrl('d') | Key::Delete => {
app.command.delete(1);
}
Key::Ctrl('a') | Key::Home => {
app.command.move_home();
}
Key::Ctrl('e') | Key::End => {
app.command.move_end();
}
Key::Ctrl('k') => {
app.command.kill_line();
}
Key::Ctrl('u') => {
app.command.discard_line();
}
Key::Ctrl('w') => {
app.command.delete_prev_word(Word::Emacs, 1);
}
Key::Alt('d') => {
app.command.delete_word(At::AfterEnd, Word::Emacs, 1);
}
Key::Alt('f') => {
app.command.move_to_next_word(At::AfterEnd, Word::Emacs, 1);
}
Key::Alt('b') => {
app.command.move_to_prev_word(Word::Emacs, 1);
}
Key::Alt('t') => {
app.command.transpose_words(1);
}
_ => {}
},
AppMode::TaskLog => match input {
Key::Char('\n') => match app.task_log() {
Ok(_) => {
app.mode = AppMode::TaskReport;
app.update();
}
Err(e) => {
app.mode = AppMode::TaskError;
app.error = e;
}
},
Key::Esc => {
app.command.update("", 0);
app.mode = AppMode::TaskReport;
}
Key::Ctrl('f') | Key::Right => {
app.command.move_forward(1);
}
Key::Ctrl('b') | Key::Left => {
app.command.move_backward(1);
}
Key::Char(c) => {
app.command.insert(c, 1);
}
Key::Ctrl('h') | Key::Backspace => {
app.command.backspace(1);
}
Key::Ctrl('d') | Key::Delete => {
app.command.delete(1);
}
Key::Ctrl('a') | Key::Home => {
app.command.move_home();
}
Key::Ctrl('e') | Key::End => {
app.command.move_end();
}
Key::Ctrl('k') => {
app.command.kill_line();
}
Key::Ctrl('u') => {
app.command.discard_line();
}
Key::Ctrl('w') => {
app.command.delete_prev_word(Word::Emacs, 1);
}
Key::Alt('d') => {
app.command.delete_word(At::AfterEnd, Word::Emacs, 1);
}
Key::Alt('f') => {
app.command.move_to_next_word(At::AfterEnd, Word::Emacs, 1);
}
Key::Alt('b') => {
app.command.move_to_prev_word(Word::Emacs, 1);
}
Key::Alt('t') => {
app.command.transpose_words(1);
}
_ => {}
},
AppMode::TaskAnnotate => match input {
Key::Char('\n') => match app.task_annotate() {
Ok(_) => {
app.mode = AppMode::TaskReport;
app.update();
}
Err(e) => {
app.mode = AppMode::TaskError;
app.error = e;
}
},
Key::Esc => {
app.command.update("", 0);
app.mode = AppMode::TaskReport;
}
Key::Ctrl('f') | Key::Right => {
app.command.move_forward(1);
}
Key::Ctrl('b') | Key::Left => {
app.command.move_backward(1);
}
Key::Char(c) => {
app.command.insert(c, 1);
}
Key::Ctrl('h') | Key::Backspace => {
app.command.backspace(1);
}
Key::Ctrl('d') | Key::Delete => {
app.command.delete(1);
}
Key::Ctrl('a') | Key::Home => {
app.command.move_home();
}
Key::Ctrl('e') | Key::End => {
app.command.move_end();
}
Key::Ctrl('k') => {
app.command.kill_line();
}
Key::Ctrl('u') => {
app.command.discard_line();
}
Key::Ctrl('w') => {
app.command.delete_prev_word(Word::Emacs, 1);
}
Key::Alt('d') => {
app.command.delete_word(At::AfterEnd, Word::Emacs, 1);
}
Key::Alt('f') => {
app.command.move_to_next_word(At::AfterEnd, Word::Emacs, 1);
}
Key::Alt('b') => {
app.command.move_to_prev_word(Word::Emacs, 1);
}
Key::Alt('t') => {
app.command.transpose_words(1);
}
_ => {}
},
AppMode::TaskAdd => match input {
Key::Char('\n') => match app.task_add() {
Ok(_) => {
app.mode = AppMode::TaskReport;
app.update();
}
Err(e) => {
app.mode = AppMode::TaskError;
app.error = e;
}
},
Key::Esc => {
app.command.update("", 0);
app.mode = AppMode::TaskReport;
}
Key::Ctrl('f') | Key::Right => {
app.command.move_forward(1);
}
Key::Ctrl('b') | Key::Left => {
app.command.move_backward(1);
}
Key::Char(c) => {
app.command.insert(c, 1);
}
Key::Ctrl('h') | Key::Backspace => {
app.command.backspace(1);
}
Key::Ctrl('d') | Key::Delete => {
app.command.delete(1);
}
Key::Ctrl('a') | Key::Home => {
app.command.move_home();
}
Key::Ctrl('e') | Key::End => {
app.command.move_end();
}
Key::Ctrl('k') => {
app.command.kill_line();
}
Key::Ctrl('u') => {
app.command.discard_line();
}
Key::Ctrl('w') => {
app.command.delete_prev_word(Word::Emacs, 1);
}
Key::Alt('d') => {
app.command.delete_word(At::AfterEnd, Word::Emacs, 1);
}
Key::Alt('f') => {
app.command.move_to_next_word(At::AfterEnd, Word::Emacs, 1);
}
Key::Alt('b') => {
app.command.move_to_prev_word(Word::Emacs, 1);
}
Key::Alt('t') => {
app.command.transpose_words(1);
}
_ => {}
},
AppMode::TaskFilter => match input {
Key::Char('\n') | Key::Esc => {
app.mode = AppMode::TaskReport;
app.update();
}
Key::Ctrl('f') | Key::Right => {
app.filter.move_forward(1);
}
Key::Ctrl('b') | Key::Left => {
app.filter.move_backward(1);
}
Key::Char(c) => {
app.filter.insert(c, 1);
}
Key::Ctrl('h') | Key::Backspace => {
app.filter.backspace(1);
}
Key::Ctrl('d') | Key::Delete => {
app.filter.delete(1);
}
Key::Ctrl('a') | Key::Home => {
app.filter.move_home();
}
Key::Ctrl('e') | Key::End => {
app.filter.move_end();
}
Key::Ctrl('k') => {
app.filter.kill_line();
}
Key::Ctrl('u') => {
app.filter.discard_line();
}
Key::Ctrl('w') => {
app.filter.delete_prev_word(Word::Emacs, 1);
}
Key::Alt('d') => {
app.filter.delete_word(At::AfterEnd, Word::Emacs, 1);
}
Key::Alt('f') => {
app.filter.move_to_next_word(At::AfterEnd, Word::Emacs, 1);
}
Key::Alt('b') => {
app.filter.move_to_prev_word(Word::Emacs, 1);
}
Key::Alt('t') => {
app.filter.transpose_words(1);
}
_ => {}
},
AppMode::TaskError => match input {
_ => {
app.mode = AppMode::TaskReport;
}
},
AppMode::Calendar => match input {
Key::Char('[') => {
app.mode = AppMode::TaskReport;
}
Key::Ctrl('c') | Key::Char('q') => app.should_quit = true,
_ => {}
},
},
Event::Input(input) => app.handle_input(input, &mut terminal, &events),
Event::Tick => app.update(),
}

View file

@ -1,10 +1,8 @@
#[cfg(feature = "crossterm")]
use crossterm::{
event::{self, DisableMouseCapture, EnableMouseCapture},
execute,
terminal::{disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen},
};
#[cfg(feature = "crossterm")]
use tui::{backend::CrosstermBackend, Terminal};
use std::io::{self, Write};
@ -44,7 +42,6 @@ pub enum Event<I> {
Tick,
}
#[cfg(feature = "crossterm")]
pub fn setup_terminal() -> Terminal<CrosstermBackend<io::Stdout>> {
enable_raw_mode().unwrap();
let mut stdout = io::stdout();
@ -53,7 +50,6 @@ pub fn setup_terminal() -> Terminal<CrosstermBackend<io::Stdout>> {
Terminal::new(backend).unwrap()
}
#[cfg(feature = "crossterm")]
pub fn destruct_terminal(mut terminal: Terminal<CrosstermBackend<io::Stdout>>) {
disable_raw_mode().unwrap();
execute!(io::stdout(), LeaveAlternateScreen, DisableMouseCapture).unwrap();
@ -132,7 +128,6 @@ impl Events {
self.rx.recv()
}
#[cfg(feature = "crossterm")]
pub fn pause_event_loop(&self, terminal: &mut Terminal<CrosstermBackend<io::Stdout>>) {
*self.pause_stdin.lock().unwrap() = true;
std::thread::sleep(std::time::Duration::from_millis(50));
@ -141,7 +136,6 @@ impl Events {
terminal.show_cursor().unwrap();
}
#[cfg(feature = "crossterm")]
pub fn resume_event_loop(&self, terminal: &mut Terminal<CrosstermBackend<io::Stdout>>) {
enable_raw_mode().unwrap();
execute!(io::stdout(), EnterAlternateScreen, EnableMouseCapture).unwrap();