diff --git a/src/grid/mod.rs b/src/grid/mod.rs index 3495be1d..faf67772 100644 --- a/src/grid/mod.rs +++ b/src/grid/mod.rs @@ -73,17 +73,6 @@ pub struct Grid { /// Invariant: lines is equivalent to raw.len() lines: index::Line, - /// Template row. - /// - /// This is used to quickly populate new lines and clear recycled lines - /// during scroll wrapping. - #[serde(skip)] - template_row: Row, - - /// Template cell for populating template_row - #[serde(skip)] - template: T, - /// Offset of displayed area /// /// If the displayed region isn't at the bottom of the screen, it stays @@ -126,7 +115,6 @@ pub enum Scroll { impl Grid { pub fn new(lines: index::Line, cols: index::Column, scrollback: usize, template: T) -> Grid { let mut raw = Storage::with_capacity(*lines + scrollback, lines); - let template_row = Row::new(cols, &template); // Allocate all lines in the buffer, including scrollback history // @@ -134,15 +122,13 @@ impl Grid { // 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()); + raw.push(Row::new(cols, &template)); } Grid { raw, cols, lines, - template_row, - template, display_offset: 0, scroll_limit: 0, selection: None, @@ -200,20 +186,25 @@ impl Grid { } } - pub fn resize(&mut self, lines: index::Line, cols: index::Column) { + pub fn resize( + &mut self, + lines: index::Line, + cols: index::Column, + template: &T, + ) { // Check that there's actually work to do and return early if not if lines == self.lines && cols == self.cols { return; } match self.lines.cmp(&lines) { - Ordering::Less => self.grow_lines(lines), + Ordering::Less => self.grow_lines(lines, template), Ordering::Greater => self.shrink_lines(lines), Ordering::Equal => (), } match self.cols.cmp(&cols) { - Ordering::Less => self.grow_cols(cols), + Ordering::Less => self.grow_cols(cols, template), Ordering::Greater => self.shrink_cols(cols), Ordering::Equal => (), } @@ -237,7 +228,11 @@ impl Grid { /// Alacritty takes a different approach. Rather than trying to move with /// the scrollback, we simply pull additional lines from the back of the /// buffer in order to populate the new area. - fn grow_lines(&mut self, new_line_count: index::Line) { + fn grow_lines( + &mut self, + new_line_count: index::Line, + template: &T, + ) { let previous_scroll_limit = self.scroll_limit; let lines_added = new_line_count - self.lines; @@ -246,21 +241,18 @@ impl Grid { self.lines = new_line_count; // Add new lines to bottom - self.scroll_up(&(Line(0)..new_line_count), lines_added); + self.scroll_up(&(Line(0)..new_line_count), lines_added, template); self.scroll_limit = self.scroll_limit.saturating_sub(*lines_added); } - fn grow_cols(&mut self, cols: index::Column) { + fn grow_cols(&mut self, cols: index::Column, template: &T) { for row in self.raw.iter_mut() { - row.grow(cols, &self.template); + row.grow(cols, template); } // Update self cols self.cols = cols; - - // Also update template_row to be the correct length - self.template_row.grow(cols, &self.template); } /// Remove lines from the visible area @@ -304,7 +296,12 @@ impl Grid { } #[inline] - pub fn scroll_down(&mut self, region: &Range, positions: index::Line) { + pub fn scroll_down( + &mut self, + region: &Range, + positions: index::Line, + template: &T, + ) { // Whether or not there is a scrolling region active, as long as it // starts at the top, we can do a full rotation which just involves // changing the start index. @@ -328,7 +325,7 @@ impl Grid { // Finally, reset recycled lines for i in IndexRange(Line(0)..positions) { - self.raw[i].reset(&self.template_row); + self.raw[i].reset(&template); } } else { // Subregion rotation @@ -337,7 +334,7 @@ impl Grid { } for line in IndexRange(region.start .. (region.start + positions)) { - self.raw[line].reset(&self.template_row); + self.raw[line].reset(&template); } } } @@ -346,7 +343,12 @@ impl Grid { /// /// This is the performance-sensitive part of scrolling. #[inline] - pub fn scroll_up(&mut self, region: &Range, positions: index::Line) { + pub fn scroll_up( + &mut self, + region: &Range, + positions: index::Line, + template: &T + ) { if region.start == Line(0) { // Update display offset when not pinned to active area if self.display_offset != 0 { @@ -372,7 +374,7 @@ impl Grid { // // Recycled lines are just above the end of the scrolling region. for i in 0..*positions { - self.raw[region.end - i - 1].reset(&self.template_row); + self.raw[region.end - i - 1].reset(&template); } } else { // Subregion rotation @@ -382,7 +384,7 @@ impl Grid { // Clear reused lines for line in IndexRange((region.end - positions) .. region.end) { - self.raw[line].reset(&self.template_row); + self.raw[line].reset(&template); } } } @@ -432,7 +434,6 @@ impl Grid { } self.cols = cols; - self.template_row.shrink(cols); } } diff --git a/src/grid/row.rs b/src/grid/row.rs index f6b2a20e..f7e4a98a 100644 --- a/src/grid/row.rs +++ b/src/grid/row.rs @@ -37,8 +37,10 @@ impl Row { /// Resets contents to the contents of `other` #[inline] - pub fn reset(&mut self, other: &Row) { - self.copy_from_slice(&**other); + pub fn reset(&mut self, other: &T) { + for item in &mut self.0 { + *item = *other; + } } } diff --git a/src/grid/storage.rs b/src/grid/storage.rs index 0f1ba9c5..b620b9c0 100644 --- a/src/grid/storage.rs +++ b/src/grid/storage.rs @@ -56,11 +56,6 @@ impl Storage { self.inner.push(item) } - #[inline] - pub fn pop(&mut self) -> Option { - self.inner.pop() - } - #[inline] pub fn len(&self) -> usize { self.inner.len() @@ -76,12 +71,6 @@ impl Storage { ((self.len() + self.zero + *self.visible_lines) - *requested) % self.len() } - pub fn swap(&mut self, a: usize, b: usize) { - let a = self.compute_index(a); - let b = self.compute_index(b); - self.inner.swap(a, b); - } - pub fn swap_lines(&mut self, a: Line, b: Line) { let a = self.compute_line_index(a); let b = self.compute_line_index(b); diff --git a/src/grid/tests.rs b/src/grid/tests.rs index 107e7103..3e229fb6 100644 --- a/src/grid/tests.rs +++ b/src/grid/tests.rs @@ -29,7 +29,7 @@ fn scroll_up() { info!("grid: {:?}", grid); - grid.scroll_up(&(Line(0)..Line(10)), Line(2)); + grid.scroll_up(&(Line(0)..Line(10)), Line(2), &0); info!("grid: {:?}", grid); @@ -65,7 +65,7 @@ fn scroll_down() { info!("grid: {:?}", grid); - grid.scroll_down(&(Line(0)..Line(10)), Line(2)); + grid.scroll_down(&(Line(0)..Line(10)), Line(2), &0); info!("grid: {:?}", grid); diff --git a/src/selection.rs b/src/selection.rs index 188df348..6f910bce 100644 --- a/src/selection.rs +++ b/src/selection.rs @@ -181,9 +181,6 @@ impl Selection { ) -> Option where G: SemanticSearch + Dimensions { - let mut start = initial_expansion.start; - let mut end = initial_expansion.end; - // Normalize ordering of selected cells let (front, tail) = if region.start < region.end { (region.start, region.end) @@ -191,13 +188,11 @@ impl Selection { (region.end, region.start) }; - if front < tail && front.line == tail.line { - start = grid.semantic_search_left(front); - end = grid.semantic_search_right(tail); + let (mut start, mut end) = if front < tail && front.line == tail.line { + (grid.semantic_search_left(front), grid.semantic_search_right(tail)) } else { - start = grid.semantic_search_right(front); - end = grid.semantic_search_left(tail); - } + (grid.semantic_search_right(front), grid.semantic_search_left(tail)) + }; if start > end { ::std::mem::swap(&mut start, &mut end); diff --git a/src/term/mod.rs b/src/term/mod.rs index dcefac54..3f8929b6 100644 --- a/src/term/mod.rs +++ b/src/term/mod.rs @@ -1117,19 +1117,19 @@ impl Term { // Scroll up to keep cursor in terminal if self.cursor.point.line >= num_lines { let lines = self.cursor.point.line - num_lines + 1; - self.grid.scroll_up(&(Line(0)..old_lines), lines); + self.grid.scroll_up(&(Line(0)..old_lines), lines, &self.cursor.template); } // Scroll up alt grid as well if self.cursor_save_alt.point.line >= num_lines { let lines = self.cursor_save_alt.point.line - num_lines + 1; - self.alt_grid.scroll_up(&(Line(0)..old_lines), lines); + self.alt_grid.scroll_up(&(Line(0)..old_lines), lines, &self.cursor_save_alt.template); } debug!("num_cols, num_lines = {}, {}", num_cols, num_lines); // Resize grids to new size - self.grid.resize(num_lines, num_cols); - self.alt_grid.resize(num_lines, num_cols); + self.grid.resize(num_lines, num_cols, &self.cursor.template); + self.alt_grid.resize(num_lines, num_cols, &self.cursor_save_alt.template); // Reset scrolling region to new size self.scroll_region = Line(0)..self.grid.num_lines(); @@ -1195,7 +1195,7 @@ impl Term { let lines = min(lines, self.scroll_region.end - self.scroll_region.start); // Scroll between origin and bottom - self.grid.scroll_down(&(origin..self.scroll_region.end), lines); + self.grid.scroll_down(&(origin..self.scroll_region.end), lines, &self.cursor.template); } /// Scroll screen up @@ -1208,7 +1208,7 @@ impl Term { let lines = min(lines, self.scroll_region.end - self.scroll_region.start); // Scroll from origin to bottom less number of lines - self.grid.scroll_up(&(origin..self.scroll_region.end), lines); + self.grid.scroll_up(&(origin..self.scroll_region.end), lines, &self.cursor.template); } fn deccolm(&mut self) {