mirror of
https://github.com/wez/wezterm.git
synced 2024-12-23 13:21:38 +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.erase_in_display(EraseInDisplay::EraseToStartOfDisplay);
|
||||||
term.cup(1, 1);
|
term.cup(1, 1);
|
||||||
term.print("hello, world!");
|
term.print("hello, world!");
|
||||||
assert_visible_contents(
|
assert_visible_contents(&term, file!(), line!(), &["", " hello, wo", "rld!", "", ""]);
|
||||||
&term,
|
|
||||||
file!(),
|
|
||||||
line!(),
|
|
||||||
&[" ", " hello, wo", "rld!", "", ""],
|
|
||||||
);
|
|
||||||
|
|
||||||
term.erase_in_display(EraseInDisplay::EraseToStartOfDisplay);
|
term.erase_in_display(EraseInDisplay::EraseToStartOfDisplay);
|
||||||
assert_visible_contents(
|
assert_visible_contents(
|
||||||
&term,
|
&term,
|
||||||
file!(),
|
file!(),
|
||||||
line!(),
|
line!(),
|
||||||
&[" ", " ", " ", "", ""],
|
&["", " ", " ", "", ""],
|
||||||
);
|
);
|
||||||
|
|
||||||
term.cup(0, 2);
|
term.cup(0, 2);
|
||||||
term.print("woot");
|
term.print("woot");
|
||||||
term.cup(2, 2);
|
term.cup(2, 2);
|
||||||
term.erase_in_line(EraseInLine::EraseToEndOfLine);
|
term.erase_in_line(EraseInLine::EraseToEndOfLine);
|
||||||
assert_visible_contents(
|
assert_visible_contents(&term, file!(), line!(), &["", " ", "wo", "", ""]);
|
||||||
&term,
|
|
||||||
file!(),
|
|
||||||
line!(),
|
|
||||||
&[" ", " ", "wo", "", ""],
|
|
||||||
);
|
|
||||||
|
|
||||||
term.erase_in_line(EraseInLine::EraseToStartOfLine);
|
term.erase_in_line(EraseInLine::EraseToStartOfLine);
|
||||||
assert_visible_contents(
|
assert_visible_contents(&term, file!(), line!(), &["", " ", " ", "", ""]);
|
||||||
&term,
|
|
||||||
file!(),
|
|
||||||
line!(),
|
|
||||||
&[" ", " ", " ", "", ""],
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Ensure that we dirty lines as the cursor is moved around, otherwise
|
/// Ensure that we dirty lines as the cursor is moved around, otherwise
|
||||||
|
@ -11,6 +11,7 @@ keywords = ["terminal", "readline", "console", "curses"]
|
|||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
# backtrace = "0.3"
|
||||||
base64 = "0.13"
|
base64 = "0.13"
|
||||||
bitflags = "1.3"
|
bitflags = "1.3"
|
||||||
cassowary = {version="0.3", optional=true}
|
cassowary = {version="0.3", optional=true}
|
||||||
|
@ -682,22 +682,20 @@ impl Line {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if let CellStorage::C(cl) = &mut self.cells {
|
if let CellStorage::C(cl) = &mut self.cells {
|
||||||
if idx == cl.len {
|
if idx >= cl.len && cell == Cell::blank() {
|
||||||
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())
|
|
||||||
{
|
|
||||||
// Appending blank beyond end of line; is already
|
// Appending blank beyond end of line; is already
|
||||||
// implicitly blank
|
// implicitly blank
|
||||||
return;
|
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!(
|
log::info!(
|
||||||
"cannot append {cell:?} to {:?} as idx={idx} and cl.len is {}",
|
"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) {
|
pub fn prune_trailing_blanks(&mut self, seqno: SequenceNo) {
|
||||||
if let CellStorage::C(cl) = &self.cells {
|
if let CellStorage::C(cl) = &mut self.cells {
|
||||||
if !cl.text.ends_with(' ') {
|
if cl.prune_trailing_blanks() {
|
||||||
// There are no trailing blanks
|
self.update_last_change_seqno(seqno);
|
||||||
return;
|
self.invalidate_zones();
|
||||||
}
|
}
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let def_attr = CellAttributes::blank();
|
let def_attr = CellAttributes::blank();
|
||||||
@ -857,6 +856,11 @@ impl Line {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn fill_range(&mut self, cols: Range<usize>, cell: &Cell, seqno: SequenceNo) {
|
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 {
|
for x in cols {
|
||||||
// FIXME: we can skip the look-back for second and subsequent iterations
|
// FIXME: we can skip the look-back for second and subsequent iterations
|
||||||
self.set_cell_impl(x, cell.clone(), true, seqno);
|
self.set_cell_impl(x, cell.clone(), true, seqno);
|
||||||
@ -904,6 +908,7 @@ impl Line {
|
|||||||
CellStorage::V(_) => return,
|
CellStorage::V(_) => return,
|
||||||
CellStorage::C(cl) => cl.to_cell_vec(),
|
CellStorage::C(cl) => cl.to_cell_vec(),
|
||||||
};
|
};
|
||||||
|
// log::info!("make_cells\n{:?}", backtrace::Backtrace::new());
|
||||||
self.cells = CellStorage::V(VecStorage::new(cells));
|
self.cells = CellStorage::V(VecStorage::new(cells));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -967,9 +972,19 @@ impl Line {
|
|||||||
/// to this line.
|
/// to this line.
|
||||||
/// This function is used by rewrapping logic when joining wrapped
|
/// This function is used by rewrapping logic when joining wrapped
|
||||||
/// lines back together.
|
/// lines back together.
|
||||||
pub fn append_line(&mut self, mut other: Line, seqno: SequenceNo) {
|
pub fn append_line(&mut self, other: Line, seqno: SequenceNo) {
|
||||||
self.coerce_vec_storage()
|
match &mut self.cells {
|
||||||
.append(&mut other.coerce_vec_storage());
|
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.update_last_change_seqno(seqno);
|
||||||
self.invalidate_zones();
|
self.invalidate_zones();
|
||||||
}
|
}
|
||||||
@ -1450,6 +1465,36 @@ impl ClusteredLine {
|
|||||||
self.len += cell_width;
|
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) {
|
fn set_last_cell_was_wrapped(&mut self, wrapped: bool) {
|
||||||
if let Some(last_cell) = self.iter().last() {
|
if let Some(last_cell) = self.iter().last() {
|
||||||
if last_cell.attrs().wrapped() == wrapped {
|
if last_cell.attrs().wrapped() == wrapped {
|
||||||
|
Loading…
Reference in New Issue
Block a user