aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJesse Luehrs <doy@tozt.net>2019-10-30 11:55:15 -0400
committerJesse Luehrs <doy@tozt.net>2019-10-30 11:55:15 -0400
commit31d086b7a9e0937af9f573cbcfab0c3f17a24010 (patch)
tree17b39a8249dc811e7f016edfb587a0fda4e4bacd
parent894bc82b1fb2180657919b992bc812552fa707ba (diff)
downloadvt100-rust-31d086b7a9e0937af9f573cbcfab0c3f17a24010.tar.gz
vt100-rust-31d086b7a9e0937af9f573cbcfab0c3f17a24010.zip
more passing tests
-rw-r--r--src/grid.rs87
-rw-r--r--src/screen.rs26
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),
_ => {}
}
}