Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'helix-tui/src/buffer.rs')
| -rw-r--r-- | helix-tui/src/buffer.rs | 64 |
1 files changed, 24 insertions, 40 deletions
diff --git a/helix-tui/src/buffer.rs b/helix-tui/src/buffer.rs index 4f57e8e5..bfcf35ac 100644 --- a/helix-tui/src/buffer.rs +++ b/helix-tui/src/buffer.rs @@ -1,4 +1,3 @@ -//! Contents of a terminal screen. A [Buffer] is made up of [Cell]s. use crate::text::{Span, Spans}; use helix_core::unicode::width::UnicodeWidthStr; use std::cmp::min; @@ -6,7 +5,7 @@ use unicode_segmentation::UnicodeSegmentation; use helix_view::graphics::{Color, Modifier, Rect, Style, UnderlineStyle}; -/// One cell of the terminal. Contains one stylized grapheme. +/// A buffer cell #[derive(Debug, Clone, PartialEq, Eq)] pub struct Cell { pub symbol: String, @@ -18,33 +17,28 @@ pub struct Cell { } impl Cell { - /// Set the cell's grapheme pub fn set_symbol(&mut self, symbol: &str) -> &mut Cell { self.symbol.clear(); self.symbol.push_str(symbol); self } - /// Set the cell's grapheme to a [char] pub fn set_char(&mut self, ch: char) -> &mut Cell { self.symbol.clear(); self.symbol.push(ch); self } - /// Set the foreground [Color] pub fn set_fg(&mut self, color: Color) -> &mut Cell { self.fg = color; self } - /// Set the background [Color] pub fn set_bg(&mut self, color: Color) -> &mut Cell { self.bg = color; self } - /// Set the [Style] of the cell pub fn set_style(&mut self, style: Style) -> &mut Cell { if let Some(c) = style.fg { self.fg = c; @@ -64,7 +58,6 @@ impl Cell { self } - /// Returns the current style of the cell pub fn style(&self) -> Style { Style::default() .fg(self.fg) @@ -74,7 +67,6 @@ impl Cell { .add_modifier(self.modifier) } - /// Resets the cell to a default blank state pub fn reset(&mut self) { self.symbol.clear(); self.symbol.push(' '); @@ -334,44 +326,43 @@ impl Buffer { return (x, y); } - let mut index = self.index_of(x, y); - let mut rendered_width = 0; - let mut graphemes = string.grapheme_indices(true); + let max_offset = min( + self.area.right() as usize - 1, + width.saturating_add(x as usize), + ); + let mut start_index = self.index_of(x, y); + let mut end_index = self.index_of(max_offset as u16, y); + + if truncate_end { + self.content[end_index].set_symbol("…"); + end_index -= 1; + } if truncate_start { - for _ in 0..graphemes.next().map(|(_, g)| g.width()).unwrap_or_default() { - self.content[index].set_symbol("…"); - index += 1; - rendered_width += 1; - } + self.content[start_index].set_symbol("…"); + start_index += 1; } - for (byte_offset, s) in graphemes { - let grapheme_width = s.width(); - if truncate_end && rendered_width + grapheme_width >= width { + let graphemes = string.grapheme_indices(true); + + for (byte_offset, s) in graphemes.skip(truncate_start as usize) { + if start_index > end_index { break; } - if grapheme_width == 0 { + let width = s.width(); + if width == 0 { continue; } - self.content[index].set_symbol(s); - self.content[index].set_style(style(byte_offset)); + self.content[start_index].set_symbol(s); + self.content[start_index].set_style(style(byte_offset)); // Reset following cells if multi-width (they would be hidden by the grapheme): - for i in index + 1..index + grapheme_width { + for i in start_index + 1..start_index + width { self.content[i].reset(); } - index += grapheme_width; - rendered_width += grapheme_width; - } - - if truncate_end { - for _ in 0..width.saturating_sub(rendered_width) { - self.content[index].set_symbol("…"); - index += 1; - } + start_index += width; } (x, y) @@ -503,8 +494,6 @@ impl Buffer { (x_offset as u16, y) } - /// Print at most the first `width` characters of a [Spans] if enough space is available - /// until the end of the line. Appends a `…` at the end of truncated lines. pub fn set_spans_truncated(&mut self, x: u16, y: u16, spans: &Spans, width: u16) -> (u16, u16) { // prevent panic if out of range if !self.in_bounds(x, y) || width == 0 { @@ -546,8 +535,6 @@ impl Buffer { (x_offset as u16, y) } - /// Print at most the first `width` characters of a [Spans] if enough space is available - /// until the end of the line pub fn set_spans(&mut self, x: u16, y: u16, spans: &Spans, width: u16) -> (u16, u16) { let mut remaining_width = width; let mut x = x; @@ -569,8 +556,6 @@ impl Buffer { (x, y) } - /// Print at most the first `width` characters of a [Span] if enough space is available - /// until the end of the line pub fn set_span(&mut self, x: u16, y: u16, span: &Span, width: u16) -> (u16, u16) { self.set_stringn(x, y, span.content.as_ref(), width as usize, span.style) } @@ -587,7 +572,6 @@ impl Buffer { } } - /// Set all cells in the [area](Rect) to the given [Style] pub fn set_style(&mut self, area: Rect, style: Style) { for y in area.top()..area.bottom() { for x in area.left()..area.right() { |