diff options
author | Joe Wilm <joe@jwilm.com> | 2018-02-11 21:25:33 -0800 |
---|---|---|
committer | Joe Wilm <joe@jwilm.com> | 2018-03-07 09:46:18 -0800 |
commit | 6d1d41f8c77968547b43603db51a5efeac21a400 (patch) | |
tree | f324989e4e673db22c2147b0e0d6e6c86c727af7 | |
parent | 7af765502f22c1f836b047b83e95025e121f3aca (diff) | |
download | alacritty-6d1d41f8c77968547b43603db51a5efeac21a400.tar.gz alacritty-6d1d41f8c77968547b43603db51a5efeac21a400.zip |
wip scrollback
-rw-r--r-- | src/grid/mod.rs | 35 | ||||
-rw-r--r-- | src/grid/row.rs | 8 |
2 files changed, 35 insertions, 8 deletions
diff --git a/src/grid/mod.rs b/src/grid/mod.rs index 12702ddf..f0bd2f6f 100644 --- a/src/grid/mod.rs +++ b/src/grid/mod.rs @@ -35,6 +35,9 @@ mod tests; mod storage; use self::storage::Storage; +/// Lines to keep in scrollback buffer +const SCROLLBACK_LINES: usize = 100_000; + /// Convert a type to a linear index range. pub trait ToRange { fn to_range(&self) -> RangeInclusive<index::Linear>; @@ -87,6 +90,13 @@ pub struct Grid<T> { /// Temporary row storage for scrolling with a region temp: Vec<Row<T>>, + + /// Offset of displayed area + /// + /// If the displayed region isn't at the bottom of the screen, it stays + /// stationary while more text is emitted. The scrolling implementation + /// updates this offset accordingly. + display_offset: usize, } pub struct GridIterator<'a, T: 'a> { @@ -96,9 +106,15 @@ pub struct GridIterator<'a, T: 'a> { impl<T: Copy + Clone> Grid<T> { pub fn new(lines: index::Line, cols: index::Column, template: T) -> Grid<T> { - let mut raw = Storage::with_capacity(*lines); + let mut raw = Storage::with_capacity(*lines + SCROLLBACK_LINES); let template_row = Row::new(cols, &template); - for _ in IndexRange(index::Line(0)..lines) { + + // Allocate all lines in the buffer, including scrollback history + // + // TODO (jwilm) Allocating each line at this point is expensive and + // delays startup. A nice solution might be having `Row` delay + // allocation until it's actually used. + for _ in 0..raw.capacity() { raw.push(template_row.clone()); } @@ -191,6 +207,11 @@ impl<T: Copy + Clone> Grid<T> { #[inline] pub fn scroll_up(&mut self, region: &Range<index::Line>, positions: index::Line) { if region.start == Line(0) { + // Update display offset when not pinned to active area + if self.display_offset != 0 { + self.display_offset += *positions; + } + // Rotate the entire line buffer. If there's a scrolling region // active, the bottom lines are restored in the next step. self.raw.rotate_up(*positions); @@ -319,14 +340,16 @@ impl<T> Index<index::Line> for Grid<T> { #[inline] fn index(&self, index: index::Line) -> &Row<T> { - &self.raw[index.0] + let index = self.lines.0 - index.0; + &self.raw[index] } } impl<T> IndexMut<index::Line> for Grid<T> { #[inline] fn index_mut(&mut self, index: index::Line) -> &mut Row<T> { - &mut self.raw[index.0] + let index = self.lines.0 - index.0; + &mut self.raw[index] } } @@ -335,14 +358,14 @@ impl<'point, T> Index<&'point Point> for Grid<T> { #[inline] fn index<'a>(&'a self, point: &Point) -> &'a T { - &self.raw[point.line.0][point.col] + &self[point.line][point.col] } } impl<'point, T> IndexMut<&'point Point> for Grid<T> { #[inline] fn index_mut<'a, 'b>(&'a mut self, point: &'b Point) -> &'a mut T { - &mut self.raw[point.line.0][point.col] + &mut self[point.line][point.col] } } diff --git a/src/grid/row.rs b/src/grid/row.rs index e9cf8dc9..1c83d45d 100644 --- a/src/grid/row.rs +++ b/src/grid/row.rs @@ -22,7 +22,10 @@ use index::Column; /// A row in the grid #[derive(Clone, Debug, Serialize, Deserialize, Eq, PartialEq)] -pub struct Row<T>(Vec<T>); +pub struct Row<T> { + data: Vec<T>, + id: u64 +} impl<T: Copy + Clone> Row<T> { pub fn new(columns: Column, template: &T) -> Row<T> { @@ -37,8 +40,9 @@ impl<T: Copy + Clone> Row<T> { /// Resets contents to the contents of `other` #[inline] - pub fn reset(&mut self, other: &Row<T>) { + pub fn reset(&mut self, other: &Row<T>, id: u64) { self.copy_from_slice(&**other); + self.id = id; } } |