diff --git a/crates/editor/src/display_map/fold_map.rs b/crates/editor/src/display_map/fold_map.rs index 92456836a9..197b85497b 100644 --- a/crates/editor/src/display_map/fold_map.rs +++ b/crates/editor/src/display_map/fold_map.rs @@ -1,3 +1,5 @@ +use crate::display_map::inlay_map::InlayChunk; + use super::{ Highlights, inlay_map::{InlayBufferRows, InlayChunks, InlayEdit, InlayOffset, InlayPoint, InlaySnapshot}, @@ -1060,7 +1062,7 @@ impl sum_tree::Summary for TransformSummary { } #[derive(Copy, Clone, Eq, PartialEq, Debug, Default, Ord, PartialOrd, Hash)] -pub struct FoldId(usize); +pub struct FoldId(pub(super) usize); impl From for ElementId { fn from(val: FoldId) -> Self { @@ -1311,7 +1313,7 @@ impl DerefMut for ChunkRendererContext<'_, '_> { pub struct FoldChunks<'a> { transform_cursor: Cursor<'a, Transform, (FoldOffset, InlayOffset)>, inlay_chunks: InlayChunks<'a>, - inlay_chunk: Option<(InlayOffset, language::Chunk<'a>)>, + inlay_chunk: Option<(InlayOffset, InlayChunk<'a>)>, inlay_offset: InlayOffset, output_offset: FoldOffset, max_output_offset: FoldOffset, @@ -1403,7 +1405,8 @@ impl<'a> Iterator for FoldChunks<'a> { } // Otherwise, take a chunk from the buffer's text. - if let Some((buffer_chunk_start, mut chunk)) = self.inlay_chunk.clone() { + if let Some((buffer_chunk_start, mut inlay_chunk)) = self.inlay_chunk.clone() { + let chunk = &mut inlay_chunk.chunk; let buffer_chunk_end = buffer_chunk_start + InlayOffset(chunk.text.len()); let transform_end = self.transform_cursor.end(&()).1; let chunk_end = buffer_chunk_end.min(transform_end); @@ -1428,7 +1431,7 @@ impl<'a> Iterator for FoldChunks<'a> { is_tab: chunk.is_tab, is_inlay: chunk.is_inlay, underline: chunk.underline, - renderer: None, + renderer: inlay_chunk.renderer, }); } diff --git a/crates/editor/src/display_map/inlay_map.rs b/crates/editor/src/display_map/inlay_map.rs index e7d8868d42..4f7c4962f2 100644 --- a/crates/editor/src/display_map/inlay_map.rs +++ b/crates/editor/src/display_map/inlay_map.rs @@ -1,4 +1,4 @@ -use crate::{HighlightStyles, InlayId}; +use crate::{ChunkRenderer, HighlightStyles, InlayId, display_map::FoldId}; use collections::BTreeSet; use gpui::{Hsla, Rgba}; use language::{Chunk, Edit, Point, TextSummary}; @@ -8,9 +8,11 @@ use multi_buffer::{ use std::{ cmp, ops::{Add, AddAssign, Range, Sub, SubAssign}, + sync::Arc, }; use sum_tree::{Bias, Cursor, SumTree}; use text::{Patch, Rope}; +use ui::{ActiveTheme, IntoElement as _, ParentElement as _, Styled as _, div}; use super::{Highlights, custom_highlights::CustomHighlightsChunks}; @@ -252,6 +254,13 @@ pub struct InlayChunks<'a> { snapshot: &'a InlaySnapshot, } +#[derive(Clone)] +pub struct InlayChunk<'a> { + pub chunk: Chunk<'a>, + /// Whether the inlay should be customly rendered. + pub renderer: Option, +} + impl InlayChunks<'_> { pub fn seek(&mut self, new_range: Range) { self.transforms.seek(&new_range.start, Bias::Right, &()); @@ -271,7 +280,7 @@ impl InlayChunks<'_> { } impl<'a> Iterator for InlayChunks<'a> { - type Item = Chunk<'a>; + type Item = InlayChunk<'a>; fn next(&mut self) -> Option { if self.output_offset == self.max_output_offset { @@ -296,9 +305,12 @@ impl<'a> Iterator for InlayChunks<'a> { chunk.text = suffix; self.output_offset.0 += prefix.len(); - Chunk { - text: prefix, - ..chunk.clone() + InlayChunk { + chunk: Chunk { + text: prefix, + ..chunk.clone() + }, + renderer: None, } } Transform::Inlay(inlay) => { @@ -313,6 +325,7 @@ impl<'a> Iterator for InlayChunks<'a> { } } + let mut renderer = None; let mut highlight_style = match inlay.id { InlayId::InlineCompletion(_) => { self.highlight_styles.inline_completion.map(|s| { @@ -325,14 +338,33 @@ impl<'a> Iterator for InlayChunks<'a> { } InlayId::Hint(_) => self.highlight_styles.inlay_hint, InlayId::DebuggerValue(_) => self.highlight_styles.inlay_hint, - InlayId::Color(_) => match inlay.color { - Some(color) => { - let mut style = self.highlight_styles.inlay_hint.unwrap_or_default(); - style.color = Some(color); - Some(style) + InlayId::Color(id) => { + if let Some(color) = inlay.color { + renderer = Some(ChunkRenderer { + id: FoldId(id), + render: Arc::new(move |cx| { + div() + .w_4() + .h_4() + .relative() + .child( + div() + .absolute() + .right_1() + .w_3p5() + .h_3p5() + .border_2() + .border_color(cx.theme().colors().border) + .bg(color), + ) + .into_any_element() + }), + constrain_width: false, + measured_width: None, + }); } - None => self.highlight_styles.inlay_hint, - }, + self.highlight_styles.inlay_hint + } }; let next_inlay_highlight_endpoint; let offset_in_inlay = self.output_offset - self.transforms.start().0; @@ -370,11 +402,14 @@ impl<'a> Iterator for InlayChunks<'a> { self.output_offset.0 += chunk.len(); - Chunk { - text: chunk, - highlight_style, - is_inlay: true, - ..Default::default() + InlayChunk { + chunk: Chunk { + text: chunk, + highlight_style, + is_inlay: true, + ..Chunk::default() + }, + renderer, } } }; @@ -1066,7 +1101,7 @@ impl InlaySnapshot { #[cfg(test)] pub fn text(&self) -> String { self.chunks(Default::default()..self.len(), false, Highlights::default()) - .map(|chunk| chunk.text) + .map(|chunk| chunk.chunk.text) .collect() } @@ -1704,7 +1739,7 @@ mod tests { ..Highlights::default() }, ) - .map(|chunk| chunk.text) + .map(|chunk| chunk.chunk.text) .collect::(); assert_eq!( actual_text, diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index fedd9222ec..419e3c4ae9 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -547,6 +547,7 @@ pub enum SoftWrap { #[derive(Clone)] pub struct EditorStyle { pub background: Hsla, + pub border: Hsla, pub local_player: PlayerColor, pub text: TextStyle, pub scrollbar_width: Pixels, @@ -562,6 +563,7 @@ impl Default for EditorStyle { fn default() -> Self { Self { background: Hsla::default(), + border: Hsla::default(), local_player: PlayerColor::default(), text: TextStyle::default(), scrollbar_width: Pixels::default(), @@ -22405,6 +22407,7 @@ impl Render for Editor { &cx.entity(), EditorStyle { background, + border: cx.theme().colors().border, local_player: cx.theme().players().local(), text: text_style, scrollbar_width: EditorElement::SCROLLBAR_WIDTH,