diff options
author | Tim Oram <dev@mitmaro.ca> | 2021-01-17 19:12:51 -0330 |
---|---|---|
committer | Tim Oram <dev@mitmaro.ca> | 2021-01-27 19:03:19 -0330 |
commit | 65ffadbe8481cd1c852f585fe1e14820f2c74f67 (patch) | |
tree | 470d17b0bc9faca6726fbd0f0120f2735bd47013 | |
parent | 8fd1c53e23d91ccb3051ab030042966eebe327f4 (diff) |
Add mutable to curses
-rw-r--r-- | Cargo.lock | 1 | ||||
-rw-r--r-- | Cargo.toml | 1 | ||||
-rw-r--r-- | src/confirm_abort/mod.rs | 11 | ||||
-rw-r--r-- | src/confirm_rebase/mod.rs | 6 | ||||
-rw-r--r-- | src/display/mod.rs | 198 | ||||
-rw-r--r-- | src/display/ncurses.rs | 20 | ||||
-rw-r--r-- | src/display/size.rs | 19 | ||||
-rw-r--r-- | src/display/testutil.rs | 16 | ||||
-rw-r--r-- | src/display/virtual_curses.rs | 21 | ||||
-rw-r--r-- | src/edit/mod.rs | 11 | ||||
-rw-r--r-- | src/external_editor/mod.rs | 104 | ||||
-rw-r--r-- | src/input/input_handler.rs | 47 | ||||
-rw-r--r-- | src/list/mod.rs | 11 | ||||
-rw-r--r-- | src/main.rs | 9 | ||||
-rw-r--r-- | src/process/error.rs | 6 | ||||
-rw-r--r-- | src/process/help.rs | 6 | ||||
-rw-r--r-- | src/process/mod.rs | 14 | ||||
-rw-r--r-- | src/process/modules.rs | 32 | ||||
-rw-r--r-- | src/process/process_module.rs | 8 | ||||
-rw-r--r-- | src/process/tests.rs | 80 | ||||
-rw-r--r-- | src/process/testutil.rs | 22 | ||||
-rw-r--r-- | src/process/window_size_error.rs | 6 | ||||
-rw-r--r-- | src/show_commit/mod.rs | 6 | ||||
-rw-r--r-- | src/view/mod.rs | 174 |
24 files changed, 385 insertions, 444 deletions
@@ -135,6 +135,7 @@ dependencies = [ "clap", "concat-idents", "git2", + "lazy_static", "num-format", "pancurses", "rstest", @@ -56,6 +56,7 @@ concat-idents = "1.1.2" rstest = "0.6.4" serial_test = "0.5.1" tempfile = "3.2.0" +lazy_static = "1.4.0" [features] default = [] diff --git a/src/confirm_abort/mod.rs b/src/confirm_abort/mod.rs index d0a05ac..a6e7d6d 100644 --- a/src/confirm_abort/mod.rs +++ b/src/confirm_abort/mod.rs @@ -1,4 +1,4 @@ -use crate::input::input_handler::{InputHandler, InputMode}; +use crate::input::input_handler::InputMode; use crate::input::Input; use crate::process::exit_status::ExitStatus; use crate::process::process_module::ProcessModule; @@ -21,13 +21,8 @@ impl ProcessModule for ConfirmAbort { &self.view_data } - fn handle_input( - &mut self, - input_handler: &InputHandler<'_>, - rebase_todo: &mut TodoFile, - _view: &View<'_>, - ) -> ProcessResult { - let input = input_handler.get_input(InputMode::Confirm); + fn handle_input(&mut self, view: &View<'_>, rebase_todo: &mut TodoFile) -> ProcessResult { + let input = view.get_input(InputMode::Confirm); let mut result = ProcessResult::new().input(input); match input { Input::Yes => { diff --git a/src/confirm_rebase/mod.rs b/src/confirm_rebase/mod.rs index 362a515..7da9484 100644 --- a/src/confirm_rebase/mod.rs +++ b/src/confirm_rebase/mod.rs @@ -1,4 +1,4 @@ -use crate::input::input_handler::{InputHandler, InputMode}; +use crate::input::input_handler::InputMode; use crate::input::Input; use crate::process::exit_status::ExitStatus; use crate::process::process_module::ProcessModule; @@ -21,8 +21,8 @@ impl ProcessModule for ConfirmRebase { &self.view_data } - fn handle_input(&mut self, input_handler: &InputHandler<'_>, _: &mut TodoFile, _view: &View<'_>) -> ProcessResult { - let input = input_handler.get_input(InputMode::Confirm); + fn handle_input(&mut self, view: &View<'_>, _: &mut TodoFile) -> ProcessResult { + let input = view.get_input(InputMode::Confirm); let mut result = ProcessResult::new().input(input); match input { Input::Yes => { diff --git a/src/display/mod.rs b/src/display/mod.rs index d8621b7..1d7fdfd 100644 --- a/src/display/mod.rs +++ b/src/display/mod.rs @@ -15,14 +15,17 @@ mod utils; use crate::config::theme::Theme; use crate::display::color_manager::ColorManager; -use crate::display::curses::{chtype, Curses, Input, A_DIM, A_REVERSE, A_UNDERLINE}; +use crate::display::curses::{chtype, Curses, A_DIM, A_REVERSE, A_UNDERLINE}; use crate::display::display_color::DisplayColor; pub use crate::display::size::Size; +use crate::input::input_handler::{InputHandler, InputMode}; +use crate::input::Input; use std::cell::RefCell; use std::convert::TryInto; pub struct Display<'d> { - curses: &'d Curses, + curses: &'d mut Curses, + input_handler: InputHandler<'d>, height: RefCell<usize>, width: RefCell<usize>, action_break: (chtype, chtype), @@ -43,7 +46,7 @@ pub struct Display<'d> { } impl<'d> Display<'d> { - pub(crate) fn new(curses: &'d mut Curses, theme: &'d Theme) -> Self { + pub(crate) fn new(input_handler: InputHandler<'d>, curses: &'d mut Curses, theme: &'d Theme) -> Self { let mut color_manager = ColorManager::new(); let normal = color_manager.register_selectable_color_pairs( curses, @@ -135,10 +138,15 @@ impl<'d> Display<'d> { theme.color_background, theme.color_selected_background, ); + + let height = curses.get_max_y().try_into().expect("Invalid window height"); + let width = curses.get_max_x().try_into().expect("Invalid window height"); + Self { curses, - height: RefCell::new(curses.get_max_y().try_into().expect("Invalid window height")), - width: RefCell::new(curses.get_max_x().try_into().expect("Invalid window width")), + input_handler, + height: RefCell::new(height), + width: RefCell::new(width), normal, indicator, action_break, @@ -157,21 +165,21 @@ impl<'d> Display<'d> { } } - pub(crate) fn draw_str(&self, s: &str) { + pub(crate) fn draw_str(&mut self, s: &str) { self.curses.addstr(s); } - pub(crate) fn clear(&self) { + pub(crate) fn clear(&mut self) { self.color(DisplayColor::Normal, false); self.set_style(false, false, false); self.curses.erase(); } - pub(crate) fn refresh(&self) { + pub(crate) fn refresh(&mut self) { self.curses.refresh(); } - pub(crate) fn color(&self, color: DisplayColor, selected: bool) { + pub(crate) fn color(&mut self, color: DisplayColor, selected: bool) { self.curses.attrset( if selected { match color { @@ -214,13 +222,13 @@ impl<'d> Display<'d> { ); } - pub(crate) fn set_style(&self, dim: bool, underline: bool, reverse: bool) { + pub(crate) fn set_style(&mut self, dim: bool, underline: bool, reverse: bool) { self.set_dim(dim); self.set_underline(underline); self.set_reverse(reverse); } - fn set_dim(&self, on: bool) { + fn set_dim(&mut self, on: bool) { if on { self.curses.attron(A_DIM); } @@ -229,7 +237,7 @@ impl<'d> Display<'d> { } } - fn set_underline(&self, on: bool) { + fn set_underline(&mut self, on: bool) { // Windows uses blue text for underlined words if !cfg!(windows) && on { self.curses.attron(A_UNDERLINE); @@ -239,7 +247,7 @@ impl<'d> Display<'d> { } } - fn set_reverse(&self, on: bool) { + fn set_reverse(&mut self, on: bool) { if on { self.curses.attron(A_REVERSE); } @@ -248,44 +256,43 @@ impl<'d> Display<'d> { } } - #[allow(clippy::unwrap_in_result)] - pub(crate) fn getch(&self) -> Option<Input> { - let input = self.curses.getch(); + pub(crate) fn get_input(&self, mode: InputMode) -> Input { + self.curses.getch().map_or(Input::Other, |input| { + let input = self.input_handler.get_input(mode, input); - if let Some(Input::KeyResize) = input { - self.curses.resize_term(0, 0); - self.height - .replace(self.curses.get_max_y().try_into().expect("Invalid window height")); - self.width - .replace(self.curses.get_max_x().try_into().expect("Invalid window width")); - } - input + if input == Input::Resize { + self.curses.resize_term(0, 0); + self.height + .replace(self.curses.get_max_y().try_into().expect("Invalid window height")); + self.width + .replace(self.curses.get_max_x().try_into().expect("Invalid window width")); + } + input + }) } pub(crate) fn get_window_size(&self) -> Size { Size::new(*self.width.borrow(), *self.height.borrow()) } - pub(crate) fn fill_end_of_line(&self) { + pub(crate) fn fill_end_of_line(&mut self) { self.curses.hline(' ', self.curses.get_max_x()); } - pub(crate) fn ensure_at_line_start(&self, y: i32) { + pub(crate) fn ensure_at_line_start(&mut self, y: i32) { self.curses.mv(y, 0); } - pub(crate) fn move_from_end_of_line(&self, right: i32) { + pub(crate) fn move_from_end_of_line(&mut self, right: i32) { self.curses.mv(self.curses.get_cur_y(), self.curses.get_max_x() - right); } - /// Leaves curses mode, runs the specified callback, and re-enables curses. - pub(crate) fn leave_temporarily<F, T>(&self, callback: F) -> T - where F: FnOnce() -> T { + pub(crate) fn def_prog_mode(&self) { self.curses.def_prog_mode(); - self.curses.endwin(); - let rv = callback(); + } + + pub(crate) fn reset_prog_mode(&self) { self.curses.reset_prog_mode(); - rv } pub(crate) fn end(&self) { @@ -301,7 +308,7 @@ mod tests { #[test] #[serial_test::serial()] fn windows_set_style_underline_disabled() { - display_module_test(|mut test_context: TestContext| { + display_module_test(|mut test_context: TestContext<'_>| { let display = Display::new(&mut test_context.curses, &test_context.config.theme); display.set_style(true, true, true); assert!(test_context.curses.is_dimmed()); @@ -314,6 +321,7 @@ mod tests { #[cfg(all(unix, test))] mod tests { use super::*; + use crate::display::curses::Input as CursesInput; use crate::display::testutil::{display_module_test, TestContext}; use crate::display::virtual_curses::State; use rstest::rstest; @@ -321,10 +329,14 @@ mod tests { #[test] #[serial_test::serial] fn draw_str() { - display_module_test(|mut test_context: TestContext| { - let display = Display::new(&mut test_context.curses, &test_context.config.theme); + display_module_test(|mut test_context: TestContext<'_>| { + let mut display = Display::new( + test_context.input_handler, + &mut test_context.curses, + &test_context.config.theme, + ); display.draw_str("Test String"); - let output = test_context.curses.get_output(); + let output = Curses::get_output(); assert_eq!(output, vec!["Test String"]); }); } @@ -332,15 +344,19 @@ mod tests { #[test] #[serial_test::serial] fn clear() { - display_module_test(|mut test_context: TestContext| { + display_module_test(|mut test_context: TestContext<'_>| { test_context.curses.addstr("Test String"); test_context.curses.attron(curses::A_DIM); test_context.curses.attron(curses::A_REVERSE); test_context.curses.attron(curses::A_UNDERLINE); - let display = Display::new(&mut test_context.curses, &test_context.config.theme); + let mut display = Display::new( + test_context.input_handler, + &mut test_context.curses, + &test_context.config.theme, + ); display.clear(); - assert!(test_context.curses.get_output().is_empty()); + assert!(Curses::get_output().is_empty()); assert!(!test_context.curses.is_dimmed()); assert!(!test_context.curses.is_reverse()); assert!(!test_context.curses.is_underline()); @@ -350,8 +366,12 @@ mod tests { #[test] #[serial_test::serial] fn reset() { - display_module_test(|mut test_context: TestContext| { - let display = Display::new(&mut test_context.curses, &test_context.config.theme); + display_module_test(|mut test_context: TestContext<'_>| { + let mut display = Display::new( + test_context.input_handler, + &mut test_context.curses, + &test_context.config.theme, + ); display.refresh(); assert_eq!(test_context.curses.get_state(), State::Refreshed); }); @@ -394,8 +414,12 @@ mod tests { )] #[serial_test::serial()] fn color(display_color: DisplayColor, selected: bool, expected: chtype) { - display_module_test(|mut test_context: TestContext| { - let display = Display::new(&mut test_context.curses, &test_context.config.theme); + display_module_test(|mut test_context: TestContext<'_>| { + let mut display = Display::new( + test_context.input_handler, + &mut test_context.curses, + &test_context.config.theme, + ); display.color(display_color, selected); assert!(test_context.curses.is_color_enabled(expected)); }); @@ -416,8 +440,12 @@ mod tests { )] #[serial_test::serial()] fn style(dim: bool, underline: bool, reverse: bool) { - display_module_test(|mut test_context: TestContext| { - let display = Display::new(&mut test_context.curses, &test_context.config.theme); + display_module_test(|mut test_context: TestContext<'_>| { + let mut display = Display::new( + test_context.input_handler, + &mut test_context.curses, + &test_context.config.theme, + ); display.set_style(dim, underline, reverse); assert_eq!(test_context.curses.is_dimmed(), dim); assert_eq!(test_context.curses.is_underline(), underline); @@ -428,20 +456,28 @@ mod tests { #[test] #[serial_test::serial] fn getch_normal_input() { - display_module_test(|mut test_context: TestContext| { - test_context.curses.set_inputs(vec![Input::Character('z')]); - let display = Display::new(&mut test_context.curses, &test_context.config.theme); - assert_eq!(display.getch().unwrap(), Input::Character('z')); + display_module_test(|mut test_context: TestContext<'_>| { + test_context.curses.set_inputs(vec![CursesInput::Character('z')]); + let display = Display::new( + test_context.input_handler, + &mut test_context.curses, + &test_context.config.theme, + ); + assert_eq!(display.get_input(InputMode::Default), Input::Character('z')); }); } #[test] #[serial_test::serial] - fn getch_resize() { - display_module_test(|mut test_context: TestContext| { - test_context.curses.set_inputs(vec![Input::KeyResize]); - let display = Display::new(&mut test_context.curses, &test_context.config.theme); - assert_eq!(display.getch().unwrap(), Input::KeyResize); + fn get_input_resize() { + display_module_test(|mut test_context: TestContext<'_>| { + test_context.curses.set_inputs(vec![CursesInput::KeyResize]); + let display = Display::new( + test_context.input_handler, + &mut test_context.curses, + &test_context.config.theme, + ); + assert_eq!(display.get_input(InputMode::Default), Input::Resize); assert_eq!(test_context.curses.get_state(), State::Resized); }); } @@ -449,9 +485,13 @@ mod tests { #[test] #[serial_test::serial] fn get_window_size() { - display_module_test(|mut test_context: TestContext| { + display_module_test(|mut test_context: TestContext<'_>| { test_context.curses.resize_term(10, 12); - let display = Display::new(&mut test_context.curses, &test_context.config.theme); + let display = Display::new( + test_context.input_handler, + &mut test_context.curses, + &test_context.config.theme, + ); assert_eq!(display.get_window_size(), Size::new(12, 10)); }); } @@ -459,21 +499,29 @@ mod tests { #[test] #[serial_test::serial] fn fill_end_of_line() { - display_module_test(|mut test_context: TestContext| { + display_module_test(|mut test_context: TestContext<'_>| { test_context.curses.resize_term(10, 23); - let display = Display::new(&mut test_context.curses, &test_context.config.theme); + let mut display = Display::new( + test_context.input_handler, + &mut test_context.curses, + &test_context.config.theme, + ); display.fill_end_of_line(); - assert_eq!(test_context.curses.get_output()[0], "{HLINE| |23}"); + assert_eq!(Curses::get_output()[0], "{HLINE| |23}"); }); } #[test] #[serial_test::serial] fn ensure_at_line_start() { - display_module_test(|mut test_context: TestContext| { + display_module_test(|mut test_context: TestContext<'_>| { test_context.curses.resize_term(5, 25); test_context.curses.mv(10, 12); - let display = Display::new(&mut test_context.curses, &test_context.config.theme); + let mut display = Display::new( + test_context.input_handler, + &mut test_context.curses, + &test_context.config.theme, + ); display.ensure_at_line_start(5); assert_eq!(test_context.curses.get_cur_y(), 5); assert_eq!(test_context.curses.get_cur_x(), 0); @@ -483,10 +531,14 @@ mod tests { #[test] #[serial_test::serial] fn move_from_end_of_line() { - display_module_test(|mut test_context: TestContext| { + display_module_test(|mut test_context: TestContext<'_>| { test_context.curses.resize_term(5, 25); test_context.curses.mv(5, 20); - let display = Display::new(&mut test_context.curses, &test_context.config.theme); + let mut display = Display::new( + test_context.input_handler, + &mut test_context.curses, + &test_context.config.theme, + ); display.move_from_end_of_line(5); assert_eq!(test_context.curses.get_cur_x(), 20); }); @@ -494,19 +546,13 @@ mod tests { #[test] #[serial_test::serial] - fn leave_temporarily() { - display_module_test(|mut test_context: TestContext| { - let display = Display::new(&mut test_context.curses, &test_context.config.theme); - assert_eq!(display.leave_temporarily(|| "Done"), "Done"); - assert_eq!(test_context.curses.get_state(), State::Normal); - }); - } - - #[test] - #[serial_test::serial] fn end() { - display_module_test(|mut test_context: TestContext| { - let display = Display::new(&mut test_context.curses, &test_context.config.theme); + display_module_test(|mut test_context: TestContext<'_>| { + let display = Display::new( + test_context.input_handler, + &mut test_context.curses, + &test_context.config.theme, + ); display.end(); assert_eq!(test_context.curses.get_state(), State::Ended); }); diff --git a/src/display/ncurses.rs b/src/display/ncurses.rs index 731e592..bac101f 100644 --- a/src/display/ncurses.rs +++ b/src/display/ncurses.rs @@ -50,12 +50,12 @@ impl Curses { } #[allow(clippy::unused_self)] - pub(super) fn init_color(&self, index: i16, red: i16, green: i16, blue: i16) { + pub(super) fn init_color(&mut self, index: i16, red: i16, green: i16, blue: i16) { pancurses::init_color(index, red, green, blue); } #[allow(clippy::unused_self)] - pub(super) fn init_color_pair(&self, index: i16, foreground: i16, background: i16) -> chtype { + pub(super) fn init_color_pair(&mut self, index: i16, foreground: i16, background: i16) -> chtype { pancurses::init_pair(index, foreground, background); // curses seems to init a pair for i16 but read with u64 pancurses::COLOR_PAIR(index as chtype) @@ -65,27 +65,27 @@ impl Curses { &self.color_mode } - pub(super) fn erase(&self) { + pub(super) fn erase(&mut self) { self.window.erase(); } - pub(super) fn refresh(&self) { + pub(super) fn refresh(&mut self) { self.window.refresh(); } - pub(super) fn addstr(&self, s: &str) { + pub(super) fn addstr(&mut self, s: &str) { self.window.addstr(s); } - pub(super) fn attrset<T: Into<chtype>>(&self, attributes: T) { + pub(super) fn attrset<T: Into<chtype>>(&mut self, attributes: T) { self.window.attrset(attributes); } - pub(super) fn attron<T: Into<chtype>>(&self, attributes: T) { + pub(super) fn attron<T: Into<chtype>>(&mut self, attributes: T) { self.window.attron(attributes); } - pub(super) fn attroff<T: Into<chtype>>(&self, attributes: T) { + pub(super) fn attroff<T: Into<chtype>>(&mut self, attributes: T) { self.window.attroff(attributes); } @@ -105,11 +105,11 @@ impl Curses { self.window.get_max_x() } - pub(crate) fn hline(&self, ch: char, width: i32) { + pub(crate) fn hline(&mut self, ch: char, width: i32) { self.window.hline(ch, width); } - pub(crate) fn mv(&self, y: i32, x: i32) { + pub(crate) fn mv(&mut self, y: i32, x: i32) { self.window.mv(y, x); } diff --git a/src/display/size.rs b/src/display/size.rs new file mode 100644 index 0000000..7509f48 --- /dev/null +++ b/src/display/size.rs @@ -0,0 +1,19 @@ +#[derive(Debug, PartialEq)] +pub struct Size { + width: usize, + height: usize, +} + +impl Size { + pub const fn new(width: usize, height: usize) -> Self { + Self { width, height } + } + + pub const fn width(&self) -> usize { + self.width + } + + pub const fn height(&self) -> usize { + self.height + } +} diff --git a/src/display/testutil.rs b/src/display/testutil.rs index 3b1ddfe..e0d9e2f 100644 --- a/src/display/testutil.rs +++ b/src/display/testutil.rs @@ -1,15 +1,17 @@ use crate::config::Config; use crate::display::curses::Curses; +use crate::input::input_handler::InputHandler; use std::env::set_var; use std::path::Path; -pub struct TestContext { - pub config: Config, +pub struct TestContext<'t> { + pub config: &'t Config, pub curses: Curses, + pub input_handler: InputHandler<'t>, } pub fn display_module_test<F>(callback: F) -where F: FnOnce(TestContext) { +where F: FnOnce(TestContext<'_>) { set_var( "GIT_DIR", Path::new(env!("CARGO_MANIFEST_DIR")) @@ -21,5 +23,11 @@ where F: FnOnce(TestContext) { ); let config = Config::new().unwrap(); let curses = Curses::new(); - callback(TestContext { config, curses }); + curses.erase(); + let input_handler = InputHandler::new(&config.key_bindings); + callback(TestContext { + config: &config, + curses, + input_handler, + }); } diff --git a/src/display/virtual_curses.rs b/src/display/virtual_curses.rs index 39d2d63..6497de0 100644 --- a/src/display/virtual_curses.rs +++ b/src/display/virtual_curses.rs @@ -1,7 +1,9 @@ use crate::display::color_mode::ColorMode; use crate::display::utils::detect_color_mode; +use lazy_static::lazy_static; pub use pancurses::{chtype, Input}; use std::cell::RefCell; +use std::sync::Mutex; pub const A_DIM: chtype = 64; pub const A_REVERSE: chtype = 128; @@ -15,6 +17,10 @@ pub const COLOR_MAGENTA: i16 = 5; pub const COLOR_CYAN: i16 = 6; pub const COLOR_WHITE: i16 = 7; +lazy_static! { + static ref OUTPUT: Mutex<Vec<String>> = Mutex::new(vec![]); +} + #[derive(Copy, Clone, Debug, PartialEq)] pub enum State { Normal, @@ -30,7 +36,6 @@ pub struct Curses { color_pairs: [(i16, i16); 255], colors: [(i16, i16, i16); 255], input: RefCell<Vec<Input>>, - output: RefCell<Vec<String>>, position: RefCell<(i32, i32)>, size: RefCell<(i32, i32)>, state: RefCell<State>, @@ -44,7 +49,6 @@ impl Curses { color_pairs: [(0, 0); 255], colors: [(0, 0, 0); 255], input: RefCell::new(vec![Input::KeyExit]), - output: RefCell::new(vec![]), position: RefCell::new((0, 0)), size: RefCell::new((10, 10)), state: RefCell::new(State::Normal), @@ -57,8 +61,8 @@ impl Curses { &self.colors } - pub(crate) fn get_output(&self) -> Vec<String> { - self.output.borrow().clone() + pub(crate) fn get_output() -> Vec<String> { + OUTPUT.lock().unwrap().clone() } pub(crate) const fn get_color_pairs(&self) -> &[(i16, i16); 255] { @@ -109,16 +113,18 @@ impl Curses { &self.color_mode } + #[allow(clippy::unused_self)] pub(super) fn erase(&self) { - self.output.borrow_mut().clear(); + OUTPUT.lock().unwrap().clear(); } pub(super) fn refresh(&self) { self.state.replace(State::Refreshed); } + #[allow(clippy::unused_self)] pub(super) fn addstr(&self, s: &str) { - self.output.borrow_mut().push(String::from(s)); + OUTPUT.lock().unwrap().push(String::from(s)); } pub(super) fn attrset<T: Into<chtype>>(&self, attributes: T) { @@ -158,8 +164,9 @@ impl Curses { (*self.size.borrow()).1 } + #[allow(clippy::unused_self)] pub(crate) fn hline(&self, ch: char, width: i32) { - self.output.borrow_mut().push(format!("{{HLINE|{}|{}}}", ch, width)); + OUTPUT.lock().unwrap().push(format!("{{HLINE|{}|{}}}", ch, width)); } pub(crate) fn mv(&self, y: i32, x: i32) { diff --git a/src/edit/mod.rs b/src/edit/mod.rs index fc67f50..8ea6b47 100644 --- a/src/edit/mod.rs +++ b/src/edit/mod.rs @@ -1,5 +1,5 @@ use crate::display::display_color::DisplayColor; -use crate::input::input_handler::{InputHandler, InputMode}; +use crate::input::input_handler::InputMode; use crate::input::Input; use crate::process::process_module::ProcessModule; use crate::process::process_result::ProcessResult; @@ -70,14 +70,9 @@ impl ProcessModule for Edit { &self.view_data } - fn handle_input( - &mut self, - input_handler: &InputHandler<'_>, - todo_file: &mut TodoFile, - view: &View<'_>, - ) -> ProcessResult { + fn handle_input(&mut self, view: &View<'_>, todo_file: &mut TodoFile) -> ProcessResult { let result = loop { - let input = input_handler.get_input(InputMode::Raw); + let input = view.get_input(InputMode::Raw); let result = ProcessResult::new().input(input); match input { Input::Character(c) => { diff --git a/src/external_editor/mod.rs b/src/external_editor/mod.rs index f61973f..3a0d5e1 100644 --- a/src/external_editor/mod.rs +++ b/src/external_editor/mod.rs @@ -1,9 +1,8 @@ mod argument_tolkenizer; use crate::display::display_color::DisplayColor; -use crate::display::Display; use crate::external_editor::argument_tolkenizer::tolkenize; -use crate::input::input_handler::{InputHandler, InputMode}; +use crate::input::input_handler::InputMode; use crate::input::Input; use crate::process::exit_status::ExitStatus; use crate::process::process_module::ProcessModule; @@ -27,16 +26,15 @@ enum ExternalEditorState { Error(Error), } -pub struct ExternalEditor<'e> { +pub struct ExternalEditor { editor: String, - display: &'e Display<'e>, state: ExternalEditorState, view_data: ViewData, invalid_selection: bool, lines: Vec<Line>, } -impl<'e> ProcessModule for ExternalEditor<'e> { +impl ProcessModule for ExternalEditor { fn activate(&mut self, todo_file: &TodoFile, _: State) -> ProcessResult { let mut result = ProcessResult::new(); self.state = ExternalEditorState::Active; @@ -110,16 +108,11 @@ impl<'e> ProcessModule for ExternalEditor<'e> { &self.view_data } - fn handle_input( - &mut self, - input_handler: &InputHandler<'_>, - todo_file: &mut TodoFile, - view: &View<'_>, - ) -> ProcessResult { + fn handle_input(&mut self, view: &View<'_>, todo_file: &mut TodoFile) -> ProcessResult { let mut result = ProcessResult::new(); match self.state { ExternalEditorState::Active => { - if let Err(e) = self.run_editor(todo_file) { + if let Err(e) = self.run_editor(view, todo_file) { self.state = ExternalEditorState::Error(e); } else { @@ -138,7 +131,7 @@ impl<'e> ProcessModule for ExternalEditor<'e> { result = result.input(Input::Other); }, ExternalEditorState::Empty => { - let input = input_handler.get_input(InputMode::Default); + let input = view.get_input(InputMode::Default); result = result.input(input); if let Some(input) = self.handle_standard_inputs(view, input) { self.invalid_selection = false; @@ -154,7 +147,7 @@ impl<'e> ProcessModule for ExternalEditor<'e> { } }, ExternalEditorState::Error(_) => { - let input = input_handler.get_input(InputMode::Default); + let input = view.get_input(InputMode::Default); result = result.input(input); if let Some(input) = self.handle_standard_inputs(view, input) { self.invalid_selection = false; @@ -184,14 +177,13 @@ impl<'e> ProcessModule for ExternalEditor<'e> { } } -impl<'e> ExternalEditor<'e> { - pub(crate) fn new(display: &'e Display<'_>, editor: &str) -> Self { +impl ExternalEditor { + pub(crate) fn new(editor: &str) -> Self { let mut view_data = ViewData::new(); view_data.set_show_title(true); Self { editor: String::from(editor), - display, state: ExternalEditorState::Active, view_data, invalid_selection: false, @@ -215,7 +207,7 @@ impl<'e> ExternalEditor<'e> { None } - fn run_editor(&mut self, todo_file: &TodoFile) -> Result<()> { + fn run_editor(&mut self, view: &View<'_>, todo_file: &TodoFile) -> Result<()> { let mut arguments = tolkenize(self.editor.as_str()) .map_or(Err(anyhow!("Invalid editor: \"{}\"", self.editor)), |args| { if args.is_empty() { @@ -245,7 +237,7 @@ impl<'e> ExternalEditor<'e> { } cmd.status().map_err(|e| anyhow!(e).context("Unable to run editor")) }; - let exit_status: ProcessExitStatus = self.display.leave_temporarily(callback)?; + let exit_status: ProcessExitStatus = view.leave_temporarily(callback)?; if !exit_status.success() { return Err(anyhow!("Editor returned a non-zero exit status")); @@ -319,10 +311,7 @@ mod te |