aboutsummaryrefslogtreecommitdiff
path: root/helix-tui/src/buffer.rs
diff options
context:
space:
mode:
authorBlaž Hrastnik2021-11-06 15:28:19 +0000
committerBlaž Hrastnik2021-11-06 15:28:19 +0000
commitf2b709a3c3a9cc036bfea46734efd7e4100eb34b (patch)
treead5f921f13659e5ba395442e13389af317ee81b0 /helix-tui/src/buffer.rs
parentcde57dae356021c6ca8c2a2ed68777bd9d0bc0b2 (diff)
parentf979bdc442ab3150a369ff8bee0703e90e32e2a4 (diff)
Merge branch 'master' into debug
Diffstat (limited to 'helix-tui/src/buffer.rs')
-rw-r--r--helix-tui/src/buffer.rs78
1 files changed, 56 insertions, 22 deletions
diff --git a/helix-tui/src/buffer.rs b/helix-tui/src/buffer.rs
index 377e3e39..f480bc2f 100644
--- a/helix-tui/src/buffer.rs
+++ b/helix-tui/src/buffer.rs
@@ -266,12 +266,14 @@ impl Buffer {
where
S: AsRef<str>,
{
- self.set_string_truncated(x, y, string, width, style, false)
+ self.set_string_truncated(x, y, string, width, style, false, false)
}
/// Print at most the first `width` characters of a string if enough space is available
- /// until the end of the line. If `markend` is true appends a `…` at the end of
- /// truncated lines.
+ /// until the end of the line. If `ellipsis` is true appends a `…` at the end of
+ /// truncated lines. If `truncate_start` is `true`, truncate the beginning of the string
+ /// instead of the end.
+ #[allow(clippy::too_many_arguments)]
pub fn set_string_truncated<S>(
&mut self,
x: u16,
@@ -280,6 +282,7 @@ impl Buffer {
width: usize,
style: Style,
ellipsis: bool,
+ truncate_start: bool,
) -> (u16, u16)
where
S: AsRef<str>,
@@ -289,28 +292,59 @@ impl Buffer {
let width = if ellipsis { width - 1 } else { width };
let graphemes = UnicodeSegmentation::graphemes(string.as_ref(), true);
let max_offset = min(self.area.right() as usize, width.saturating_add(x as usize));
- for s in graphemes {
- let width = s.width();
- if width == 0 {
- continue;
+ if !truncate_start {
+ for s in graphemes {
+ let width = s.width();
+ if width == 0 {
+ continue;
+ }
+ // `x_offset + width > max_offset` could be integer overflow on 32-bit machines if we
+ // change dimenstions to usize or u32 and someone resizes the terminal to 1x2^32.
+ if width > max_offset.saturating_sub(x_offset) {
+ break;
+ }
+
+ self.content[index].set_symbol(s);
+ self.content[index].set_style(style);
+ // Reset following cells if multi-width (they would be hidden by the grapheme),
+ for i in index + 1..index + width {
+ self.content[i].reset();
+ }
+ index += width;
+ x_offset += width;
}
- // `x_offset + width > max_offset` could be integer overflow on 32-bit machines if we
- // change dimenstions to usize or u32 and someone resizes the terminal to 1x2^32.
- if width > max_offset.saturating_sub(x_offset) {
- break;
+ if ellipsis && x_offset - (x as usize) < string.as_ref().width() {
+ self.content[index].set_symbol("…");
}
-
- self.content[index].set_symbol(s);
- self.content[index].set_style(style);
- // Reset following cells if multi-width (they would be hidden by the grapheme),
- for i in index + 1..index + width {
- self.content[i].reset();
+ } else {
+ let mut start_index = self.index_of(x, y);
+ let mut index = self.index_of(max_offset as u16, y);
+
+ let total_width = string.as_ref().width();
+ let truncated = total_width > width;
+ if ellipsis && truncated {
+ self.content[start_index].set_symbol("…");
+ start_index += 1;
+ }
+ if !truncated {
+ index -= width - total_width;
+ }
+ for s in graphemes.rev() {
+ let width = s.width();
+ if width == 0 {
+ continue;
+ }
+ let start = index - width;
+ if start < start_index {
+ break;
+ }
+ self.content[start].set_symbol(s);
+ self.content[start].set_style(style);
+ for i in start + 1..index {
+ self.content[i].reset();
+ }
+ index -= width;
}
- index += width;
- x_offset += width;
- }
- if ellipsis && x_offset - (x as usize) < string.as_ref().width() {
- self.content[index].set_symbol("…");
}
(x_offset as u16, y)
}