From 172115528605bacc5af3995a74ea60168f2b0d90 Mon Sep 17 00:00:00 2001 From: Jesse Luehrs Date: Thu, 18 Nov 2021 02:09:43 -0500 Subject: refactor to potentially allow for displaying other things --- src/action.rs | 29 +++++++++++----------- src/history.rs | 76 +++++++++++++++++++++++++++++++++------------------------- src/state.rs | 75 +++++++++++++++++++++++++++++++++++++++++---------------- 3 files changed, 113 insertions(+), 67 deletions(-) (limited to 'src') diff --git a/src/action.rs b/src/action.rs index 22f088e..bb8958f 100644 --- a/src/action.rs +++ b/src/action.rs @@ -4,7 +4,8 @@ pub enum Action { ForceRedraw, Run(String), UpdateFocus(crate::state::Focus), - ToggleFullscreen(usize), + UpdateScene(crate::state::Scene), + CheckUpdateScene, Resize((u16, u16)), Quit, } @@ -38,7 +39,8 @@ struct Pending { force_redraw: Option<()>, run: std::collections::VecDeque, focus: Option, - fullscreen: std::collections::VecDeque, + scene: Option, + check_scene: Option<()>, size: Option<(u16, u16)>, done: bool, } @@ -54,7 +56,8 @@ impl Pending { || self.force_redraw.is_some() || !self.run.is_empty() || self.focus.is_some() - || !self.fullscreen.is_empty() + || self.scene.is_some() + || self.check_scene.is_some() || self.size.is_some() } @@ -68,18 +71,17 @@ impl Pending { if self.focus.is_some() { return Some(Action::UpdateFocus(self.focus.take().unwrap())); } - if !self.fullscreen.is_empty() { - return Some(Action::ToggleFullscreen( - self.fullscreen.pop_front().unwrap(), - )); + if self.scene.is_some() { + return Some(Action::UpdateScene(self.scene.take().unwrap())); } - if self.force_redraw.is_some() { - self.force_redraw.take(); + if self.check_scene.take().is_some() { + return Some(Action::CheckUpdateScene); + } + if self.force_redraw.take().is_some() { self.render.take(); return Some(Action::ForceRedraw); } - if self.render.is_some() { - self.render.take(); + if self.render.take().is_some() { return Some(Action::Render); } if self.done { @@ -94,9 +96,8 @@ impl Pending { Some(Action::ForceRedraw) => self.force_redraw = Some(()), Some(Action::Run(cmd)) => self.run.push_back(cmd.to_string()), Some(Action::UpdateFocus(focus)) => self.focus = Some(*focus), - Some(Action::ToggleFullscreen(idx)) => { - self.fullscreen.push_back(*idx); - } + Some(Action::UpdateScene(scene)) => self.scene = Some(*scene), + Some(Action::CheckUpdateScene) => self.check_scene = Some(()), Some(Action::Resize(size)) => self.size = Some(*size), Some(Action::Quit) | None => self.done = true, } diff --git a/src/history.rs b/src/history.rs index d6f198a..d20de80 100644 --- a/src/history.rs +++ b/src/history.rs @@ -30,14 +30,6 @@ impl History { repl_lines: usize, focus: Option, ) -> anyhow::Result<()> { - if let Some(idx) = focus { - let mut entry = self.entries[idx].lock_arc().await; - if entry.should_fullscreen() { - entry.render_fullscreen(out); - return Ok(()); - } - } - let mut used_lines = repl_lines; let mut pos = None; for (idx, entry) in self.entries.iter().enumerate().rev() { @@ -66,6 +58,15 @@ impl History { Ok(()) } + pub async fn render_fullscreen( + &self, + out: &mut textmode::Output, + idx: usize, + ) { + let mut entry = self.entries[idx].lock_arc().await; + entry.render_fullscreen(out); + } + pub async fn resize(&mut self, size: (u16, u16)) { self.size = size; for entry in &self.entries { @@ -123,7 +124,7 @@ impl History { self.entries[idx].lock_arc().await.toggle_fullscreen(); } - pub async fn is_fullscreen(&self, idx: usize) -> bool { + pub async fn should_fullscreen(&self, idx: usize) -> bool { self.entries[idx].lock_arc().await.should_fullscreen() } @@ -352,34 +353,45 @@ fn run_process( let write = async { Res::Write(input_r.recv().await) }; let resize = async { Res::Resize(resize_r.recv().await) }; match read.race(write).race(resize).await { - Res::Read(res) => { - match res { - Ok(bytes) => { - entry.lock_arc().await.vt.process(&buf[..bytes]); - } - Err(e) => { - if e.raw_os_error() != Some(libc::EIO) { - eprintln!("pty read failed: {:?}", e); - } - // XXX not sure if this is safe - are we sure - // the child exited? - entry.lock_arc().await.exit_info = Some( - ExitInfo::new(child.status().await.unwrap()), - ); + Res::Read(res) => match res { + Ok(bytes) => { + let mut entry = entry.lock_arc().await; + let pre_alternate_screen = + entry.vt.screen().alternate_screen(); + entry.vt.process(&buf[..bytes]); + let post_alternate_screen = + entry.vt.screen().alternate_screen(); + if entry.fullscreen.is_none() + && pre_alternate_screen != post_alternate_screen + { action_w - .send(crate::action::Action::UpdateFocus( - crate::state::Focus::Readline, - )) + .send(crate::action::Action::CheckUpdateScene) .await .unwrap(); - break; } + action_w + .send(crate::action::Action::Render) + .await + .unwrap(); } - action_w - .send(crate::action::Action::Render) - .await - .unwrap(); - } + Err(e) => { + if e.raw_os_error() != Some(libc::EIO) { + eprintln!("pty read failed: {:?}", e); + } + // XXX not sure if this is safe - are we sure + // the child exited? + entry.lock_arc().await.exit_info = Some( + ExitInfo::new(child.status().await.unwrap()), + ); + action_w + .send(crate::action::Action::UpdateFocus( + crate::state::Focus::Readline, + )) + .await + .unwrap(); + break; + } + }, Res::Write(res) => match res { Ok(bytes) => { pty.write(&bytes).await.unwrap(); diff --git a/src/state.rs b/src/state.rs index c348d7f..155034e 100644 --- a/src/state.rs +++ b/src/state.rs @@ -4,6 +4,7 @@ pub struct State { readline: crate::readline::Readline, history: crate::history::History, focus: Focus, + scene: Scene, escape: bool, hide_readline: bool, } @@ -13,10 +14,12 @@ impl State { let readline = crate::readline::Readline::new(); let history = crate::history::History::new(); let focus = Focus::Readline; + let scene = Scene::Readline; Self { readline, history, focus, + scene, escape: false, hide_readline: false, } @@ -38,9 +41,8 @@ impl State { } textmode::Key::Char('f') => { if let Focus::History(idx) = self.focus { - return Some( - crate::action::Action::ToggleFullscreen(idx), - ); + self.history.toggle_fullscreen(idx).await; + return Some(crate::action::Action::CheckUpdateScene); } } textmode::Key::Char('j') => { @@ -105,24 +107,32 @@ impl State { hard: bool, ) -> anyhow::Result<()> { out.clear(); - match self.focus { - Focus::Readline => { - self.history - .render(out, self.readline.lines(), None) - .await?; - self.readline.render(out, true).await?; - } - Focus::History(idx) => { - if self.hide_readline || self.history.is_fullscreen(idx).await - { - self.history.render(out, 0, Some(idx)).await?; - } else { + match self.scene { + Scene::Readline => match self.focus { + Focus::Readline => { self.history - .render(out, self.readline.lines(), Some(idx)) + .render(out, self.readline.lines(), None) .await?; - let pos = out.screen().cursor_position(); - self.readline.render(out, false).await?; - out.move_to(pos.0, pos.1); + self.readline.render(out, true).await?; + } + Focus::History(idx) => { + if self.hide_readline { + self.history.render(out, 0, Some(idx)).await?; + } else { + self.history + .render(out, self.readline.lines(), Some(idx)) + .await?; + let pos = out.screen().cursor_position(); + self.readline.render(out, false).await?; + out.move_to(pos.0, pos.1); + } + } + }, + Scene::Fullscreen => { + if let Focus::History(idx) = self.focus { + self.history.render_fullscreen(out, idx).await; + } else { + unreachable!(); } } } @@ -155,9 +165,13 @@ impl State { crate::action::Action::UpdateFocus(new_focus) => { self.focus = new_focus; self.hide_readline = false; + self.scene = self.default_scene(new_focus).await; } - crate::action::Action::ToggleFullscreen(idx) => { - self.history.toggle_fullscreen(idx).await; + crate::action::Action::UpdateScene(new_scene) => { + self.scene = new_scene; + } + crate::action::Action::CheckUpdateScene => { + self.scene = self.default_scene(self.focus).await; } crate::action::Action::Resize(new_size) => { self.readline.resize(new_size).await; @@ -172,6 +186,19 @@ impl State { } self.render(out, hard_refresh).await.unwrap(); } + + async fn default_scene(&self, focus: Focus) -> Scene { + match focus { + Focus::Readline => Scene::Readline, + Focus::History(idx) => { + if self.history.should_fullscreen(idx).await { + Scene::Fullscreen + } else { + Scene::Readline + } + } + } + } } #[derive(Copy, Clone, Debug)] @@ -179,3 +206,9 @@ pub enum Focus { Readline, History(usize), } + +#[derive(Copy, Clone, Debug)] +pub enum Scene { + Readline, + Fullscreen, +} -- cgit v1.2.3-54-g00ecf