diff options
author | Joe Wilm <joe@jwilm.com> | 2016-06-08 10:39:49 -0700 |
---|---|---|
committer | Joe Wilm <joe@jwilm.com> | 2016-06-08 10:39:49 -0700 |
commit | 8126841ed37a9cc249f646b830b3d3d48aaf4ed7 (patch) | |
tree | 781dcedf8bd704071447119d9cecb216203b2c3e /src/grid.rs | |
parent | 0e7bb8d76e45af6154b0fb76184ae55df7cf80e1 (diff) | |
download | r-alacritty-8126841ed37a9cc249f646b830b3d3d48aaf4ed7.tar.gz r-alacritty-8126841ed37a9cc249f646b830b3d3d48aaf4ed7.tar.bz2 r-alacritty-8126841ed37a9cc249f646b830b3d3d48aaf4ed7.zip |
Add support for scrolling regions
It's now possible to move around within Vim without the screen becoming
corrupt!
The ANSI parser now calls a (new) `set_scrolling_region` on the handler
when the DECSTBM CSI is received. In order to provide a sensible default
in case that the sequence doesn't include arguments, a TermInfo trait
was added which currently has methods for inspecting number of rows and
columns. This was added as an additional trait instead of being included
on Handler since they have semantically different purposes. The tests
had to be updated to account for the additional trait bounds.
The utilities module now has a `Rotate` trait which is implemented for
the built-in slice type. This means that slices and anything derefing to
a slice can be rotated. Since VecDeque doesn't support slicing (it's
a circular buffer), the grid rows are now held in a Vec to support
rotation.
For ergomomic access to the grid for scrolling and clearing regions,
additional Index/IndexMut implementations were added to the grid::Row
type.
Finally, a `reset` method was added to `Cell` which properly resets the
state to default (instead of just clearing the char). This supports
region clearing and also fixed a bug where cell backgrounds would remain
after being cleared.
Diffstat (limited to 'src/grid.rs')
-rw-r--r-- | src/grid.rs | 76 |
1 files changed, 57 insertions, 19 deletions
diff --git a/src/grid.rs b/src/grid.rs index e094867d..7a1fedb8 100644 --- a/src/grid.rs +++ b/src/grid.rs @@ -1,10 +1,11 @@ //! Functions for computing properties of the terminal grid -use std::collections::{vec_deque, VecDeque}; -use std::ops::{Index, IndexMut, Deref, DerefMut}; +use std::ops::{Index, IndexMut, Deref, DerefMut, Range, RangeTo, RangeFrom}; use std::slice::{Iter, IterMut}; -use term::Cursor; +use util::Rotate; + +use term::{Cursor, DEFAULT_FG, DEFAULT_BG}; use ::Rgb; /// Calculate the number of cells for an axis @@ -40,13 +41,22 @@ impl Cell { flags: CellFlags::empty(), } } + + pub fn reset(&mut self) { + self.c = ' '; + self.flags = CellFlags::empty(); + + // FIXME shouldn't know about term + self.bg = DEFAULT_BG; + self.fg = DEFAULT_FG; + } } /// Represents the terminal display contents #[derive(Clone)] pub struct Grid { /// Rows in the grid. Each row holds a list of cells corresponding to the columns in that row. - raw: VecDeque<Row>, + raw: Vec<Row>, /// Number of columns cols: usize, @@ -59,9 +69,9 @@ pub struct Grid { impl Grid { pub fn new(rows: usize, cols: usize) -> Grid { - let mut raw = VecDeque::with_capacity(rows); + let mut raw = Vec::with_capacity(rows); for _ in 0..rows { - raw.push_back(Row::new(cols)); + raw.push(Row::new(cols)); } Grid { @@ -72,12 +82,12 @@ impl Grid { } #[inline] - pub fn rows(&self) -> vec_deque::Iter<Row> { + pub fn rows(&self) -> Iter<Row> { self.raw.iter() } #[inline] - pub fn rows_mut(&mut self) -> vec_deque::IterMut<Row> { + pub fn rows_mut(&mut self) -> IterMut<Row> { self.raw.iter_mut() } @@ -91,22 +101,20 @@ impl Grid { self.raw[0].len() } - pub fn feed(&mut self) { - // do the borrowck dance - let row = self.raw.pop_front().unwrap(); - self.raw.push_back(row); + pub fn scroll(&mut self, region: Range<usize>, positions: isize) { + self.raw[region].rotate(positions) } - pub fn unfeed(&mut self) { - // do the borrowck dance - let row = self.raw.pop_back().unwrap(); - self.raw.push_front(row); + #[inline] + pub fn clear(&mut self) { + let region = 0..self.num_rows(); + self.clear_region(region); } - pub fn clear(&mut self) { - for row in self.raw.iter_mut() { + pub fn clear_region(&mut self, region: Range<usize>) { + for row in self.raw[region].iter_mut() { for cell in row.iter_mut() { - cell.c = ' '; + cell.reset(); } } } @@ -190,3 +198,33 @@ impl IndexMut<usize> for Row { &mut self.0[index] } } + +impl Index<RangeFrom<usize>> for Row { + type Output = [Cell]; + #[inline] + fn index<'a>(&'a self, index: RangeFrom<usize>) -> &'a [Cell] { + &self.0[index] + } +} + +impl IndexMut<RangeFrom<usize>> for Row { + #[inline] + fn index_mut<'a>(&'a mut self, index: RangeFrom<usize>) -> &'a mut [Cell] { + &mut self.0[index] + } +} + +impl Index<RangeTo<usize>> for Row { + type Output = [Cell]; + #[inline] + fn index<'a>(&'a self, index: RangeTo<usize>) -> &'a [Cell] { + &self.0[index] + } +} + +impl IndexMut<RangeTo<usize>> for Row { + #[inline] + fn index_mut<'a>(&'a mut self, index: RangeTo<usize>) -> &'a mut [Cell] { + &mut self.0[index] + } +} |