logiguard fork v3: full patch set on verified 8c74db0 tree

Includes prior-session patches (carry forward so the app compiles):
  - crates/gpui/build.rs: cross-compile manifest fix
  - crates/gpui/src/platform.rs: PlatformWindow::activate_with_token trait method
  - crates/gpui/src/window.rs: Window::activate_with_token public API
  - crates/gpui_linux/src/linux/wayland/window.rs: WaylandWindow::activate_with_token + activate() keyboard-serial fix

Plus the focus-serial fix:
  - serial.rs: SerialKind::KeyboardEnter
  - client.rs: store wl_keyboard.enter serial; latest_serial_of()

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Mohamad Khani
2026-07-14 01:52:12 +03:30
commit b9819977a5
3984 changed files with 1487015 additions and 0 deletions

View File

@@ -0,0 +1,26 @@
[package]
name = "theme_importer"
version = "0.1.0"
edition.workspace = true
publish.workspace = true
license = "GPL-3.0-or-later"
[lints]
workspace = true
[dependencies]
anyhow.workspace = true
clap = { workspace = true, features = ["derive"] }
collections.workspace = true
gpui.workspace = true
indexmap.workspace = true
log.workspace = true
palette.workspace = true
serde.workspace = true
serde_json.workspace = true
serde_json_lenient.workspace = true
simplelog.workspace= true
strum = { workspace = true, features = ["derive"] }
theme.workspace = true
theme_settings.workspace = true
vscode_theme = "0.2.0"

View File

@@ -0,0 +1 @@
../../LICENSE-GPL

View File

@@ -0,0 +1,5 @@
# Zed Theme Importer
```sh
cargo run -p theme_importer -- dark-plus-syntax-color-theme.json --output output-theme.json
```

View File

@@ -0,0 +1,56 @@
use anyhow::Result;
use gpui::Hsla;
use palette::FromColor;
#[allow(unused)]
pub(crate) fn try_parse_color(color: &str) -> Result<Hsla> {
let rgba = gpui::Rgba::try_from(color)?;
let rgba = palette::rgb::Srgba::from_components((rgba.r, rgba.g, rgba.b, rgba.a));
let hsla = palette::Hsla::from_color(rgba);
let hsla = gpui::hsla(
hsla.hue.into_positive_degrees() / 360.,
hsla.saturation,
hsla.lightness,
hsla.alpha,
);
Ok(hsla)
}
#[allow(unused)]
pub(crate) fn pack_color(color: Hsla) -> u32 {
let hsla = palette::Hsla::from_components((color.h * 360., color.s, color.l, color.a));
let rgba = palette::rgb::Srgba::from_color(hsla);
let rgba = rgba.into_format::<u8, u8>();
u32::from(rgba)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
pub fn test_serialize_color() {
let color = "#b4637aff";
let hsla = try_parse_color(color).unwrap();
let packed = pack_color(hsla);
assert_eq!(format!("#{:x}", packed), color);
}
#[test]
pub fn test_serialize_color_with_palette() {
let color = "#b4637aff";
let rgba = gpui::Rgba::try_from(color).unwrap();
let rgba = palette::rgb::Srgba::from_components((rgba.r, rgba.g, rgba.b, rgba.a));
let hsla = palette::Hsla::from_color(rgba);
let rgba = palette::rgb::Srgba::from_color(hsla);
let rgba = rgba.into_format::<u8, u8>();
assert_eq!(format!("#{:x}", rgba), color);
}
}

View File

