wip scrollback
This commit is contained in:
parent
84769ce170
commit
94796a70fc
|
@ -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]
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue