aboutsummaryrefslogtreecommitdiff
path: root/alacritty_terminal/src/grid/resize.rs
diff options
context:
space:
mode:
Diffstat (limited to 'alacritty_terminal/src/grid/resize.rs')
-rw-r--r--alacritty_terminal/src/grid/resize.rs47
1 files changed, 33 insertions, 14 deletions
diff --git a/alacritty_terminal/src/grid/resize.rs b/alacritty_terminal/src/grid/resize.rs
index acdc040e..1a16e09e 100644
--- a/alacritty_terminal/src/grid/resize.rs
+++ b/alacritty_terminal/src/grid/resize.rs
@@ -1,16 +1,24 @@
//! Grid resize and reflow.
use std::cmp::{min, Ordering};
+use std::mem;
use crate::index::{Column, Line};
-use crate::term::cell::Flags;
+use crate::term::cell::{Flags, ResetDiscriminant};
use crate::grid::row::Row;
use crate::grid::{Dimensions, Grid, GridCell};
-impl<T: GridCell + Default + PartialEq + Copy> Grid<T> {
+impl<T: GridCell + Default + PartialEq + Clone> Grid<T> {
/// Resize the grid's width and/or height.
- pub fn resize(&mut self, reflow: bool, lines: Line, cols: Column) {
+ pub fn resize<D>(&mut self, reflow: bool, lines: Line, cols: Column)
+ where
+ T: ResetDiscriminant<D>,
+ D: PartialEq,
+ {
+ // Use empty template cell for resetting cells due to resize.
+ let template = mem::take(&mut self.cursor.template);
+
match self.lines.cmp(&lines) {
Ordering::Less => self.grow_lines(lines),
Ordering::Greater => self.shrink_lines(lines),
@@ -22,6 +30,9 @@ impl<T: GridCell + Default + PartialEq + Copy> Grid<T> {
Ordering::Greater => self.shrink_cols(reflow, cols),
Ordering::Equal => (),
}
+
+ // Restore template cell.
+ self.cursor.template = template;
}
/// Add lines to the visible area.
@@ -29,11 +40,15 @@ impl<T: GridCell + Default + PartialEq + Copy> Grid<T> {
/// Alacritty keeps the cursor at the bottom of the terminal as long as there
/// is scrollback available. Once scrollback is exhausted, new lines are
/// simply added to the bottom of the screen.
- fn grow_lines(&mut self, new_line_count: Line) {
+ fn grow_lines<D>(&mut self, new_line_count: Line)
+ where
+ T: ResetDiscriminant<D>,
+ D: PartialEq,
+ {
let lines_added = new_line_count - self.lines;
// Need to resize before updating buffer.
- self.raw.grow_visible_lines(new_line_count, Row::new(self.cols, T::default()));
+ self.raw.grow_visible_lines(new_line_count);
self.lines = new_line_count;
let history_size = self.history_size();
@@ -42,7 +57,7 @@ impl<T: GridCell + Default + PartialEq + Copy> Grid<T> {
// Move existing lines up for every line that couldn't be pulled from history.
if from_history != lines_added.0 {
let delta = lines_added - from_history;
- self.scroll_up(&(Line(0)..new_line_count), delta, T::default());
+ self.scroll_up(&(Line(0)..new_line_count), delta);
}
// Move cursor down for every line pulled from history.
@@ -60,11 +75,15 @@ impl<T: GridCell + Default + PartialEq + Copy> Grid<T> {
/// of the terminal window.
///
/// Alacritty takes the same approach.
- fn shrink_lines(&mut self, target: Line) {
+ fn shrink_lines<D>(&mut self, target: Line)
+ where
+ T: ResetDiscriminant<D>,
+ D: PartialEq,
+ {
// Scroll up to keep content inside the window.
let required_scrolling = (self.cursor.point.line + 1).saturating_sub(target.0);
if required_scrolling > 0 {
- self.scroll_up(&(Line(0)..self.lines), Line(required_scrolling), T::default());
+ self.scroll_up(&(Line(0)..self.lines), Line(required_scrolling));
// Clamp cursors to the new viewport size.
self.cursor.point.line = min(self.cursor.point.line, target - 1);
@@ -194,7 +213,7 @@ impl<T: GridCell + Default + PartialEq + Copy> Grid<T> {
if reversed.len() < self.lines.0 {
let delta = self.lines.0 - reversed.len();
self.cursor.point.line.0 = self.cursor.point.line.saturating_sub(delta);
- reversed.append(&mut vec![Row::new(cols, T::default()); delta]);
+ reversed.resize_with(self.lines.0, || Row::new(cols));
}
// Pull content down to put cursor in correct position, or move cursor up if there's no
@@ -211,7 +230,7 @@ impl<T: GridCell + Default + PartialEq + Copy> Grid<T> {
let mut new_raw = Vec::with_capacity(reversed.len());
for mut row in reversed.drain(..).rev() {
if row.len() < cols.0 {
- row.grow(cols, T::default());
+ row.grow(cols);
}
new_raw.push(row);
}
@@ -269,11 +288,11 @@ impl<T: GridCell + Default + PartialEq + Copy> Grid<T> {
// Insert spacer if a wide char would be wrapped into the last column.
if row.len() >= cols.0 && row[cols - 1].flags().contains(Flags::WIDE_CHAR) {
- wrapped.insert(0, row[cols - 1]);
-
let mut spacer = T::default();
spacer.flags_mut().insert(Flags::LEADING_WIDE_CHAR_SPACER);
- row[cols - 1] = spacer;
+
+ let wide_char = mem::replace(&mut row[cols - 1], spacer);
+ wrapped.insert(0, wide_char);
}
// Remove wide char spacer before shrinking.
@@ -330,7 +349,7 @@ impl<T: GridCell + Default + PartialEq + Copy> Grid<T> {
// Make sure new row is at least as long as new width.
let occ = wrapped.len();
if occ < cols.0 {
- wrapped.append(&mut vec![T::default(); cols.0 - occ]);
+ wrapped.resize_with(cols.0, T::default);
}
row = Row::from_vec(wrapped, occ);
}