@@ -0,0 +1,130 @@
mod color;
mod vscode;
use std::fs::File;
use std::io::{Read, Write};
use std::path::PathBuf;
use anyhow::{Context as _, Result};
use clap::Parser;
use collections::IndexMap;
use log::LevelFilter;
use serde::Deserialize;
use simplelog::ColorChoice;
use simplelog::{TermLogger, TerminalMode};
use theme::{Appearance, AppearanceContent};
use crate::vscode::VsCodeTheme;
use crate::vscode::VsCodeThemeConverter;
const ZED_THEME_SCHEMA_URL: &str = "https://zed.dev/schema/themes/v0.2.0.json";
#[derive(Debug, Clone, Copy, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum ThemeAppearanceJson {
Light,
Dark,
}
impl From<ThemeAppearanceJson> for AppearanceContent {
fn from(value: ThemeAppearanceJson) -> Self {
match value {
ThemeAppearanceJson::Light => Self::Light,
ThemeAppearanceJson::Dark => Self::Dark,
}
}
}
impl From<ThemeAppearanceJson> for Appearance {
fn from(value: ThemeAppearanceJson) -> Self {
match value {
ThemeAppearanceJson::Light => Self::Light,
ThemeAppearanceJson::Dark => Self::Dark,
}
}
}
#[derive(Debug, Deserialize)]
pub struct ThemeMetadata {
pub name: String,
pub file_name: String,
pub appearance: ThemeAppearanceJson,
}
#[derive(Parser)]
#[command(author, version, about, long_about = None)]
struct Args {
/// The path to the theme to import.
theme_path: PathBuf,
/// Whether to warn when values are missing from the theme.
#[arg(long)]
warn_on_missing: bool,
/// The path to write the output to.
#[arg(long, short)]
output: Option<PathBuf>,
}
fn main() -> Result<()> {
let args = Args::parse();
let log_config = {
let mut config = simplelog::ConfigBuilder::new();
if !args.warn_on_missing {
config.add_filter_ignore_str("theme_printer");
}
config.build()
};
TermLogger::init(
LevelFilter::Trace,
log_config,
TerminalMode::Stderr,
ColorChoice::Auto,
)
.expect("could not initialize logger");
let theme_file_path = args.theme_path;
let mut buffer = Vec::new();
match File::open(&theme_file_path).and_then(|mut file| file.read_to_end(&mut buffer)) {
Ok(_) => {}
Err(err) => {
log::info!("Failed to open file at path: {:?}", theme_file_path);
return Err(err)?;
}
};
let vscode_theme: VsCodeTheme = serde_json_lenient::from_slice(&buffer)
.context(format!("failed to parse theme {theme_file_path:?}"))?;
let theme_metadata = ThemeMetadata {
name: vscode_theme.name.clone().unwrap_or("".to_string()),
appearance: ThemeAppearanceJson::Dark,
file_name: "".to_string(),
};
let converter = VsCodeThemeConverter::new(vscode_theme, theme_metadata, IndexMap::default());
let theme = converter.convert()?;
let mut theme = serde_json::to_value(theme).unwrap();
theme.as_object_mut().unwrap().insert(
"$schema".to_string(),
serde_json::Value::String(ZED_THEME_SCHEMA_URL.to_string()),
);
let theme_json = serde_json::to_string_pretty(&theme).unwrap();
if let Some(output) = args.output {
let mut file = File::create(output)?;
file.write_all(theme_json.as_bytes())?;
} else {
println!("{}", theme_json);
}
log::info!("Done!");
Ok(())
}

View File

@@ -0,0 +1,7 @@
mod converter;
mod syntax;
mod theme;
pub use converter::*;
pub use syntax::*;
pub use theme::*;

View File

