mirror of
https://github.com/wez/wezterm.git
synced 2024-12-23 05:12:40 +03:00
termwiz: avoid cluster -> vec conversions in a few more cases
This reduces the resident memory by another ~10% because it avoids keeping as many runs of whitespace. Runtime for `time cat enwiki8.wiki` is still ~11-12s, resident: 530K refs: https://github.com/wez/wezterm/issues/1626
This commit is contained in:
parent
8002a17242
commit
7be01110ca
@ -509,39 +509,24 @@ fn basic_output() {
|
||||
term.erase_in_display(EraseInDisplay::EraseToStartOfDisplay);
|
||||
term.cup(1, 1);
|
||||
term.print("hello, world!");
|
||||
assert_visible_contents(
|
||||
&term,
|
||||
file!(),
|
||||
line!(),
|
||||
&[" ", " hello, wo", "rld!", "", ""],
|
||||
);
|
||||
assert_visible_contents(&term, file!(), line!(), &["", " hello, wo", "rld!", "", ""]);
|
||||
|
||||
term.erase_in_display(EraseInDisplay::EraseToStartOfDisplay);
|
||||
assert_visible_contents(
|
||||
&term,
|
||||
file!(),
|
||||
line!(),
|
||||
&[" ", " ", " ", "", ""],
|
||||
&["", " ", " ", "", ""],
|
||||
);
|
||||
|
||||
term.cup(0, 2);
|
||||
term.print("woot");
|
||||
term.cup(2, 2);
|
||||
term.erase_in_line(EraseInLine::EraseToEndOfLine);
|
||||
assert_visible_contents(
|
||||
&term,
|
||||
file!(),
|
||||
line!(),
|
||||
&[" ", " ", "wo", "", ""],
|
||||
);
|
||||
assert_visible_contents(&term, file!(), line!(), &["", " ", "wo", "", ""]);
|
||||
|
||||
term.erase_in_line(EraseInLine::EraseToStartOfLine);
|
||||
assert_visible_contents(
|
||||
&term,
|
||||
file!(),
|
||||
line!(),
|
||||
&[" ", " ", " ", "", ""],
|
||||
);
|
||||
assert_visible_contents(&term, file!(), line!(), &["", " ", " ", "", ""]);
|
||||
}
|
||||
|
||||
/// Ensure that we dirty lines as the cursor is moved around, otherwise
|
||||
|
@ -11,6 +11,7 @@ keywords = ["terminal", "readline", "console", "curses"]
|
||||
readme = "README.md"
|
||||
|
||||
[dependencies]
|
||||
# backtrace = "0.3"
|
||||
base64 = "0.13"
|
||||
bitflags = "1.3"
|
||||
cassowary = {version="0.3", optional=true}
|
||||
|
@ -682,22 +682,20 @@ impl Line {
|
||||
}
|
||||
|
||||
if let CellStorage::C(cl) = &mut self.cells {
|
||||
if idx == cl.len {
|
||||
cl.append(cell);
|
||||
return;
|
||||
}
|
||||
if idx > cl.len
|
||||
&& cell.str() == " "
|
||||
&& cl
|
||||
.clusters
|
||||
.last()
|
||||
.map(|c| c.attrs == *cell.attrs())
|
||||
.unwrap_or_else(|| *cell.attrs() == CellAttributes::default())
|
||||
{
|
||||
if idx >= cl.len && cell == Cell::blank() {
|
||||
// Appending blank beyond end of line; is already
|
||||
// implicitly blank
|
||||
return;
|
||||
}
|
||||
while cl.len < idx {
|
||||
// Fill out any implied blanks until we can append
|
||||
// their intended cell content
|
||||
cl.append(Cell::blank());
|
||||
}
|
||||
if idx == cl.len {
|
||||
cl.append(cell);
|
||||
return;
|
||||
}
|
||||
/*
|
||||
log::info!(
|
||||
"cannot append {cell:?} to {:?} as idx={idx} and cl.len is {}",
|
||||
@ -837,11 +835,12 @@ impl Line {
|
||||
}
|
||||
|
||||
pub fn prune_trailing_blanks(&mut self, seqno: SequenceNo) {
|
||||
if let CellStorage::C(cl) = &self.cells {
|
||||
if !cl.text.ends_with(' ') {
|
||||
// There are no trailing blanks
|
||||
return;
|
||||
if let CellStorage::C(cl) = &mut self.cells {
|
||||
if cl.prune_trailing_blanks() {
|
||||
self.update_last_change_seqno(seqno);
|
||||
self.invalidate_zones();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
let def_attr = CellAttributes::blank();
|
||||
@ -857,6 +856,11 @@ impl Line {
|
||||
}
|
||||
|
||||
pub fn fill_range(&mut self, cols: Range<usize>, cell: &Cell, seqno: SequenceNo) {
|
||||
if self.len() == 0 && *cell == Cell::blank() {
|
||||
// We would be filling it with blanks only to prune
|
||||
// them all away again before we return; NOP
|
||||
return;
|
||||
}
|
||||
for x in cols {
|
||||
// FIXME: we can skip the look-back for second and subsequent iterations
|
||||
self.set_cell_impl(x, cell.clone(), true, seqno);
|
||||
@ -904,6 +908,7 @@ impl Line {
|
||||
CellStorage::V(_) => return,
|
||||
CellStorage::C(cl) => cl.to_cell_vec(),
|
||||
};
|
||||
// log::info!("make_cells\n{:?}", backtrace::Backtrace::new());
|
||||
self.cells = CellStorage::V(VecStorage::new(cells));
|
||||
}
|
||||
|
||||
@ -967,9 +972,19 @@ impl Line {
|
||||
/// to this line.
|
||||
/// This function is used by rewrapping logic when joining wrapped
|
||||
/// lines back together.
|
||||
pub fn append_line(&mut self, mut other: Line, seqno: SequenceNo) {
|
||||
self.coerce_vec_storage()
|
||||
.append(&mut other.coerce_vec_storage());
|
||||
pub fn append_line(&mut self, other: Line, seqno: SequenceNo) {
|
||||
match &mut self.cells {
|
||||
CellStorage::V(cells) => {
|
||||
for cell in other.visible_cells() {
|
||||
cells.push(cell.as_cell());
|
||||
}
|
||||
}
|
||||
CellStorage::C(cl) => {
|
||||
for cell in other.visible_cells() {
|
||||
cl.append(cell.as_cell());
|
||||
}
|
||||
}
|
||||
}
|
||||
self.update_last_change_seqno(seqno);
|
||||
self.invalidate_zones();
|
||||
}
|
||||
@ -1450,6 +1465,36 @@ impl ClusteredLine {
|
||||
self.len += cell_width;
|
||||
}
|
||||
|
||||
fn prune_trailing_blanks(&mut self) -> bool {
|
||||
let num_spaces = self.text.chars().rev().take_while(|&c| c == ' ').count();
|
||||
if num_spaces == 0 {
|
||||
return false;
|
||||
}
|
||||
|
||||
let blank = CellAttributes::blank();
|
||||
let mut pruned = false;
|
||||
for _ in 0..num_spaces {
|
||||
let mut need_pop = false;
|
||||
if let Some(cluster) = self.clusters.last_mut() {
|
||||
if cluster.attrs != blank {
|
||||
break;
|
||||
}
|
||||
cluster.cell_width -= 1;
|
||||
self.text.pop();
|
||||
self.len -= 1;
|
||||
pruned = true;
|
||||
if cluster.cell_width == 0 {
|
||||
need_pop = true;
|
||||
}
|
||||
}
|
||||
if need_pop {
|
||||
self.clusters.pop();
|
||||
}
|
||||
}
|
||||
|
||||
pruned
|
||||
}
|
||||
|
||||
fn set_last_cell_was_wrapped(&mut self, wrapped: bool) {
|
||||
if let Some(last_cell) = self.iter().last() {
|
||||
if last_cell.attrs().wrapped() == wrapped {
|
||||
|
Loading…
Reference in New Issue
Block a user