diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/event.rs | 3 | ||||
-rw-r--r-- | src/history.rs | 11 | ||||
-rw-r--r-- | src/main.rs | 23 | ||||
-rw-r--r-- | src/readline.rs | 3 | ||||
-rw-r--r-- | src/state.rs | 66 |
5 files changed, 55 insertions, 51 deletions
diff --git a/src/event.rs b/src/event.rs index ca44239..62a12c8 100644 --- a/src/event.rs +++ b/src/event.rs @@ -6,7 +6,6 @@ pub enum Event { ProcessAlternateScreen, ProcessExit, ClockTimer, - Quit, } pub struct Reader { @@ -119,7 +118,7 @@ impl Pending { } Some(Event::ProcessExit) => self.process_exit = true, Some(Event::ClockTimer) => self.clock_timer = true, - Some(Event::Quit) | None => self.done = true, + None => self.done = true, } } } diff --git a/src/history.rs b/src/history.rs index 59cf822..048c1c7 100644 --- a/src/history.rs +++ b/src/history.rs @@ -2,7 +2,6 @@ use async_std::io::{ReadExt as _, WriteExt as _}; use futures_lite::future::FutureExt as _; use pty_process::Command as _; use std::os::unix::process::ExitStatusExt as _; -use textmode::Textmode as _; pub struct History { size: (u16, u16), @@ -21,7 +20,7 @@ impl History { pub async fn render( &self, - out: &mut textmode::Output, + out: &mut impl textmode::Textmode, repl_lines: usize, focus: Option<usize>, scrolling: bool, @@ -63,7 +62,7 @@ impl History { pub async fn render_fullscreen( &self, - out: &mut textmode::Output, + out: &mut impl textmode::Textmode, idx: usize, ) { let mut entry = self.entries[idx].lock_arc().await; @@ -271,7 +270,7 @@ impl Entry { fn render( &mut self, - out: &mut textmode::Output, + out: &mut impl textmode::Textmode, idx: usize, entry_count: usize, width: u16, @@ -386,7 +385,7 @@ impl Entry { out.reset_attributes(); } - fn render_fullscreen(&mut self, out: &mut textmode::Output) { + fn render_fullscreen(&mut self, out: &mut impl textmode::Textmode) { let screen = self.vt.screen(); let new_audible_bell_state = screen.audible_bell_count(); let new_visual_bell_state = screen.visual_bell_count(); @@ -406,7 +405,7 @@ impl Entry { out.reset_attributes(); } - fn set_bgcolor(&self, out: &mut textmode::Output, focus: bool) { + fn set_bgcolor(&self, out: &mut impl textmode::Textmode, focus: bool) { if focus { out.set_bgcolor(textmode::Color::Rgb(32, 32, 64)); } else { diff --git a/src/main.rs b/src/main.rs index 225b21b..20e805c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,5 +1,6 @@ #![warn(clippy::pedantic)] #![warn(clippy::nursery)] +#![allow(clippy::future_not_send)] #![allow(clippy::missing_const_for_fn)] #![allow(clippy::struct_excessive_bools)] #![allow(clippy::too_many_arguments)] @@ -17,6 +18,7 @@ mod state; mod util; use async_std::stream::StreamExt as _; +use textmode::Textmode as _; // the time crate is currently unable to get the local offset on unix due to // soundness concerns, so we have to do it manually/: @@ -61,7 +63,8 @@ async fn async_main() -> anyhow::Result<()> { let (event_w, event_r) = async_std::channel::unbounded(); let mut state = state::State::new(get_offset()); - state.render(&mut output, true).await.unwrap(); + state.render(&mut output).await.unwrap(); + output.hard_refresh().await?; { let mut signals = signal_hook_async_std::Signals::new(&[ @@ -109,7 +112,23 @@ async fn async_main() -> anyhow::Result<()> { let event_reader = event::Reader::new(event_r); while let Some(event) = event_reader.recv().await { - state.handle_event(event, &mut output, &event_w).await; + match state.handle_event(event, &event_w).await { + Some(state::Action::Refresh) => { + state.render(&mut output).await?; + output.refresh().await?; + } + Some(state::Action::HardRefresh) => { + state.render(&mut output).await?; + output.hard_refresh().await?; + } + Some(state::Action::Resize(rows, cols)) => { + output.set_size(rows, cols); + state.render(&mut output).await?; + output.hard_refresh().await?; + } + Some(state::Action::Quit) => break, + None => {} + } } Ok(()) diff --git a/src/readline.rs b/src/readline.rs index e13c00f..585d6b6 100644 --- a/src/readline.rs +++ b/src/readline.rs @@ -1,4 +1,3 @@ -use textmode::Textmode as _; use unicode_width::{UnicodeWidthChar as _, UnicodeWidthStr as _}; pub struct Readline { @@ -18,7 +17,7 @@ impl Readline { pub async fn render( &self, - out: &mut textmode::Output, + out: &mut impl textmode::Textmode, entry_count: usize, focus: bool, offset: time::UtcOffset, diff --git a/src/state.rs b/src/state.rs index a3d251b..cdc3cdb 100644 --- a/src/state.rs +++ b/src/state.rs @@ -1,5 +1,3 @@ -use textmode::Textmode as _; - #[derive(Copy, Clone, Debug)] enum Focus { Readline, @@ -13,6 +11,13 @@ enum Scene { Fullscreen, } +pub enum Action { + Refresh, + HardRefresh, + Resize(u16, u16), + Quit, +} + pub struct State { readline: crate::readline::Readline, history: crate::history::History, @@ -38,8 +43,7 @@ impl State { pub async fn render( &self, - out: &mut textmode::Output, - hard: bool, + out: &mut impl textmode::Textmode, ) -> anyhow::Result<()> { out.clear(); match self.scene { @@ -119,29 +123,22 @@ impl State { } } } - if hard { - out.hard_refresh().await?; - } else { - out.refresh().await?; - } Ok(()) } pub async fn handle_event( &mut self, event: crate::event::Event, - out: &mut textmode::Output, event_w: &async_std::channel::Sender<crate::event::Event>, - ) { - let mut hard_refresh = false; + ) -> Option<Action> { match event { crate::event::Event::Key(key) => { - let (quit, hard) = if self.escape { + return if self.escape { self.escape = false; self.handle_key_escape(key).await } else if key == textmode::Key::Ctrl(b'e') { self.escape = true; - (false, false) + None } else { match self.focus { Focus::Readline => { @@ -150,25 +147,18 @@ impl State { } Focus::History(idx) => { self.handle_key_history(key, idx).await; - (false, false) + None } Focus::Scrolling(_) => { self.handle_key_escape(key).await } } }; - if quit { - event_w.send(crate::event::Event::Quit).await.unwrap(); - } - if hard { - hard_refresh = true; - } } crate::event::Event::Resize(new_size) => { self.readline.resize(new_size).await; self.history.resize(new_size).await; - out.set_size(new_size.0, new_size.1); - hard_refresh = true; + return Some(Action::Resize(new_size.0, new_size.1)); } crate::event::Event::ProcessOutput => { // the number of visible lines may have changed, so make sure @@ -201,28 +191,24 @@ impl State { } } crate::event::Event::ClockTimer => {} - crate::event::Event::Quit => { - // the debouncer should return None in this case - unreachable!(); - } - } - self.render(out, hard_refresh).await.unwrap(); + }; + Some(Action::Refresh) } async fn handle_key_escape( &mut self, key: textmode::Key, - ) -> (bool, bool) { + ) -> Option<Action> { match key { textmode::Key::Ctrl(b'd') => { - return (true, false); + return Some(Action::Quit); } textmode::Key::Ctrl(b'e') => { self.set_focus(Focus::Scrolling(self.focus_idx()), None) .await; } textmode::Key::Ctrl(b'l') => { - return (false, true); + return Some(Action::HardRefresh); } textmode::Key::Ctrl(b'm') => { let idx = self.focus_idx(); @@ -293,26 +279,28 @@ impl State { textmode::Key::Char('r') => { self.set_focus(Focus::Readline, None).await; } - _ => {} + _ => { + return None; + } } - (false, false) + Some(Action::Refresh) } async fn handle_key_readline( &mut self, key: textmode::Key, event_w: async_std::channel::Sender<crate::event::Event>, - ) -> (bool, bool) { + ) -> Option<Action> { match key { textmode::Key::Char(c) => { self.readline.add_input(&c.to_string()); } textmode::Key::Ctrl(b'c') => self.readline.clear_input(), textmode::Key::Ctrl(b'd') => { - return (true, false); + return Some(Action::Quit); } textmode::Key::Ctrl(b'l') => { - return (false, true); + return Some(Action::HardRefresh); } textmode::Key::Ctrl(b'm') => { let cmd = self.readline.input(); @@ -336,9 +324,9 @@ impl State { .await; } } - _ => {} + _ => return None, } - (false, false) + Some(Action::Refresh) } async fn handle_key_history(&mut self, key: textmode::Key, idx: usize) { |