Rework color indicators visual representation (#33605)
Use a div-based rendering code instead of using a text Closes https://github.com/zed-industries/zed/discussions/33507 Before: <img width="410" alt="before_dark" src="https://github.com/user-attachments/assets/66ad63ae-7836-4dc7-8176-a2ff5a38bcd4" /> After: <img width="407" alt="after_dark" src="https://github.com/user-attachments/assets/0b627da8-461b-4f19-b236-4a69bf5952a0" /> Before: <img width="409" alt="before_light" src="https://github.com/user-attachments/assets/ebcfabec-fcda-4b63-aee6-c702888f0db4" /> After: <img width="410" alt="after_light" src="https://github.com/user-attachments/assets/c0da42a1-d6b3-4e08-a56c-9966c07e442d" /> The border is not that contrast as in VSCode examples in the issue, but I'm supposed to use the right thing in1e11de48ee/crates/editor/src/display_map/inlay_map.rs (L357)
based on41583fb066/crates/theme/src/styles/colors.rs (L16-L17)
Another oddity is that the border starts to shrink on `cmd-=` (`zed::IncreaseBufferFontSize`): <img width="1244" alt="image" src="https://github.com/user-attachments/assets/f424edc0-ca0c-4b02-96d4-6da7bf70449a" /> but that needs a different part of code to be adjusted hence skipped. Tailwind CSS example: <img width="1108" alt="image" src="https://github.com/user-attachments/assets/10ada4dc-ea8c-46d3-b285-d895bbd6a619" /> Release Notes: - Reworked color indicators visual representation
This commit is contained in:
parent
e5bcd720e1
commit
047d515abf
3 changed files with 64 additions and 23 deletions
|
@ -1,3 +1,5 @@
|
||||||
|
use crate::display_map::inlay_map::InlayChunk;
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
Highlights,
|
Highlights,
|
||||||
inlay_map::{InlayBufferRows, InlayChunks, InlayEdit, InlayOffset, InlayPoint, InlaySnapshot},
|
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)]
|
#[derive(Copy, Clone, Eq, PartialEq, Debug, Default, Ord, PartialOrd, Hash)]
|
||||||
pub struct FoldId(usize);
|
pub struct FoldId(pub(super) usize);
|
||||||
|
|
||||||
impl From<FoldId> for ElementId {
|
impl From<FoldId> for ElementId {
|
||||||
fn from(val: FoldId) -> Self {
|
fn from(val: FoldId) -> Self {
|
||||||
|
@ -1311,7 +1313,7 @@ impl DerefMut for ChunkRendererContext<'_, '_> {
|
||||||
pub struct FoldChunks<'a> {
|
pub struct FoldChunks<'a> {
|
||||||
transform_cursor: Cursor<'a, Transform, (FoldOffset, InlayOffset)>,
|
transform_cursor: Cursor<'a, Transform, (FoldOffset, InlayOffset)>,
|
||||||
inlay_chunks: InlayChunks<'a>,
|
inlay_chunks: InlayChunks<'a>,
|
||||||
inlay_chunk: Option<(InlayOffset, language::Chunk<'a>)>,
|
inlay_chunk: Option<(InlayOffset, InlayChunk<'a>)>,
|
||||||
inlay_offset: InlayOffset,
|
inlay_offset: InlayOffset,
|
||||||
output_offset: FoldOffset,
|
output_offset: FoldOffset,
|
||||||
max_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.
|
// 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 buffer_chunk_end = buffer_chunk_start + InlayOffset(chunk.text.len());
|
||||||
let transform_end = self.transform_cursor.end(&()).1;
|
let transform_end = self.transform_cursor.end(&()).1;
|
||||||
let chunk_end = buffer_chunk_end.min(transform_end);
|
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_tab: chunk.is_tab,
|
||||||
is_inlay: chunk.is_inlay,
|
is_inlay: chunk.is_inlay,
|
||||||
underline: chunk.underline,
|
underline: chunk.underline,
|
||||||
renderer: None,
|
renderer: inlay_chunk.renderer,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use crate::{HighlightStyles, InlayId};
|
use crate::{ChunkRenderer, HighlightStyles, InlayId, display_map::FoldId};
|
||||||
use collections::BTreeSet;
|
use collections::BTreeSet;
|
||||||
use gpui::{Hsla, Rgba};
|
use gpui::{Hsla, Rgba};
|
||||||
use language::{Chunk, Edit, Point, TextSummary};
|
use language::{Chunk, Edit, Point, TextSummary};
|
||||||
|
@ -8,9 +8,11 @@ use multi_buffer::{
|
||||||
use std::{
|
use std::{
|
||||||
cmp,
|
cmp,
|
||||||
ops::{Add, AddAssign, Range, Sub, SubAssign},
|
ops::{Add, AddAssign, Range, Sub, SubAssign},
|
||||||
|
sync::Arc,
|
||||||
};
|
};
|
||||||
use sum_tree::{Bias, Cursor, SumTree};
|
use sum_tree::{Bias, Cursor, SumTree};
|
||||||
use text::{Patch, Rope};
|
use text::{Patch, Rope};
|
||||||
|
use ui::{ActiveTheme, IntoElement as _, ParentElement as _, Styled as _, div};
|
||||||
|
|
||||||
use super::{Highlights, custom_highlights::CustomHighlightsChunks};
|
use super::{Highlights, custom_highlights::CustomHighlightsChunks};
|
||||||
|
|
||||||
|
@ -252,6 +254,13 @@ pub struct InlayChunks<'a> {
|
||||||
snapshot: &'a InlaySnapshot,
|
snapshot: &'a InlaySnapshot,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct InlayChunk<'a> {
|
||||||
|
pub chunk: Chunk<'a>,
|
||||||
|
/// Whether the inlay should be customly rendered.
|
||||||
|
pub renderer: Option<ChunkRenderer>,
|
||||||
|
}
|
||||||
|
|
||||||
impl InlayChunks<'_> {
|
impl InlayChunks<'_> {
|
||||||
pub fn seek(&mut self, new_range: Range<InlayOffset>) {
|
pub fn seek(&mut self, new_range: Range<InlayOffset>) {
|
||||||
self.transforms.seek(&new_range.start, Bias::Right, &());
|
self.transforms.seek(&new_range.start, Bias::Right, &());
|
||||||
|
@ -271,7 +280,7 @@ impl InlayChunks<'_> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Iterator for InlayChunks<'a> {
|
impl<'a> Iterator for InlayChunks<'a> {
|
||||||
type Item = Chunk<'a>;
|
type Item = InlayChunk<'a>;
|
||||||
|
|
||||||
fn next(&mut self) -> Option<Self::Item> {
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
if self.output_offset == self.max_output_offset {
|
if self.output_offset == self.max_output_offset {
|
||||||
|
@ -296,9 +305,12 @@ impl<'a> Iterator for InlayChunks<'a> {
|
||||||
|
|
||||||
chunk.text = suffix;
|
chunk.text = suffix;
|
||||||
self.output_offset.0 += prefix.len();
|
self.output_offset.0 += prefix.len();
|
||||||
Chunk {
|
InlayChunk {
|
||||||
text: prefix,
|
chunk: Chunk {
|
||||||
..chunk.clone()
|
text: prefix,
|
||||||
|
..chunk.clone()
|
||||||
|
},
|
||||||
|
renderer: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Transform::Inlay(inlay) => {
|
Transform::Inlay(inlay) => {
|
||||||
|
@ -313,6 +325,7 @@ impl<'a> Iterator for InlayChunks<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let mut renderer = None;
|
||||||
let mut highlight_style = match inlay.id {
|
let mut highlight_style = match inlay.id {
|
||||||
InlayId::InlineCompletion(_) => {
|
InlayId::InlineCompletion(_) => {
|
||||||
self.highlight_styles.inline_completion.map(|s| {
|
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::Hint(_) => self.highlight_styles.inlay_hint,
|
||||||
InlayId::DebuggerValue(_) => self.highlight_styles.inlay_hint,
|
InlayId::DebuggerValue(_) => self.highlight_styles.inlay_hint,
|
||||||
InlayId::Color(_) => match inlay.color {
|
InlayId::Color(id) => {
|
||||||
Some(color) => {
|
if let Some(color) = inlay.color {
|
||||||
let mut style = self.highlight_styles.inlay_hint.unwrap_or_default();
|
renderer = Some(ChunkRenderer {
|
||||||
style.color = Some(color);
|
id: FoldId(id),
|
||||||
Some(style)
|
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 next_inlay_highlight_endpoint;
|
||||||
let offset_in_inlay = self.output_offset - self.transforms.start().0;
|
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();
|
self.output_offset.0 += chunk.len();
|
||||||
|
|
||||||
Chunk {
|
InlayChunk {
|
||||||
text: chunk,
|
chunk: Chunk {
|
||||||
highlight_style,
|
text: chunk,
|
||||||
is_inlay: true,
|
highlight_style,
|
||||||
..Default::default()
|
is_inlay: true,
|
||||||
|
..Chunk::default()
|
||||||
|
},
|
||||||
|
renderer,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -1066,7 +1101,7 @@ impl InlaySnapshot {
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
pub fn text(&self) -> String {
|
pub fn text(&self) -> String {
|
||||||
self.chunks(Default::default()..self.len(), false, Highlights::default())
|
self.chunks(Default::default()..self.len(), false, Highlights::default())
|
||||||
.map(|chunk| chunk.text)
|
.map(|chunk| chunk.chunk.text)
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1704,7 +1739,7 @@ mod tests {
|
||||||
..Highlights::default()
|
..Highlights::default()
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
.map(|chunk| chunk.text)
|
.map(|chunk| chunk.chunk.text)
|
||||||
.collect::<String>();
|
.collect::<String>();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
actual_text,
|
actual_text,
|
||||||
|
|
|
@ -547,6 +547,7 @@ pub enum SoftWrap {
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct EditorStyle {
|
pub struct EditorStyle {
|
||||||
pub background: Hsla,
|
pub background: Hsla,
|
||||||
|
pub border: Hsla,
|
||||||
pub local_player: PlayerColor,
|
pub local_player: PlayerColor,
|
||||||
pub text: TextStyle,
|
pub text: TextStyle,
|
||||||
pub scrollbar_width: Pixels,
|
pub scrollbar_width: Pixels,
|
||||||
|
@ -562,6 +563,7 @@ impl Default for EditorStyle {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
background: Hsla::default(),
|
background: Hsla::default(),
|
||||||
|
border: Hsla::default(),
|
||||||
local_player: PlayerColor::default(),
|
local_player: PlayerColor::default(),
|
||||||
text: TextStyle::default(),
|
text: TextStyle::default(),
|
||||||
scrollbar_width: Pixels::default(),
|
scrollbar_width: Pixels::default(),
|
||||||
|
@ -22405,6 +22407,7 @@ impl Render for Editor {
|
||||||
&cx.entity(),
|
&cx.entity(),
|
||||||
EditorStyle {
|
EditorStyle {
|
||||||
background,
|
background,
|
||||||
|
border: cx.theme().colors().border,
|
||||||
local_player: cx.theme().players().local(),
|
local_player: cx.theme().players().local(),
|
||||||
text: text_style,
|
text: text_style,
|
||||||
scrollbar_width: EditorElement::SCROLLBAR_WIDTH,
|
scrollbar_width: EditorElement::SCROLLBAR_WIDTH,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue