From 6715e5247cd78fc325375b550eeb73317b8c7004 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Mon, 27 Mar 2023 11:54:33 +0200 Subject: [PATCH] Rework `SuggestionMap` to take highlight style when retrieving chunks --- crates/editor/src/display_map.rs | 21 ++++-- crates/editor/src/display_map/block_map.rs | 7 +- .../editor/src/display_map/suggestion_map.rs | 24 ++++--- crates/editor/src/display_map/tab_map.rs | 18 +++-- crates/editor/src/display_map/wrap_map.rs | 12 ++-- crates/editor/src/editor.rs | 12 ---- crates/editor/src/element.rs | 70 ++++++++++--------- crates/theme/src/theme.rs | 1 + styles/src/styleTree/editor.ts | 3 + 9 files changed, 95 insertions(+), 73 deletions(-) diff --git a/crates/editor/src/display_map.rs b/crates/editor/src/display_map.rs index f49b9e34b8..7788e8d38d 100644 --- a/crates/editor/src/display_map.rs +++ b/crates/editor/src/display_map.rs @@ -382,7 +382,7 @@ impl DisplaySnapshot { /// Returns text chunks starting at the given display row until the end of the file pub fn text_chunks(&self, display_row: u32) -> impl Iterator { self.block_snapshot - .chunks(display_row..self.max_point().row() + 1, false, None) + .chunks(display_row..self.max_point().row() + 1, false, None, None) .map(|h| h.text) } @@ -390,7 +390,7 @@ impl DisplaySnapshot { pub fn reverse_text_chunks(&self, display_row: u32) -> impl Iterator { (0..=display_row).into_iter().rev().flat_map(|row| { self.block_snapshot - .chunks(row..row + 1, false, None) + .chunks(row..row + 1, false, None, None) .map(|h| h.text) .collect::>() .into_iter() @@ -398,9 +398,18 @@ impl DisplaySnapshot { }) } - pub fn chunks(&self, display_rows: Range, language_aware: bool) -> DisplayChunks<'_> { - self.block_snapshot - .chunks(display_rows, language_aware, Some(&self.text_highlights)) + pub fn chunks( + &self, + display_rows: Range, + language_aware: bool, + suggestion_highlight: Option, + ) -> DisplayChunks<'_> { + self.block_snapshot.chunks( + display_rows, + language_aware, + Some(&self.text_highlights), + suggestion_highlight, + ) } pub fn chars_at( @@ -1691,7 +1700,7 @@ pub mod tests { ) -> Vec<(String, Option, Option)> { let snapshot = map.update(cx, |map, cx| map.snapshot(cx)); let mut chunks: Vec<(String, Option, Option)> = Vec::new(); - for chunk in snapshot.chunks(rows, true) { + for chunk in snapshot.chunks(rows, true, None) { let syntax_color = chunk .syntax_highlight_id .and_then(|id| id.style(theme)?.color); diff --git a/crates/editor/src/display_map/block_map.rs b/crates/editor/src/display_map/block_map.rs index adea668179..c4af03e703 100644 --- a/crates/editor/src/display_map/block_map.rs +++ b/crates/editor/src/display_map/block_map.rs @@ -4,7 +4,7 @@ use super::{ }; use crate::{Anchor, ExcerptId, ExcerptRange, ToPoint as _}; use collections::{Bound, HashMap, HashSet}; -use gpui::{ElementBox, RenderContext}; +use gpui::{fonts::HighlightStyle, ElementBox, RenderContext}; use language::{BufferSnapshot, Chunk, Patch, Point}; use parking_lot::Mutex; use std::{ @@ -572,7 +572,7 @@ impl<'a> BlockMapWriter<'a> { impl BlockSnapshot { #[cfg(test)] pub fn text(&self) -> String { - self.chunks(0..self.transforms.summary().output_rows, false, None) + self.chunks(0..self.transforms.summary().output_rows, false, None, None) .map(|chunk| chunk.text) .collect() } @@ -582,6 +582,7 @@ impl BlockSnapshot { rows: Range, language_aware: bool, text_highlights: Option<&'a TextHighlights>, + suggestion_highlight: Option, ) -> BlockChunks<'a> { let max_output_row = cmp::min(rows.end, self.transforms.summary().output_rows); let mut cursor = self.transforms.cursor::<(BlockRow, WrapRow)>(); @@ -614,6 +615,7 @@ impl BlockSnapshot { input_start..input_end, language_aware, text_highlights, + suggestion_highlight, ), input_chunk: Default::default(), transforms: cursor, @@ -1498,6 +1500,7 @@ mod tests { start_row as u32..blocks_snapshot.max_point().row + 1, false, None, + None, ) .map(|chunk| chunk.text) .collect::(); diff --git a/crates/editor/src/display_map/suggestion_map.rs b/crates/editor/src/display_map/suggestion_map.rs index 2d0225644f..e76904df17 100644 --- a/crates/editor/src/display_map/suggestion_map.rs +++ b/crates/editor/src/display_map/suggestion_map.rs @@ -60,7 +60,6 @@ impl SuggestionPoint { pub struct Suggestion { pub position: T, pub text: Rope, - pub highlight_style: HighlightStyle, } pub struct SuggestionMap(Mutex); @@ -93,7 +92,6 @@ impl SuggestionMap { Suggestion { position: fold_offset, text: new_suggestion.text, - highlight_style: new_suggestion.highlight_style, } }); @@ -369,7 +367,7 @@ impl SuggestionSnapshot { pub fn chars_at(&self, start: SuggestionPoint) -> impl '_ + Iterator { let start = self.to_offset(start); - self.chunks(start..self.len(), false, None) + self.chunks(start..self.len(), false, None, None) .flat_map(|chunk| chunk.text.chars()) } @@ -378,6 +376,7 @@ impl SuggestionSnapshot { range: Range, language_aware: bool, text_highlights: Option<&'a TextHighlights>, + suggestion_highlight: Option, ) -> SuggestionChunks<'a> { if let Some(suggestion) = self.suggestion.as_ref() { let suggestion_range = @@ -421,7 +420,7 @@ impl SuggestionSnapshot { prefix_chunks, suggestion_chunks, suffix_chunks, - highlight_style: suggestion.highlight_style, + highlight_style: suggestion_highlight, } } else { SuggestionChunks { @@ -432,7 +431,7 @@ impl SuggestionSnapshot { )), suggestion_chunks: None, suffix_chunks: None, - highlight_style: Default::default(), + highlight_style: None, } } } @@ -467,7 +466,7 @@ impl SuggestionSnapshot { #[cfg(test)] pub fn text(&self) -> String { - self.chunks(Default::default()..self.len(), false, None) + self.chunks(Default::default()..self.len(), false, None, None) .map(|chunk| chunk.text) .collect() } @@ -477,7 +476,7 @@ pub struct SuggestionChunks<'a> { prefix_chunks: Option>, suggestion_chunks: Option>, suffix_chunks: Option>, - highlight_style: HighlightStyle, + highlight_style: Option, } impl<'a> Iterator for SuggestionChunks<'a> { @@ -497,7 +496,7 @@ impl<'a> Iterator for SuggestionChunks<'a> { return Some(Chunk { text: chunk, syntax_highlight_id: None, - highlight_style: Some(self.highlight_style), + highlight_style: self.highlight_style, diagnostic_severity: None, is_unnecessary: false, }); @@ -563,7 +562,6 @@ mod tests { Some(Suggestion { position: 3, text: "123\n456".into(), - highlight_style: Default::default(), }), fold_snapshot, Default::default(), @@ -692,7 +690,12 @@ mod tests { start = expected_text.clip_offset(start, Bias::Right); let actual_text = suggestion_snapshot - .chunks(SuggestionOffset(start)..SuggestionOffset(end), false, None) + .chunks( + SuggestionOffset(start)..SuggestionOffset(end), + false, + None, + None, + ) .map(|chunk| chunk.text) .collect::(); assert_eq!( @@ -816,7 +819,6 @@ mod tests { .collect::() .as_str() .into(), - highlight_style: Default::default(), }) }; diff --git a/crates/editor/src/display_map/tab_map.rs b/crates/editor/src/display_map/tab_map.rs index 45c92ea7b8..b77556175d 100644 --- a/crates/editor/src/display_map/tab_map.rs +++ b/crates/editor/src/display_map/tab_map.rs @@ -3,6 +3,7 @@ use super::{ TextHighlights, }; use crate::MultiBufferSnapshot; +use gpui::fonts::HighlightStyle; use language::{Chunk, Point}; use parking_lot::Mutex; use std::{cmp, mem, num::NonZeroU32, ops::Range}; @@ -47,6 +48,7 @@ impl TabMap { suggestion_edit.old.end..old_max_offset, false, None, + None, ) { let patterns: &[_] = &['\t', '\n']; if let Some(ix) = chunk.text.find(patterns) { @@ -126,6 +128,7 @@ impl TabSnapshot { TabPoint::new(row, 0)..TabPoint::new(row + 1, 0), false, None, + None, ) .map(|chunk| chunk.text.len() as u32) .sum::() @@ -153,7 +156,7 @@ impl TabSnapshot { self.max_point() }; for c in self - .chunks(range.start..line_end, false, None) + .chunks(range.start..line_end, false, None, None) .flat_map(|chunk| chunk.text.chars()) { if c == '\n' { @@ -167,7 +170,12 @@ impl TabSnapshot { last_line_chars = first_line_chars; } else { for _ in self - .chunks(TabPoint::new(range.end.row(), 0)..range.end, false, None) + .chunks( + TabPoint::new(range.end.row(), 0)..range.end, + false, + None, + None, + ) .flat_map(|chunk| chunk.text.chars()) { last_line_chars += 1; @@ -188,6 +196,7 @@ impl TabSnapshot { range: Range, language_aware: bool, text_highlights: Option<&'a TextHighlights>, + suggestion_highlight: Option, ) -> TabChunks<'a> { let (input_start, expanded_char_column, to_next_stop) = self.to_suggestion_point(range.start, Bias::Left); @@ -206,6 +215,7 @@ impl TabSnapshot { input_start..input_end, language_aware, text_highlights, + suggestion_highlight, ), column: expanded_char_column, output_position: range.start.0, @@ -225,7 +235,7 @@ impl TabSnapshot { #[cfg(test)] pub fn text(&self) -> String { - self.chunks(TabPoint::zero()..self.max_point(), false, None) + self.chunks(TabPoint::zero()..self.max_point(), false, None, None) .map(|chunk| chunk.text) .collect() } @@ -574,7 +584,7 @@ mod tests { assert_eq!( expected_text, tabs_snapshot - .chunks(start..end, false, None) + .chunks(start..end, false, None, None) .map(|c| c.text) .collect::(), "chunks({:?}..{:?})", diff --git a/crates/editor/src/display_map/wrap_map.rs b/crates/editor/src/display_map/wrap_map.rs index f0d10ad423..e55953d2b5 100644 --- a/crates/editor/src/display_map/wrap_map.rs +++ b/crates/editor/src/display_map/wrap_map.rs @@ -5,8 +5,9 @@ use super::{ }; use crate::MultiBufferSnapshot; use gpui::{ - fonts::FontId, text_layout::LineWrapper, Entity, ModelContext, ModelHandle, MutableAppContext, - Task, + fonts::{FontId, HighlightStyle}, + text_layout::LineWrapper, + Entity, ModelContext, ModelHandle, MutableAppContext, Task, }; use language::{Chunk, Point}; use lazy_static::lazy_static; @@ -444,6 +445,7 @@ impl WrapSnapshot { TabPoint::new(edit.new_rows.start, 0)..new_tab_snapshot.max_point(), false, None, + None, ); let mut edit_transforms = Vec::::new(); for _ in edit.new_rows.start..edit.new_rows.end { @@ -573,6 +575,7 @@ impl WrapSnapshot { rows: Range, language_aware: bool, text_highlights: Option<&'a TextHighlights>, + suggestion_highlight: Option, ) -> WrapChunks<'a> { let output_start = WrapPoint::new(rows.start, 0); let output_end = WrapPoint::new(rows.end, 0); @@ -590,6 +593,7 @@ impl WrapSnapshot { input_start..input_end, language_aware, text_highlights, + suggestion_highlight, ), input_chunk: Default::default(), output_position: output_start, @@ -1315,7 +1319,7 @@ mod tests { } pub fn text_chunks(&self, wrap_row: u32) -> impl Iterator { - self.chunks(wrap_row..self.max_point().row() + 1, false, None) + self.chunks(wrap_row..self.max_point().row() + 1, false, None, None) .map(|h| h.text) } @@ -1339,7 +1343,7 @@ mod tests { } let actual_text = self - .chunks(start_row..end_row, true, None) + .chunks(start_row..end_row, true, None, None) .map(|c| c.text) .collect::(); assert_eq!( diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index edfacae268..40428e1261 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -2753,10 +2753,6 @@ impl Editor { Some(Suggestion { position, text: completion.text.as_str().into(), - highlight_style: HighlightStyle { - color: Some(Color::from_u32(0x777777ff)), - ..Default::default() - }, }), cx, ) @@ -2779,10 +2775,6 @@ impl Editor { Some(Suggestion { position, text: completion.text.as_str().into(), - highlight_style: HighlightStyle { - color: Some(Color::from_u32(0x777777ff)), - ..Default::default() - }, }), cx, ) @@ -2813,10 +2805,6 @@ impl Editor { Some(Suggestion { position: self.copilot_state.position, text: completion.text.as_str().into(), - highlight_style: HighlightStyle { - color: Some(Color::from_u32(0x777777ff)), - ..Default::default() - }, }), cx, ) diff --git a/crates/editor/src/element.rs b/crates/editor/src/element.rs index 780f8cd1d5..c349559d7d 100644 --- a/crates/editor/src/element.rs +++ b/crates/editor/src/element.rs @@ -1318,45 +1318,47 @@ impl EditorElement { .collect() } else { let style = &self.style; - let chunks = snapshot.chunks(rows.clone(), true).map(|chunk| { - let mut highlight_style = chunk - .syntax_highlight_id - .and_then(|id| id.style(&style.syntax)); + let chunks = snapshot + .chunks(rows.clone(), true, Some(style.theme.suggestion)) + .map(|chunk| { + let mut highlight_style = chunk + .syntax_highlight_id + .and_then(|id| id.style(&style.syntax)); + + if let Some(chunk_highlight) = chunk.highlight_style { + if let Some(highlight_style) = highlight_style.as_mut() { + highlight_style.highlight(chunk_highlight); + } else { + highlight_style = Some(chunk_highlight); + } + } + + let mut diagnostic_highlight = HighlightStyle::default(); + + if chunk.is_unnecessary { + diagnostic_highlight.fade_out = Some(style.unnecessary_code_fade); + } + + if let Some(severity) = chunk.diagnostic_severity { + // Omit underlines for HINT/INFO diagnostics on 'unnecessary' code. + if severity <= DiagnosticSeverity::WARNING || !chunk.is_unnecessary { + let diagnostic_style = super::diagnostic_style(severity, true, style); + diagnostic_highlight.underline = Some(Underline { + color: Some(diagnostic_style.message.text.color), + thickness: 1.0.into(), + squiggly: true, + }); + } + } - if let Some(chunk_highlight) = chunk.highlight_style { if let Some(highlight_style) = highlight_style.as_mut() { - highlight_style.highlight(chunk_highlight); + highlight_style.highlight(diagnostic_highlight); } else { - highlight_style = Some(chunk_highlight); + highlight_style = Some(diagnostic_highlight); } - } - let mut diagnostic_highlight = HighlightStyle::default(); - - if chunk.is_unnecessary { - diagnostic_highlight.fade_out = Some(style.unnecessary_code_fade); - } - - if let Some(severity) = chunk.diagnostic_severity { - // Omit underlines for HINT/INFO diagnostics on 'unnecessary' code. - if severity <= DiagnosticSeverity::WARNING || !chunk.is_unnecessary { - let diagnostic_style = super::diagnostic_style(severity, true, style); - diagnostic_highlight.underline = Some(Underline { - color: Some(diagnostic_style.message.text.color), - thickness: 1.0.into(), - squiggly: true, - }); - } - } - - if let Some(highlight_style) = highlight_style.as_mut() { - highlight_style.highlight(diagnostic_highlight); - } else { - highlight_style = Some(diagnostic_highlight); - } - - (chunk.text, highlight_style) - }); + (chunk.text, highlight_style) + }); layout_highlighted_chunks( chunks, &style.text, diff --git a/crates/theme/src/theme.rs b/crates/theme/src/theme.rs index d6a4a431e9..ef6a73f5d7 100644 --- a/crates/theme/src/theme.rs +++ b/crates/theme/src/theme.rs @@ -573,6 +573,7 @@ pub struct Editor { pub line_number_active: Color, pub guest_selections: Vec, pub syntax: Arc, + pub suggestion: HighlightStyle, pub diagnostic_path_header: DiagnosticPathHeader, pub diagnostic_header: DiagnosticHeader, pub error_diagnostic: DiagnosticStyle, diff --git a/styles/src/styleTree/editor.ts b/styles/src/styleTree/editor.ts index 4a7aae4c1b..e0c73109fc 100644 --- a/styles/src/styleTree/editor.ts +++ b/styles/src/styleTree/editor.ts @@ -43,6 +43,9 @@ export default function editor(colorScheme: ColorScheme) { background: background(layer), activeLineBackground: withOpacity(background(layer, "on"), 0.75), highlightedLineBackground: background(layer, "on"), + suggestion: { + color: foreground(layer, "disabled") + }, codeActions: { indicator: { color: foreground(layer, "variant"),