@@ -0,0 +1,277 @@
use anyhow::Result;
use collections::IndexMap;
use strum::IntoEnumIterator;
use theme_settings::{
FontStyleContent, FontWeightContent, HighlightStyleContent, StatusColorsContent,
ThemeColorsContent, ThemeContent, ThemeStyleContent, WindowBackgroundContent,
};
use crate::ThemeMetadata;
use crate::vscode::{VsCodeTheme, VsCodeTokenScope};
use super::ZedSyntaxToken;
pub(crate) fn try_parse_font_weight(font_style: &str) -> Option<FontWeightContent> {
match font_style {
style if style.contains("bold") => Some(FontWeightContent::BOLD),
_ => None,
}
}
pub(crate) fn try_parse_font_style(font_style: &str) -> Option<FontStyleContent> {
match font_style {
style if style.contains("italic") => Some(FontStyleContent::Italic),
style if style.contains("oblique") => Some(FontStyleContent::Oblique),
_ => None,
}
}
pub struct VsCodeThemeConverter {
theme: VsCodeTheme,
theme_metadata: ThemeMetadata,
syntax_overrides: IndexMap<String, Vec<String>>,
}
impl VsCodeThemeConverter {
pub fn new(
theme: VsCodeTheme,
theme_metadata: ThemeMetadata,
syntax_overrides: IndexMap<String, Vec<String>>,
) -> Self {
Self {
theme,
theme_metadata,
syntax_overrides,
}
}
pub fn convert(self) -> Result<ThemeContent> {
let appearance = self.theme_metadata.appearance.into();
let status_colors = self.convert_status_colors()?;
let theme_colors = self.convert_theme_colors()?;
let syntax_theme = self.convert_syntax_theme()?;
Ok(ThemeContent {
name: self.theme_metadata.name,
appearance,
style: ThemeStyleContent {
window_background_appearance: Some(WindowBackgroundContent::Opaque),
accents: Vec::new(), //TODO can we read this from the theme?
colors: theme_colors,
status: status_colors,
players: Vec::new(),
syntax: syntax_theme,
},
})
}
fn convert_status_colors(&self) -> Result<StatusColorsContent> {
let vscode_colors = &self.theme.colors;
let vscode_base_status_colors = StatusColorsContent {
hint: Some("#969696ff".to_string()),
..Default::default()
};
Ok(StatusColorsContent {
conflict: vscode_colors
.git_decoration
.conflicting_resource_foreground
.clone(),
created: vscode_colors.editor_gutter.added_background.clone(),
deleted: vscode_colors.editor_gutter.deleted_background.clone(),
error: vscode_colors.editor_error.foreground.clone(),
error_background: vscode_colors.editor_error.background.clone(),
error_border: vscode_colors.editor_error.border.clone(),
hidden: vscode_colors.tab.inactive_foreground.clone(),
hint: vscode_colors
.editor_inlay_hint
.foreground
.clone()
.or(vscode_base_status_colors.hint),
hint_border: vscode_colors.editor_hint.border.clone(),
ignored: vscode_colors
.git_decoration
.ignored_resource_foreground
.clone(),
info: vscode_colors.editor_info.foreground.clone(),
info_background: vscode_colors.editor_info.background.clone(),
info_border: vscode_colors.editor_info.border.clone(),
modified: vscode_colors.editor_gutter.modified_background.clone(),
// renamed: None,
// success: None,
warning: vscode_colors.editor_warning.foreground.clone(),
warning_background: vscode_colors.editor_warning.background.clone(),
warning_border: vscode_colors.editor_warning.border.clone(),
..Default::default()
})
}
fn convert_theme_colors(&self) -> Result<ThemeColorsContent> {
let vscode_colors = &self.theme.colors;
let vscode_panel_border = vscode_colors.panel.border.clone();
let vscode_tab_inactive_background = vscode_colors.tab.inactive_background.clone();
let vscode_editor_foreground = vscode_colors.editor.foreground.clone();
let vscode_editor_background = vscode_colors.editor.background.clone();
let vscode_scrollbar_slider_background = vscode_colors.scrollbar_slider.background.clone();
let vscode_token_colors_foreground = self
.theme
.token_colors
.iter()
.find(|token_color| token_color.scope.is_none())
.and_then(|token_color| token_color.settings.foreground.as_ref())
.cloned();
Ok(ThemeColorsContent {
border: vscode_panel_border.clone(),
border_variant: vscode_panel_border.clone(),
border_focused: vscode_colors.focus_border.clone(),
border_selected: vscode_panel_border.clone(),
border_transparent: vscode_panel_border.clone(),
border_disabled: vscode_panel_border.clone(),
elevated_surface_background: vscode_colors.dropdown.background.clone(),
surface_background: vscode_colors.panel.background.clone(),
background: vscode_editor_background.clone(),
element_background: vscode_colors.button.background.clone(),
element_hover: vscode_colors.list.hover_background.clone(),
element_selected: vscode_colors.list.active_selection_background.clone(),
drop_target_background: vscode_colors.list.drop_background.clone(),
ghost_element_hover: vscode_colors.list.hover_background.clone(),
ghost_element_selected: vscode_colors.list.active_selection_background.clone(),
text: vscode_colors
.foreground
.clone()
.or(vscode_token_colors_foreground.clone()),
text_muted: vscode_colors.tab.inactive_foreground.clone(),
status_bar_background: vscode_colors.status_bar.background.clone(),
title_bar_background: vscode_colors.title_bar.active_background.clone(),
toolbar_background: vscode_colors
.breadcrumb
.background
.clone()
.or(vscode_editor_background.clone()),
tab_bar_background: vscode_colors.editor_group_header.tabs_background.clone(),
tab_inactive_background: vscode_tab_inactive_background.clone(),
tab_active_background: vscode_colors
.tab
.active_background
.clone()
.or(vscode_tab_inactive_background),
search_match_background: vscode_colors.editor.find_match_background.clone(),
panel_background: vscode_colors.panel.background.clone(),
pane_group_border: vscode_colors.editor_group.border.clone(),
scrollbar_thumb_background: vscode_scrollbar_slider_background.clone(),
scrollbar_thumb_hover_background: vscode_colors
.scrollbar_slider
.hover_background
.clone(),
scrollbar_thumb_active_background: vscode_colors
.scrollbar_slider
.active_background
.clone(),
scrollbar_thumb_border: vscode_scrollbar_slider_background,
scrollbar_track_background: vscode_editor_background.clone(),
scrollbar_track_border: vscode_colors.editor_overview_ruler.border.clone(),
minimap_thumb_background: vscode_colors.minimap_slider.background.clone(),
minimap_thumb_hover_background: vscode_colors.minimap_slider.hover_background.clone(),
minimap_thumb_active_background: vscode_colors.minimap_slider.active_background.clone(),
editor_foreground: vscode_editor_foreground.or(vscode_token_colors_foreground),
editor_background: vscode_editor_background.clone(),
editor_gutter_background: vscode_editor_background,
editor_active_line_background: vscode_colors.editor.line_highlight_background.clone(),
editor_line_number: vscode_colors.editor_line_number.foreground.clone(),
editor_active_line_number: vscode_colors.editor.foreground.clone(),
editor_wrap_guide: vscode_panel_border.clone(),
editor_active_wrap_guide: vscode_panel_border,
editor_document_highlight_bracket_background: vscode_colors
.editor_bracket_match
.background
.clone(),
terminal_background: vscode_colors.terminal.background.clone(),
terminal_ansi_black: vscode_colors.terminal.ansi_black.clone(),
terminal_ansi_bright_black: vscode_colors.terminal.ansi_bright_black.clone(),
terminal_ansi_red: vscode_colors.terminal.ansi_red.clone(),
terminal_ansi_bright_red: vscode_colors.terminal.ansi_bright_red.clone(),
terminal_ansi_green: vscode_colors.terminal.ansi_green.clone(),
terminal_ansi_bright_green: vscode_colors.terminal.ansi_bright_green.clone(),
terminal_ansi_yellow: vscode_colors.terminal.ansi_yellow.clone(),
terminal_ansi_bright_yellow: vscode_colors.terminal.ansi_bright_yellow.clone(),
terminal_ansi_blue: vscode_colors.terminal.ansi_blue.clone(),
terminal_ansi_bright_blue: vscode_colors.terminal.ansi_bright_blue.clone(),
terminal_ansi_magenta: vscode_colors.terminal.ansi_magenta.clone(),
terminal_ansi_bright_magenta: vscode_colors.terminal.ansi_bright_magenta.clone(),
terminal_ansi_cyan: vscode_colors.terminal.ansi_cyan.clone(),
terminal_ansi_bright_cyan: vscode_colors.terminal.ansi_bright_cyan.clone(),
terminal_ansi_white: vscode_colors.terminal.ansi_white.clone(),
terminal_ansi_bright_white: vscode_colors.terminal.ansi_bright_white.clone(),
link_text_hover: vscode_colors.text_link.active_foreground.clone(),
vim_yank_background: vscode_colors.editor.range_highlight_background.clone(),
..Default::default()
})
}
fn convert_syntax_theme(&self) -> Result<IndexMap<String, HighlightStyleContent>> {
let mut highlight_styles = IndexMap::default();
for syntax_token in ZedSyntaxToken::iter() {
let override_match = self
.syntax_overrides
.get(&syntax_token.to_string())
.and_then(|scope| {
self.theme.token_colors.iter().find(|token_color| {
token_color.scope == Some(VsCodeTokenScope::Many(scope.clone()))
})
});
let best_match = override_match
.or_else(|| syntax_token.find_best_token_color_match(&self.theme.token_colors))
.or_else(|| {
syntax_token.fallbacks().iter().find_map(|fallback| {
fallback.find_best_token_color_match(&self.theme.token_colors)
})
});
let Some(token_color) = best_match else {
log::warn!("No matching token color found for '{syntax_token}'");
continue;
};
log::info!(
"Matched '{syntax_token}' to '{}'",
token_color
.name
.clone()
.or_else(|| token_color
.scope
.as_ref()
.map(|scope| format!("{:?}", scope)))
.unwrap_or_else(|| "no identifier".to_string())
);
let highlight_style = HighlightStyleContent {
color: token_color.settings.foreground.clone(),
background_color: token_color.settings.background.clone(),
font_style: token_color
.settings
.font_style
.as_ref()
.and_then(|style| try_parse_font_style(style)),
font_weight: token_color
.settings
.font_style
.as_ref()
.and_then(|style| try_parse_font_weight(style)),
};
if highlight_style.is_empty() {
continue;
}
highlight_styles.insert(syntax_token.to_string(), highlight_style);
}
Ok(highlight_styles)
}
}

