diff --git a/crates/editor/src/display_map.rs b/crates/editor/src/display_map.rs index b117120e81..e62f715cf3 100644 --- a/crates/editor/src/display_map.rs +++ b/crates/editor/src/display_map.rs @@ -392,7 +392,13 @@ 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, None) + .chunks( + display_row..self.max_point().row() + 1, + false, + None, + None, + None, + ) .map(|h| h.text) } @@ -400,7 +406,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, None) + .chunks(row..row + 1, false, None, None, None) .map(|h| h.text) .collect::>() .into_iter() @@ -412,13 +418,15 @@ impl DisplaySnapshot { &self, display_rows: Range, language_aware: bool, - inlay_highlights: Option, + hint_highlights: Option, + suggestion_highlights: Option, ) -> DisplayChunks<'_> { self.block_snapshot.chunks( display_rows, language_aware, Some(&self.text_highlights), - inlay_highlights, + hint_highlights, + suggestion_highlights, ) } @@ -1711,7 +1719,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, None) { + for chunk in snapshot.chunks(rows, true, None, 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 8f78c3885a..4b76ded3d5 100644 --- a/crates/editor/src/display_map/block_map.rs +++ b/crates/editor/src/display_map/block_map.rs @@ -573,9 +573,15 @@ impl<'a> BlockMapWriter<'a> { impl BlockSnapshot { #[cfg(test)] pub fn text(&self) -> String { - self.chunks(0..self.transforms.summary().output_rows, false, None, None) - .map(|chunk| chunk.text) - .collect() + self.chunks( + 0..self.transforms.summary().output_rows, + false, + None, + None, + None, + ) + .map(|chunk| chunk.text) + .collect() } pub fn chunks<'a>( @@ -583,7 +589,8 @@ impl BlockSnapshot { rows: Range, language_aware: bool, text_highlights: Option<&'a TextHighlights>, - inlay_highlights: Option, + hint_highlights: Option, + suggestion_highlights: Option, ) -> BlockChunks<'a> { let max_output_row = cmp::min(rows.end, self.transforms.summary().output_rows); let mut cursor = self.transforms.cursor::<(BlockRow, WrapRow)>(); @@ -616,7 +623,8 @@ impl BlockSnapshot { input_start..input_end, language_aware, text_highlights, - inlay_highlights, + hint_highlights, + suggestion_highlights, ), input_chunk: Default::default(), transforms: cursor, @@ -1495,6 +1503,7 @@ mod tests { false, None, None, + None, ) .map(|chunk| chunk.text) .collect::(); diff --git a/crates/editor/src/display_map/fold_map.rs b/crates/editor/src/display_map/fold_map.rs index 7d8eae29ab..01b29e1e1a 100644 --- a/crates/editor/src/display_map/fold_map.rs +++ b/crates/editor/src/display_map/fold_map.rs @@ -475,7 +475,7 @@ pub struct FoldSnapshot { impl FoldSnapshot { #[cfg(test)] pub fn text(&self) -> String { - self.chunks(FoldOffset(0)..self.len(), false, None, None) + self.chunks(FoldOffset(0)..self.len(), false, None, None, None) .map(|c| c.text) .collect() } @@ -652,7 +652,8 @@ impl FoldSnapshot { range: Range, language_aware: bool, text_highlights: Option<&'a TextHighlights>, - inlay_highlights: Option, + hint_highlights: Option, + suggestion_highlights: Option, ) -> FoldChunks<'a> { let mut transform_cursor = self.transforms.cursor::<(FoldOffset, InlayOffset)>(); @@ -674,7 +675,8 @@ impl FoldSnapshot { inlay_start..inlay_end, language_aware, text_highlights, - inlay_highlights, + hint_highlights, + suggestion_highlights, ), inlay_chunk: None, inlay_offset: inlay_start, @@ -685,7 +687,7 @@ impl FoldSnapshot { } pub fn chars_at(&self, start: FoldPoint) -> impl '_ + Iterator { - self.chunks(start.to_offset(self)..self.len(), false, None, None) + self.chunks(start.to_offset(self)..self.len(), false, None, None, None) .flat_map(|chunk| chunk.text.chars()) } @@ -1514,7 +1516,7 @@ mod tests { let text = &expected_text[start.0..end.0]; assert_eq!( snapshot - .chunks(start..end, false, Some(&highlights), None) + .chunks(start..end, false, Some(&highlights), None, None) .map(|c| c.text) .collect::(), text, diff --git a/crates/editor/src/display_map/inlay_map.rs b/crates/editor/src/display_map/inlay_map.rs index 7806c75f17..1b6884dcc6 100644 --- a/crates/editor/src/display_map/inlay_map.rs +++ b/crates/editor/src/display_map/inlay_map.rs @@ -194,7 +194,8 @@ pub struct InlayChunks<'a> { inlay_chunks: Option>, output_offset: InlayOffset, max_output_offset: InlayOffset, - highlight_style: Option, + hint_highlight_style: Option, + suggestion_highlight_style: Option, highlight_endpoints: Peekable>, active_highlights: BTreeMap, HighlightStyle>, snapshot: &'a InlaySnapshot, @@ -281,9 +282,13 @@ impl<'a> Iterator for InlayChunks<'a> { let chunk = inlay_chunks.next().unwrap(); self.output_offset.0 += chunk.len(); + let highlight_style = match inlay.id { + InlayId::Suggestion(_) => self.suggestion_highlight_style, + InlayId::Hint(_) => self.hint_highlight_style, + }; Chunk { text: chunk, - highlight_style: self.highlight_style, + highlight_style, ..Default::default() } } @@ -576,7 +581,7 @@ impl InlayMap { let mut to_remove = Vec::new(); let mut to_insert = Vec::new(); let snapshot = &mut self.snapshot; - for _ in 0..rng.gen_range(1..=5) { + for i in 0..rng.gen_range(1..=5) { if self.inlays.is_empty() || rng.gen() { let position = snapshot.buffer.random_byte_range(0, rng).start; let bias = if rng.gen() { Bias::Left } else { Bias::Right }; @@ -595,8 +600,14 @@ impl InlayMap { bias, text ); + + let inlay_id = if i % 2 == 0 { + InlayId::Hint(post_inc(next_inlay_id)) + } else { + InlayId::Suggestion(post_inc(next_inlay_id)) + }; to_insert.push(( - InlayId(post_inc(next_inlay_id)), + inlay_id, InlayProperties { position: snapshot.buffer.anchor_at(position, bias), text, @@ -927,7 +938,8 @@ impl InlaySnapshot { range: Range, language_aware: bool, text_highlights: Option<&'a TextHighlights>, - inlay_highlight_style: Option, + hint_highlights: Option, + suggestion_highlights: Option, ) -> InlayChunks<'a> { let mut cursor = self.transforms.cursor::<(InlayOffset, usize)>(); cursor.seek(&range.start, Bias::Right, &()); @@ -1002,7 +1014,8 @@ impl InlaySnapshot { buffer_chunk: None, output_offset: range.start, max_output_offset: range.end, - highlight_style: inlay_highlight_style, + hint_highlight_style: hint_highlights, + suggestion_highlight_style: suggestion_highlights, highlight_endpoints: highlight_endpoints.into_iter().peekable(), active_highlights: Default::default(), snapshot: self, @@ -1011,7 +1024,7 @@ impl InlaySnapshot { #[cfg(test)] pub fn text(&self) -> String { - self.chunks(Default::default()..self.len(), false, None, None) + self.chunks(Default::default()..self.len(), false, None, None, None) .map(|chunk| chunk.text) .collect() } @@ -1078,7 +1091,7 @@ mod tests { let (inlay_snapshot, _) = inlay_map.splice( Vec::new(), vec![( - InlayId(post_inc(&mut next_inlay_id)), + InlayId::Hint(post_inc(&mut next_inlay_id)), InlayProperties { position: buffer.read(cx).snapshot(cx).anchor_after(3), text: "|123|", @@ -1157,14 +1170,14 @@ mod tests { Vec::new(), vec![ ( - InlayId(post_inc(&mut next_inlay_id)), + InlayId::Hint(post_inc(&mut next_inlay_id)), InlayProperties { position: buffer.read(cx).snapshot(cx).anchor_before(3), text: "|123|", }, ), ( - InlayId(post_inc(&mut next_inlay_id)), + InlayId::Suggestion(post_inc(&mut next_inlay_id)), InlayProperties { position: buffer.read(cx).snapshot(cx).anchor_after(3), text: "|456|", @@ -1370,21 +1383,21 @@ mod tests { Vec::new(), vec![ ( - InlayId(post_inc(&mut next_inlay_id)), + InlayId::Hint(post_inc(&mut next_inlay_id)), InlayProperties { position: buffer.read(cx).snapshot(cx).anchor_before(0), text: "|123|\n", }, ), ( - InlayId(post_inc(&mut next_inlay_id)), + InlayId::Hint(post_inc(&mut next_inlay_id)), InlayProperties { position: buffer.read(cx).snapshot(cx).anchor_before(4), text: "|456|", }, ), ( - InlayId(post_inc(&mut next_inlay_id)), + InlayId::Suggestion(post_inc(&mut next_inlay_id)), InlayProperties { position: buffer.read(cx).snapshot(cx).anchor_before(7), text: "\n|567|\n", @@ -1489,7 +1502,13 @@ mod tests { start = expected_text.clip_offset(start, Bias::Right); let actual_text = inlay_snapshot - .chunks(InlayOffset(start)..InlayOffset(end), false, None, None) + .chunks( + InlayOffset(start)..InlayOffset(end), + false, + None, + None, + None, + ) .map(|chunk| chunk.text) .collect::(); assert_eq!( diff --git a/crates/editor/src/display_map/tab_map.rs b/crates/editor/src/display_map/tab_map.rs index eaaaeed8ad..ca73f6a1a7 100644 --- a/crates/editor/src/display_map/tab_map.rs +++ b/crates/editor/src/display_map/tab_map.rs @@ -70,6 +70,7 @@ impl TabMap { false, None, None, + None, ) { for (ix, _) in chunk.text.match_indices('\t') { let offset_from_edit = offset_from_edit + (ix as u32); @@ -182,7 +183,7 @@ impl TabSnapshot { self.max_point() }; for c in self - .chunks(range.start..line_end, false, None, None) + .chunks(range.start..line_end, false, None, None, None) .flat_map(|chunk| chunk.text.chars()) { if c == '\n' { @@ -201,6 +202,7 @@ impl TabSnapshot { false, None, None, + None, ) .flat_map(|chunk| chunk.text.chars()) { @@ -222,7 +224,8 @@ impl TabSnapshot { range: Range, language_aware: bool, text_highlights: Option<&'a TextHighlights>, - inlay_highlights: Option, + hint_highlights: Option, + suggestion_highlights: Option, ) -> TabChunks<'a> { let (input_start, expanded_char_column, to_next_stop) = self.to_fold_point(range.start, Bias::Left); @@ -243,7 +246,8 @@ impl TabSnapshot { input_start..input_end, language_aware, text_highlights, - inlay_highlights, + hint_highlights, + suggestion_highlights, ), input_column, column: expanded_char_column, @@ -266,7 +270,7 @@ impl TabSnapshot { #[cfg(test)] pub fn text(&self) -> String { - self.chunks(TabPoint::zero()..self.max_point(), false, None, None) + self.chunks(TabPoint::zero()..self.max_point(), false, None, None, None) .map(|chunk| chunk.text) .collect() } @@ -595,6 +599,7 @@ mod tests { false, None, None, + None, ) .map(|c| c.text) .collect::(), @@ -669,7 +674,7 @@ mod tests { let mut chunks = Vec::new(); let mut was_tab = false; let mut text = String::new(); - for chunk in snapshot.chunks(start..snapshot.max_point(), false, None, None) { + for chunk in snapshot.chunks(start..snapshot.max_point(), false, None, None, None) { if chunk.is_tab != was_tab { if !text.is_empty() { chunks.push((mem::take(&mut text), was_tab)); @@ -738,7 +743,7 @@ mod tests { let expected_summary = TextSummary::from(expected_text.as_str()); assert_eq!( tabs_snapshot - .chunks(start..end, false, None, None) + .chunks(start..end, false, None, None, None) .map(|c| c.text) .collect::(), expected_text, diff --git a/crates/editor/src/display_map/wrap_map.rs b/crates/editor/src/display_map/wrap_map.rs index 0e7f1f8167..fe4723abee 100644 --- a/crates/editor/src/display_map/wrap_map.rs +++ b/crates/editor/src/display_map/wrap_map.rs @@ -446,6 +446,7 @@ impl WrapSnapshot { false, None, None, + None, ); let mut edit_transforms = Vec::::new(); for _ in edit.new_rows.start..edit.new_rows.end { @@ -575,7 +576,8 @@ impl WrapSnapshot { rows: Range, language_aware: bool, text_highlights: Option<&'a TextHighlights>, - inlay_highlights: Option, + hint_highlights: Option, + suggestion_highlights: Option, ) -> WrapChunks<'a> { let output_start = WrapPoint::new(rows.start, 0); let output_end = WrapPoint::new(rows.end, 0); @@ -593,7 +595,8 @@ impl WrapSnapshot { input_start..input_end, language_aware, text_highlights, - inlay_highlights, + hint_highlights, + suggestion_highlights, ), input_chunk: Default::default(), output_position: output_start, @@ -1324,8 +1327,14 @@ mod tests { } pub fn text_chunks(&self, wrap_row: u32) -> impl Iterator { - self.chunks(wrap_row..self.max_point().row() + 1, false, None, None) - .map(|h| h.text) + self.chunks( + wrap_row..self.max_point().row() + 1, + false, + None, + None, + None, + ) + .map(|h| h.text) } fn verify_chunks(&mut self, rng: &mut impl Rng) { @@ -1348,7 +1357,7 @@ mod tests { } let actual_text = self - .chunks(start_row..end_row, true, None, None) + .chunks(start_row..end_row, true, None, None, None) .map(|c| c.text) .collect::(); assert_eq!( diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index 65beec6d97..e96b3d41c3 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -184,8 +184,11 @@ pub struct GutterHover { pub hovered: bool, } -#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)] -pub struct InlayId(usize); +#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] +pub enum InlayId { + Suggestion(usize), + Hint(usize), +} actions!( editor, @@ -3449,7 +3452,7 @@ impl Editor { to_remove.push(suggestion.id); } - let suggestion_inlay_id = self.next_inlay_id(); + let suggestion_inlay_id = InlayId::Suggestion(post_inc(&mut self.next_inlay_id)); let to_insert = vec![( suggestion_inlay_id, InlayProperties { @@ -7588,10 +7591,6 @@ impl Editor { cx.write_to_clipboard(ClipboardItem::new(lines)); } - pub fn next_inlay_id(&mut self) -> InlayId { - InlayId(post_inc(&mut self.next_inlay_id)) - } - pub fn inlay_hint_cache(&self) -> &InlayHintCache { &self.inlay_hint_cache } diff --git a/crates/editor/src/element.rs b/crates/editor/src/element.rs index 928df1027f..d1e6f29bbe 100644 --- a/crates/editor/src/element.rs +++ b/crates/editor/src/element.rs @@ -1392,7 +1392,12 @@ impl EditorElement { } else { let style = &self.style; let chunks = snapshot - .chunks(rows.clone(), true, Some(style.theme.hint)) + .chunks( + rows.clone(), + true, + Some(style.theme.hint), + Some(style.theme.suggestion), + ) .map(|chunk| { let mut highlight_style = chunk .syntax_highlight_id diff --git a/crates/editor/src/inlay_hint_cache.rs b/crates/editor/src/inlay_hint_cache.rs index 9c686c7980..d499474a01 100644 --- a/crates/editor/src/inlay_hint_cache.rs +++ b/crates/editor/src/inlay_hint_cache.rs @@ -616,7 +616,7 @@ async fn fetch_and_update_hints( for new_hint in new_update.add_to_cache { let new_hint_position = multi_buffer_snapshot .anchor_in_excerpt(query.excerpt_id, new_hint.position); - let new_inlay_id = InlayId(post_inc(&mut editor.next_inlay_id)); + let new_inlay_id = InlayId::Hint(post_inc(&mut editor.next_inlay_id)); if editor .inlay_hint_cache .allowed_hint_kinds