diff --git a/crates/editor2/src/editor.rs b/crates/editor2/src/editor.rs index 43d1fecc58..05660df430 100644 --- a/crates/editor2/src/editor.rs +++ b/crates/editor2/src/editor.rs @@ -43,7 +43,7 @@ use gpui::{ AppContext, AsyncWindowContext, BackgroundExecutor, Bounds, ClipboardItem, Context, EventEmitter, FocusHandle, FocusableView, FontFeatures, FontStyle, FontWeight, HighlightStyle, Hsla, InputHandler, KeyContext, Model, MouseButton, ParentElement, Pixels, Render, RenderOnce, - SharedString, Styled, Subscription, Task, TextStyle, UniformListScrollHandle, View, + SharedString, Styled, Subscription, Task, TextRun, TextStyle, UniformListScrollHandle, View, ViewContext, VisualContext, WeakView, WhiteSpace, WindowContext, }; use highlight_matching_bracket::refresh_matching_bracket_highlights; @@ -10080,11 +10080,25 @@ pub fn diagnostic_style( pub fn combine_syntax_and_fuzzy_match_highlights( text: &str, - default_style: HighlightStyle, + default_style: TextStyle, syntax_ranges: impl Iterator, HighlightStyle)>, match_indices: &[usize], -) -> Vec<(Range, HighlightStyle)> { - let mut result = Vec::new(); +) -> Vec { + let mut current_index = 0; + let mut runs = Vec::new(); + let mut push_run = |range: Range, highlight_style: HighlightStyle| { + if current_index < range.start { + runs.push(default_style.clone().to_run(range.start - current_index)); + } + runs.push( + default_style + .clone() + .highlight(highlight_style) + .to_run(range.len()), + ); + current_index = range.end; + }; + let mut match_indices = match_indices.iter().copied().peekable(); for (range, mut syntax_highlight) in syntax_ranges.chain([(usize::MAX..0, Default::default())]) @@ -10099,9 +10113,7 @@ pub fn combine_syntax_and_fuzzy_match_highlights( } match_indices.next(); let end_index = char_ix_after(match_index, text); - let mut match_style = default_style; - match_style.font_weight = Some(FontWeight::BOLD); - result.push((match_index..end_index, match_style)); + push_run(match_index..end_index, FontWeight::BOLD.into()); } if range.start == usize::MAX { @@ -10118,7 +10130,7 @@ pub fn combine_syntax_and_fuzzy_match_highlights( match_indices.next(); if match_index > offset { - result.push((offset..match_index, syntax_highlight)); + push_run(offset..match_index, syntax_highlight); } let mut end_index = char_ix_after(match_index, text); @@ -10133,20 +10145,24 @@ pub fn combine_syntax_and_fuzzy_match_highlights( let mut match_style = syntax_highlight; match_style.font_weight = Some(FontWeight::BOLD); - result.push((match_index..end_index, match_style)); + push_run(match_index..end_index, match_style); offset = end_index; } if offset < range.end { - result.push((offset..range.end, syntax_highlight)); + push_run(offset..range.end, syntax_highlight); } } + if current_index < text.len() { + runs.push(default_style.to_run(text.len() - current_index)); + } + fn char_ix_after(ix: usize, text: &str) -> usize { ix + text[ix..].chars().next().unwrap().len_utf8() } - result + runs } pub fn styled_runs_for_code_label<'a>( diff --git a/crates/editor2/src/editor_tests.rs b/crates/editor2/src/editor_tests.rs index f0609fc9a8..42a1bf3c62 100644 --- a/crates/editor2/src/editor_tests.rs +++ b/crates/editor2/src/editor_tests.rs @@ -6758,6 +6758,13 @@ fn test_combine_syntax_and_fuzzy_match_highlights() { ..Default::default() }, ), + ( + 12..13, + HighlightStyle { + color: Some(Hsla::blue()), + ..Default::default() + }, + ), ]; let match_indices = [4, 6, 7, 8]; assert_eq!( @@ -6768,43 +6775,27 @@ fn test_combine_syntax_and_fuzzy_match_highlights() { &match_indices, ), &[ - ( - 0..3, - HighlightStyle { - color: Some(Hsla::red()), - ..Default::default() - }, - ), - ( - 4..5, - HighlightStyle { + TextStyle::default().highlight(Hsla::red()).to_run(3), + TextStyle::default().to_run(1), + TextStyle::default() + .highlight(HighlightStyle { color: Some(Hsla::green()), - font_weight: Some(gpui::FontWeight::BOLD), + font_weight: Some(FontWeight::BOLD), ..Default::default() - }, - ), - ( - 5..6, - HighlightStyle { + }) + .to_run(1), + TextStyle::default().highlight(Hsla::green()).to_run(1), + TextStyle::default() + .highlight(HighlightStyle { color: Some(Hsla::green()), + font_weight: Some(FontWeight::BOLD), ..Default::default() - }, - ), - ( - 6..8, - HighlightStyle { - color: Some(Hsla::green()), - font_weight: Some(gpui::FontWeight::BOLD), - ..Default::default() - }, - ), - ( - 8..9, - HighlightStyle { - font_weight: Some(gpui::FontWeight::BOLD), - ..Default::default() - }, - ), + }) + .to_run(2), + TextStyle::default().highlight(FontWeight::BOLD).to_run(1), + TextStyle::default().to_run(3), + TextStyle::default().highlight(Hsla::blue()).to_run(1), + TextStyle::default().to_run(3), ] ); } diff --git a/crates/gpui2/src/style.rs b/crates/gpui2/src/style.rs index 77d732032b..472b81c0f8 100644 --- a/crates/gpui2/src/style.rs +++ b/crates/gpui2/src/style.rs @@ -168,7 +168,8 @@ impl Default for TextStyle { } impl TextStyle { - pub fn highlight(mut self, style: HighlightStyle) -> Self { + pub fn highlight(mut self, style: impl Into) -> Self { + let style = style.into(); if let Some(weight) = style.font_weight { self.font_weight = weight; } @@ -502,6 +503,15 @@ impl From for HighlightStyle { } } +impl From for HighlightStyle { + fn from(font_weight: FontWeight) -> Self { + Self { + font_weight: Some(font_weight), + ..Default::default() + } + } +} + impl From for HighlightStyle { fn from(color: Rgba) -> Self { Self {