Add serialized versions of themes (#6885)
This PR adds serialized versions of each of the themes that currently ship with Zed. In a future PR we'll be looking to make these the canonical representations of the built-in themes. Note that we're intentionally repurposing the `theme_importer` to do this, so that crate is a bit rough-and-ready at the moment. Release Notes: - N/A
This commit is contained in:
parent
9d6414b0cc
commit
0fe0683ef4
25 changed files with 13672 additions and 14 deletions
|
@ -23,5 +23,5 @@ serde.workspace = true
|
|||
serde_json.workspace = true
|
||||
simplelog = "0.9"
|
||||
strum = { version = "0.25.0", features = ["derive"] }
|
||||
theme = { path = "../theme", features = ["importing-themes"] }
|
||||
theme = { path = "../theme", features = [] }
|
||||
uuid.workspace = true
|
||||
|
|
|
@ -16,13 +16,17 @@ use any_ascii::any_ascii;
|
|||
use anyhow::{anyhow, Context, Result};
|
||||
use clap::Parser;
|
||||
use convert_case::{Case, Casing};
|
||||
use gpui::Hsla;
|
||||
use indexmap::IndexMap;
|
||||
use indoc::formatdoc;
|
||||
use json_comments::StripComments;
|
||||
use log::LevelFilter;
|
||||
use serde::Deserialize;
|
||||
use simplelog::{TermLogger, TerminalMode};
|
||||
use theme::{Appearance, UserTheme, UserThemeFamily};
|
||||
use theme::{
|
||||
Appearance, FontWeightContent, HighlightStyleContent, StatusColorsContent, ThemeColorsContent,
|
||||
ThemeContent, ThemeFamilyContent, ThemeStyleContent, UserTheme, UserThemeFamily,
|
||||
};
|
||||
|
||||
use crate::theme_printer::UserThemeFamilyPrinter;
|
||||
use crate::vscode::VsCodeTheme;
|
||||
|
@ -100,6 +104,38 @@ fn main() -> Result<()> {
|
|||
TermLogger::init(LevelFilter::Trace, log_config, TerminalMode::Mixed)
|
||||
.expect("could not initialize logger");
|
||||
|
||||
if 1 < 2 {
|
||||
let themes = Vec::new();
|
||||
// Uncomment this line when you need to regenerate themes.
|
||||
// let themes = theme::all_user_themes();
|
||||
|
||||
let mut families = Vec::new();
|
||||
|
||||
for family in themes {
|
||||
families.push(convert_family(family));
|
||||
}
|
||||
|
||||
for family in families {
|
||||
let theme_family_slug = any_ascii(&family.name)
|
||||
.replace("(", "")
|
||||
.replace(")", "")
|
||||
.to_case(Case::Snake);
|
||||
|
||||
let output_dir = PathBuf::from("assets/themes/").join(&theme_family_slug);
|
||||
|
||||
fs::create_dir_all(&output_dir)?;
|
||||
|
||||
let mut output_file =
|
||||
File::create(output_dir.join(format!("{theme_family_slug}.json")))?;
|
||||
|
||||
let theme_json = serde_json::to_string_pretty(&family).unwrap();
|
||||
|
||||
output_file.write_all(format!("{theme_json}\n").as_bytes())?;
|
||||
}
|
||||
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let mut theme_families = Vec::new();
|
||||
|
||||
/// Whether VS Code themes should be imported.
|
||||
|
@ -420,3 +456,240 @@ fn format_themes_crate() -> std::io::Result<std::process::Output> {
|
|||
.args(["fmt", "--package", "theme"])
|
||||
.output()
|
||||
}
|
||||
|
||||
fn convert_family(family: UserThemeFamily) -> ThemeFamilyContent {
|
||||
ThemeFamilyContent {
|
||||
name: family.name,
|
||||
author: family.author,
|
||||
themes: family.themes.into_iter().map(convert_theme).collect(),
|
||||
}
|
||||
}
|
||||
|
||||
fn convert_theme(theme: UserTheme) -> ThemeContent {
|
||||
ThemeContent {
|
||||
name: theme.name,
|
||||
appearance: match theme.appearance {
|
||||
Appearance::Light => theme::AppearanceContent::Light,
|
||||
Appearance::Dark => theme::AppearanceContent::Dark,
|
||||
},
|
||||
style: convert_theme_styles(theme.styles),
|
||||
}
|
||||
}
|
||||
|
||||
fn serialize_color(color: Hsla) -> String {
|
||||
let rgba = color.to_rgb();
|
||||
format!("#{:08x}", u32::from(rgba))
|
||||
}
|
||||
|
||||
fn convert_theme_styles(styles: theme::UserThemeStylesRefinement) -> ThemeStyleContent {
|
||||
ThemeStyleContent {
|
||||
colors: ThemeColorsContent {
|
||||
border: styles.colors.border.map(serialize_color),
|
||||
border_variant: styles.colors.border_variant.map(serialize_color),
|
||||
border_focused: styles.colors.border_focused.map(serialize_color),
|
||||
border_selected: styles.colors.border_selected.map(serialize_color),
|
||||
border_transparent: styles.colors.border_transparent.map(serialize_color),
|
||||
border_disabled: styles.colors.border_disabled.map(serialize_color),
|
||||
elevated_surface_background: styles
|
||||
.colors
|
||||
.elevated_surface_background
|
||||
.map(serialize_color),
|
||||
surface_background: styles.colors.surface_background.map(serialize_color),
|
||||
background: styles.colors.background.map(serialize_color),
|
||||
element_background: styles.colors.element_background.map(serialize_color),
|
||||
element_hover: styles.colors.element_hover.map(serialize_color),
|
||||
element_active: styles.colors.element_active.map(serialize_color),
|
||||
element_selected: styles.colors.element_selected.map(serialize_color),
|
||||
element_disabled: styles.colors.element_disabled.map(serialize_color),
|
||||
drop_target_background: styles.colors.drop_target_background.map(serialize_color),
|
||||
ghost_element_background: styles.colors.ghost_element_background.map(serialize_color),
|
||||
ghost_element_hover: styles.colors.ghost_element_hover.map(serialize_color),
|
||||
ghost_element_active: styles.colors.ghost_element_active.map(serialize_color),
|
||||
ghost_element_selected: styles.colors.ghost_element_selected.map(serialize_color),
|
||||
ghost_element_disabled: styles.colors.ghost_element_disabled.map(serialize_color),
|
||||
text: styles.colors.text.map(serialize_color),
|
||||
text_muted: styles.colors.text_muted.map(serialize_color),
|
||||
text_placeholder: styles.colors.text_placeholder.map(serialize_color),
|
||||
text_disabled: styles.colors.text_disabled.map(serialize_color),
|
||||
text_accent: styles.colors.text_accent.map(serialize_color),
|
||||
icon: styles.colors.icon.map(serialize_color),
|
||||
icon_muted: styles.colors.icon_muted.map(serialize_color),
|
||||
icon_disabled: styles.colors.icon_disabled.map(serialize_color),
|
||||
icon_placeholder: styles.colors.icon_placeholder.map(serialize_color),
|
||||
icon_accent: styles.colors.icon_accent.map(serialize_color),
|
||||
status_bar_background: styles.colors.status_bar_background.map(serialize_color),
|
||||
title_bar_background: styles.colors.title_bar_background.map(serialize_color),
|
||||
toolbar_background: styles.colors.toolbar_background.map(serialize_color),
|
||||
tab_bar_background: styles.colors.tab_bar_background.map(serialize_color),
|
||||
tab_inactive_background: styles.colors.tab_inactive_background.map(serialize_color),
|
||||
tab_active_background: styles.colors.tab_active_background.map(serialize_color),
|
||||
search_match_background: styles.colors.search_match_background.map(serialize_color),
|
||||
panel_background: styles.colors.panel_background.map(serialize_color),
|
||||
panel_focused_border: styles.colors.panel_focused_border.map(serialize_color),
|
||||
pane_focused_border: styles.colors.pane_focused_border.map(serialize_color),
|
||||
scrollbar_thumb_background: styles
|
||||
.colors
|
||||
.scrollbar_thumb_background
|
||||
.map(serialize_color),
|
||||
scrollbar_thumb_hover_background: styles
|
||||
.colors
|
||||
.scrollbar_thumb_hover_background
|
||||
.map(serialize_color),
|
||||
scrollbar_thumb_border: styles.colors.scrollbar_thumb_border.map(serialize_color),
|
||||
scrollbar_track_background: styles
|
||||
.colors
|
||||
.scrollbar_track_background
|
||||
.map(serialize_color),
|
||||
scrollbar_track_border: styles.colors.scrollbar_track_border.map(serialize_color),
|
||||
editor_foreground: styles.colors.editor_foreground.map(serialize_color),
|
||||
editor_background: styles.colors.editor_background.map(serialize_color),
|
||||
editor_gutter_background: styles.colors.editor_gutter_background.map(serialize_color),
|
||||
editor_subheader_background: styles
|
||||
.colors
|
||||
.editor_subheader_background
|
||||
.map(serialize_color),
|
||||
editor_active_line_background: styles
|
||||
.colors
|
||||
.editor_active_line_background
|
||||
.map(serialize_color),
|
||||
editor_highlighted_line_background: styles
|
||||
.colors
|
||||
.editor_highlighted_line_background
|
||||
.map(serialize_color),
|
||||
editor_line_number: styles.colors.editor_line_number.map(serialize_color),
|
||||
editor_active_line_number: styles.colors.editor_active_line_number.map(serialize_color),
|
||||
editor_invisible: styles.colors.editor_invisible.map(serialize_color),
|
||||
editor_wrap_guide: styles.colors.editor_wrap_guide.map(serialize_color),
|
||||
editor_active_wrap_guide: styles.colors.editor_active_wrap_guide.map(serialize_color),
|
||||
editor_document_highlight_read_background: styles
|
||||
.colors
|
||||
.editor_document_highlight_read_background
|
||||
.map(serialize_color),
|
||||
editor_document_highlight_write_background: styles
|
||||
.colors
|
||||
.editor_document_highlight_write_background
|
||||
.map(serialize_color),
|
||||
terminal_background: styles.colors.terminal_background.map(serialize_color),
|
||||
terminal_foreground: styles.colors.terminal_foreground.map(serialize_color),
|
||||
terminal_bright_foreground: styles
|
||||
.colors
|
||||
.terminal_bright_foreground
|
||||
.map(serialize_color),
|
||||
terminal_dim_foreground: styles.colors.terminal_dim_foreground.map(serialize_color),
|
||||
terminal_ansi_black: styles.colors.terminal_ansi_black.map(serialize_color),
|
||||
terminal_ansi_bright_black: styles
|
||||
.colors
|
||||
.terminal_ansi_bright_black
|
||||
.map(serialize_color),
|
||||
terminal_ansi_dim_black: styles.colors.terminal_ansi_dim_black.map(serialize_color),
|
||||
terminal_ansi_red: styles.colors.terminal_ansi_red.map(serialize_color),
|
||||
terminal_ansi_bright_red: styles.colors.terminal_ansi_bright_red.map(serialize_color),
|
||||
terminal_ansi_dim_red: styles.colors.terminal_ansi_dim_red.map(serialize_color),
|
||||
terminal_ansi_green: styles.colors.terminal_ansi_green.map(serialize_color),
|
||||
terminal_ansi_bright_green: styles
|
||||
.colors
|
||||
.terminal_ansi_bright_green
|
||||
.map(serialize_color),
|
||||
terminal_ansi_dim_green: styles.colors.terminal_ansi_dim_green.map(serialize_color),
|
||||
terminal_ansi_yellow: styles.colors.terminal_ansi_yellow.map(serialize_color),
|
||||
terminal_ansi_bright_yellow: styles
|
||||
.colors
|
||||
.terminal_ansi_bright_yellow
|
||||
.map(serialize_color),
|
||||
terminal_ansi_dim_yellow: styles.colors.terminal_ansi_dim_yellow.map(serialize_color),
|
||||
terminal_ansi_blue: styles.colors.terminal_ansi_blue.map(serialize_color),
|
||||
terminal_ansi_bright_blue: styles.colors.terminal_ansi_bright_blue.map(serialize_color),
|
||||
terminal_ansi_dim_blue: styles.colors.terminal_ansi_dim_blue.map(serialize_color),
|
||||
terminal_ansi_magenta: styles.colors.terminal_ansi_magenta.map(serialize_color),
|
||||
terminal_ansi_bright_magenta: styles
|
||||
.colors
|
||||
.terminal_ansi_bright_magenta
|
||||
.map(serialize_color),
|
||||
terminal_ansi_dim_magenta: styles.colors.terminal_ansi_dim_magenta.map(serialize_color),
|
||||
terminal_ansi_cyan: styles.colors.terminal_ansi_cyan.map(serialize_color),
|
||||
terminal_ansi_bright_cyan: styles.colors.terminal_ansi_bright_cyan.map(serialize_color),
|
||||
terminal_ansi_dim_cyan: styles.colors.terminal_ansi_dim_cyan.map(serialize_color),
|
||||
terminal_ansi_white: styles.colors.terminal_ansi_white.map(serialize_color),
|
||||
terminal_ansi_bright_white: styles
|
||||
.colors
|
||||
.terminal_ansi_bright_white
|
||||
.map(serialize_color),
|
||||
terminal_ansi_dim_white: styles.colors.terminal_ansi_dim_white.map(serialize_color),
|
||||
link_text_hover: styles.colors.link_text_hover.map(serialize_color),
|
||||
},
|
||||
status: StatusColorsContent {
|
||||
conflict: styles.status.conflict.map(serialize_color),
|
||||
conflict_background: styles.status.conflict_background.map(serialize_color),
|
||||
conflict_border: styles.status.conflict_border.map(serialize_color),
|
||||
created: styles.status.created.map(serialize_color),
|
||||
created_background: styles.status.created_background.map(serialize_color),
|
||||
created_border: styles.status.created_border.map(serialize_color),
|
||||
deleted: styles.status.deleted.map(serialize_color),
|
||||
deleted_background: styles.status.deleted_background.map(serialize_color),
|
||||
deleted_border: styles.status.deleted_border.map(serialize_color),
|
||||
error: styles.status.error.map(serialize_color),
|
||||
error_background: styles.status.error_background.map(serialize_color),
|
||||
error_border: styles.status.error_border.map(serialize_color),
|
||||
hidden: styles.status.hidden.map(serialize_color),
|
||||
hidden_background: styles.status.hidden_background.map(serialize_color),
|
||||
hidden_border: styles.status.hidden_border.map(serialize_color),
|
||||
hint: styles.status.hint.map(serialize_color),
|
||||
hint_background: styles.status.hint_background.map(serialize_color),
|
||||
hint_border: styles.status.hint_border.map(serialize_color),
|
||||
ignored: styles.status.ignored.map(serialize_color),
|
||||
ignored_background: styles.status.ignored_background.map(serialize_color),
|
||||
ignored_border: styles.status.ignored_border.map(serialize_color),
|
||||
info: styles.status.info.map(serialize_color),
|
||||
info_background: styles.status.info_background.map(serialize_color),
|
||||
info_border: styles.status.info_border.map(serialize_color),
|
||||
modified: styles.status.modified.map(serialize_color),
|
||||
modified_background: styles.status.modified_background.map(serialize_color),
|
||||
modified_border: styles.status.modified_border.map(serialize_color),
|
||||
predictive: styles.status.predictive.map(serialize_color),
|
||||
predictive_background: styles.status.predictive_background.map(serialize_color),
|
||||
predictive_border: styles.status.predictive_border.map(serialize_color),
|
||||
renamed: styles.status.renamed.map(serialize_color),
|
||||
renamed_background: styles.status.renamed_background.map(serialize_color),
|
||||
renamed_border: styles.status.renamed_border.map(serialize_color),
|
||||
success: styles.status.success.map(serialize_color),
|
||||
success_background: styles.status.success_background.map(serialize_color),
|
||||
success_border: styles.status.success_border.map(serialize_color),
|
||||
unreachable: styles.status.unreachable.map(serialize_color),
|
||||
unreachable_background: styles.status.unreachable_background.map(serialize_color),
|
||||
unreachable_border: styles.status.unreachable_border.map(serialize_color),
|
||||
warning: styles.status.warning.map(serialize_color),
|
||||
warning_background: styles.status.warning_background.map(serialize_color),
|
||||
warning_border: styles.status.warning_border.map(serialize_color),
|
||||
},
|
||||
syntax: styles
|
||||
.syntax
|
||||
.map(|syntax| {
|
||||
IndexMap::from_iter(syntax.highlights.into_iter().map(|(name, style)| {
|
||||
(
|
||||
name,
|
||||
HighlightStyleContent {
|
||||
color: style.color.map(serialize_color),
|
||||
font_style: style.font_style.map(|font_style| match font_style {
|
||||
theme::UserFontStyle::Normal => theme::FontStyleContent::Normal,
|
||||
theme::UserFontStyle::Italic => theme::FontStyleContent::Italic,
|
||||
theme::UserFontStyle::Oblique => theme::FontStyleContent::Oblique,
|
||||
}),
|
||||
font_weight: style.font_weight.map(|font_weight| match font_weight.0 {
|
||||
_ if font_weight.0 == 100.0 => FontWeightContent::Thin,
|
||||
_ if font_weight.0 == 200.0 => FontWeightContent::ExtraLight,
|
||||
_ if font_weight.0 == 300.0 => FontWeightContent::Light,
|
||||
_ if font_weight.0 == 400.0 => FontWeightContent::Normal,
|
||||
_ if font_weight.0 == 500.0 => FontWeightContent::Medium,
|
||||
_ if font_weight.0 == 600.0 => FontWeightContent::Semibold,
|
||||
_ if font_weight.0 == 700.0 => FontWeightContent::Bold,
|
||||
_ if font_weight.0 == 800.0 => FontWeightContent::ExtraBold,
|
||||
_ if font_weight.0 == 900.0 => FontWeightContent::Black,
|
||||
_ => unreachable!(),
|
||||
}),
|
||||
},
|
||||
)
|
||||
}))
|
||||
})
|
||||
.unwrap_or_default(),
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue