small software-rendered rust tty
alternate screens
| -rw-r--r-- | src/main.rs | 17 | ||||
| -rw-r--r-- | src/term.rs | 50 |
2 files changed, 54 insertions, 13 deletions
diff --git a/src/main.rs b/src/main.rs index 66585e4..3a2cac6 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,7 +4,8 @@ deref_patterns, generic_const_exprs, impl_trait_in_bindings, - if_let_guard + if_let_guard, + import_trait_associated_functions )] use std::fs::File; use std::io::Write; @@ -127,6 +128,7 @@ fn main() -> Result<()> { Apostrophe => b"'", Space => b" ", Period => b".", + Slash if shifting => b"?", Slash => b"/", Backslash => b"\\", Backspace => b"", @@ -181,16 +183,7 @@ fn main() -> Result<()> { let cols = (w.get_size().0 as f32 / fw).floor() as u16 + 1; let rows = (w.get_size().1 as f32 / fh).floor() as u16; dbg!(rows, cols); - let mut t = Terminal { - style: Default::default(), - saved_cursor: (1, 1), - cursor: (1, 1), - size: (cols, rows), - row: 0, - cells: vec![Cell::default(); cols as usize * rows as usize], - p: Default::default(), - mode: Mode::Normal, - }; + let mut t = Terminal::new((cols, rows), false); unsafe { let x = winsize { ws_row: rows, @@ -226,7 +219,7 @@ fn main() -> Result<()> { fn tpaxrse() { println!("-------------------"); let mut x = TerminalInputParser::new(); - for c in "[?2004h(B)0[1;40r[m[?7h[?1h=[?1h=[H[J[0;7m GNU nano 8.4 New Buffer [1;113H[m[38;33H[0;7m[ Welcome to nano. For basic help, type Ctrl+G. ][m".as_bytes() { + for c in "\x1b[?1049h".as_bytes() { use ctlfun::TerminalInput::*; match x.parse_byte(*c) { Char(x) => { diff --git a/src/term.rs b/src/term.rs index e858c5c..394e1a7 100644 --- a/src/term.rs +++ b/src/term.rs @@ -1,4 +1,5 @@ use std::iter::repeat_n; +use std::ops::Not; use ctlfun::Parameter::*; use ctlfun::TerminalInput::*; @@ -14,6 +15,29 @@ pub struct Terminal { pub row: usize, pub p: TerminalInputParser, pub mode: Mode, + + pub alternate: Option<Box<Self>>, +} + +use std::default::Default::default; +impl Terminal { + pub fn new(sz @ (c, r): (u16, u16), alt: bool) -> Self { + Self { + style: default(), + saved_cursor: (1, 1), + cursor: (1, 1), + size: sz, + row: 0, + cells: vec![Cell::default(); c as usize * r as usize], + p: default(), + mode: Mode::Normal, + + alternate: alt + .not() + .then(|| Terminal::new(sz, true)) + .map(Box::new), + } + } } pub enum Mode { Normal, @@ -50,6 +74,9 @@ impl Terminal { fn decrc(&mut self) { self.cursor = self.saved_cursor; } + fn clear(&mut self) { + // TODO + } #[implicit_fn::implicit_fn] pub fn rx(&mut self, x: u8) { match self.p.parse_byte(x) { @@ -229,7 +256,28 @@ impl Terminal { ) => { self.decrc(); } - + Control(ControlFunction { + start: b'[', + params: [Value(n)], + end: b'h' | b'l', + .. + }) => match n { + 2004 => {} + 1047 if let Some(mut alt) = self.alternate.take() => { + alt.clear(); + std::mem::swap(self, &mut *alt); + self.alternate = Some(alt); + } + 1048 => self.decsc(), + 1049 if let Some(mut alt) = self.alternate.take() => { + alt.clear(); + self.decsc(); + std::mem::swap(self, &mut *alt); + self.decrc(); + self.alternate = Some(alt); + } + _ => {} + }, Control(ControlFunction { start: b'\x1b', params: [], |