Skip to repository content1470 lines · 51.9 KB · rust
tenant.openagents/omega
No repository description is available.
OpenAgents Git authority 2026-07-28T03:34:13.938Z Public web read
NIP-34 coordinate
30617:7649603503856e5148d571eac2766b288a8ff1e9e35d380337a1d2b0015b4f92:omegaMaintainersHidden in public view
References2 branches · 1 tag
Read-only clone
git clone https://openagents.com/git/tenant.openagents/omega.gitBrowse files
theme.rs
1use collections::{HashMap, IndexMap};
2use schemars::JsonSchema;
3use serde::{Deserialize, Deserializer, Serialize};
4use serde_json::Value;
5use settings_macros::{MergeFrom, with_fallible_options};
6use std::{borrow::Cow, fmt::Display, sync::Arc};
7
8use crate::serialize_f32_with_two_decimal_places;
9
10/// OpenType font features as a map of feature tag to value.
11/// This is a content type that mirrors `gpui::FontFeatures` but without the Arc wrapper.
12/// Values can be specified as booleans (true=1, false=0) or integers.
13#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, MergeFrom)]
14#[serde(transparent)]
15pub struct FontFeaturesContent(pub IndexMap<String, u32>);
16
17impl FontFeaturesContent {
18 pub fn new() -> Self {
19 Self(IndexMap::default())
20 }
21}
22
23#[derive(Debug, serde::Deserialize)]
24#[serde(untagged)]
25enum FeatureValue {
26 Bool(bool),
27 Number(serde_json::Number),
28}
29
30fn is_valid_feature_tag(tag: &str) -> bool {
31 tag.len() == 4 && tag.chars().all(|c| c.is_ascii_alphanumeric())
32}
33
34impl<'de> Deserialize<'de> for FontFeaturesContent {
35 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
36 where
37 D: Deserializer<'de>,
38 {
39 use serde::de::{MapAccess, Visitor};
40 use std::fmt;
41
42 struct FontFeaturesVisitor;
43
44 impl<'de> Visitor<'de> for FontFeaturesVisitor {
45 type Value = FontFeaturesContent;
46
47 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
48 formatter.write_str("a map of font features")
49 }
50
51 fn visit_map<M>(self, mut access: M) -> Result<Self::Value, M::Error>
52 where
53 M: MapAccess<'de>,
54 {
55 let mut feature_map = IndexMap::default();
56
57 while let Some((key, value)) =
58 access.next_entry::<String, Option<FeatureValue>>()?
59 {
60 if !is_valid_feature_tag(&key) {
61 log::error!("Incorrect font feature tag: {}", key);
62 continue;
63 }
64 if let Some(value) = value {
65 match value {
66 FeatureValue::Bool(enable) => {
67 feature_map.insert(key, if enable { 1 } else { 0 });
68 }
69 FeatureValue::Number(value) => {
70 if value.is_u64() {
71 feature_map.insert(key, value.as_u64().unwrap() as u32);
72 } else {
73 log::error!(
74 "Incorrect font feature value {} for feature tag {}",
75 value,
76 key
77 );
78 continue;
79 }
80 }
81 }
82 }
83 }
84
85 Ok(FontFeaturesContent(feature_map))
86 }
87 }
88
89 deserializer.deserialize_map(FontFeaturesVisitor)
90 }
91}
92
93impl JsonSchema for FontFeaturesContent {
94 fn schema_name() -> Cow<'static, str> {
95 "FontFeaturesContent".into()
96 }
97
98 fn json_schema(_: &mut schemars::SchemaGenerator) -> schemars::Schema {
99 use schemars::json_schema;
100 json_schema!({
101 "type": "object",
102 "patternProperties": {
103 "[0-9a-zA-Z]{4}$": {
104 "type": ["boolean", "integer"],
105 "minimum": 0,
106 "multipleOf": 1
107 }
108 },
109 "additionalProperties": false
110 })
111 }
112}
113
114/// Settings for rendering text in UI and text buffers.
115
116#[with_fallible_options]
117#[derive(Clone, PartialEq, Debug, Default, Serialize, Deserialize, JsonSchema, MergeFrom)]
118pub struct ThemeSettingsContent {
119 /// The default font size for text in the UI.
120 pub ui_font_size: Option<FontSize>,
121 /// The name of a font to use for rendering in the UI.
122 pub ui_font_family: Option<FontFamilyName>,
123 /// The font fallbacks to use for rendering in the UI.
124 #[schemars(default = "default_font_fallbacks")]
125 #[schemars(extend("uniqueItems" = true))]
126 pub ui_font_fallbacks: Option<Vec<FontFamilyName>>,
127 /// The OpenType features to enable for text in the UI.
128 #[schemars(default = "default_font_features")]
129 pub ui_font_features: Option<FontFeaturesContent>,
130 /// The weight of the UI font in CSS units from 100 to 900.
131 #[schemars(default = "default_buffer_font_weight")]
132 pub ui_font_weight: Option<FontWeightContent>,
133 /// The name of a font to use for rendering in text buffers.
134 pub buffer_font_family: Option<FontFamilyName>,
135 /// The font fallbacks to use for rendering in text buffers.
136 #[schemars(extend("uniqueItems" = true))]
137 pub buffer_font_fallbacks: Option<Vec<FontFamilyName>>,
138 /// The default font size for rendering in text buffers.
139 pub buffer_font_size: Option<FontSize>,
140 /// The weight of the editor font in CSS units from 100 to 900.
141 #[schemars(default = "default_buffer_font_weight")]
142 pub buffer_font_weight: Option<FontWeightContent>,
143 /// The buffer's line height.
144 pub buffer_line_height: Option<BufferLineHeight>,
145 /// The OpenType features to enable for rendering in text buffers.
146 #[schemars(default = "default_font_features")]
147 pub buffer_font_features: Option<FontFeaturesContent>,
148 /// The font size for agent responses in the agent panel. Falls back to the UI font size if unset.
149 pub agent_ui_font_size: Option<FontSize>,
150 /// The font size for user messages in the agent panel.
151 pub agent_buffer_font_size: Option<FontSize>,
152 pub git_commit_buffer_font_size: Option<FontSize>,
153 /// The name of a font to use for rendering in the markdown preview.
154 /// Falls back to the UI font if unset.
155 pub markdown_preview_font_family: Option<FontFamilyName>,
156 /// The name of a font to use for code (code blocks and inline code) in the
157 /// markdown preview. Falls back to the buffer font if unset.
158 pub markdown_preview_code_font_family: Option<FontFamilyName>,
159 /// The font size to use for rendering in the markdown preview.
160 /// Falls back to the UI font size if unset.
161 pub markdown_preview_font_size: Option<FontSize>,
162 /// The theme to use for the markdown preview.
163 /// Falls back to the main editor theme if unset.
164 pub markdown_preview_theme: Option<ThemeSelection>,
165 /// The name of the Omega theme to use.
166 pub theme: Option<ThemeSelection>,
167 /// The name of the icon theme to use.
168 pub icon_theme: Option<IconThemeSelection>,
169
170 /// UNSTABLE: Expect many elements to be broken.
171 ///
172 // Controls the density of the UI.
173 #[serde(rename = "unstable.ui_density")]
174 pub ui_density: Option<UiDensity>,
175
176 /// How much to fade out unused code.
177 #[schemars(range(min = 0.0, max = 0.9))]
178 pub unnecessary_code_fade: Option<CodeFade>,
179
180 /// EXPERIMENTAL: Overrides for the current theme.
181 ///
182 /// These values will override the ones on the current theme specified in `theme`.
183 #[serde(rename = "experimental.theme_overrides")]
184 pub experimental_theme_overrides: Option<ThemeStyleContent>,
185
186 /// Overrides per theme
187 ///
188 /// These values will override the ones on the specified theme
189 #[serde(default)]
190 pub theme_overrides: HashMap<String, ThemeStyleContent>,
191}
192
193/// A font size value in pixels, wrapping around `f32` for custom settings UI rendering.
194#[derive(
195 Clone,
196 Copy,
197 Debug,
198 Serialize,
199 Deserialize,
200 JsonSchema,
201 MergeFrom,
202 PartialEq,
203 PartialOrd,
204 derive_more::FromStr,
205)]
206#[serde(transparent)]
207pub struct FontSize(#[serde(serialize_with = "serialize_f32_with_two_decimal_places")] pub f32);
208
209impl Display for FontSize {
210 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
211 write!(f, "{:.2}", self.0)
212 }
213}
214
215impl From<f32> for FontSize {
216 fn from(value: f32) -> Self {
217 Self(value)
218 }
219}
220
221#[derive(
222 Clone,
223 Copy,
224 Debug,
225 Serialize,
226 Deserialize,
227 JsonSchema,
228 MergeFrom,
229 PartialEq,
230 PartialOrd,
231 derive_more::FromStr,
232)]
233#[serde(transparent)]
234pub struct CodeFade(#[serde(serialize_with = "serialize_f32_with_two_decimal_places")] pub f32);
235
236impl Display for CodeFade {
237 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
238 write!(f, "{:.2}", self.0)
239 }
240}
241
242impl From<f32> for CodeFade {
243 fn from(x: f32) -> Self {
244 Self(x)
245 }
246}
247
248fn default_font_features() -> Option<FontFeaturesContent> {
249 Some(FontFeaturesContent::default())
250}
251
252fn default_font_fallbacks() -> Option<Vec<FontFamilyName>> {
253 Some(Vec::new())
254}
255
256fn default_buffer_font_weight() -> Option<FontWeightContent> {
257 Some(FontWeightContent::NORMAL)
258}
259
260/// Represents the selection of a theme, which can be either static or dynamic.
261#[derive(
262 Clone,
263 Debug,
264 Serialize,
265 Deserialize,
266 JsonSchema,
267 MergeFrom,
268 PartialEq,
269 Eq,
270 strum::EnumDiscriminants,
271)]
272#[strum_discriminants(derive(strum::VariantArray, strum::VariantNames, strum::FromRepr))]
273#[serde(untagged)]
274pub enum ThemeSelection {
275 /// A static theme selection, represented by a single theme name.
276 Static(ThemeName),
277 /// A dynamic theme selection, which can change based the [ThemeMode].
278 Dynamic {
279 /// The mode used to determine which theme to use.
280 #[serde(default)]
281 mode: ThemeAppearanceMode,
282 /// The theme to use for light mode.
283 light: ThemeName,
284 /// The theme to use for dark mode.
285 dark: ThemeName,
286 },
287}
288
289// Aiur is dark-only (omega#70), so the light default comes from Ayu.
290pub const DEFAULT_LIGHT_THEME: &'static str = "Ayu Light";
291pub const DEFAULT_DARK_THEME: &'static str = "Aiur";
292
293impl Default for ThemeSelection {
294 fn default() -> Self {
295 Self::Dynamic {
296 mode: ThemeAppearanceMode::default(),
297 light: ThemeName(DEFAULT_LIGHT_THEME.into()),
298 dark: ThemeName(DEFAULT_DARK_THEME.into()),
299 }
300 }
301}
302
303/// Represents the selection of an icon theme, which can be either static or dynamic.
304#[derive(
305 Clone,
306 Debug,
307 Serialize,
308 Deserialize,
309 JsonSchema,
310 MergeFrom,
311 PartialEq,
312 Eq,
313 strum::EnumDiscriminants,
314)]
315#[strum_discriminants(derive(strum::VariantArray, strum::VariantNames, strum::FromRepr))]
316#[serde(untagged)]
317pub enum IconThemeSelection {
318 /// A static icon theme selection, represented by a single icon theme name.
319 Static(IconThemeName),
320 /// A dynamic icon theme selection, which can change based on the [`ThemeMode`].
321 Dynamic {
322 /// The mode used to determine which theme to use.
323 #[serde(default)]
324 mode: ThemeAppearanceMode,
325 /// The icon theme to use for light mode.
326 light: IconThemeName,
327 /// The icon theme to use for dark mode.
328 dark: IconThemeName,
329 },
330}
331
332/// The mode use to select a theme.
333///
334/// `Light` and `Dark` will select their respective themes.
335///
336/// `System` will select the theme based on the system's appearance.
337#[derive(
338 Debug,
339 PartialEq,
340 Eq,
341 Clone,
342 Copy,
343 Default,
344 Serialize,
345 Deserialize,
346 JsonSchema,
347 MergeFrom,
348 strum::VariantArray,
349 strum::VariantNames,
350)]
351#[serde(rename_all = "snake_case")]
352pub enum ThemeAppearanceMode {
353 /// Use the specified `light` theme.
354 Light,
355
356 /// Use the specified `dark` theme.
357 Dark,
358
359 /// Use the theme based on the system's appearance.
360 #[default]
361 System,
362}
363
364/// Specifies the density of the UI.
365/// Note: This setting is still experimental. See [this tracking issue](https://github.com/zed-industries/zed/issues/18078)
366#[derive(
367 Debug,
368 Default,
369 PartialEq,
370 Eq,
371 PartialOrd,
372 Ord,
373 Hash,
374 Clone,
375 Copy,
376 Serialize,
377 Deserialize,
378 JsonSchema,
379 MergeFrom,
380)]
381#[serde(rename_all = "snake_case")]
382pub enum UiDensity {
383 /// A denser UI with tighter spacing and smaller elements.
384 #[serde(alias = "compact")]
385 Compact,
386 #[default]
387 #[serde(alias = "default")]
388 /// The default UI density.
389 Default,
390 #[serde(alias = "comfortable")]
391 /// A looser UI with more spacing and larger elements.
392 Comfortable,
393}
394
395impl UiDensity {
396 /// The spacing ratio of a given density.
397 /// TODO: Standardize usage throughout the app or remove
398 pub fn spacing_ratio(self) -> f32 {
399 match self {
400 UiDensity::Compact => 0.75,
401 UiDensity::Default => 1.0,
402 UiDensity::Comfortable => 1.25,
403 }
404 }
405}
406
407/// Font family name.
408#[with_fallible_options]
409#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq, Eq)]
410#[serde(transparent)]
411pub struct FontFamilyName(pub Arc<str>);
412
413impl AsRef<str> for FontFamilyName {
414 fn as_ref(&self) -> &str {
415 &self.0
416 }
417}
418
419impl From<String> for FontFamilyName {
420 fn from(value: String) -> Self {
421 Self(Arc::from(value))
422 }
423}
424
425impl From<FontFamilyName> for String {
426 fn from(value: FontFamilyName) -> Self {
427 value.0.to_string()
428 }
429}
430
431/// The buffer's line height.
432#[derive(
433 Clone,
434 Copy,
435 Debug,
436 Serialize,
437 Deserialize,
438 PartialEq,
439 JsonSchema,
440 MergeFrom,
441 Default,
442 strum::EnumDiscriminants,
443)]
444#[strum_discriminants(derive(strum::VariantArray, strum::VariantNames, strum::FromRepr))]
445#[serde(rename_all = "snake_case")]
446pub enum BufferLineHeight {
447 /// A less dense line height.
448 #[default]
449 Comfortable,
450 /// The default line height.
451 Standard,
452 /// A custom line height, where 1.0 is the font's height. Must be at least 1.0.
453 Custom(#[serde(deserialize_with = "deserialize_line_height")] f32),
454}
455
456fn deserialize_line_height<'de, D>(deserializer: D) -> Result<f32, D::Error>
457where
458 D: serde::Deserializer<'de>,
459{
460 let value = f32::deserialize(deserializer)?;
461 if value < 1.0 {
462 return Err(serde::de::Error::custom(
463 "buffer_line_height.custom must be at least 1.0",
464 ));
465 }
466
467 Ok(value)
468}
469
470/// The content of a serialized theme.
471#[with_fallible_options]
472#[derive(Debug, Clone, Default, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq)]
473#[serde(default)]
474pub struct ThemeStyleContent {
475 #[serde(rename = "background.appearance")]
476 pub window_background_appearance: Option<WindowBackgroundContent>,
477
478 #[serde(default)]
479 pub accents: Vec<AccentContent>,
480
481 #[serde(flatten, default)]
482 pub colors: ThemeColorsContent,
483
484 #[serde(flatten, default)]
485 pub status: StatusColorsContent,
486
487 #[serde(default)]
488 pub players: Vec<PlayerColorContent>,
489
490 /// The styles for syntax nodes.
491 #[serde(default)]
492 pub syntax: IndexMap<String, HighlightStyleContent>,
493}
494
495#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq)]
496pub struct AccentContent(pub Option<String>);
497
498#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq)]
499pub struct PlayerColorContent {
500 pub cursor: Option<String>,
501 pub background: Option<String>,
502 pub selection: Option<String>,
503}
504
505/// Theme name.
506#[with_fallible_options]
507#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq, Eq)]
508#[serde(transparent)]
509pub struct ThemeName(pub Arc<str>);
510
511/// Icon Theme Name
512#[with_fallible_options]
513#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq, Eq)]
514#[serde(transparent)]
515pub struct IconThemeName(pub Arc<str>);
516
517#[with_fallible_options]
518#[derive(Debug, Clone, Default, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq)]
519#[serde(default)]
520pub struct ThemeColorsContent {
521 /// Border color. Used for most borders, is usually a high contrast color.
522 #[serde(rename = "border")]
523 pub border: Option<String>,
524
525 /// Border color. Used for deemphasized borders, like a visual divider between two sections
526 #[serde(rename = "border.variant")]
527 pub border_variant: Option<String>,
528
529 /// Border color. Used for focused elements, like keyboard focused list item.
530 #[serde(rename = "border.focused")]
531 pub border_focused: Option<String>,
532
533 /// Border color. Used for selected elements, like an active search filter or selected checkbox.
534 #[serde(rename = "border.selected")]
535 pub border_selected: Option<String>,
536
537 /// Border color. Used for transparent borders. Used for placeholder borders when an element gains a border on state change.
538 #[serde(rename = "border.transparent")]
539 pub border_transparent: Option<String>,
540
541 /// Border color. Used for disabled elements, like a disabled input or button.
542 #[serde(rename = "border.disabled")]
543 pub border_disabled: Option<String>,
544
545 /// Background color. Used for elevated surfaces, like a context menu, popup, or dialog.
546 #[serde(rename = "elevated_surface.background")]
547 pub elevated_surface_background: Option<String>,
548
549 /// Background Color. Used for grounded surfaces like a panel or tab.
550 #[serde(rename = "surface.background")]
551 pub surface_background: Option<String>,
552
553 /// Background Color. Used for the app background and blank panels or windows.
554 #[serde(rename = "background")]
555 pub background: Option<String>,
556
557 /// Background Color. Used for the background of an element that should have a different background than the surface it's on.
558 ///
559 /// Elements might include: Buttons, Inputs, Checkboxes, Radio Buttons...
560 ///
561 /// For an element that should have the same background as the surface it's on, use `ghost_element_background`.
562 #[serde(rename = "element.background")]
563 pub element_background: Option<String>,
564
565 /// Background Color. Used for the hover state of an element that should have a different background than the surface it's on.
566 ///
567 /// Hover states are triggered by the mouse entering an element, or a finger touching an element on a touch screen.
568 #[serde(rename = "element.hover")]
569 pub element_hover: Option<String>,
570
571 /// Background Color. Used for the active state of an element that should have a different background than the surface it's on.
572 ///
573 /// Active states are triggered by the mouse button being pressed down on an element, or the Return button or other activator being pressed.
574 #[serde(rename = "element.active")]
575 pub element_active: Option<String>,
576
577 /// Background Color. Used for the selected state of an element that should have a different background than the surface it's on.
578 ///
579 /// Selected states are triggered by the element being selected (or "activated") by the user.
580 ///
581 /// This could include a selected checkbox, a toggleable button that is toggled on, etc.
582 #[serde(rename = "element.selected")]
583 pub element_selected: Option<String>,
584
585 /// Background Color. Used for the disabled state of an element that should have a different background than the surface it's on.
586 ///
587 /// Disabled states are shown when a user cannot interact with an element, like a disabled button or input.
588 #[serde(rename = "element.disabled")]
589 pub element_disabled: Option<String>,
590
591 /// Background Color. Used for the background of selections in a UI element.
592 #[serde(rename = "element.selection_background")]
593 pub element_selection_background: Option<String>,
594
595 /// Background Color. Used for the area that shows where a dragged element will be dropped.
596 #[serde(rename = "drop_target.background")]
597 pub drop_target_background: Option<String>,
598
599 /// Border Color. Used for the border that shows where a dragged element will be dropped.
600 #[serde(rename = "drop_target.border")]
601 pub drop_target_border: Option<String>,
602
603 /// Used for the background of a ghost element that should have the same background as the surface it's on.
604 ///
605 /// Elements might include: Buttons, Inputs, Checkboxes, Radio Buttons...
606 ///
607 /// For an element that should have a different background than the surface it's on, use `element_background`.
608 #[serde(rename = "ghost_element.background")]
609 pub ghost_element_background: Option<String>,
610
611 /// Background Color. Used for the hover state of a ghost element that should have the same background as the surface it's on.
612 ///
613 /// Hover states are triggered by the mouse entering an element, or a finger touching an element on a touch screen.
614 #[serde(rename = "ghost_element.hover")]
615 pub ghost_element_hover: Option<String>,
616
617 /// Background Color. Used for the active state of a ghost element that should have the same background as the surface it's on.
618 ///
619 /// Active states are triggered by the mouse button being pressed down on an element, or the Return button or other activator being pressed.
620 #[serde(rename = "ghost_element.active")]
621 pub ghost_element_active: Option<String>,
622
623 /// Background Color. Used for the selected state of a ghost element that should have the same background as the surface it's on.
624 ///
625 /// Selected states are triggered by the element being selected (or "activated") by the user.
626 ///
627 /// This could include a selected checkbox, a toggleable button that is toggled on, etc.
628 #[serde(rename = "ghost_element.selected")]
629 pub ghost_element_selected: Option<String>,
630
631 /// Background Color. Used for the disabled state of a ghost element that should have the same background as the surface it's on.
632 ///
633 /// Disabled states are shown when a user cannot interact with an element, like a disabled button or input.
634 #[serde(rename = "ghost_element.disabled")]
635 pub ghost_element_disabled: Option<String>,
636
637 /// Text Color. Default text color used for most text.
638 #[serde(rename = "text")]
639 pub text: Option<String>,
640
641 /// Text Color. Color of muted or deemphasized text. It is a subdued version of the standard text color.
642 #[serde(rename = "text.muted")]
643 pub text_muted: Option<String>,
644
645 /// Text Color. Color of the placeholder text typically shown in input fields to guide the user to enter valid data.
646 #[serde(rename = "text.placeholder")]
647 pub text_placeholder: Option<String>,
648
649 /// Text Color. Color used for text denoting disabled elements. Typically, the color is faded or grayed out to emphasize the disabled state.
650 #[serde(rename = "text.disabled")]
651 pub text_disabled: Option<String>,
652
653 /// Text Color. Color used for emphasis or highlighting certain text, like an active filter or a matched character in a search.
654 #[serde(rename = "text.accent")]
655 pub text_accent: Option<String>,
656
657 /// Fill Color. Used for the default fill color of an icon.
658 #[serde(rename = "icon")]
659 pub icon: Option<String>,
660
661 /// Fill Color. Used for the muted or deemphasized fill color of an icon.
662 ///
663 /// This might be used to show an icon in an inactive pane, or to deemphasize a series of icons to give them less visual weight.
664 #[serde(rename = "icon.muted")]
665 pub icon_muted: Option<String>,
666
667 /// Fill Color. Used for the disabled fill color of an icon.
668 ///
669 /// Disabled states are shown when a user cannot interact with an element, like a icon button.
670 #[serde(rename = "icon.disabled")]
671 pub icon_disabled: Option<String>,
672
673 /// Fill Color. Used for the placeholder fill color of an icon.
674 ///
675 /// This might be used to show an icon in an input that disappears when the user enters text.
676 #[serde(rename = "icon.placeholder")]
677 pub icon_placeholder: Option<String>,
678
679 /// Fill Color. Used for the accent fill color of an icon.
680 ///
681 /// This might be used to show when a toggleable icon button is selected.
682 #[serde(rename = "icon.accent")]
683 pub icon_accent: Option<String>,
684
685 /// Color used to accent some of the debuggers elements
686 /// Only accent breakpoint & breakpoint related symbols right now
687 #[serde(rename = "debugger.accent")]
688 pub debugger_accent: Option<String>,
689
690 #[serde(rename = "status_bar.background")]
691 pub status_bar_background: Option<String>,
692
693 #[serde(rename = "title_bar.background")]
694 pub title_bar_background: Option<String>,
695
696 #[serde(rename = "title_bar.inactive_background")]
697 pub title_bar_inactive_background: Option<String>,
698
699 #[serde(rename = "toolbar.background")]
700 pub toolbar_background: Option<String>,
701
702 #[serde(rename = "tab_bar.background")]
703 pub tab_bar_background: Option<String>,
704
705 #[serde(rename = "tab.inactive_background")]
706 pub tab_inactive_background: Option<String>,
707
708 #[serde(rename = "tab.active_background")]
709 pub tab_active_background: Option<String>,
710
711 #[serde(rename = "search.match_background")]
712 pub search_match_background: Option<String>,
713
714 #[serde(rename = "search.active_match_background")]
715 pub search_active_match_background: Option<String>,
716
717 #[serde(rename = "panel.background")]
718 pub panel_background: Option<String>,
719
720 #[serde(rename = "panel.focused_border")]
721 pub panel_focused_border: Option<String>,
722
723 #[serde(rename = "panel.indent_guide")]
724 pub panel_indent_guide: Option<String>,
725
726 #[serde(rename = "panel.indent_guide_hover")]
727 pub panel_indent_guide_hover: Option<String>,
728
729 #[serde(rename = "panel.indent_guide_active")]
730 pub panel_indent_guide_active: Option<String>,
731
732 #[serde(rename = "panel.overlay_background")]
733 pub panel_overlay_background: Option<String>,
734
735 #[serde(rename = "panel.overlay_hover")]
736 pub panel_overlay_hover: Option<String>,
737
738 #[serde(rename = "pane.focused_border")]
739 pub pane_focused_border: Option<String>,
740
741 #[serde(rename = "pane_group.border")]
742 pub pane_group_border: Option<String>,
743
744 /// The deprecated version of `scrollbar.thumb.background`.
745 ///
746 /// Don't use this field.
747 #[serde(rename = "scrollbar_thumb.background", skip_serializing)]
748 #[schemars(skip)]
749 pub deprecated_scrollbar_thumb_background: Option<String>,
750
751 /// The color of the scrollbar thumb.
752 #[serde(rename = "scrollbar.thumb.background")]
753 pub scrollbar_thumb_background: Option<String>,
754
755 /// The color of the scrollbar thumb when hovered over.
756 #[serde(rename = "scrollbar.thumb.hover_background")]
757 pub scrollbar_thumb_hover_background: Option<String>,
758
759 /// The color of the scrollbar thumb whilst being actively dragged.
760 #[serde(rename = "scrollbar.thumb.active_background")]
761 pub scrollbar_thumb_active_background: Option<String>,
762
763 /// The border color of the scrollbar thumb.
764 #[serde(rename = "scrollbar.thumb.border")]
765 pub scrollbar_thumb_border: Option<String>,
766
767 /// The background color of the scrollbar track.
768 #[serde(rename = "scrollbar.track.background")]
769 pub scrollbar_track_background: Option<String>,
770
771 /// The border color of the scrollbar track.
772 #[serde(rename = "scrollbar.track.border")]
773 pub scrollbar_track_border: Option<String>,
774
775 /// The color of the minimap thumb.
776 #[serde(rename = "minimap.thumb.background")]
777 pub minimap_thumb_background: Option<String>,
778
779 /// The color of the minimap thumb when hovered over.
780 #[serde(rename = "minimap.thumb.hover_background")]
781 pub minimap_thumb_hover_background: Option<String>,
782
783 /// The color of the minimap thumb whilst being actively dragged.
784 #[serde(rename = "minimap.thumb.active_background")]
785 pub minimap_thumb_active_background: Option<String>,
786
787 /// The border color of the minimap thumb.
788 #[serde(rename = "minimap.thumb.border")]
789 pub minimap_thumb_border: Option<String>,
790
791 #[serde(rename = "editor.foreground")]
792 pub editor_foreground: Option<String>,
793
794 #[serde(rename = "editor.background")]
795 pub editor_background: Option<String>,
796
797 #[serde(rename = "editor.gutter.background")]
798 pub editor_gutter_background: Option<String>,
799
800 #[serde(rename = "editor.subheader.background")]
801 pub editor_subheader_background: Option<String>,
802
803 #[serde(rename = "editor.active_line.background")]
804 pub editor_active_line_background: Option<String>,
805
806 #[serde(rename = "editor.highlighted_line.background")]
807 pub editor_highlighted_line_background: Option<String>,
808
809 /// Background of active line of debugger
810 #[serde(rename = "editor.debugger_active_line.background")]
811 pub editor_debugger_active_line_background: Option<String>,
812
813 /// Text Color. Used for the text of the line number in the editor gutter.
814 #[serde(rename = "editor.line_number")]
815 pub editor_line_number: Option<String>,
816
817 /// Text Color. Used for the text of the line number in the editor gutter when the line is highlighted.
818 #[serde(rename = "editor.active_line_number")]
819 pub editor_active_line_number: Option<String>,
820
821 /// Text Color. Used for the text of the line number in the editor gutter when the line is hovered over.
822 #[serde(rename = "editor.hover_line_number")]
823 pub editor_hover_line_number: Option<String>,
824
825 /// Text Color. Used to mark invisible characters in the editor.
826 ///
827 /// Example: spaces, tabs, carriage returns, etc.
828 #[serde(rename = "editor.invisible")]
829 pub editor_invisible: Option<String>,
830
831 #[serde(rename = "editor.wrap_guide")]
832 pub editor_wrap_guide: Option<String>,
833
834 #[serde(rename = "editor.active_wrap_guide")]
835 pub editor_active_wrap_guide: Option<String>,
836
837 #[serde(rename = "editor.indent_guide")]
838 pub editor_indent_guide: Option<String>,
839
840 #[serde(rename = "editor.indent_guide_active")]
841 pub editor_indent_guide_active: Option<String>,
842
843 /// Read-access of a symbol, like reading a variable.
844 ///
845 /// A document highlight is a range inside a text document which deserves
846 /// special attention. Usually a document highlight is visualized by changing
847 /// the background color of its range.
848 #[serde(rename = "editor.document_highlight.read_background")]
849 pub editor_document_highlight_read_background: Option<String>,
850
851 /// Read-access of a symbol, like reading a variable.
852 ///
853 /// A document highlight is a range inside a text document which deserves
854 /// special attention. Usually a document highlight is visualized by changing
855 /// the background color of its range.
856 #[serde(rename = "editor.document_highlight.write_background")]
857 pub editor_document_highlight_write_background: Option<String>,
858
859 /// Highlighted brackets background color.
860 ///
861 /// Matching brackets in the cursor scope are highlighted with this background color.
862 #[serde(rename = "editor.document_highlight.bracket_background")]
863 pub editor_document_highlight_bracket_background: Option<String>,
864
865 /// Filled background color for added diff hunk row highlights in the editor.
866 #[serde(rename = "editor.diff_hunk.added.background")]
867 pub editor_diff_hunk_added_background: Option<String>,
868
869 /// Hollow background color for added diff hunk row highlights in the editor.
870 #[serde(rename = "editor.diff_hunk.added.hollow_background")]
871 pub editor_diff_hunk_added_hollow_background: Option<String>,
872
873 /// Hollow border color for added diff hunk row highlights in the editor.
874 #[serde(rename = "editor.diff_hunk.added.hollow_border")]
875 pub editor_diff_hunk_added_hollow_border: Option<String>,
876
877 /// Filled background color for deleted diff hunk row highlights in the editor.
878 #[serde(rename = "editor.diff_hunk.deleted.background")]
879 pub editor_diff_hunk_deleted_background: Option<String>,
880
881 /// Hollow background color for deleted diff hunk row highlights in the editor.
882 #[serde(rename = "editor.diff_hunk.deleted.hollow_background")]
883 pub editor_diff_hunk_deleted_hollow_background: Option<String>,
884
885 /// Hollow border color for deleted diff hunk row highlights in the editor.
886 #[serde(rename = "editor.diff_hunk.deleted.hollow_border")]
887 pub editor_diff_hunk_deleted_hollow_border: Option<String>,
888
889 /// Terminal background color.
890 #[serde(rename = "terminal.background")]
891 pub terminal_background: Option<String>,
892
893 /// Terminal foreground color.
894 #[serde(rename = "terminal.foreground")]
895 pub terminal_foreground: Option<String>,
896
897 /// Terminal ANSI background color.
898 #[serde(rename = "terminal.ansi.background")]
899 pub terminal_ansi_background: Option<String>,
900
901 /// Bright terminal foreground color.
902 #[serde(rename = "terminal.bright_foreground")]
903 pub terminal_bright_foreground: Option<String>,
904
905 /// Dim terminal foreground color.
906 #[serde(rename = "terminal.dim_foreground")]
907 pub terminal_dim_foreground: Option<String>,
908
909 /// Black ANSI terminal color.
910 #[serde(rename = "terminal.ansi.black")]
911 pub terminal_ansi_black: Option<String>,
912
913 /// Bright black ANSI terminal color.
914 #[serde(rename = "terminal.ansi.bright_black")]
915 pub terminal_ansi_bright_black: Option<String>,
916
917 /// Dim black ANSI terminal color.
918 #[serde(rename = "terminal.ansi.dim_black")]
919 pub terminal_ansi_dim_black: Option<String>,
920
921 /// Red ANSI terminal color.
922 #[serde(rename = "terminal.ansi.red")]
923 pub terminal_ansi_red: Option<String>,
924
925 /// Bright red ANSI terminal color.
926 #[serde(rename = "terminal.ansi.bright_red")]
927 pub terminal_ansi_bright_red: Option<String>,
928
929 /// Dim red ANSI terminal color.
930 #[serde(rename = "terminal.ansi.dim_red")]
931 pub terminal_ansi_dim_red: Option<String>,
932
933 /// Green ANSI terminal color.
934 #[serde(rename = "terminal.ansi.green")]
935 pub terminal_ansi_green: Option<String>,
936
937 /// Bright green ANSI terminal color.
938 #[serde(rename = "terminal.ansi.bright_green")]
939 pub terminal_ansi_bright_green: Option<String>,
940
941 /// Dim green ANSI terminal color.
942 #[serde(rename = "terminal.ansi.dim_green")]
943 pub terminal_ansi_dim_green: Option<String>,
944
945 /// Yellow ANSI terminal color.
946 #[serde(rename = "terminal.ansi.yellow")]
947 pub terminal_ansi_yellow: Option<String>,
948
949 /// Bright yellow ANSI terminal color.
950 #[serde(rename = "terminal.ansi.bright_yellow")]
951 pub terminal_ansi_bright_yellow: Option<String>,
952
953 /// Dim yellow ANSI terminal color.
954 #[serde(rename = "terminal.ansi.dim_yellow")]
955 pub terminal_ansi_dim_yellow: Option<String>,
956
957 /// Blue ANSI terminal color.
958 #[serde(rename = "terminal.ansi.blue")]
959 pub terminal_ansi_blue: Option<String>,
960
961 /// Bright blue ANSI terminal color.
962 #[serde(rename = "terminal.ansi.bright_blue")]
963 pub terminal_ansi_bright_blue: Option<String>,
964
965 /// Dim blue ANSI terminal color.
966 #[serde(rename = "terminal.ansi.dim_blue")]
967 pub terminal_ansi_dim_blue: Option<String>,
968
969 /// Magenta ANSI terminal color.
970 #[serde(rename = "terminal.ansi.magenta")]
971 pub terminal_ansi_magenta: Option<String>,
972
973 /// Bright magenta ANSI terminal color.
974 #[serde(rename = "terminal.ansi.bright_magenta")]
975 pub terminal_ansi_bright_magenta: Option<String>,
976
977 /// Dim magenta ANSI terminal color.
978 #[serde(rename = "terminal.ansi.dim_magenta")]
979 pub terminal_ansi_dim_magenta: Option<String>,
980
981 /// Cyan ANSI terminal color.
982 #[serde(rename = "terminal.ansi.cyan")]
983 pub terminal_ansi_cyan: Option<String>,
984
985 /// Bright cyan ANSI terminal color.
986 #[serde(rename = "terminal.ansi.bright_cyan")]
987 pub terminal_ansi_bright_cyan: Option<String>,
988
989 /// Dim cyan ANSI terminal color.
990 #[serde(rename = "terminal.ansi.dim_cyan")]
991 pub terminal_ansi_dim_cyan: Option<String>,
992
993 /// White ANSI terminal color.
994 #[serde(rename = "terminal.ansi.white")]
995 pub terminal_ansi_white: Option<String>,
996
997 /// Bright white ANSI terminal color.
998 #[serde(rename = "terminal.ansi.bright_white")]
999 pub terminal_ansi_bright_white: Option<String>,
1000
1001 /// Dim white ANSI terminal color.
1002 #[serde(rename = "terminal.ansi.dim_white")]
1003 pub terminal_ansi_dim_white: Option<String>,
1004
1005 #[serde(rename = "link_text.hover")]
1006 pub link_text_hover: Option<String>,
1007
1008 /// Added version control color.
1009 #[serde(rename = "version_control.added")]
1010 pub version_control_added: Option<String>,
1011
1012 /// Deleted version control color.
1013 #[serde(rename = "version_control.deleted")]
1014 pub version_control_deleted: Option<String>,
1015
1016 /// Modified version control color.
1017 #[serde(rename = "version_control.modified")]
1018 pub version_control_modified: Option<String>,
1019
1020 /// Renamed version control color.
1021 #[serde(rename = "version_control.renamed")]
1022 pub version_control_renamed: Option<String>,
1023
1024 /// Conflict version control color.
1025 #[serde(rename = "version_control.conflict")]
1026 pub version_control_conflict: Option<String>,
1027
1028 /// Ignored version control color.
1029 #[serde(rename = "version_control.ignored")]
1030 pub version_control_ignored: Option<String>,
1031
1032 /// Color for added words in word diffs.
1033 #[serde(rename = "version_control.word_added")]
1034 pub version_control_word_added: Option<String>,
1035
1036 /// Color for deleted words in word diffs.
1037 #[serde(rename = "version_control.word_deleted")]
1038 pub version_control_word_deleted: Option<String>,
1039
1040 /// Background color for row highlights of "ours" regions in merge conflicts.
1041 #[serde(rename = "version_control.conflict_marker.ours")]
1042 pub version_control_conflict_marker_ours: Option<String>,
1043
1044 /// Background color for row highlights of "theirs" regions in merge conflicts.
1045 #[serde(rename = "version_control.conflict_marker.theirs")]
1046 pub version_control_conflict_marker_theirs: Option<String>,
1047
1048 /// Deprecated in favor of `version_control_conflict_marker_ours`.
1049 #[deprecated]
1050 pub version_control_conflict_ours_background: Option<String>,
1051
1052 /// Deprecated in favor of `version_control_conflict_marker_theirs`.
1053 #[deprecated]
1054 pub version_control_conflict_theirs_background: Option<String>,
1055
1056 /// Background color for Vim Normal mode indicator.
1057 #[serde(rename = "vim.normal.background")]
1058 pub vim_normal_background: Option<String>,
1059 /// Background color for Vim Insert mode indicator.
1060 #[serde(rename = "vim.insert.background")]
1061 pub vim_insert_background: Option<String>,
1062 /// Background color for Vim Replace mode indicator.
1063 #[serde(rename = "vim.replace.background")]
1064 pub vim_replace_background: Option<String>,
1065 /// Background color for Vim Visual mode indicator.
1066 #[serde(rename = "vim.visual.background")]
1067 pub vim_visual_background: Option<String>,
1068 /// Background color for Vim Visual Line mode indicator.
1069 #[serde(rename = "vim.visual_line.background")]
1070 pub vim_visual_line_background: Option<String>,
1071 /// Background color for Vim Visual Block mode indicator.
1072 #[serde(rename = "vim.visual_block.background")]
1073 pub vim_visual_block_background: Option<String>,
1074 /// Background color for Vim yank highlight.
1075 #[serde(rename = "vim.yank.background")]
1076 pub vim_yank_background: Option<String>,
1077 /// Foreground color for Helix jump labels.
1078 #[serde(rename = "vim.helix_jump_label.foreground")]
1079 pub vim_helix_jump_label_foreground: Option<String>,
1080 /// Background color for Vim Helix Normal mode indicator.
1081 #[serde(rename = "vim.helix_normal.background")]
1082 pub vim_helix_normal_background: Option<String>,
1083 /// Background color for Vim Helix Select mode indicator.
1084 #[serde(rename = "vim.helix_select.background")]
1085 pub vim_helix_select_background: Option<String>,
1086 /// Background color for Vim Normal mode indicator.
1087 #[serde(rename = "vim.normal.foreground")]
1088 pub vim_normal_foreground: Option<String>,
1089 /// Foreground color for Vim Insert mode indicator.
1090 #[serde(rename = "vim.insert.foreground")]
1091 pub vim_insert_foreground: Option<String>,
1092 /// Foreground color for Vim Replace mode indicator.
1093 #[serde(rename = "vim.replace.foreground")]
1094 pub vim_replace_foreground: Option<String>,
1095 /// Foreground color for Vim Visual mode indicator.
1096 #[serde(rename = "vim.visual.foreground")]
1097 pub vim_visual_foreground: Option<String>,
1098 /// Foreground color for Vim Visual Line mode indicator.
1099 #[serde(rename = "vim.visual_line.foreground")]
1100 pub vim_visual_line_foreground: Option<String>,
1101 /// Foreground color for Vim Visual Block mode indicator.
1102 #[serde(rename = "vim.visual_block.foreground")]
1103 pub vim_visual_block_foreground: Option<String>,
1104 /// Foreground color for Vim Helix Normal mode indicator.
1105 #[serde(rename = "vim.helix_normal.foreground")]
1106 pub vim_helix_normal_foreground: Option<String>,
1107 /// Foreground color for Vim Helix Select mode indicator.
1108 #[serde(rename = "vim.helix_select.foreground")]
1109 pub vim_helix_select_foreground: Option<String>,
1110}
1111
1112#[derive(Debug, Clone, Default, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq)]
1113#[serde(default)]
1114pub struct HighlightStyleContent {
1115 pub color: Option<String>,
1116
1117 #[serde(
1118 skip_serializing_if = "Option::is_none",
1119 deserialize_with = "treat_error_as_none"
1120 )]
1121 pub background_color: Option<String>,
1122
1123 #[serde(
1124 skip_serializing_if = "Option::is_none",
1125 deserialize_with = "treat_error_as_none"
1126 )]
1127 pub font_style: Option<FontStyleContent>,
1128
1129 #[serde(
1130 skip_serializing_if = "Option::is_none",
1131 deserialize_with = "treat_error_as_none"
1132 )]
1133 pub font_weight: Option<FontWeightContent>,
1134}
1135
1136impl HighlightStyleContent {
1137 pub fn is_empty(&self) -> bool {
1138 self.color.is_none()
1139 && self.background_color.is_none()
1140 && self.font_style.is_none()
1141 && self.font_weight.is_none()
1142 }
1143}
1144
1145fn treat_error_as_none<'de, T, D>(deserializer: D) -> Result<Option<T>, D::Error>
1146where
1147 T: Deserialize<'de>,
1148 D: Deserializer<'de>,
1149{
1150 let value: Value = Deserialize::deserialize(deserializer)?;
1151 Ok(T::deserialize(value).ok())
1152}
1153
1154#[with_fallible_options]
1155#[derive(Debug, Clone, Default, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq)]
1156#[serde(default)]
1157pub struct StatusColorsContent {
1158 /// Indicates some kind of conflict, like a file changed on disk while it was open, or
1159 /// merge conflicts in a Git repository.
1160 #[serde(rename = "conflict")]
1161 pub conflict: Option<String>,
1162
1163 #[serde(rename = "conflict.background")]
1164 pub conflict_background: Option<String>,
1165
1166 #[serde(rename = "conflict.border")]
1167 pub conflict_border: Option<String>,
1168
1169 /// Indicates something new, like a new file added to a Git repository.
1170 #[serde(rename = "created")]
1171 pub created: Option<String>,
1172
1173 #[serde(rename = "created.background")]
1174 pub created_background: Option<String>,
1175
1176 #[serde(rename = "created.border")]
1177 pub created_border: Option<String>,
1178
1179 /// Indicates that something no longer exists, like a deleted file.
1180 #[serde(rename = "deleted")]
1181 pub deleted: Option<String>,
1182
1183 #[serde(rename = "deleted.background")]
1184 pub deleted_background: Option<String>,
1185
1186 #[serde(rename = "deleted.border")]
1187 pub deleted_border: Option<String>,
1188
1189 /// Indicates a system error, a failed operation or a diagnostic error.
1190 #[serde(rename = "error")]
1191 pub error: Option<String>,
1192
1193 #[serde(rename = "error.background")]
1194 pub error_background: Option<String>,
1195
1196 #[serde(rename = "error.border")]
1197 pub error_border: Option<String>,
1198
1199 /// Represents a hidden status, such as a file being hidden in a file tree.
1200 #[serde(rename = "hidden")]
1201 pub hidden: Option<String>,
1202
1203 #[serde(rename = "hidden.background")]
1204 pub hidden_background: Option<String>,
1205
1206 #[serde(rename = "hidden.border")]
1207 pub hidden_border: Option<String>,
1208
1209 /// Indicates a hint or some kind of additional information.
1210 #[serde(rename = "hint")]
1211 pub hint: Option<String>,
1212
1213 #[serde(rename = "hint.background")]
1214 pub hint_background: Option<String>,
1215
1216 #[serde(rename = "hint.border")]
1217 pub hint_border: Option<String>,
1218
1219 /// Indicates that something is deliberately ignored, such as a file or operation ignored by Git.
1220 #[serde(rename = "ignored")]
1221 pub ignored: Option<String>,
1222
1223 #[serde(rename = "ignored.background")]
1224 pub ignored_background: Option<String>,
1225
1226 #[serde(rename = "ignored.border")]
1227 pub ignored_border: Option<String>,
1228
1229 /// Represents informational status updates or messages.
1230 #[serde(rename = "info")]
1231 pub info: Option<String>,
1232
1233 #[serde(rename = "info.background")]
1234 pub info_background: Option<String>,
1235
1236 #[serde(rename = "info.border")]
1237 pub info_border: Option<String>,
1238
1239 /// Indicates a changed or altered status, like a file that has been edited.
1240 #[serde(rename = "modified")]
1241 pub modified: Option<String>,
1242
1243 #[serde(rename = "modified.background")]
1244 pub modified_background: Option<String>,
1245
1246 #[serde(rename = "modified.border")]
1247 pub modified_border: Option<String>,
1248
1249 /// Indicates something that is predicted, like automatic code completion, or generated code.
1250 #[serde(rename = "predictive")]
1251 pub predictive: Option<String>,
1252
1253 #[serde(rename = "predictive.background")]
1254 pub predictive_background: Option<String>,
1255
1256 #[serde(rename = "predictive.border")]
1257 pub predictive_border: Option<String>,
1258
1259 /// Represents a renamed status, such as a file that has been renamed.
1260 #[serde(rename = "renamed")]
1261 pub renamed: Option<String>,
1262
1263 #[serde(rename = "renamed.background")]
1264 pub renamed_background: Option<String>,
1265
1266 #[serde(rename = "renamed.border")]
1267 pub renamed_border: Option<String>,
1268
1269 /// Indicates a successful operation or task completion.
1270 #[serde(rename = "success")]
1271 pub success: Option<String>,
1272
1273 #[serde(rename = "success.background")]
1274 pub success_background: Option<String>,
1275
1276 #[serde(rename = "success.border")]
1277 pub success_border: Option<String>,
1278
1279 /// Indicates some kind of unreachable status, like a block of code that can never be reached.
1280 #[serde(rename = "unreachable")]
1281 pub unreachable: Option<String>,
1282
1283 #[serde(rename = "unreachable.background")]
1284 pub unreachable_background: Option<String>,
1285
1286 #[serde(rename = "unreachable.border")]
1287 pub unreachable_border: Option<String>,
1288
1289 /// Represents a warning status, like an operation that is about to fail.
1290 #[serde(rename = "warning")]
1291 pub warning: Option<String>,
1292
1293 #[serde(rename = "warning.background")]
1294 pub warning_background: Option<String>,
1295
1296 #[serde(rename = "warning.border")]
1297 pub warning_border: Option<String>,
1298}
1299
1300/// The background appearance of the window.
1301#[derive(Debug, PartialEq, Clone, Copy, Serialize, Deserialize, JsonSchema, MergeFrom)]
1302#[serde(rename_all = "snake_case")]
1303pub enum WindowBackgroundContent {
1304 Opaque,
1305 Transparent,
1306 Blurred,
1307}
1308
1309#[derive(Debug, Clone, Copy, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq)]
1310#[serde(rename_all = "snake_case")]
1311pub enum FontStyleContent {
1312 Normal,
1313 Italic,
1314 Oblique,
1315}
1316
1317#[derive(
1318 Clone,
1319 Copy,
1320 Debug,
1321 PartialEq,
1322 PartialOrd,
1323 Serialize,
1324 Deserialize,
1325 MergeFrom,
1326 derive_more::FromStr,
1327)]
1328#[serde(transparent)]
1329pub struct FontWeightContent(pub f32);
1330
1331impl Display for FontWeightContent {
1332 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1333 write!(f, "{}", self.0)
1334 }
1335}
1336
1337impl From<f32> for FontWeightContent {
1338 fn from(weight: f32) -> Self {
1339 FontWeightContent(weight)
1340 }
1341}
1342
1343impl Default for FontWeightContent {
1344 fn default() -> Self {
1345 Self::NORMAL
1346 }
1347}
1348
1349impl FontWeightContent {
1350 pub const THIN: FontWeightContent = FontWeightContent(100.0);
1351 pub const EXTRA_LIGHT: FontWeightContent = FontWeightContent(200.0);
1352 pub const LIGHT: FontWeightContent = FontWeightContent(300.0);
1353 pub const NORMAL: FontWeightContent = FontWeightContent(400.0);
1354 pub const MEDIUM: FontWeightContent = FontWeightContent(500.0);
1355 pub const SEMIBOLD: FontWeightContent = FontWeightContent(600.0);
1356 pub const BOLD: FontWeightContent = FontWeightContent(700.0);
1357 pub const EXTRA_BOLD: FontWeightContent = FontWeightContent(800.0);
1358 pub const BLACK: FontWeightContent = FontWeightContent(900.0);
1359}
1360
1361impl schemars::JsonSchema for FontWeightContent {
1362 fn schema_name() -> std::borrow::Cow<'static, str> {
1363 "FontWeightContent".into()
1364 }
1365
1366 fn json_schema(_: &mut schemars::SchemaGenerator) -> schemars::Schema {
1367 use schemars::json_schema;
1368 json_schema!({
1369 "type": "number",
1370 "minimum": Self::THIN.0,
1371 "maximum": Self::BLACK.0,
1372 "default": Self::NORMAL.0,
1373 "description": "Font weight value between 100 (thin) and 900 (black)"
1374 })
1375 }
1376}
1377
1378#[cfg(test)]
1379mod tests {
1380 use super::*;
1381 use serde_json::json;
1382
1383 #[test]
1384 fn test_buffer_line_height_deserialize_valid() {
1385 assert_eq!(
1386 serde_json::from_value::<BufferLineHeight>(json!("comfortable")).unwrap(),
1387 BufferLineHeight::Comfortable
1388 );
1389 assert_eq!(
1390 serde_json::from_value::<BufferLineHeight>(json!("standard")).unwrap(),
1391 BufferLineHeight::Standard
1392 );
1393 assert_eq!(
1394 serde_json::from_value::<BufferLineHeight>(json!({"custom": 1.0})).unwrap(),
1395 BufferLineHeight::Custom(1.0)
1396 );
1397 assert_eq!(
1398 serde_json::from_value::<BufferLineHeight>(json!({"custom": 1.5})).unwrap(),
1399 BufferLineHeight::Custom(1.5)
1400 );
1401 }
1402
1403 #[test]
1404 fn test_buffer_line_height_deserialize_invalid() {
1405 assert!(
1406 serde_json::from_value::<BufferLineHeight>(json!({"custom": 0.99}))
1407 .err()
1408 .unwrap()
1409 .to_string()
1410 .contains("buffer_line_height.custom must be at least 1.0")
1411 );
1412 assert!(
1413 serde_json::from_value::<BufferLineHeight>(json!({"custom": 0.0}))
1414 .err()
1415 .unwrap()
1416 .to_string()
1417 .contains("buffer_line_height.custom must be at least 1.0")
1418 );
1419 assert!(
1420 serde_json::from_value::<BufferLineHeight>(json!({"custom": -1.0}))
1421 .err()
1422 .unwrap()
1423 .to_string()
1424 .contains("buffer_line_height.custom must be at least 1.0")
1425 );
1426 }
1427
1428 #[test]
1429 fn test_buffer_font_weight_schema_has_default() {
1430 use schemars::schema_for;
1431
1432 let schema = schema_for!(ThemeSettingsContent);
1433 let schema_value = serde_json::to_value(&schema).unwrap();
1434
1435 let properties = &schema_value["properties"];
1436 let buffer_font_weight = &properties["buffer_font_weight"];
1437
1438 assert!(
1439 buffer_font_weight.get("default").is_some(),
1440 "buffer_font_weight should have a default value in the schema"
1441 );
1442
1443 let default_value = &buffer_font_weight["default"];
1444 assert_eq!(
1445 default_value.as_f64(),
1446 Some(FontWeightContent::NORMAL.0 as f64),
1447 "buffer_font_weight default should be 400.0 (FontWeightContent::NORMAL)"
1448 );
1449
1450 let defs = &schema_value["$defs"];
1451 let font_weight_def = &defs["FontWeightContent"];
1452
1453 assert_eq!(
1454 font_weight_def["minimum"].as_f64(),
1455 Some(FontWeightContent::THIN.0 as f64),
1456 "FontWeightContent should have minimum of 100.0"
1457 );
1458 assert_eq!(
1459 font_weight_def["maximum"].as_f64(),
1460 Some(FontWeightContent::BLACK.0 as f64),
1461 "FontWeightContent should have maximum of 900.0"
1462 );
1463 assert_eq!(
1464 font_weight_def["default"].as_f64(),
1465 Some(FontWeightContent::NORMAL.0 as f64),
1466 "FontWeightContent should have default of 400.0"
1467 );
1468 }
1469}
1470