View File

@@ -0,0 +1,310 @@
use indexmap::IndexMap;
use serde::Deserialize;
use strum::EnumIter;
#[derive(Debug, PartialEq, Eq, Deserialize)]
#[serde(untagged)]
pub enum VsCodeTokenScope {
One(String),
Many(Vec<String>),
}
#[derive(Debug, Deserialize)]
pub struct VsCodeTokenColor {
pub name: Option<String>,
pub scope: Option<VsCodeTokenScope>,
pub settings: VsCodeTokenColorSettings,
}
#[derive(Debug, Deserialize)]
pub struct VsCodeTokenColorSettings {
pub foreground: Option<String>,
pub background: Option<String>,
#[serde(rename = "fontStyle")]
pub font_style: Option<String>,
}
#[derive(Debug, PartialEq, Copy, Clone, EnumIter)]
pub enum ZedSyntaxToken {
Attribute,
Boolean,
Comment,
CommentDoc,
Constant,
Constructor,
Embedded,
Emphasis,
EmphasisStrong,
Enum,
Function,
Hint,
Keyword,
Label,
LinkText,
LinkUri,
Number,
Operator,
Predictive,
Preproc,
Primary,
Property,
Punctuation,
PunctuationBracket,
PunctuationDelimiter,
PunctuationListMarker,
PunctuationSpecial,
String,
StringEscape,
StringRegex,
StringSpecial,
StringSpecialSymbol,
Tag,
TextLiteral,
Title,
Type,
Variable,
VariableSpecial,
Variant,
}
impl std::fmt::Display for ZedSyntaxToken {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
"{}",
match self {
ZedSyntaxToken::Attribute => "attribute",
ZedSyntaxToken::Boolean => "boolean",
ZedSyntaxToken::Comment => "comment",
ZedSyntaxToken::CommentDoc => "comment.doc",
ZedSyntaxToken::Constant => "constant",
ZedSyntaxToken::Constructor => "constructor",
ZedSyntaxToken::Embedded => "embedded",
ZedSyntaxToken::Emphasis => "emphasis",
ZedSyntaxToken::EmphasisStrong => "emphasis.strong",
ZedSyntaxToken::Enum => "enum",
ZedSyntaxToken::Function => "function",
ZedSyntaxToken::Hint => "hint",
ZedSyntaxToken::Keyword => "keyword",
ZedSyntaxToken::Label => "label",
ZedSyntaxToken::LinkText => "link_text",
ZedSyntaxToken::LinkUri => "link_uri",
ZedSyntaxToken::Number => "number",
ZedSyntaxToken::Operator => "operator",
ZedSyntaxToken::Predictive => "predictive",
ZedSyntaxToken::Preproc => "preproc",
ZedSyntaxToken::Primary => "primary",
ZedSyntaxToken::Property => "property",
ZedSyntaxToken::Punctuation => "punctuation",
ZedSyntaxToken::PunctuationBracket => "punctuation.bracket",
ZedSyntaxToken::PunctuationDelimiter => "punctuation.delimiter",
ZedSyntaxToken::PunctuationListMarker => "punctuation.list_marker",
ZedSyntaxToken::PunctuationSpecial => "punctuation.special",
ZedSyntaxToken::String => "string",
ZedSyntaxToken::StringEscape => "string.escape",
ZedSyntaxToken::StringRegex => "string.regex",
ZedSyntaxToken::StringSpecial => "string.special",
ZedSyntaxToken::StringSpecialSymbol => "string.special.symbol",
ZedSyntaxToken::Tag => "tag",
ZedSyntaxToken::TextLiteral => "text.literal",
ZedSyntaxToken::Title => "title",
ZedSyntaxToken::Type => "type",
ZedSyntaxToken::Variable => "variable",
ZedSyntaxToken::VariableSpecial => "variable.special",
ZedSyntaxToken::Variant => "variant",
}
)
}
}
impl ZedSyntaxToken {
pub fn find_best_token_color_match<'a>(
&self,
token_colors: &'a [VsCodeTokenColor],
) -> Option<&'a VsCodeTokenColor> {
let mut ranked_matches = IndexMap::new();
for (ix, token_color) in token_colors.iter().enumerate() {
if token_color.settings.foreground.is_none() {
continue;
}
let Some(rank) = self.rank_match(token_color) else {
continue;
};
if rank > 0 {
ranked_matches.insert(ix, rank);
}
}
ranked_matches
.into_iter()
.max_by_key(|(_, rank)| *rank)
.map(|(ix, _)| &token_colors[ix])
}
fn rank_match(&self, token_color: &VsCodeTokenColor) -> Option<u32> {
let candidate_scopes = match token_color.scope.as_ref()? {
VsCodeTokenScope::One(scope) => vec![scope],
VsCodeTokenScope::Many(scopes) => scopes.iter().collect(),
}
.iter()
.flat_map(|scope| scope.split(',').map(|s| s.trim()))
.collect::<Vec<_>>();
let scopes_to_match = self.to_vscode();
let number_of_scopes_to_match = scopes_to_match.len();
let mut matches = 0;
for (ix, scope) in scopes_to_match.into_iter().enumerate() {
// Assign each entry a weight that is inversely proportional to its
// position in the list.
//
// Entries towards the front are weighted higher than those towards the end.
let weight = (number_of_scopes_to_match - ix) as u32;
if candidate_scopes.contains(&scope) {
matches += 1 + weight;
}
}
Some(matches)
}
pub fn fallbacks(&self) -> &[Self] {
match self {
ZedSyntaxToken::CommentDoc => &[ZedSyntaxToken::Comment],
ZedSyntaxToken::Number => &[ZedSyntaxToken::Constant],
ZedSyntaxToken::VariableSpecial => &[ZedSyntaxToken::Variable],
ZedSyntaxToken::PunctuationBracket
| ZedSyntaxToken::PunctuationDelimiter
| ZedSyntaxToken::PunctuationListMarker
| ZedSyntaxToken::PunctuationSpecial => &[ZedSyntaxToken::Punctuation],
ZedSyntaxToken::StringEscape
| ZedSyntaxToken::StringRegex
| ZedSyntaxToken::StringSpecial
| ZedSyntaxToken::StringSpecialSymbol => &[ZedSyntaxToken::String],
_ => &[],
}
}
fn to_vscode(self) -> Vec<&'static str> {
match self {
ZedSyntaxToken::Attribute => vec!["entity.other.attribute-name"],
ZedSyntaxToken::Boolean => vec!["constant.language"],
ZedSyntaxToken::Comment => vec!["comment"],
ZedSyntaxToken::CommentDoc => vec!["comment.block.documentation"],
ZedSyntaxToken::Constant => vec!["constant", "constant.language", "constant.character"],
ZedSyntaxToken::Constructor => {
vec![
"entity.name.tag",
"entity.name.function.definition.special.constructor",
]
}
ZedSyntaxToken::Embedded => vec!["meta.embedded"],
ZedSyntaxToken::Emphasis => vec!["markup.italic"],
ZedSyntaxToken::EmphasisStrong => vec![
"markup.bold",
"markup.italic markup.bold",
"markup.bold markup.italic",
],
ZedSyntaxToken::Enum => vec!["support.type.enum"],
ZedSyntaxToken::Function => vec![
"entity.function",
"entity.name.function",
"variable.function",
],
ZedSyntaxToken::Hint => vec![],
ZedSyntaxToken::Keyword => vec![
"keyword",
"keyword.other.fn.rust",
"keyword.control",
"keyword.control.fun",
"keyword.control.class",
"punctuation.accessor",
"entity.name.tag",
],
ZedSyntaxToken::Label => vec![
"label",
"entity.name",
"entity.name.import",
"entity.name.package",
],
ZedSyntaxToken::LinkText => vec!["markup.underline.link", "string.other.link"],
ZedSyntaxToken::LinkUri => vec!["markup.underline.link", "string.other.link"],
ZedSyntaxToken::Number => vec!["constant.numeric", "number"],
ZedSyntaxToken::Operator => vec!["operator", "keyword.operator"],
ZedSyntaxToken::Predictive => vec![],
ZedSyntaxToken::Preproc => vec![
"preproc",
"meta.preprocessor",
"punctuation.definition.preprocessor",
],
ZedSyntaxToken::Primary => vec![],
ZedSyntaxToken::Property => vec![
"variable.member",
"support.type.property-name",
"variable.object.property",
"variable.other.field",
],
ZedSyntaxToken::Punctuation => vec![
"punctuation",
"punctuation.section",
"punctuation.accessor",
"punctuation.separator",
"punctuation.definition.tag",
],
ZedSyntaxToken::PunctuationBracket => vec![
"punctuation.bracket",
"punctuation.definition.tag.begin",
"punctuation.definition.tag.end",
],
ZedSyntaxToken::PunctuationDelimiter => vec![
"punctuation.delimiter",
"punctuation.separator",
"punctuation.terminator",
],
ZedSyntaxToken::PunctuationListMarker => {
vec!["markup.list punctuation.definition.list.begin"]
}
ZedSyntaxToken::PunctuationSpecial => vec!["punctuation.special"],
ZedSyntaxToken::String => vec!["string"],
ZedSyntaxToken::StringEscape => {
vec!["string.escape", "constant.character", "constant.other"]
}
ZedSyntaxToken::StringRegex => vec!["string.regex"],
ZedSyntaxToken::StringSpecial => vec!["string.special", "constant.other.symbol"],
ZedSyntaxToken::StringSpecialSymbol => {
vec!["string.special.symbol", "constant.other.symbol"]
}
ZedSyntaxToken::Tag => vec!["tag", "entity.name.tag", "meta.tag.sgml"],
ZedSyntaxToken::TextLiteral => vec!["text.literal", "string"],
ZedSyntaxToken::Title => vec!["title", "entity.name"],
ZedSyntaxToken::Type => vec![
"entity.name.type",
"entity.name.type.primitive",
"entity.name.type.numeric",
"keyword.type",
"support.type",
"support.type.primitive",
"support.class",
],
ZedSyntaxToken::Variable => vec![
"variable",
"variable.language",
"variable.member",
"variable.parameter",
"variable.parameter.function-call",
],
ZedSyntaxToken::VariableSpecial => vec![
"variable.special",
"variable.member",
"variable.annotation",
"variable.language",
],
ZedSyntaxToken::Variant => vec!["variant"],
}
}
}

