mirror of
https://github.com/wez/wezterm.git
synced 2024-12-24 05:42:03 +03:00
micro-opt scroll_up some more
This commit is contained in:
parent
48997f02d1
commit
aa95eaefd9
@ -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 |
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
|
@ -112,11 +112,16 @@ impl Screen {
|
||||
}
|
||||
|
||||
let width = line.cells.len();
|
||||
// if the line isn't wide enough, pad it out with the default attributes
|
||||
if x >= width {
|
||||
line.cells.resize(x + 1, Cell::default());
|
||||
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
|
||||
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),
|
||||
|
Loading…
Reference in New Issue
Block a user