diff options
author | Jesse Luehrs <doy@tozt.net> | 2019-10-30 11:55:15 -0400 |
---|---|---|
committer | Jesse Luehrs <doy@tozt.net> | 2019-10-30 11:55:15 -0400 |
commit | 31d086b7a9e0937af9f573cbcfab0c3f17a24010 (patch) | |
tree | 17b39a8249dc811e7f016edfb587a0fda4e4bacd | |
parent | 894bc82b1fb2180657919b992bc812552fa707ba (diff) | |
download | vt100-rust-31d086b7a9e0937af9f573cbcfab0c3f17a24010.tar.gz vt100-rust-31d086b7a9e0937af9f573cbcfab0c3f17a24010.zip |
more passing tests
-rw-r--r-- | src/grid.rs | 87 | ||||
-rw-r--r-- | src/screen.rs | 26 |
2 files changed, 95 insertions, 18 deletions
diff --git a/src/grid.rs b/src/grid.rs index d29a619..033383b 100644 --- a/src/grid.rs +++ b/src/grid.rs @@ -3,6 +3,8 @@ pub struct Grid { pos: Pos, saved_pos: Pos, rows: Vec<crate::row::Row>, + scroll_top: u16, + scroll_bottom: u16, } impl Grid { @@ -12,6 +14,8 @@ impl Grid { pos: Pos::default(), saved_pos: Pos::default(), rows: vec![crate::row::Row::new(size.cols); size.rows as usize], + scroll_top: 0, + scroll_bottom: size.rows - 1, } } @@ -29,7 +33,8 @@ impl Grid { pub fn set_pos(&mut self, pos: Pos) { self.pos = pos; - self.row_clamp(); + self.row_clamp_top(); + self.row_clamp_bottom(); self.col_clamp(); } @@ -149,50 +154,90 @@ impl Grid { pub fn insert_lines(&mut self, pos: Pos, count: u16) { for _ in 0..count { + self.rows.remove(self.scroll_bottom as usize); self.rows.insert( pos.row as usize, crate::row::Row::new(self.size.cols), ); } - self.rows.truncate(self.size.rows as usize) } pub fn delete_lines(&mut self, pos: Pos, count: u16) { for _ in 0..(count.min(self.size.rows - pos.row)) { + self.rows.insert( + self.scroll_bottom as usize + 1, + crate::row::Row::new(self.size.cols), + ); self.rows.remove(pos.row as usize); } - self.rows.resize( - self.size.rows as usize, - crate::row::Row::new(self.size.cols), - ) } pub fn scroll_up(&mut self, count: u16) { - self.delete_lines(Pos { row: 0, col: 0 }, count); + self.delete_lines( + Pos { + row: self.scroll_top, + col: 0, + }, + count, + ); } pub fn scroll_down(&mut self, count: u16) { - self.insert_lines(Pos { row: 0, col: 0 }, count); + self.insert_lines( + Pos { + row: self.scroll_top, + col: 0, + }, + count, + ); + } + + // TODO: left/right + pub fn set_scroll_region( + &mut self, + top: u16, + bottom: u16, + _left: u16, + _right: u16, + ) { + let bottom = bottom.min(self.size().rows - 1); + if top < bottom { + self.scroll_top = top; + self.scroll_bottom = bottom; + } else { + self.scroll_top = 0; + self.scroll_bottom = self.size().rows - 1; + } + self.pos.row = self.scroll_top; + self.pos.col = 0; } pub fn row_inc_clamp(&mut self, count: u16) { self.pos.row = self.pos.row.saturating_add(count); - self.row_clamp(); + self.row_clamp_bottom(); } pub fn row_inc_scroll(&mut self, count: u16) { self.pos.row = self.pos.row.saturating_add(count); - let lines = self.row_clamp(); + let lines = self.row_clamp_bottom(); self.scroll_up(lines); } - pub fn row_dec(&mut self, count: u16) { + pub fn row_dec_clamp(&mut self, count: u16) { + self.pos.row = self.pos.row.saturating_sub(count); + self.row_clamp_top(); + } + + pub fn row_dec_scroll(&mut self, count: u16) { self.pos.row = self.pos.row.saturating_sub(count); + let lines = self.row_clamp_top(); + self.scroll_down(lines); } pub fn row_set(&mut self, i: u16) { self.pos.row = i; - self.row_clamp(); + self.row_clamp_top(); + self.row_clamp_bottom(); } pub fn col_inc_clamp(&mut self, count: u16) { @@ -220,10 +265,20 @@ impl Grid { self.col_clamp(); } - fn row_clamp(&mut self) -> u16 { - if self.pos.row > self.size.rows - 1 { - let rows = self.pos.row - (self.size.rows - 1); - self.pos.row = self.size.rows - 1; + fn row_clamp_top(&mut self) -> u16 { + if self.pos.row < self.scroll_top { + let rows = self.scroll_top - self.pos.row; + self.pos.row = self.scroll_top; + rows + } else { + 0 + } + } + + fn row_clamp_bottom(&mut self) -> u16 { + if self.pos.row > self.scroll_bottom { + let rows = self.pos.row - self.scroll_bottom; + self.pos.row = self.scroll_bottom; rows } else { 0 diff --git a/src/screen.rs b/src/screen.rs index e5e2e7e..9f35546 100644 --- a/src/screen.rs +++ b/src/screen.rs @@ -143,7 +143,7 @@ impl State { // ESC M fn ri(&mut self) { - self.grid_mut().row_dec(1); + self.grid_mut().row_dec_scroll(1); } // ESC c @@ -168,7 +168,7 @@ impl State { // CSI A fn cuu(&mut self, params: &[i64]) { let offset = params.get(0).copied().unwrap_or(1); - self.grid_mut().row_dec(offset as u16); + self.grid_mut().row_dec_clamp(offset as u16); } // CSI B @@ -416,6 +416,27 @@ impl State { } } + // CSI r + fn csr(&mut self, params: &[i64]) { + let top = if let Some(top) = params.get(0).map(|i| *i as u16) { + top as u16 - 1 + } else { + return; + }; + let bottom = if let Some(bottom) = params.get(1).map(|i| *i as u16) { + bottom as u16 - 1 + } else { + return; + }; + let left = params.get(2).map(|i| *i as u16).unwrap_or(1) - 1; + let right = params + .get(3) + .map(|i| *i as u16) + .unwrap_or(self.grid().size().cols) + - 1; + self.grid_mut().set_scroll_region(top, bottom, left, right); + } + // osc codes fn osc0(&mut self, s: &[u8]) { @@ -498,6 +519,7 @@ impl vte::Perform for State { 'h' => self.sm(intermediates.get(0).copied(), params), 'l' => self.rm(intermediates.get(0).copied(), params), 'm' => self.sgr(params), + 'r' => self.csr(params), _ => {} } } |