View File

@@ -0,0 +1,40 @@
use serde::Deserialize;
use vscode_theme::Colors;
use crate::vscode::VsCodeTokenColor;
#[derive(Deserialize, Debug)]
pub struct VsCodeTheme {
#[serde(rename = "$schema")]
#[expect(
unused,
reason = "This field was found to be unused with serde library bump; it's left as is due to insufficient context on PO's side, but it *may* be fine to remove"
)]
pub schema: Option<String>,
pub name: Option<String>,
#[expect(
unused,
reason = "This field was found to be unused with serde library bump; it's left as is due to insufficient context on PO's side, but it *may* be fine to remove"
)]
pub author: Option<String>,
#[expect(
unused,
reason = "This field was found to be unused with serde library bump; it's left as is due to insufficient context on PO's side, but it *may* be fine to remove"
)]
pub maintainers: Option<Vec<String>>,
#[serde(rename = "semanticClass")]
#[expect(
unused,
reason = "This field was found to be unused with serde library bump; it's left as is due to insufficient context on PO's side, but it *may* be fine to remove"
)]
pub semantic_class: Option<String>,
#[expect(
unused,
reason = "This field was found to be unused with serde library bump; it's left as is due to insufficient context on PO's side, but it *may* be fine to remove"
)]
#[serde(rename = "semanticHighlighting")]
pub semantic_highlighting: Option<bool>,
pub colors: Colors,
#[serde(rename = "tokenColors")]
pub token_colors: Vec<VsCodeTokenColor>,
}