diff --git a/helix-term/src/ui/picker.rs b/helix-term/src/ui/picker.rs index 3f3aaba2b..1940a9b62 100644 --- a/helix-term/src/ui/picker.rs +++ b/helix-term/src/ui/picker.rs @@ -308,7 +308,10 @@ impl Picker { F: Fn(&mut Context, &T, Action) + 'static, { let columns: Arc<[_]> = columns.into_iter().collect(); - let matcher_columns = columns.iter().filter(|col| col.filter).count() as u32; + let matcher_columns = columns + .iter() + .filter(|col: &&Column| col.filter) + .count() as u32; assert!(matcher_columns > 0); let matcher = Nucleo::new( Config::DEFAULT, diff --git a/helix-tui/src/text.rs b/helix-tui/src/text.rs index 1317a0095..a9c36503a 100644 --- a/helix-tui/src/text.rs +++ b/helix-tui/src/text.rs @@ -374,6 +374,30 @@ impl<'a> Text<'a> { self.lines.len() } + /// Patch text with a new style. Only updates fields that are in the new style. + /// + /// # Examples + /// + /// ```rust + /// # use helix_tui::text::Text; + /// # use helix_view::graphics::{Color, Style}; + /// let style1 = Style::default().fg(Color::Yellow); + /// let style2 = Style::default().fg(Color::Yellow).bg(Color::Black); + /// let mut half_styled_text = Text::styled(String::from("The first line\nThe second line"), style1); + /// let full_styled_text = Text::styled(String::from("The first line\nThe second line"), style2); + /// assert_ne!(half_styled_text, full_styled_text); + /// + /// half_styled_text.patch_style(Style::default().bg(Color::Black)); + /// assert_eq!(half_styled_text, full_styled_text); + /// ``` + pub fn patch_style(&mut self, style: Style) { + for line in &mut self.lines { + for span in &mut line.0 { + span.style = span.style.patch(style); + } + } + } + /// Apply a new style to existing text. /// /// # Examples @@ -386,13 +410,13 @@ impl<'a> Text<'a> { /// let styled_text = Text::styled(String::from("The first line\nThe second line"), style); /// assert_ne!(raw_text, styled_text); /// - /// raw_text.patch_style(style); + /// raw_text.set_style(style); /// assert_eq!(raw_text, styled_text); /// ``` - pub fn patch_style(&mut self, style: Style) { + pub fn set_style(&mut self, style: Style) { for line in &mut self.lines { for span in &mut line.0 { - span.style = span.style.patch(style); + span.style = style; } } } diff --git a/helix-tui/src/widgets/table.rs b/helix-tui/src/widgets/table.rs index 234df2e4b..57f448834 100644 --- a/helix-tui/src/widgets/table.rs +++ b/helix-tui/src/widgets/table.rs @@ -38,8 +38,15 @@ impl Cell<'_> { /// Set the `Style` of this cell. pub fn style(mut self, style: Style) -> Self { self.style = style; + self.content.set_style(style); self } + + /// Set the `Style` of this cell. + pub fn set_style(&mut self, style: Style) { + self.style = style; + self.content.set_style(style); + } } impl<'a, T> From for Cell<'a> @@ -453,6 +460,9 @@ impl Table<'_> { }; if is_selected { buf.set_style(table_row_area, self.highlight_style); + for cell in &mut table_row.cells { + cell.set_style(self.highlight_style); + } } let mut col = table_row_start_col; for (width, cell) in columns_widths.iter().zip(table_row.cells.iter()) { diff --git a/helix-tui/tests/text.rs b/helix-tui/tests/text.rs new file mode 100644 index 000000000..c5fbde8dc --- /dev/null +++ b/helix-tui/tests/text.rs @@ -0,0 +1,128 @@ +use helix_tui::text::{Span, Spans, StyledGrapheme, Text}; +use helix_view::graphics::{Color, Modifier, Style}; + +// Text +#[test] +fn text_width() { + let text = Text::from("The first line\nThe second line"); + assert_eq!(15, text.width()); +} + +#[test] +fn text_height() { + let text = Text::from("The first line\nThe second line"); + assert_eq!(2, text.height()); +} + +#[test] +fn patch_style() { + let style1 = Style::default().fg(Color::Yellow); + let style2 = Style::default().fg(Color::Yellow).bg(Color::Black); + let mut half_styled_text = + Text::styled(String::from("The first line\nThe second line"), style1); + let full_styled_text = Text::styled(String::from("The first line\nThe second line"), style2); + assert_ne!(half_styled_text, full_styled_text); + + half_styled_text.patch_style(Style::default().bg(Color::Black)); + assert_eq!(half_styled_text, full_styled_text); +} + +#[test] +fn set_style() { + let style = Style::default() + .fg(Color::Yellow) + .add_modifier(Modifier::ITALIC); + let mut raw_text = Text::raw("The first line\nThe second line"); + let styled_text = Text::styled(String::from("The first line\nThe second line"), style); + assert_ne!(raw_text, styled_text); + + raw_text.set_style(style); + assert_eq!(raw_text, styled_text); +} + +#[test] +fn text_extend() { + let style = Style::default() + .fg(Color::Yellow) + .add_modifier(Modifier::ITALIC); + let mut text = Text::from("The first line\nThe second line"); + assert_eq!(2, text.height()); + + // Adding two more unstyled lines + text.extend(Text::raw("These are two\nmore lines!")); + assert_eq!(4, text.height()); + + // Adding a final two styled lines + text.extend(Text::styled("Some more lines\nnow with more style!", style)); + assert_eq!(6, text.height()); +} + +// Span + +#[test] +fn styled_graphemes() { + let style = Style::default().fg(Color::Yellow); + let span = Span::styled("Text", style); + let style = Style::default().fg(Color::Green).bg(Color::Black); + let styled_graphemes = span.styled_graphemes(style); + assert_eq!( + vec![ + StyledGrapheme { + symbol: "T", + style: Style { + fg: Some(Color::Yellow), + bg: Some(Color::Black), + underline_color: None, + underline_style: None, + add_modifier: Modifier::empty(), + sub_modifier: Modifier::empty(), + }, + }, + StyledGrapheme { + symbol: "e", + style: Style { + fg: Some(Color::Yellow), + bg: Some(Color::Black), + underline_color: None, + underline_style: None, + add_modifier: Modifier::empty(), + sub_modifier: Modifier::empty(), + }, + }, + StyledGrapheme { + symbol: "x", + style: Style { + fg: Some(Color::Yellow), + bg: Some(Color::Black), + underline_color: None, + underline_style: None, + add_modifier: Modifier::empty(), + sub_modifier: Modifier::empty(), + }, + }, + StyledGrapheme { + symbol: "t", + style: Style { + fg: Some(Color::Yellow), + bg: Some(Color::Black), + underline_color: None, + underline_style: None, + add_modifier: Modifier::empty(), + sub_modifier: Modifier::empty(), + }, + }, + ], + styled_graphemes.collect::>() + ); +} + +// Spans + +#[test] +fn spans_width() { + let spans = Spans::from(vec![ + Span::styled("My", Style::default().fg(Color::Yellow)), + Span::raw(" text"), + ]); + assert_eq!(7, spans.width()); +}