diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index 64009448570bb56f60fdd053ca9e3188b2f69e25..bd12b1f5ba589a0470b5d988e9aaeb361e9c3598 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -4393,20 +4393,14 @@ impl Editor { editor .buffer .update(cx, |buffer, cx| buffer.edit([0..0], &old_name, cx)); - editor.select_ranges( - [tail_offset_in_rename_range..cursor_offset_in_rename_range], - None, - cx, - ); + editor.select_all(&SelectAll, cx); editor }); this.highlight_text::( vec![range.clone()], HighlightStyle { - color: Color::transparent_black(), - font_properties: todo!(), - underline: todo!(), - fade_out: todo!(), + fade_out: Some(style.rename_fade), + ..Default::default() }, cx, ); @@ -4500,7 +4494,7 @@ impl Editor { fn take_rename(&mut self, cx: &mut ViewContext) -> Option { let rename = self.pending_rename.take()?; self.remove_blocks([rename.block_id].into_iter().collect(), cx); - self.clear_background_highlights::(cx); + self.clear_text_highlights::(cx); let editor = rename.editor.read(cx); let snapshot = self.buffer.read(cx).snapshot(cx); diff --git a/crates/editor/src/element.rs b/crates/editor/src/element.rs index ae3a09dc13615c175d2053cffa2f8c5905bc99d0..13161f90834cb5821743453b17a4c38a8e102f8d 100644 --- a/crates/editor/src/element.rs +++ b/crates/editor/src/element.rs @@ -606,30 +606,34 @@ impl EditorElement { } else { let style = &self.style; let chunks = snapshot.chunks(rows.clone(), true).map(|chunk| { - let mut highlight_style = HighlightStyle { - color: style.text.color, - font_properties: style.text.font_properties, - ..Default::default() - }; - - if let Some(syntax_highlight_style) = chunk + let mut highlight_style = chunk .syntax_highlight_id - .and_then(|id| id.style(&style.syntax)) - { - highlight_style.highlight(syntax_highlight_style); - } + .and_then(|id| id.style(&style.syntax)); - if let Some(style) = chunk.highlight_style { - highlight_style.highlight(style); + 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); + } } if let Some(severity) = chunk.diagnostic { let diagnostic_style = super::diagnostic_style(severity, true, style); - highlight_style.underline = Some(Underline { - color: diagnostic_style.message.text.color, - thickness: 1.0.into(), - squiggly: true, - }); + let diagnostic_highlight = HighlightStyle { + underline: Some(Underline { + color: diagnostic_style.message.text.color, + thickness: 1.0.into(), + squiggly: true, + }), + ..Default::default() + }; + + if let Some(highlight_style) = highlight_style.as_mut() { + highlight_style.highlight(diagnostic_highlight); + } else { + highlight_style = Some(diagnostic_highlight); + } } (chunk.text, highlight_style) diff --git a/crates/gpui/src/color.rs b/crates/gpui/src/color.rs index 1057cbe7aa3dc690c1539fb6f91ad342b0198217..f31a80a831d43812307833312b03e3b670a111b9 100644 --- a/crates/gpui/src/color.rs +++ b/crates/gpui/src/color.rs @@ -50,9 +50,11 @@ impl Color { } pub fn blend(source: Color, dest: Color) -> Color { - // If source is fully opaque, don't blend. + // Skip blending if we don't need it. if source.a == 255 { return source; + } else if source.a == 0 { + return dest; } let source = source.0.to_f32(); @@ -66,11 +68,9 @@ impl Color { Self(ColorF::new(r, g, b, a).to_u8()) } - pub fn fade_out(&mut self, factor: f32) { - let source_alpha = 1. - factor.clamp(0., 1.); - let dest_alpha = self.0.a as f32 / 255.; - let dest_alpha = source_alpha + (dest_alpha * (1. - source_alpha)); - self.0.a = (dest_alpha * (1. / 255.)) as u8; + pub fn fade_out(&mut self, fade: f32) { + let fade = fade.clamp(0., 1.); + self.0.a = (self.0.a as f32 * (1. - fade)) as u8; } } diff --git a/crates/gpui/src/elements/text.rs b/crates/gpui/src/elements/text.rs index 681464611721da812572297d0edb1d828271348d..707bad55e699f412a5a7e1e05b5289289ad0d934 100644 --- a/crates/gpui/src/elements/text.rs +++ b/crates/gpui/src/elements/text.rs @@ -69,18 +69,15 @@ impl Element for Text { let result; if let Some((range, highlight_style)) = highlight_ranges.peek() { if offset < range.start { - result = Some(( - &self.text[offset..range.start], - HighlightStyle::from(&self.style), - )); + result = Some((&self.text[offset..range.start], None)); offset = range.start; } else { - result = Some((&self.text[range.clone()], *highlight_style)); + result = Some((&self.text[range.clone()], Some(*highlight_style))); highlight_ranges.next(); offset = range.end; } } else if offset < self.text.len() { - result = Some((&self.text[offset..], HighlightStyle::from(&self.style))); + result = Some((&self.text[offset..], None)); offset = self.text.len(); } else { result = None; @@ -200,7 +197,7 @@ impl Element for Text { /// Perform text layout on a series of highlighted chunks of text. pub fn layout_highlighted_chunks<'a>( - chunks: impl Iterator, + chunks: impl Iterator)>, text_style: &'a TextStyle, text_layout_cache: &'a TextLayoutCache, font_cache: &'a Arc, @@ -228,12 +225,29 @@ pub fn layout_highlighted_chunks<'a>( } if !line_chunk.is_empty() && !line_exceeded_max_len { + let font_properties; + let mut color; + let underline; + + if let Some(highlight_style) = highlight_style { + font_properties = highlight_style.font_properties; + color = Color::blend(highlight_style.color, text_style.color); + if let Some(fade) = highlight_style.fade_out { + color.fade_out(fade); + } + underline = highlight_style.underline; + } else { + font_properties = text_style.font_properties; + color = text_style.color; + underline = None; + } + // Avoid a lookup if the font properties match the previous ones. - let font_id = if highlight_style.font_properties == prev_font_properties { + let font_id = if font_properties == prev_font_properties { prev_font_id } else { font_cache - .select_font(text_style.font_family_id, &highlight_style.font_properties) + .select_font(text_style.font_family_id, &font_properties) .unwrap_or(text_style.font_id) }; @@ -251,12 +265,12 @@ pub fn layout_highlighted_chunks<'a>( line_chunk.len(), RunStyle { font_id, - color: highlight_style.color, - underline: highlight_style.underline, + color, + underline, }, )); prev_font_id = font_id; - prev_font_properties = highlight_style.font_properties; + prev_font_properties = font_properties; } } } diff --git a/crates/gpui/src/fonts.rs b/crates/gpui/src/fonts.rs index 60073a64d63d1cd6202dc3213061c607abb2f631..d2fab7467d0d586034099ef386e03689b5ae1c28 100644 --- a/crates/gpui/src/fonts.rs +++ b/crates/gpui/src/fonts.rs @@ -267,8 +267,16 @@ impl HighlightStyle { pub fn highlight(&mut self, other: HighlightStyle) { self.color = Color::blend(other.color, self.color); - if let Some(factor) = other.fade_out { - self.color.fade_out(factor); + match (other.fade_out, self.fade_out) { + (Some(source_fade), None) => self.fade_out = Some(source_fade), + (Some(source_fade), Some(dest_fade)) => { + let source_alpha = 1. - source_fade; + let dest_alpha = 1. - dest_fade; + let blended_alpha = source_alpha + (dest_alpha * source_fade); + let blended_fade = 1. - blended_alpha; + self.fade_out = Some(blended_fade); + } + _ => {} } self.font_properties = other.font_properties; if other.underline.is_some() { diff --git a/crates/theme/src/theme.rs b/crates/theme/src/theme.rs index c96db5aab2ad3082520f8b3b96f7a93d4928c5a4..d372c2fd31b682fb03d090cce77f295adb9f48cd 100644 --- a/crates/theme/src/theme.rs +++ b/crates/theme/src/theme.rs @@ -282,6 +282,7 @@ pub struct Editor { pub gutter_padding_factor: f32, pub active_line_background: Color, pub highlighted_line_background: Color, + pub rename_fade: f32, pub document_highlight_read_background: Color, pub document_highlight_write_background: Color, pub diff_background_deleted: Color, diff --git a/crates/zed/assets/themes/_base.toml b/crates/zed/assets/themes/_base.toml index 59a488c896b4791e66514a2f0b76f409e8483342..97c3c55fcb83442c9e44f7f8afb8def796862fc3 100644 --- a/crates/zed/assets/themes/_base.toml +++ b/crates/zed/assets/themes/_base.toml @@ -249,6 +249,7 @@ gutter_background = "$surface.1" gutter_padding_factor = 2.5 active_line_background = "$state.active_line" highlighted_line_background = "$state.highlighted_line" +rename_fade = 0.6 document_highlight_read_background = "#99999920" document_highlight_write_background = "#99999916" diff_background_deleted = "$state.deleted_line"