From 45553512fd8bc672d4ca4bdbbd9e914a7650620c Mon Sep 17 00:00:00 2001 From: Jesse Luehrs Date: Tue, 1 Mar 2022 02:41:34 -0500 Subject: refactor --- src/shell/history/entry.rs | 101 +++++++++------------------------------------ src/shell/history/mod.rs | 1 + src/shell/history/vt.rs | 97 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 117 insertions(+), 82 deletions(-) create mode 100644 src/shell/history/vt.rs (limited to 'src') diff --git a/src/shell/history/entry.rs b/src/shell/history/entry.rs index 3b4717b..90509d3 100644 --- a/src/shell/history/entry.rs +++ b/src/shell/history/entry.rs @@ -9,12 +9,7 @@ pub struct Entry { cmdline: String, env: Env, state: State, - vt: vt100::Parser, - audible_bell_state: usize, - visual_bell_state: usize, - audible_bell: bool, - visual_bell: bool, - real_bell_pending: bool, + vt: super::vt::Vt, fullscreen: Option, input: tokio::sync::mpsc::UnboundedSender>, resize: tokio::sync::mpsc::UnboundedSender<(u16, u16)>, @@ -35,12 +30,7 @@ impl Entry { cmdline, env, state: State::Running(span), - vt: vt100::Parser::new(size.0, size.1, 0), - audible_bell_state: 0, - visual_bell_state: 0, - audible_bell: false, - visual_bell: false, - real_bell_pending: false, + vt: super::vt::Vt::new(size), input, resize, fullscreen: None, @@ -77,12 +67,6 @@ impl Entry { }, ); - self.bell(out); - if focused { - self.audible_bell = false; - self.visual_bell = false; - } - set_bgcolor(out, idx, focused); out.set_fgcolor(textmode::color::YELLOW); let entry_count_width = format!("{}", entry_count + 1).len(); @@ -107,7 +91,11 @@ impl Entry { } out.reset_attributes(); - if self.audible_bell || self.visual_bell { + self.vt.bell(out, focused); + + let vt = &self.vt; + + if vt.is_bell() { out.set_bgcolor(textmode::Color::Rgb(64, 16, 16)); } else { set_bgcolor(out, idx, focused); @@ -164,7 +152,7 @@ impl Entry { out.write_str(" "); out.reset_attributes(); - if self.binary() { + if vt.binary() { let msg = "This appears to be binary data. Fullscreen this entry to view anyway."; let len: u16 = msg.len().try_into().unwrap(); out.move_to( @@ -175,7 +163,8 @@ impl Entry { out.write_str(msg); out.hide_cursor(true); } else { - let last_row = self.output_lines(focused && !scrolling); + let last_row = + vt.output_lines(focused && !scrolling, self.running()); let mut max_lines = self.max_lines(entry_count); if last_row > max_lines { out.write(b"\r\n"); @@ -185,7 +174,7 @@ impl Entry { max_lines -= 1; } let mut out_row = out.screen().cursor_position().0 + 1; - let screen = self.vt.screen(); + let screen = vt.screen(); let pos = screen.cursor_position(); let mut wrapped = false; let mut cursor_found = None; @@ -216,14 +205,14 @@ impl Entry { } } } + out.reset_attributes(); } pub fn render_fullscreen(&mut self, out: &mut impl textmode::Textmode) { - out.write(&self.vt.screen().state_formatted()); - self.bell(out); - self.audible_bell = false; - self.visual_bell = false; + let vt = &mut self.vt; + out.write(&vt.screen().state_formatted()); + vt.bell(out, true); out.reset_attributes(); } @@ -236,31 +225,16 @@ impl Entry { pub fn resize(&mut self, size: (u16, u16)) { if self.running() { self.resize.send(size).unwrap(); - self.vt.set_size(size.0, size.1); + self.vt.set_size(size); } } pub fn size(&self) -> (u16, u16) { - self.vt.screen().size() + self.vt.size() } pub fn process(&mut self, input: &[u8]) { self.vt.process(input); - let screen = self.vt.screen(); - - let new_audible_bell_state = screen.audible_bell_count(); - if new_audible_bell_state != self.audible_bell_state { - self.audible_bell = true; - self.real_bell_pending = true; - self.audible_bell_state = new_audible_bell_state; - } - - let new_visual_bell_state = screen.visual_bell_count(); - if new_visual_bell_state != self.visual_bell_state { - self.visual_bell = true; - self.real_bell_pending = true; - self.visual_bell_state = new_visual_bell_state; - } } pub fn cmd(&self) -> &str { @@ -287,46 +261,21 @@ impl Entry { matches!(self.state, State::Running(_)) } - pub fn binary(&self) -> bool { - self.vt.screen().errors() > 5 - } - pub fn lines(&self, entry_count: usize, focused: bool) -> usize { 1 + std::cmp::min( - self.output_lines(focused), + self.vt.output_lines(focused, self.running()), self.max_lines(entry_count), ) } fn max_lines(&self, entry_count: usize) -> usize { if self.env.idx() == entry_count - 1 { - usize::from(self.size().0) * 2 / 3 + 15 } else { 5 } } - pub fn output_lines(&self, focused: bool) -> usize { - if self.binary() { - return 1; - } - - let screen = self.vt.screen(); - let mut last_row = 0; - for (idx, row) in screen.rows(0, self.size().1).enumerate() { - if !row.is_empty() { - last_row = idx + 1; - } - } - if focused && self.running() { - last_row = std::cmp::max( - last_row, - usize::from(screen.cursor_position().0) + 1, - ); - } - last_row - } - pub fn should_fullscreen(&self) -> bool { self.fullscreen .unwrap_or_else(|| self.vt.screen().alternate_screen()) @@ -354,18 +303,6 @@ impl Entry { State::Exited(exit_info) => Some(exit_info), } } - - fn bell(&mut self, out: &mut impl textmode::Textmode) { - if self.real_bell_pending { - if self.audible_bell { - out.write(b"\x07"); - } - if self.visual_bell { - out.write(b"\x1bg"); - } - self.real_bell_pending = false; - } - } } struct ExitInfo { diff --git a/src/shell/history/mod.rs b/src/shell/history/mod.rs index 8b67ed2..2e8b817 100644 --- a/src/shell/history/mod.rs +++ b/src/shell/history/mod.rs @@ -3,6 +3,7 @@ use crate::shell::prelude::*; mod entry; pub use entry::Entry; mod pty; +mod vt; pub struct History { size: (u16, u16), diff --git a/src/shell/history/vt.rs b/src/shell/history/vt.rs new file mode 100644 index 0000000..511cab9 --- /dev/null +++ b/src/shell/history/vt.rs @@ -0,0 +1,97 @@ +pub struct Vt { + vt: vt100::Parser, + audible_bell_state: usize, + visual_bell_state: usize, + audible_bell: bool, + visual_bell: bool, + real_bell_pending: bool, +} + +impl Vt { + pub fn new(size: (u16, u16)) -> Self { + Self { + vt: vt100::Parser::new(size.0, size.1, 0), + audible_bell_state: 0, + visual_bell_state: 0, + audible_bell: false, + visual_bell: false, + real_bell_pending: false, + } + } + + pub fn process(&mut self, bytes: &[u8]) { + self.vt.process(bytes); + let screen = self.vt.screen(); + + let new_audible_bell_state = screen.audible_bell_count(); + if new_audible_bell_state != self.audible_bell_state { + self.audible_bell = true; + self.real_bell_pending = true; + self.audible_bell_state = new_audible_bell_state; + } + + let new_visual_bell_state = screen.visual_bell_count(); + if new_visual_bell_state != self.visual_bell_state { + self.visual_bell = true; + self.real_bell_pending = true; + self.visual_bell_state = new_visual_bell_state; + } + } + + pub fn screen(&self) -> &vt100::Screen { + self.vt.screen() + } + + pub fn size(&self) -> (u16, u16) { + self.vt.screen().size() + } + + pub fn set_size(&mut self, size: (u16, u16)) { + self.vt.set_size(size.0, size.1); + } + + pub fn is_bell(&self) -> bool { + self.audible_bell || self.visual_bell + } + + pub fn bell(&mut self, out: &mut impl textmode::Textmode, focused: bool) { + if self.real_bell_pending { + if self.audible_bell { + out.write(b"\x07"); + } + if self.visual_bell { + out.write(b"\x1bg"); + } + self.real_bell_pending = false; + } + if focused { + self.audible_bell = false; + self.visual_bell = false; + } + } + + pub fn binary(&self) -> bool { + self.vt.screen().errors() > 5 + } + + pub fn output_lines(&self, focused: bool, running: bool) -> usize { + if self.binary() { + return 1; + } + + let screen = self.vt.screen(); + let mut last_row = 0; + for (idx, row) in screen.rows(0, screen.size().1).enumerate() { + if !row.is_empty() { + last_row = idx + 1; + } + } + if focused && running { + last_row = std::cmp::max( + last_row, + usize::from(screen.cursor_position().0) + 1, + ); + } + last_row + } +} -- cgit v1.2.3-54-g00ecf