editor: Allow customizing CodeLens text color (#64084)
CodeLens text currently hardcodes `text.muted`, so changing its color also changes unrelated muted UI text such as the sidebar. This adds a dedicated `editor.code_lens.foreground` theme color. When omitted, it falls back to `text.muted`, preserving the existing appearance of themes while allowing CodeLens text to be customized independently. Release Notes: - Added `editor.code_lens.foreground` for customizing CodeLens text independently. --------- Co-authored-by: Kirill Bulatov <mail4score@gmail.com>
This commit is contained in:
1 parent
1e6cc1f182
commit
fde3e42be8
7 files changed
+123
-2
No files matched your search
@@ -616,6 +616,10 @@ fn build_code_lens_renderer(line: CodeLensLine, editor: WeakEntity<Editor>) -> R
|
||||
let text_style = &cx.editor_style.text;
|
||||
let font = text_style.font();
|
||||
let font_size = text_style.font_size.to_pixels(cx.window.rem_size()) * 0.9;
|
||||
let colors = cx.app.theme().colors();
|
||||
let code_lens_color = colors
|
||||
.editor_code_lens_foreground
|
||||
.unwrap_or(colors.text_muted);
|
||||
|
||||
for (i, (title, action)) in resolved_items.into_iter().enumerate() {
|
||||
if i > 0 {
|
||||
@@ -623,7 +627,7 @@ fn build_code_lens_renderer(line: CodeLensLine, editor: WeakEntity<Editor>) -> R
|
||||
div()
|
||||
.font(font.clone())
|
||||
.text_size(font_size)
|
||||
.text_color(cx.app.theme().colors().text_muted)
|
||||
.text_color(code_lens_color)
|
||||
.child(CODE_LENS_SEPARATOR)
|
||||
.into_any_element(),
|
||||
);
|
||||
@@ -634,7 +638,7 @@ fn build_code_lens_renderer(line: CodeLensLine, editor: WeakEntity<Editor>) -> R
|
||||
.id(ElementId::from(i))
|
||||
.font(font.clone())
|
||||
.text_size(font_size)
|
||||
.text_color(cx.app.theme().colors().text_muted)
|
||||
.text_color(code_lens_color)
|
||||
.child(title.clone())
|
||||
.when_some(action, |code_lens_div, action| {
|
||||
let position = line.position;
|
||||
|
||||
@@ -842,6 +842,10 @@ pub struct ThemeColorsContent {
|
||||
#[serde(rename = "editor.foreground")]
|
||||
pub editor_foreground: Option<ThemeColor>,
|
||||
|
||||
/// Text color used for CodeLens items in the editor.
|
||||
#[serde(rename = "editor.code_lens.foreground")]
|
||||
pub editor_code_lens_foreground: Option<ThemeColor>,
|
||||
|
||||
#[serde(rename = "editor.background")]
|
||||
pub editor_background: Option<ThemeColor>,
|
||||
|
||||
|
||||
@@ -112,6 +112,7 @@ impl ThemeColors {
|
||||
minimap_thumb_active_background: neutral().light_alpha().step_5().alpha(0.7),
|
||||
minimap_thumb_border: gpui::transparent_black(),
|
||||
editor_foreground: neutral().light().step_12(),
|
||||
editor_code_lens_foreground: None,
|
||||
editor_background: neutral().light().step_1(),
|
||||
editor_gutter_background: neutral().light().step_1(),
|
||||
editor_subheader_background: neutral().light().step_2(),
|
||||
@@ -265,6 +266,7 @@ impl ThemeColors {
|
||||
minimap_thumb_active_background: neutral().dark_alpha().step_5().alpha(0.7),
|
||||
minimap_thumb_border: gpui::transparent_black(),
|
||||
editor_foreground: neutral().dark().step_12(),
|
||||
editor_code_lens_foreground: None,
|
||||
editor_background: neutral().dark().step_1(),
|
||||
editor_gutter_background: neutral().dark().step_1(),
|
||||
editor_subheader_background: neutral().dark().step_3(),
|
||||
|
||||
@@ -247,6 +247,7 @@ pub(crate) fn zed_default_dark() -> Theme {
|
||||
minimap_thumb_active_background: hsla(225.0 / 360., 11.8 / 100., 26.7 / 100., 0.7),
|
||||
minimap_thumb_border: hsla(228. / 360., 8. / 100., 25. / 100., 1.),
|
||||
editor_foreground: hsla(218. / 360., 14. / 100., 71. / 100., 1.),
|
||||
editor_code_lens_foreground: None,
|
||||
link_text_hover: blue,
|
||||
version_control_added: ADDED_COLOR,
|
||||
version_control_deleted: REMOVED_COLOR,
|
||||
|
||||
@@ -204,6 +204,10 @@ pub struct ThemeColors {
|
||||
// Editor
|
||||
// ===
|
||||
pub editor_foreground: Hsla,
|
||||
/// Text color used for CodeLens items in the editor.
|
||||
///
|
||||
/// Falls back to `text_muted` when not explicitly set.
|
||||
pub editor_code_lens_foreground: Option<Hsla>,
|
||||
pub editor_background: Hsla,
|
||||
pub editor_gutter_background: Hsla,
|
||||
pub editor_subheader_background: Hsla,
|
||||
@@ -404,6 +408,7 @@ pub enum ThemeColorField {
|
||||
MinimapThumbActiveBackground,
|
||||
MinimapThumbBorder,
|
||||
EditorForeground,
|
||||
EditorCodeLensForeground,
|
||||
EditorBackground,
|
||||
EditorGutterBackground,
|
||||
EditorSubheaderBackground,
|
||||
@@ -522,6 +527,9 @@ impl ThemeColors {
|
||||
ThemeColorField::MinimapThumbActiveBackground => self.minimap_thumb_active_background,
|
||||
ThemeColorField::MinimapThumbBorder => self.minimap_thumb_border,
|
||||
ThemeColorField::EditorForeground => self.editor_foreground,
|
||||
ThemeColorField::EditorCodeLensForeground => {
|
||||
self.editor_code_lens_foreground.unwrap_or(self.text_muted)
|
||||
}
|
||||
ThemeColorField::EditorBackground => self.editor_background,
|
||||
ThemeColorField::EditorGutterBackground => self.editor_gutter_background,
|
||||
ThemeColorField::EditorSubheaderBackground => self.editor_subheader_background,
|
||||
|
||||
@@ -541,6 +541,10 @@ pub fn theme_colors_refinement(
|
||||
.editor_foreground
|
||||
.as_ref()
|
||||
.and_then(|color| try_parse_color(color).ok()),
|
||||
editor_code_lens_foreground: this
|
||||
.editor_code_lens_foreground
|
||||
.as_ref()
|
||||
.and_then(|color| try_parse_color(color).ok()),
|
||||
editor_background: this
|
||||
.editor_background
|
||||
.as_ref()
|
||||
|
||||
@@ -765,3 +765,101 @@ impl settings::Settings for ThemeSettings {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
fn theme_with_colors(colors: ::settings::ThemeColorsContent) -> Theme {
|
||||
crate::refine_theme(&crate::ThemeContent {
|
||||
name: "Test".into(),
|
||||
appearance: ::theme::AppearanceContent::Dark,
|
||||
style: ::settings::ThemeStyleContent {
|
||||
colors,
|
||||
..Default::default()
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
fn style_with_colors(colors: ::settings::ThemeColorsContent) -> ::settings::ThemeStyleContent {
|
||||
::settings::ThemeStyleContent {
|
||||
colors,
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn code_lens_foreground_from_theme_survives_text_muted_override() {
|
||||
let magenta = ::theme::try_parse_color("#ff00ff").unwrap();
|
||||
let green = ::theme::try_parse_color("#00ff00").unwrap();
|
||||
let mut test_theme = theme_with_colors(::settings::ThemeColorsContent {
|
||||
editor_code_lens_foreground: Some("#ff00ff".into()),
|
||||
..Default::default()
|
||||
});
|
||||
|
||||
ThemeSettings::modify_theme(
|
||||
&mut test_theme,
|
||||
&style_with_colors(::settings::ThemeColorsContent {
|
||||
text_muted: Some("#00ff00".into()),
|
||||
..Default::default()
|
||||
}),
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
test_theme.styles.colors.editor_code_lens_foreground,
|
||||
Some(magenta)
|
||||
);
|
||||
assert_eq!(test_theme.styles.colors.text_muted, green);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn code_lens_foreground_from_earlier_override_survives_later_muted_override() {
|
||||
let magenta = ::theme::try_parse_color("#ff00ff").unwrap();
|
||||
let green = ::theme::try_parse_color("#00ff00").unwrap();
|
||||
let mut test_theme = theme_with_colors(Default::default());
|
||||
|
||||
ThemeSettings::modify_theme(
|
||||
&mut test_theme,
|
||||
&style_with_colors(::settings::ThemeColorsContent {
|
||||
editor_code_lens_foreground: Some("#ff00ff".into()),
|
||||
..Default::default()
|
||||
}),
|
||||
);
|
||||
ThemeSettings::modify_theme(
|
||||
&mut test_theme,
|
||||
&style_with_colors(::settings::ThemeColorsContent {
|
||||
text_muted: Some("#00ff00".into()),
|
||||
..Default::default()
|
||||
}),
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
test_theme.styles.colors.editor_code_lens_foreground,
|
||||
Some(magenta)
|
||||
);
|
||||
assert_eq!(test_theme.styles.colors.text_muted, green);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn code_lens_foreground_follows_effective_text_muted_without_explicit_color() {
|
||||
let green = ::theme::try_parse_color("#00ff00").unwrap();
|
||||
let mut test_theme = theme_with_colors(Default::default());
|
||||
|
||||
ThemeSettings::modify_theme(
|
||||
&mut test_theme,
|
||||
&style_with_colors(::settings::ThemeColorsContent {
|
||||
text_muted: Some("#00ff00".into()),
|
||||
..Default::default()
|
||||
}),
|
||||
);
|
||||
|
||||
assert_eq!(test_theme.styles.colors.editor_code_lens_foreground, None);
|
||||
assert_eq!(
|
||||
test_theme
|
||||
.styles
|
||||
.colors
|
||||
.color(::theme::ThemeColorField::EditorCodeLensForeground),
|
||||
green
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user