diff options
author | Jesse Luehrs <doy@tozt.net> | 2019-10-30 03:58:02 -0400 |
---|---|---|
committer | Jesse Luehrs <doy@tozt.net> | 2019-10-30 03:58:02 -0400 |
commit | f5dd2080f2533d0c927d23d3aef53d43ed2070db (patch) | |
tree | b103357473e5b84af7a90b985101cb923bdb243b | |
parent | 0a08887fec51d6926eb7fa35b5c2625388b71184 (diff) | |
download | vt100-rust-f5dd2080f2533d0c927d23d3aef53d43ed2070db.tar.gz vt100-rust-f5dd2080f2533d0c927d23d3aef53d43ed2070db.zip |
more passing tests
-rw-r--r-- | src/grid.rs | 108 | ||||
-rw-r--r-- | src/row.rs | 16 | ||||
-rw-r--r-- | src/screen.rs | 111 |
3 files changed, 227 insertions, 8 deletions
diff --git a/src/grid.rs b/src/grid.rs index 52a4a9e..ad1ecdc 100644 --- a/src/grid.rs +++ b/src/grid.rs @@ -14,6 +14,10 @@ impl Grid { } } + pub fn pos(&self, rows: u16, cols: u16) -> Pos { + Pos::new(rows, cols, self.size) + } + pub fn size(&self) -> &Size { &self.size } @@ -57,6 +61,103 @@ impl Grid { ) -> String { unimplemented!() } + + pub fn erase_all(&mut self) { + self.rows = vec![ + crate::row::Row::new(self.size.cols()); + self.size.rows() as usize + ]; + } + + pub fn erase_all_forward(&mut self, pos: Pos) { + for i in (pos.row() + 1)..self.size.rows() { + self.rows[i as usize] = crate::row::Row::new(self.size.cols()); + } + let row = &mut self.rows[pos.row() as usize]; + for i in pos.col()..self.size.cols() { + *row.get_mut(i).unwrap() = crate::cell::Cell::default(); + } + } + + pub fn erase_all_backward(&mut self, pos: Pos) { + for i in 0..pos.row() { + self.rows[i as usize] = crate::row::Row::new(self.size.cols()); + } + let row = &mut self.rows[pos.row() as usize]; + for i in 0..pos.col() { + *row.get_mut(i).unwrap() = crate::cell::Cell::default(); + } + } + + pub fn erase_row(&mut self, pos: Pos) { + self.rows[pos.row() as usize] = + crate::row::Row::new(self.size.cols()); + } + + pub fn erase_row_forward(&mut self, pos: Pos) { + let row = &mut self.rows[pos.row() as usize]; + for i in pos.col()..self.size.cols() { + *row.get_mut(i).unwrap() = crate::cell::Cell::default(); + } + } + + pub fn erase_row_backward(&mut self, pos: Pos) { + let row = &mut self.rows[pos.row() as usize]; + for i in 0..pos.col() { + *row.get_mut(i).unwrap() = crate::cell::Cell::default(); + } + } + + pub fn insert_cells(&mut self, pos: Pos, count: u16) { + let row = &mut self.rows[pos.row() as usize]; + for _ in 0..count { + row.insert(pos.col() as usize, crate::cell::Cell::default()); + } + row.truncate(pos.size.cols() as usize); + } + + pub fn delete_cells(&mut self, pos: Pos, count: u16) { + let row = &mut self.rows[pos.row() as usize]; + for _ in 0..(count.min(pos.size.cols() - pos.col())) { + row.remove(pos.col() as usize); + } + row.resize(pos.size.cols() as usize, crate::cell::Cell::default()); + } + + pub fn erase_cells(&mut self, pos: Pos, count: u16) { + let row = &mut self.rows[pos.row() as usize]; + for i in pos.col()..(pos.col() + count).min(pos.size.cols() - 1) { + *row.get_mut(i).unwrap() = crate::cell::Cell::default(); + } + } + + pub fn insert_lines(&mut self, pos: Pos, count: u16) { + for _ in 0..count { + self.rows.insert( + pos.row() as usize, + crate::row::Row::new(pos.size.cols()), + ); + } + self.rows.truncate(pos.size.rows() as usize) + } + + pub fn delete_lines(&mut self, pos: Pos, count: u16) { + for _ in 0..(count.min(pos.size.rows() - pos.row())) { + self.rows.remove(pos.row() as usize); + } + self.rows.resize( + pos.size.rows() as usize, + crate::row::Row::new(pos.size.cols()), + ) + } + + pub fn scroll_up(&mut self, count: u16) { + self.delete_lines(self.pos(0, 0), count); + } + + pub fn scroll_down(&mut self, count: u16) { + self.insert_lines(self.pos(0, 0), count); + } } #[derive(Copy, Clone, Debug, Default, Eq, PartialEq)] @@ -126,11 +227,16 @@ impl Pos { self.col } - pub fn col_inc(&mut self, count: u16) { + pub fn col_inc_wrap(&mut self, count: u16) { self.col = self.col.saturating_add(count); self.col_wrap(); } + pub fn col_inc_clamp(&mut self, count: u16) { + self.col = self.col.saturating_add(count); + self.col_clamp(); + } + pub fn col_dec(&mut self, count: u16) { self.col = self.col.saturating_sub(count); } @@ -20,6 +20,22 @@ impl Row { self.cells.get_mut(col as usize) } + pub fn insert(&mut self, i: usize, cell: crate::cell::Cell) { + self.cells.insert(i, cell); + } + + pub fn remove(&mut self, i: usize) { + self.cells.remove(i); + } + + pub fn truncate(&mut self, len: usize) { + self.cells.truncate(len); + } + + pub fn resize(&mut self, len: usize, cell: crate::cell::Cell) { + self.cells.resize(len, cell); + } + pub fn contents(&self, col_start: u16, col_end: u16) -> String { // XXX very inefficient let mut max_col = None; diff --git a/src/screen.rs b/src/screen.rs index dc210c1..514309c 100644 --- a/src/screen.rs +++ b/src/screen.rs @@ -38,7 +38,7 @@ impl State { } fn pos(&self, row: u16, col: u16) -> crate::grid::Pos { - crate::grid::Pos::new(row, col, *self.grid.size()) + self.grid.pos(row, col) } } @@ -51,7 +51,7 @@ impl State { let attrs = self.attrs; if let Some(cell) = self.current_cell_mut() { cell.set(c.to_string(), attrs); - self.cursor_position.col_inc(1); + self.cursor_position.col_inc_wrap(1); } else { panic!("couldn't find current cell") } @@ -82,12 +82,44 @@ impl State { // csi codes + // CSI @ + fn ich(&mut self, params: &[i64]) { + let count = params.get(0).copied().unwrap_or(1); + self.grid.insert_cells(self.cursor_position, count as u16); + } + + // CSI A + fn cuu(&mut self, params: &[i64]) { + let offset = params.get(0).copied().unwrap_or(1); + self.cursor_position.row_dec(offset as u16); + } + + // CSI B + fn cud(&mut self, params: &[i64]) { + let offset = params.get(0).copied().unwrap_or(1); + self.cursor_position.row_inc(offset as u16); + } + + // CSI C + fn cuf(&mut self, params: &[i64]) { + let offset = params.get(0).copied().unwrap_or(1); + self.cursor_position.col_inc_clamp(offset as u16); + } + // CSI D fn cub(&mut self, params: &[i64]) { let offset = params.get(0).copied().unwrap_or(1); self.cursor_position.col_dec(offset as u16); } + // CSI G + fn cha(&mut self, params: &[i64]) { + // XXX need to handle value overflow + self.cursor_position.col_set(normalize_absolute_position( + params.get(0).map(|i| *i as u16), + )); + } + // CSI H fn cup(&mut self, params: &[i64]) { // XXX need to handle value overflow @@ -100,15 +132,67 @@ impl State { // CSI J fn ed(&mut self, params: &[i64]) { match params.get(0).copied().unwrap_or(0) { - 0 => unimplemented!(), - 1 => unimplemented!(), - 2 => { - self.grid = crate::grid::Grid::new(*self.grid.size()); - } + 0 => self.grid.erase_all_forward(self.cursor_position), + 1 => self.grid.erase_all_backward(self.cursor_position), + 2 => self.grid.erase_all(), _ => {} } } + // CSI K + fn el(&mut self, params: &[i64]) { + match params.get(0).copied().unwrap_or(0) { + 0 => self.grid.erase_row_forward(self.cursor_position), + 1 => self.grid.erase_row_backward(self.cursor_position), + 2 => self.grid.erase_row(self.cursor_position), + _ => {} + } + } + + // CSI L + fn il(&mut self, params: &[i64]) { + let count = params.get(0).copied().unwrap_or(1); + self.grid.insert_lines(self.cursor_position, count as u16); + } + + // CSI M + fn dl(&mut self, params: &[i64]) { + let count = params.get(0).copied().unwrap_or(1); + self.grid.delete_lines(self.cursor_position, count as u16); + } + + // CSI P + fn dch(&mut self, params: &[i64]) { + let count = params.get(0).copied().unwrap_or(1); + self.grid.delete_cells(self.cursor_position, count as u16); + } + + // CSI S + fn su(&mut self, params: &[i64]) { + let count = params.get(0).copied().unwrap_or(1); + self.grid.scroll_up(count as u16); + } + + // CSI T + fn sd(&mut self, params: &[i64]) { + let count = params.get(0).copied().unwrap_or(1); + self.grid.scroll_down(count as u16); + } + + // CSI X + fn ech(&mut self, params: &[i64]) { + let count = params.get(0).copied().unwrap_or(1); + self.grid.erase_cells(self.cursor_position, count as u16); + } + + // CSI d + fn vpa(&mut self, params: &[i64]) { + // XXX need to handle value overflow + self.cursor_position.row_set(normalize_absolute_position( + params.get(0).map(|i| *i as u16), + )); + } + // CSI m fn sgr(&mut self, params: &[i64]) { // XXX need to handle value overflow @@ -237,9 +321,22 @@ impl vte::Perform for State { c: char, ) { match c { + '@' => self.ich(params), + 'A' => self.cuu(params), + 'B' => self.cud(params), + 'C' => self.cuf(params), 'D' => self.cub(params), + 'G' => self.cha(params), 'H' => self.cup(params), 'J' => self.ed(params), + 'K' => self.el(params), + 'L' => self.il(params), + 'M' => self.dl(params), + 'P' => self.dch(params), + 'S' => self.su(params), + 'T' => self.sd(params), + 'X' => self.ech(params), + 'd' => self.vpa(params), 'm' => self.sgr(params), _ => {} } |