summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJesse Luehrs <doy@tozt.net>2021-11-18 02:09:43 -0500
committerJesse Luehrs <doy@tozt.net>2021-11-18 02:09:43 -0500
commit172115528605bacc5af3995a74ea60168f2b0d90 (patch)
tree40abd948830ca188d4e5b190ea3e2e44141e0fe3
parent04068bf2ad233748af1ac98edb12a27bf8ffca75 (diff)
downloadnbsh-master.tar.gz
nbsh-master.zip
refactor to potentially allow for displaying other thingsHEADmaster
-rw-r--r--src/action.rs29
-rw-r--r--src/history.rs76
-rw-r--r--src/state.rs75
3 files changed, 113 insertions, 67 deletions
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<String>,
focus: Option<crate::state::Focus>,
- fullscreen: std::collections::VecDeque<usize>,
+ scene: Option<crate::state::Scene>,
+ 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<usize>,
) -> 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,
+}