Performant and correct set_spans_truncated

the previous implementation used set_string_truncated. This is not only
awkward with this kind of "streaming" string (and therefore lead to an
inefficient and incorrect initial implementation) but that function also
truncates strings of width 1 when there is only a single char available.

The implementation here is performant, correct and also handles the
single width case correctly.
feature/delete-command
Pascal Kuthe 1 year ago committed by Blaž Hrastnik
parent e72be52996
commit 67783ddfd4
No known key found for this signature in database
GPG Key ID: 1238B9C4AD889640

@ -434,28 +434,44 @@ impl Buffer {
} }
pub fn set_spans_truncated(&mut self, x: u16, y: u16, spans: &Spans, width: u16) -> (u16, u16) { pub fn set_spans_truncated(&mut self, x: u16, y: u16, spans: &Spans, width: u16) -> (u16, u16) {
let mut remaining_width = width; // prevent panic if out of range
let mut alt_x = x; if !self.in_bounds(x, y) || width == 0 {
let (text, styles) = return (x, y);
spans }
.0
.iter() let mut x_offset = x as usize;
.fold((String::new(), vec![]), |(mut s, mut h), span| { let max_offset = min(self.area.right(), width.saturating_add(x));
s.push_str(span.content.as_ref()); let mut start_index = self.index_of(x, y);
let mut styles = span let mut index = self.index_of(max_offset as u16, y);
.styled_graphemes(span.style)
.map(|grapheme| grapheme.style) let content_width = spans.width();
.collect(); let truncated = content_width > width as usize;
h.append(&mut styles); if truncated {
self.content[start_index].set_symbol("…");
let w = span.width() as u16; start_index += 1;
alt_x = alt_x + w; } else {
remaining_width = remaining_width.saturating_sub(w); index -= width as usize - content_width;
}
(s, h) for span in spans.0.iter().rev() {
}); for s in span.content.graphemes(true).rev() {
self.set_string_truncated(x, y, &text, width.into(), |idx| styles[idx], true, true); let width = s.width();
(x, y) if width == 0 {
continue;
}
let start = index - width;
if start < start_index {
break;
}
self.content[start].set_symbol(s);
self.content[start].set_style(span.style);
for i in start + 1..index {
self.content[i].reset();
}
index -= width;
x_offset += width;
}
}
(x_offset as u16, y)
} }
pub fn set_spans(&mut self, x: u16, y: u16, spans: &Spans, width: u16) -> (u16, u16) { pub fn set_spans(&mut self, x: u16, y: u16, spans: &Spans, width: u16) -> (u16, u16) {

Loading…
Cancel
Save