1
1
mirror of https://github.com/wez/wezterm.git synced 2024-12-25 06:12:16 +03:00

micro-opt scroll_up some more

This commit is contained in:
Wez Furlong 2018-02-19 09:51:59 -08:00
parent 48997f02d1
commit aa95eaefd9
4 changed files with 53 additions and 9 deletions

View File

@ -141,7 +141,7 @@ set to 80x24 with 3500 lines of scrollback. `alacritty` has no scrollback.
| xterm | 9.863 | | xterm | 9.863 |
| Gnome Terminal | 2.391 | | Gnome Terminal | 2.391 |
| Terminator 1.91 | 2.319 | | Terminator 1.91 | 2.319 |
| wezterm | 1.033 | | wezterm | 0.996 |
| kitty | 0.899 | | kitty | 0.899 |
| urxvt | 0.615 | | urxvt | 0.615 |
| alacritty | 0.421 | | alacritty | 0.421 |

View File

@ -134,7 +134,12 @@ pub struct Cell {
impl Default for Cell { impl Default for Cell {
fn default() -> Cell { fn default() -> Cell {
Cell::from_char(' ', &CellAttributes::default()) let bytes = [b' ', 0, 0, 0, 0, 0, 0];
Cell {
len: 1,
bytes,
attrs: CellAttributes::default()
}
} }
} }
@ -185,6 +190,13 @@ impl Cell {
self.str().width() self.str().width()
} }
} }
#[inline]
pub fn reset(&mut self) {
self.len = 1;
self.bytes[0] = b' ';
self.attrs = CellAttributes::default();
}
} }
impl From<char> for Cell { impl From<char> for Cell {

View File

@ -58,6 +58,14 @@ impl Line {
} }
} }
pub fn reset(&mut self, width: usize) {
let blank = Cell::default();
self.cells.resize(width, blank);
for cell in self.cells.iter_mut() {
cell.reset();
}
}
/// Recompose line into the corresponding utf8 string. /// Recompose line into the corresponding utf8 string.
/// In the future, we'll want to decompose into clusters of Cells that share /// In the future, we'll want to decompose into clusters of Cells that share
/// the same render attributes /// the same render attributes

View File

@ -112,11 +112,16 @@ impl Screen {
} }
let width = line.cells.len(); let width = line.cells.len();
let cell = Cell::from_char(c, attr);
if x == width {
line.cells.push(cell);
} else if x > width {
// if the line isn't wide enough, pad it out with the default attributes // if the line isn't wide enough, pad it out with the default attributes
if x >= width { line.cells.resize(x, Cell::default());
line.cells.resize(x + 1, Cell::default()); line.cells.push(cell);
} else {
line.cells[x] = cell;
} }
line.cells[x] = Cell::from_char(c, attr);
&line.cells[x] &line.cells[x]
} }
@ -203,18 +208,37 @@ impl Screen {
} }
}; };
// To avoid thrashing the heap, prefer to move lines that were
// scrolled off the top and re-use them at the bottom.
let to_move = lines_removed.min(num_rows);
let (to_remove, to_add) = {
for _ in 0..to_move {
let mut line = self.lines.remove(phys_scroll.start);
// Make the line like a new one of the appropriate width
line.reset(self.physical_cols);
if scroll_region.end as usize == self.physical_rows {
self.lines.push(line);
} else {
self.lines.insert(phys_scroll.end - lines_removed, line);
}
}
// We may still have some lines to add at the bottom, so
// return revised counts for remove/add
(lines_removed - to_move, num_rows - to_move)
};
// Perform the removal // Perform the removal
for _ in 0..lines_removed { for _ in 0..to_remove {
self.lines.remove(phys_scroll.start); self.lines.remove(phys_scroll.start);
} }
if scroll_region.end as usize == self.physical_rows { if scroll_region.end as usize == self.physical_rows {
// It's cheaper to push() than it is insert() at the end // It's cheaper to push() than it is insert() at the end
for _ in 0..num_rows { for _ in 0..to_add {
self.lines.push(Line::new(self.physical_cols)); self.lines.push(Line::new(self.physical_cols));
} }
} else { } else {
for _ in 0..num_rows { for _ in 0..to_add {
self.lines.insert( self.lines.insert(
phys_scroll.end - lines_removed, phys_scroll.end - lines_removed,
Line::new(self.physical_cols), Line::new(self.physical_cols),