1
1
mirror of https://github.com/wez/wezterm.git synced 2024-12-24 22:01:47 +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 |
| Gnome Terminal | 2.391 |
| Terminator 1.91 | 2.319 |
| wezterm | 1.033 |
| wezterm | 0.996 |
| kitty | 0.899 |
| urxvt | 0.615 |
| alacritty | 0.421 |

View File

@ -134,7 +134,12 @@ pub struct Cell {
impl Default for 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()
}
}
#[inline]
pub fn reset(&mut self) {
self.len = 1;
self.bytes[0] = b' ';
self.attrs = CellAttributes::default();
}
}
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.
/// In the future, we'll want to decompose into clusters of Cells that share
/// the same render attributes

View File

@ -112,11 +112,16 @@ impl Screen {
}
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 x >= width {
line.cells.resize(x + 1, Cell::default());
line.cells.resize(x, Cell::default());
line.cells.push(cell);
} else {
line.cells[x] = cell;
}
line.cells[x] = Cell::from_char(c, attr);
&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
for _ in 0..lines_removed {
for _ in 0..to_remove {
self.lines.remove(phys_scroll.start);
}
if scroll_region.end as usize == self.physical_rows {
// 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));
}
} else {
for _ in 0..num_rows {
for _ in 0..to_add {
self.lines.insert(
phys_scroll.end - lines_removed,
Line::new(self.physical_cols),