aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoe Wilm <joe@jwilm.com>2018-02-11 21:25:33 -0800
committerJoe Wilm <joe@jwilm.com>2018-03-07 09:46:18 -0800
commit6d1d41f8c77968547b43603db51a5efeac21a400 (patch)
treef324989e4e673db22c2147b0e0d6e6c86c727af7
parent7af765502f22c1f836b047b83e95025e121f3aca (diff)
downloadalacritty-6d1d41f8c77968547b43603db51a5efeac21a400.tar.gz
alacritty-6d1d41f8c77968547b43603db51a5efeac21a400.zip
wip scrollback
-rw-r--r--src/grid/mod.rs35
-rw-r--r--src/grid/row.rs8
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;
}
}