1use anyhow::Result;
2use gpui::{HighlightStyle, Hsla};
3use indexmap::IndexMap;
4use palette::FromColor;
5use schemars::JsonSchema;
6use serde::{Deserialize, Serialize};
7
8use crate::{StatusColorsRefinement, ThemeColorsRefinement};
9
10fn try_parse_color(color: &str) -> Result<Hsla> {
11 let rgba = gpui::Rgba::try_from(color)?;
12 let rgba = palette::rgb::Srgba::from_components((rgba.r, rgba.g, rgba.b, rgba.a));
13 let hsla = palette::Hsla::from_color(rgba);
14
15 let hsla = gpui::hsla(
16 hsla.hue.into_positive_degrees() / 360.,
17 hsla.saturation,
18 hsla.lightness,
19 hsla.alpha,
20 );
21
22 Ok(hsla)
23}
24
25/// The content of a serialized theme.
26#[derive(Debug, Clone, Default, Serialize, Deserialize, JsonSchema)]
27#[serde(default)]
28pub struct ThemeContent {
29 #[serde(flatten, default)]
30 pub colors: ThemeColorsContent,
31
32 #[serde(flatten, default)]
33 pub status: StatusColorsContent,
34
35 /// The styles for syntax nodes.
36 #[serde(default)]
37 pub syntax: IndexMap<String, HighlightStyleContent>,
38}
39
40impl ThemeContent {
41 /// Returns a [`ThemeColorsRefinement`] based on the colors in the [`ThemeContent`].
42 #[inline(always)]
43 pub fn theme_colors_refinement(&self) -> ThemeColorsRefinement {
44 self.colors.theme_colors_refinement()
45 }
46
47 /// Returns a [`StatusColorsRefinement`] based on the colors in the [`ThemeContent`].
48 #[inline(always)]
49 pub fn status_colors_refinement(&self) -> StatusColorsRefinement {
50 self.status.status_colors_refinement()
51 }
52
53 /// Returns the syntax style overrides in the [`ThemeContent`].
54 pub fn syntax_overrides(&self) -> Vec<(String, HighlightStyle)> {
55 self.syntax
56 .iter()
57 .map(|(key, style)| {
58 (
59 key.clone(),
60 HighlightStyle {
61 color: style
62 .color
63 .as_ref()
64 .and_then(|color| try_parse_color(&color).ok()),
65 ..Default::default()
66 },
67 )
68 })
69 .collect()
70 }
71}
72
73#[derive(Debug, Clone, Default, Serialize, Deserialize, JsonSchema)]
74#[serde(default)]
75pub struct ThemeColorsContent {
76 /// Border color. Used for most borders, is usually a high contrast color.
77 #[serde(rename = "border")]
78 pub border: Option<String>,
79
80 /// Border color. Used for deemphasized borders, like a visual divider between two sections
81 #[serde(rename = "border.variant")]
82 pub border_variant: Option<String>,
83
84 /// Border color. Used for focused elements, like keyboard focused list item.
85 #[serde(rename = "border.focused")]
86 pub border_focused: Option<String>,
87
88 /// Border color. Used for selected elements, like an active search filter or selected checkbox.
89 #[serde(rename = "border.selected")]
90 pub border_selected: Option<String>,
91
92 /// Border color. Used for transparent borders. Used for placeholder borders when an element gains a border on state change.
93 #[serde(rename = "border.transparent")]
94 pub border_transparent: Option<String>,
95
96 /// Border color. Used for disabled elements, like a disabled input or button.
97 #[serde(rename = "border.disabled")]
98 pub border_disabled: Option<String>,
99
100 /// Border color. Used for elevated surfaces, like a context menu, popup, or dialog.
101 #[serde(rename = "elevated_surface.background")]
102 pub elevated_surface_background: Option<String>,
103
104 /// Background Color. Used for grounded surfaces like a panel or tab.
105 #[serde(rename = "surface.background")]
106 pub surface_background: Option<String>,
107
108 /// Background Color. Used for the app background and blank panels or windows.
109 #[serde(rename = "background")]
110 pub background: Option<String>,
111
112 /// Background Color. Used for the background of an element that should have a different background than the surface it's on.
113 ///
114 /// Elements might include: Buttons, Inputs, Checkboxes, Radio Buttons...
115 ///
116 /// For an element that should have the same background as the surface it's on, use `ghost_element_background`.
117 #[serde(rename = "element.background")]
118 pub element_background: Option<String>,
119
120 /// Background Color. Used for the hover state of an element that should have a different background than the surface it's on.
121 ///
122 /// Hover states are triggered by the mouse entering an element, or a finger touching an element on a touch screen.
123 #[serde(rename = "element.hover")]
124 pub element_hover: Option<String>,
125
126 /// Background Color. Used for the active state of an element that should have a different background than the surface it's on.
127 ///
128 /// Active states are triggered by the mouse button being pressed down on an element, or the Return button or other activator being pressd.
129 #[serde(rename = "element.active")]
130 pub element_active: Option<String>,
131
132 /// Background Color. Used for the selected state of an element that should have a different background than the surface it's on.
133 ///
134 /// Selected states are triggered by the element being selected (or "activated") by the user.
135 ///
136 /// This could include a selected checkbox, a toggleable button that is toggled on, etc.
137 #[serde(rename = "element.selected")]
138 pub element_selected: Option<String>,
139
140 /// Background Color. Used for the disabled state of an element that should have a different background than the surface it's on.
141 ///
142 /// Disabled states are shown when a user cannot interact with an element, like a disabled button or input.
143 #[serde(rename = "element.disabled")]
144 pub element_disabled: Option<String>,
145
146 /// Background Color. Used for the area that shows where a dragged element will be dropped.
147 #[serde(rename = "drop_target.background")]
148 pub drop_target_background: Option<String>,
149
150 /// Used for the background of a ghost element that should have the same background as the surface it's on.
151 ///
152 /// Elements might include: Buttons, Inputs, Checkboxes, Radio Buttons...
153 ///
154 /// For an element that should have a different background than the surface it's on, use `element_background`.
155 #[serde(rename = "ghost_element.background")]
156 pub ghost_element_background: Option<String>,
157
158 /// Background Color. Used for the hover state of a ghost element that should have the same background as the surface it's on.
159 ///
160 /// Hover states are triggered by the mouse entering an element, or a finger touching an element on a touch screen.
161 #[serde(rename = "ghost_element.hover")]
162 pub ghost_element_hover: Option<String>,
163
164 /// Background Color. Used for the active state of a ghost element that should have the same background as the surface it's on.
165 ///
166 /// Active states are triggered by the mouse button being pressed down on an element, or the Return button or other activator being pressd.
167 #[serde(rename = "ghost_element.active")]
168 pub ghost_element_active: Option<String>,
169
170 /// Background Color. Used for the selected state of a ghost element that should have the same background as the surface it's on.
171 ///
172 /// Selected states are triggered by the element being selected (or "activated") by the user.
173 ///
174 /// This could include a selected checkbox, a toggleable button that is toggled on, etc.
175 #[serde(rename = "ghost_element.selected")]
176 pub ghost_element_selected: Option<String>,
177
178 /// Background Color. Used for the disabled state of a ghost element that should have the same background as the surface it's on.
179 ///
180 /// Disabled states are shown when a user cannot interact with an element, like a disabled button or input.
181 #[serde(rename = "ghost_element.disabled")]
182 pub ghost_element_disabled: Option<String>,
183
184 /// Text Color. Default text color used for most text.
185 #[serde(rename = "text")]
186 pub text: Option<String>,
187
188 /// Text Color. Color of muted or deemphasized text. It is a subdued version of the standard text color.
189 #[serde(rename = "text.muted")]
190 pub text_muted: Option<String>,
191
192 /// Text Color. Color of the placeholder text typically shown in input fields to guide the user to enter valid data.
193 #[serde(rename = "text.placeholder")]
194 pub text_placeholder: Option<String>,
195
196 /// Text Color. Color used for text denoting disabled elements. Typically, the color is faded or grayed out to emphasize the disabled state.
197 #[serde(rename = "text.disabled")]
198 pub text_disabled: Option<String>,
199
200 /// Text Color. Color used for emphasis or highlighting certain text, like an active filter or a matched character in a search.
201 #[serde(rename = "text.accent")]
202 pub text_accent: Option<String>,
203
204 /// Fill Color. Used for the default fill color of an icon.
205 #[serde(rename = "icon")]
206 pub icon: Option<String>,
207
208 /// Fill Color. Used for the muted or deemphasized fill color of an icon.
209 ///
210 /// This might be used to show an icon in an inactive pane, or to demphasize a series of icons to give them less visual weight.
211 #[serde(rename = "icon.muted")]
212 pub icon_muted: Option<String>,
213
214 /// Fill Color. Used for the disabled fill color of an icon.
215 ///
216 /// Disabled states are shown when a user cannot interact with an element, like a icon button.
217 #[serde(rename = "icon.disabled")]
218 pub icon_disabled: Option<String>,
219
220 /// Fill Color. Used for the placeholder fill color of an icon.
221 ///
222 /// This might be used to show an icon in an input that disappears when the user enters text.
223 #[serde(rename = "icon.placeholder")]
224 pub icon_placeholder: Option<String>,
225
226 /// Fill Color. Used for the accent fill color of an icon.
227 ///
228 /// This might be used to show when a toggleable icon button is selected.
229 #[serde(rename = "con.accent")]
230 pub icon_accent: Option<String>,
231
232 #[serde(rename = "status_bar.background")]
233 pub status_bar_background: Option<String>,
234
235 #[serde(rename = "title_bar.background")]
236 pub title_bar_background: Option<String>,
237
238 #[serde(rename = "toolbar.background")]
239 pub toolbar_background: Option<String>,
240
241 #[serde(rename = "tab_bar.background")]
242 pub tab_bar_background: Option<String>,
243
244 #[serde(rename = "tab.inactive_background")]
245 pub tab_inactive_background: Option<String>,
246
247 #[serde(rename = "tab.active_background")]
248 pub tab_active_background: Option<String>,
249
250 #[serde(rename = "search.match_background")]
251 pub search_match_background: Option<String>,
252
253 #[serde(rename = "panel.background")]
254 pub panel_background: Option<String>,
255
256 #[serde(rename = "panel.focused_border")]
257 pub panel_focused_border: Option<String>,
258
259 #[serde(rename = "pane.focused_border")]
260 pub pane_focused_border: Option<String>,
261
262 /// The color of the scrollbar thumb.
263 #[serde(rename = "scrollbar_thumb.background")]
264 pub scrollbar_thumb_background: Option<String>,
265
266 /// The color of the scrollbar thumb when hovered over.
267 #[serde(rename = "scrollbar.thumb.hover_background")]
268 pub scrollbar_thumb_hover_background: Option<String>,
269
270 /// The border color of the scrollbar thumb.
271 #[serde(rename = "scrollbar.thumb.border")]
272 pub scrollbar_thumb_border: Option<String>,
273
274 /// The background color of the scrollbar track.
275 #[serde(rename = "scrollbar.track.background")]
276 pub scrollbar_track_background: Option<String>,
277
278 /// The border color of the scrollbar track.
279 #[serde(rename = "scrollbar.track.border")]
280 pub scrollbar_track_border: Option<String>,
281
282 #[serde(rename = "editor.foreground")]
283 pub editor_foreground: Option<String>,
284
285 #[serde(rename = "editor.background")]
286 pub editor_background: Option<String>,
287
288 #[serde(rename = "editor.gutter.background")]
289 pub editor_gutter_background: Option<String>,
290
291 #[serde(rename = "editor.subheader.background")]
292 pub editor_subheader_background: Option<String>,
293
294 #[serde(rename = "editor.active_line.background")]
295 pub editor_active_line_background: Option<String>,
296
297 #[serde(rename = "editor.highlighted_line.background")]
298 pub editor_highlighted_line_background: Option<String>,
299
300 /// Text Color. Used for the text of the line number in the editor gutter.
301 #[serde(rename = "editor.line_number")]
302 pub editor_line_number: Option<String>,
303
304 /// Text Color. Used for the text of the line number in the editor gutter when the line is highlighted.
305 #[serde(rename = "editor.active_line_number")]
306 pub editor_active_line_number: Option<String>,
307
308 /// Text Color. Used to mark invisible characters in the editor.
309 ///
310 /// Example: spaces, tabs, carriage returns, etc.
311 #[serde(rename = "editor.invisible")]
312 pub editor_invisible: Option<String>,
313
314 #[serde(rename = "editor.wrap_guide")]
315 pub editor_wrap_guide: Option<String>,
316
317 #[serde(rename = "editor.active_wrap_guide")]
318 pub editor_active_wrap_guide: Option<String>,
319
320 /// Read-access of a symbol, like reading a variable.
321 ///
322 /// A document highlight is a range inside a text document which deserves
323 /// special attention. Usually a document highlight is visualized by changing
324 /// the background color of its range.
325 #[serde(rename = "editor.document_highlight.read_background")]
326 pub editor_document_highlight_read_background: Option<String>,
327
328 /// Read-access of a symbol, like reading a variable.
329 ///
330 /// A document highlight is a range inside a text document which deserves
331 /// special attention. Usually a document highlight is visualized by changing
332 /// the background color of its range.
333 #[serde(rename = "editor.document_highlight.write_background")]
334 pub editor_document_highlight_write_background: Option<String>,
335
336 /// Terminal background color.
337 #[serde(rename = "terminal.background")]
338 pub terminal_background: Option<String>,
339
340 /// Terminal foreground color.
341 #[serde(rename = "terminal.foreground")]
342 pub terminal_foreground: Option<String>,
343
344 /// Bright terminal foreground color.
345 #[serde(rename = "terminal.bright_foreground")]
346 pub terminal_bright_foreground: Option<String>,
347
348 /// Dim terminal foreground color.
349 #[serde(rename = "terminal.dim_foreground")]
350 pub terminal_dim_foreground: Option<String>,
351
352 /// Black ANSI terminal color.
353 #[serde(rename = "terminal.ansi.black")]
354 pub terminal_ansi_black: Option<String>,
355
356 /// Bright black ANSI terminal color.
357 #[serde(rename = "terminal.ansi.bright_black")]
358 pub terminal_ansi_bright_black: Option<String>,
359
360 /// Dim black ANSI terminal color.
361 #[serde(rename = "terminal.ansi.dim_black")]
362 pub terminal_ansi_dim_black: Option<String>,
363
364 /// Red ANSI terminal color.
365 #[serde(rename = "terminal.ansi.red")]
366 pub terminal_ansi_red: Option<String>,
367
368 /// Bright red ANSI terminal color.
369 #[serde(rename = "terminal.ansi.bright_red")]
370 pub terminal_ansi_bright_red: Option<String>,
371
372 /// Dim red ANSI terminal color.
373 #[serde(rename = "terminal.ansi.dim_red")]
374 pub terminal_ansi_dim_red: Option<String>,
375
376 /// Green ANSI terminal color.
377 #[serde(rename = "terminal.ansi.green")]
378 pub terminal_ansi_green: Option<String>,
379
380 /// Bright green ANSI terminal color.
381 #[serde(rename = "terminal.ansi.bright_green")]
382 pub terminal_ansi_bright_green: Option<String>,
383
384 /// Dim green ANSI terminal color.
385 #[serde(rename = "terminal.ansi.dim_green")]
386 pub terminal_ansi_dim_green: Option<String>,
387
388 /// Yellow ANSI terminal color.
389 #[serde(rename = "terminal.ansi.yellow")]
390 pub terminal_ansi_yellow: Option<String>,
391
392 /// Bright yellow ANSI terminal color.
393 #[serde(rename = "terminal.ansi.bright_yellow")]
394 pub terminal_ansi_bright_yellow: Option<String>,
395
396 /// Dim yellow ANSI terminal color.
397 #[serde(rename = "terminal.ansi.dim_yellow")]
398 pub terminal_ansi_dim_yellow: Option<String>,
399
400 /// Blue ANSI terminal color.
401 #[serde(rename = "terminal.ansi.blue")]
402 pub terminal_ansi_blue: Option<String>,
403
404 /// Bright blue ANSI terminal color.
405 #[serde(rename = "terminal.ansi.bright_blue")]
406 pub terminal_ansi_bright_blue: Option<String>,
407
408 /// Dim blue ANSI terminal color.
409 #[serde(rename = "terminal.ansi.dim_blue")]
410 pub terminal_ansi_dim_blue: Option<String>,
411
412 /// Magenta ANSI terminal color.
413 #[serde(rename = "terminal.ansi.magenta")]
414 pub terminal_ansi_magenta: Option<String>,
415
416 /// Bright magenta ANSI terminal color.
417 #[serde(rename = "terminal.ansi.bright_magenta")]
418 pub terminal_ansi_bright_magenta: Option<String>,
419
420 /// Dim magenta ANSI terminal color.
421 #[serde(rename = "terminal.ansi.dim_magenta")]
422 pub terminal_ansi_dim_magenta: Option<String>,
423
424 /// Cyan ANSI terminal color.
425 #[serde(rename = "terminal.ansi.cyan")]
426 pub terminal_ansi_cyan: Option<String>,
427
428 /// Bright cyan ANSI terminal color.
429 #[serde(rename = "terminal.ansi.bright_cyan")]
430 pub terminal_ansi_bright_cyan: Option<String>,
431
432 /// Dim cyan ANSI terminal color.
433 #[serde(rename = "terminal.ansi.dim_cyan")]
434 pub terminal_ansi_dim_cyan: Option<String>,
435
436 /// White ANSI terminal color.
437 #[serde(rename = "terminal.ansi.white")]
438 pub terminal_ansi_white: Option<String>,
439
440 /// Bright white ANSI terminal color.
441 #[serde(rename = "terminal.ansi.bright_white")]
442 pub terminal_ansi_bright_white: Option<String>,
443
444 /// Dim white ANSI terminal color.
445 #[serde(rename = "terminal.ansi.dim_white")]
446 pub terminal_ansi_dim_white: Option<String>,
447
448 #[serde(rename = "link_text.hover")]
449 pub link_text_hover: Option<String>,
450}
451
452impl ThemeColorsContent {
453 /// Returns a [`ThemeColorsRefinement`] based on the colors in the [`ThemeColorsContent`].
454 pub fn theme_colors_refinement(&self) -> ThemeColorsRefinement {
455 ThemeColorsRefinement {
456 border: self
457 .border
458 .as_ref()
459 .and_then(|color| try_parse_color(&color).ok()),
460 border_variant: self
461 .border_variant
462 .as_ref()
463 .and_then(|color| try_parse_color(&color).ok()),
464 border_focused: self
465 .border_focused
466 .as_ref()
467 .and_then(|color| try_parse_color(&color).ok()),
468 border_selected: self
469 .border_selected
470 .as_ref()
471 .and_then(|color| try_parse_color(&color).ok()),
472 border_transparent: self
473 .border_transparent
474 .as_ref()
475 .and_then(|color| try_parse_color(&color).ok()),
476 border_disabled: self
477 .border_disabled
478 .as_ref()
479 .and_then(|color| try_parse_color(&color).ok()),
480 elevated_surface_background: self
481 .elevated_surface_background
482 .as_ref()
483 .and_then(|color| try_parse_color(&color).ok()),
484 surface_background: self
485 .surface_background
486 .as_ref()
487 .and_then(|color| try_parse_color(&color).ok()),
488 background: self
489 .background
490 .as_ref()
491 .and_then(|color| try_parse_color(&color).ok()),
492 element_background: self
493 .element_background
494 .as_ref()
495 .and_then(|color| try_parse_color(&color).ok()),
496 element_hover: self
497 .element_hover
498 .as_ref()
499 .and_then(|color| try_parse_color(&color).ok()),
500 element_active: self
501 .element_active
502 .as_ref()
503 .and_then(|color| try_parse_color(&color).ok()),
504 element_selected: self
505 .element_selected
506 .as_ref()
507 .and_then(|color| try_parse_color(&color).ok()),
508 element_disabled: self
509 .element_disabled
510 .as_ref()
511 .and_then(|color| try_parse_color(&color).ok()),
512 drop_target_background: self
513 .drop_target_background
514 .as_ref()
515 .and_then(|color| try_parse_color(&color).ok()),
516 ghost_element_background: self
517 .ghost_element_background
518 .as_ref()
519 .and_then(|color| try_parse_color(&color).ok()),
520 ghost_element_hover: self
521 .ghost_element_hover
522 .as_ref()
523 .and_then(|color| try_parse_color(&color).ok()),
524 ghost_element_active: self
525 .ghost_element_active
526 .as_ref()
527 .and_then(|color| try_parse_color(&color).ok()),
528 ghost_element_selected: self
529 .ghost_element_selected
530 .as_ref()
531 .and_then(|color| try_parse_color(&color).ok()),
532 ghost_element_disabled: self
533 .ghost_element_disabled
534 .as_ref()
535 .and_then(|color| try_parse_color(&color).ok()),
536 text: self
537 .text
538 .as_ref()
539 .and_then(|color| try_parse_color(&color).ok()),
540 text_muted: self
541 .text_muted
542 .as_ref()
543 .and_then(|color| try_parse_color(&color).ok()),
544 text_placeholder: self
545 .text_placeholder
546 .as_ref()
547 .and_then(|color| try_parse_color(&color).ok()),
548 text_disabled: self
549 .text_disabled
550 .as_ref()
551 .and_then(|color| try_parse_color(&color).ok()),
552 text_accent: self
553 .text_accent
554 .as_ref()
555 .and_then(|color| try_parse_color(&color).ok()),
556 icon: self
557 .icon
558 .as_ref()
559 .and_then(|color| try_parse_color(&color).ok()),
560 icon_muted: self
561 .icon_muted
562 .as_ref()
563 .and_then(|color| try_parse_color(&color).ok()),
564 icon_disabled: self
565 .icon_disabled
566 .as_ref()
567 .and_then(|color| try_parse_color(&color).ok()),
568 icon_placeholder: self
569 .icon_placeholder
570 .as_ref()
571 .and_then(|color| try_parse_color(&color).ok()),
572 icon_accent: self
573 .icon_accent
574 .as_ref()
575 .and_then(|color| try_parse_color(&color).ok()),
576 status_bar_background: self
577 .status_bar_background
578 .as_ref()
579 .and_then(|color| try_parse_color(&color).ok()),
580 title_bar_background: self
581 .title_bar_background
582 .as_ref()
583 .and_then(|color| try_parse_color(&color).ok()),
584 toolbar_background: self
585 .toolbar_background
586 .as_ref()
587 .and_then(|color| try_parse_color(&color).ok()),
588 tab_bar_background: self
589 .tab_bar_background
590 .as_ref()
591 .and_then(|color| try_parse_color(&color).ok()),
592 tab_inactive_background: self
593 .tab_inactive_background
594 .as_ref()
595 .and_then(|color| try_parse_color(&color).ok()),
596 tab_active_background: self
597 .tab_active_background
598 .as_ref()
599 .and_then(|color| try_parse_color(&color).ok()),
600 search_match_background: self
601 .search_match_background
602 .as_ref()
603 .and_then(|color| try_parse_color(&color).ok()),
604 panel_background: self
605 .panel_background
606 .as_ref()
607 .and_then(|color| try_parse_color(&color).ok()),
608 panel_focused_border: self
609 .panel_focused_border
610 .as_ref()
611 .and_then(|color| try_parse_color(&color).ok()),
612 pane_focused_border: self
613 .pane_focused_border
614 .as_ref()
615 .and_then(|color| try_parse_color(&color).ok()),
616 scrollbar_thumb_background: self
617 .scrollbar_thumb_background
618 .as_ref()
619 .and_then(|color| try_parse_color(&color).ok()),
620 scrollbar_thumb_hover_background: self
621 .scrollbar_thumb_hover_background
622 .as_ref()
623 .and_then(|color| try_parse_color(&color).ok()),
624 scrollbar_thumb_border: self
625 .scrollbar_thumb_border
626 .as_ref()
627 .and_then(|color| try_parse_color(&color).ok()),
628 scrollbar_track_background: self
629 .scrollbar_track_background
630 .as_ref()
631 .and_then(|color| try_parse_color(&color).ok()),
632 scrollbar_track_border: self
633 .scrollbar_track_border
634 .as_ref()
635 .and_then(|color| try_parse_color(&color).ok()),
636 editor_foreground: self
637 .editor_foreground
638 .as_ref()
639 .and_then(|color| try_parse_color(&color).ok()),
640 editor_background: self
641 .editor_background
642 .as_ref()
643 .and_then(|color| try_parse_color(&color).ok()),
644 editor_gutter_background: self
645 .editor_gutter_background
646 .as_ref()
647 .and_then(|color| try_parse_color(&color).ok()),
648 editor_subheader_background: self
649 .editor_subheader_background
650 .as_ref()
651 .and_then(|color| try_parse_color(&color).ok()),
652 editor_active_line_background: self
653 .editor_active_line_background
654 .as_ref()
655 .and_then(|color| try_parse_color(&color).ok()),
656 editor_highlighted_line_background: self
657 .editor_highlighted_line_background
658 .as_ref()
659 .and_then(|color| try_parse_color(&color).ok()),
660 editor_line_number: self
661 .editor_line_number
662 .as_ref()
663 .and_then(|color| try_parse_color(&color).ok()),
664 editor_active_line_number: self
665 .editor_active_line_number
666 .as_ref()
667 .and_then(|color| try_parse_color(&color).ok()),
668 editor_invisible: self
669 .editor_invisible
670 .as_ref()
671 .and_then(|color| try_parse_color(&color).ok()),
672 editor_wrap_guide: self
673 .editor_wrap_guide
674 .as_ref()
675 .and_then(|color| try_parse_color(&color).ok()),
676 editor_active_wrap_guide: self
677 .editor_active_wrap_guide
678 .as_ref()
679 .and_then(|color| try_parse_color(&color).ok()),
680 editor_document_highlight_read_background: self
681 .editor_document_highlight_read_background
682 .as_ref()
683 .and_then(|color| try_parse_color(&color).ok()),
684 editor_document_highlight_write_background: self
685 .editor_document_highlight_write_background
686 .as_ref()
687 .and_then(|color| try_parse_color(&color).ok()),
688 terminal_background: self
689 .terminal_background
690 .as_ref()
691 .and_then(|color| try_parse_color(&color).ok()),
692 terminal_foreground: self
693 .terminal_foreground
694 .as_ref()
695 .and_then(|color| try_parse_color(&color).ok()),
696 terminal_bright_foreground: self
697 .terminal_bright_foreground
698 .as_ref()
699 .and_then(|color| try_parse_color(&color).ok()),
700 terminal_dim_foreground: self
701 .terminal_dim_foreground
702 .as_ref()
703 .and_then(|color| try_parse_color(&color).ok()),
704 terminal_ansi_black: self
705 .terminal_ansi_black
706 .as_ref()
707 .and_then(|color| try_parse_color(&color).ok()),
708 terminal_ansi_bright_black: self
709 .terminal_ansi_bright_black
710 .as_ref()
711 .and_then(|color| try_parse_color(&color).ok()),
712 terminal_ansi_dim_black: self
713 .terminal_ansi_dim_black
714 .as_ref()
715 .and_then(|color| try_parse_color(&color).ok()),
716 terminal_ansi_red: self
717 .terminal_ansi_red
718 .as_ref()
719 .and_then(|color| try_parse_color(&color).ok()),
720 terminal_ansi_bright_red: self
721 .terminal_ansi_bright_red
722 .as_ref()
723 .and_then(|color| try_parse_color(&color).ok()),
724 terminal_ansi_dim_red: self
725 .terminal_ansi_dim_red
726 .as_ref()
727 .and_then(|color| try_parse_color(&color).ok()),
728 terminal_ansi_green: self
729 .terminal_ansi_green
730 .as_ref()
731 .and_then(|color| try_parse_color(&color).ok()),
732 terminal_ansi_bright_green: self
733 .terminal_ansi_bright_green
734 .as_ref()
735 .and_then(|color| try_parse_color(&color).ok()),
736 terminal_ansi_dim_green: self
737 .terminal_ansi_dim_green
738 .as_ref()
739 .and_then(|color| try_parse_color(&color).ok()),
740 terminal_ansi_yellow: self
741 .terminal_ansi_yellow
742 .as_ref()
743 .and_then(|color| try_parse_color(&color).ok()),
744 terminal_ansi_bright_yellow: self
745 .terminal_ansi_bright_yellow
746 .as_ref()
747 .and_then(|color| try_parse_color(&color).ok()),
748 terminal_ansi_dim_yellow: self
749 .terminal_ansi_dim_yellow
750 .as_ref()
751 .and_then(|color| try_parse_color(&color).ok()),
752 terminal_ansi_blue: self
753 .terminal_ansi_blue
754 .as_ref()
755 .and_then(|color| try_parse_color(&color).ok()),
756 terminal_ansi_bright_blue: self
757 .terminal_ansi_bright_blue
758 .as_ref()
759 .and_then(|color| try_parse_color(&color).ok()),
760 terminal_ansi_dim_blue: self
761 .terminal_ansi_dim_blue
762 .as_ref()
763 .and_then(|color| try_parse_color(&color).ok()),
764 terminal_ansi_magenta: self
765 .terminal_ansi_magenta
766 .as_ref()
767 .and_then(|color| try_parse_color(&color).ok()),
768 terminal_ansi_bright_magenta: self
769 .terminal_ansi_bright_magenta
770 .as_ref()
771 .and_then(|color| try_parse_color(&color).ok()),
772 terminal_ansi_dim_magenta: self
773 .terminal_ansi_dim_magenta
774 .as_ref()
775 .and_then(|color| try_parse_color(&color).ok()),
776 terminal_ansi_cyan: self
777 .terminal_ansi_cyan
778 .as_ref()
779 .and_then(|color| try_parse_color(&color).ok()),
780 terminal_ansi_bright_cyan: self
781 .terminal_ansi_bright_cyan
782 .as_ref()
783 .and_then(|color| try_parse_color(&color).ok()),
784 terminal_ansi_dim_cyan: self
785 .terminal_ansi_dim_cyan
786 .as_ref()
787 .and_then(|color| try_parse_color(&color).ok()),
788 terminal_ansi_white: self
789 .terminal_ansi_white
790 .as_ref()
791 .and_then(|color| try_parse_color(&color).ok()),
792 terminal_ansi_bright_white: self
793 .terminal_ansi_bright_white
794 .as_ref()
795 .and_then(|color| try_parse_color(&color).ok()),
796 terminal_ansi_dim_white: self
797 .terminal_ansi_dim_white
798 .as_ref()
799 .and_then(|color| try_parse_color(&color).ok()),
800 link_text_hover: self
801 .link_text_hover
802 .as_ref()
803 .and_then(|color| try_parse_color(&color).ok()),
804 }
805 }
806}
807
808#[derive(Debug, Clone, Default, Serialize, Deserialize, JsonSchema)]
809#[serde(default)]
810pub struct StatusColorsContent {
811 /// Indicates some kind of conflict, like a file changed on disk while it was open, or
812 /// merge conflicts in a Git repository.
813 #[serde(rename = "conflict")]
814 pub conflict: Option<String>,
815
816 #[serde(rename = "conflict.background")]
817 pub conflict_background: Option<String>,
818
819 #[serde(rename = "conflict.border")]
820 pub conflict_border: Option<String>,
821
822 /// Indicates something new, like a new file added to a Git repository.
823 #[serde(rename = "created")]
824 pub created: Option<String>,
825
826 #[serde(rename = "created.background")]
827 pub created_background: Option<String>,
828
829 #[serde(rename = "created.border")]
830 pub created_border: Option<String>,
831
832 /// Indicates that something no longer exists, like a deleted file.
833 #[serde(rename = "deleted")]
834 pub deleted: Option<String>,
835
836 #[serde(rename = "deleted.background")]
837 pub deleted_background: Option<String>,
838
839 #[serde(rename = "deleted.border")]
840 pub deleted_border: Option<String>,
841
842 /// Indicates a system error, a failed operation or a diagnostic error.
843 #[serde(rename = "error")]
844 pub error: Option<String>,
845
846 #[serde(rename = "error.background")]
847 pub error_background: Option<String>,
848
849 #[serde(rename = "error.border")]
850 pub error_border: Option<String>,
851
852 /// Represents a hidden status, such as a file being hidden in a file tree.
853 #[serde(rename = "hidden")]
854 pub hidden: Option<String>,
855
856 #[serde(rename = "hidden.background")]
857 pub hidden_background: Option<String>,
858
859 #[serde(rename = "hidden.border")]
860 pub hidden_border: Option<String>,
861
862 /// Indicates a hint or some kind of additional information.
863 #[serde(rename = "hint")]
864 pub hint: Option<String>,
865
866 #[serde(rename = "hint.background")]
867 pub hint_background: Option<String>,
868
869 #[serde(rename = "hint.border")]
870 pub hint_border: Option<String>,
871
872 /// Indicates that something is deliberately ignored, such as a file or operation ignored by Git.
873 #[serde(rename = "ignored")]
874 pub ignored: Option<String>,
875
876 #[serde(rename = "ignored.background")]
877 pub ignored_background: Option<String>,
878
879 #[serde(rename = "ignored.border")]
880 pub ignored_border: Option<String>,
881
882 /// Represents informational status updates or messages.
883 #[serde(rename = "info")]
884 pub info: Option<String>,
885
886 #[serde(rename = "info.background")]
887 pub info_background: Option<String>,
888
889 #[serde(rename = "info.border")]
890 pub info_border: Option<String>,
891
892 /// Indicates a changed or altered status, like a file that has been edited.
893 #[serde(rename = "modified")]
894 pub modified: Option<String>,
895
896 #[serde(rename = "modified.background")]
897 pub modified_background: Option<String>,
898
899 #[serde(rename = "modified.border")]
900 pub modified_border: Option<String>,
901
902 /// Indicates something that is predicted, like automatic code completion, or generated code.
903 #[serde(rename = "predictive")]
904 pub predictive: Option<String>,
905
906 #[serde(rename = "predictive.background")]
907 pub predictive_background: Option<String>,
908
909 #[serde(rename = "predictive.border")]
910 pub predictive_border: Option<String>,
911
912 /// Represents a renamed status, such as a file that has been renamed.
913 #[serde(rename = "renamed")]
914 pub renamed: Option<String>,
915
916 #[serde(rename = "renamed.background")]
917 pub renamed_background: Option<String>,
918
919 #[serde(rename = "renamed.border")]
920 pub renamed_border: Option<String>,
921
922 /// Indicates a successful operation or task completion.
923 #[serde(rename = "success")]
924 pub success: Option<String>,
925
926 #[serde(rename = "success.background")]
927 pub success_background: Option<String>,
928
929 #[serde(rename = "success.border")]
930 pub success_border: Option<String>,
931
932 /// Indicates some kind of unreachable status, like a block of code that can never be reached.
933 #[serde(rename = "unreachable")]
934 pub unreachable: Option<String>,
935
936 #[serde(rename = "unreachable.background")]
937 pub unreachable_background: Option<String>,
938
939 #[serde(rename = "unreachable.border")]
940 pub unreachable_border: Option<String>,
941
942 /// Represents a warning status, like an operation that is about to fail.
943 #[serde(rename = "warning")]
944 pub warning: Option<String>,
945
946 #[serde(rename = "warning.background")]
947 pub warning_background: Option<String>,
948
949 #[serde(rename = "warning.border")]
950 pub warning_border: Option<String>,
951}
952
953impl StatusColorsContent {
954 /// Returns a [`StatusColorsRefinement`] based on the colors in the [`StatusColorsContent`].
955 pub fn status_colors_refinement(&self) -> StatusColorsRefinement {
956 StatusColorsRefinement {
957 conflict: self
958 .conflict
959 .as_ref()
960 .and_then(|color| try_parse_color(&color).ok()),
961 conflict_background: self
962 .conflict_background
963 .as_ref()
964 .and_then(|color| try_parse_color(&color).ok()),
965 conflict_border: self
966 .conflict_border
967 .as_ref()
968 .and_then(|color| try_parse_color(&color).ok()),
969 created: self
970 .created
971 .as_ref()
972 .and_then(|color| try_parse_color(&color).ok()),
973 created_background: self
974 .created_background
975 .as_ref()
976 .and_then(|color| try_parse_color(&color).ok()),
977 created_border: self
978 .created_border
979 .as_ref()
980 .and_then(|color| try_parse_color(&color).ok()),
981 deleted: self
982 .deleted
983 .as_ref()
984 .and_then(|color| try_parse_color(&color).ok()),
985 deleted_background: self
986 .deleted_background
987 .as_ref()
988 .and_then(|color| try_parse_color(&color).ok()),
989 deleted_border: self
990 .deleted_border
991 .as_ref()
992 .and_then(|color| try_parse_color(&color).ok()),
993 error: self
994 .error
995 .as_ref()
996 .and_then(|color| try_parse_color(&color).ok()),
997 error_background: self
998 .error_background
999 .as_ref()
1000 .and_then(|color| try_parse_color(&color).ok()),
1001 error_border: self
1002 .error_border
1003 .as_ref()
1004 .and_then(|color| try_parse_color(&color).ok()),
1005 hidden: self
1006 .hidden
1007 .as_ref()
1008 .and_then(|color| try_parse_color(&color).ok()),
1009 hidden_background: self
1010 .hidden_background
1011 .as_ref()
1012 .and_then(|color| try_parse_color(&color).ok()),
1013 hidden_border: self
1014 .hidden_border
1015 .as_ref()
1016 .and_then(|color| try_parse_color(&color).ok()),
1017 hint: self
1018 .hint
1019 .as_ref()
1020 .and_then(|color| try_parse_color(&color).ok()),
1021 hint_background: self
1022 .hint_background
1023 .as_ref()
1024 .and_then(|color| try_parse_color(&color).ok()),
1025 hint_border: self
1026 .hint_border
1027 .as_ref()
1028 .and_then(|color| try_parse_color(&color).ok()),
1029 ignored: self
1030 .ignored
1031 .as_ref()
1032 .and_then(|color| try_parse_color(&color).ok()),
1033 ignored_background: self
1034 .ignored_background
1035 .as_ref()
1036 .and_then(|color| try_parse_color(&color).ok()),
1037 ignored_border: self
1038 .ignored_border
1039 .as_ref()
1040 .and_then(|color| try_parse_color(&color).ok()),
1041 info: self
1042 .info
1043 .as_ref()
1044 .and_then(|color| try_parse_color(&color).ok()),
1045 info_background: self
1046 .info_background
1047 .as_ref()
1048 .and_then(|color| try_parse_color(&color).ok()),
1049 info_border: self
1050 .info_border
1051 .as_ref()
1052 .and_then(|color| try_parse_color(&color).ok()),
1053 modified: self
1054 .modified
1055 .as_ref()
1056 .and_then(|color| try_parse_color(&color).ok()),
1057 modified_background: self
1058 .modified_background
1059 .as_ref()
1060 .and_then(|color| try_parse_color(&color).ok()),
1061 modified_border: self
1062 .modified_border
1063 .as_ref()
1064 .and_then(|color| try_parse_color(&color).ok()),
1065 predictive: self
1066 .predictive
1067 .as_ref()
1068 .and_then(|color| try_parse_color(&color).ok()),
1069 predictive_background: self
1070 .predictive_background
1071 .as_ref()
1072 .and_then(|color| try_parse_color(&color).ok()),
1073 predictive_border: self
1074 .predictive_border
1075 .as_ref()
1076 .and_then(|color| try_parse_color(&color).ok()),
1077 renamed: self
1078 .renamed
1079 .as_ref()
1080 .and_then(|color| try_parse_color(&color).ok()),
1081 renamed_background: self
1082 .renamed_background
1083 .as_ref()
1084 .and_then(|color| try_parse_color(&color).ok()),
1085 renamed_border: self
1086 .renamed_border
1087 .as_ref()
1088 .and_then(|color| try_parse_color(&color).ok()),
1089 success: self
1090 .success
1091 .as_ref()
1092 .and_then(|color| try_parse_color(&color).ok()),
1093 success_background: self
1094 .success_background
1095 .as_ref()
1096 .and_then(|color| try_parse_color(&color).ok()),
1097 success_border: self
1098 .success_border
1099 .as_ref()
1100 .and_then(|color| try_parse_color(&color).ok()),
1101 unreachable: self
1102 .unreachable
1103 .as_ref()
1104 .and_then(|color| try_parse_color(&color).ok()),
1105 unreachable_background: self
1106 .unreachable_background
1107 .as_ref()
1108 .and_then(|color| try_parse_color(&color).ok()),
1109 unreachable_border: self
1110 .unreachable_border
1111 .as_ref()
1112 .and_then(|color| try_parse_color(&color).ok()),
1113 warning: self
1114 .warning
1115 .as_ref()
1116 .and_then(|color| try_parse_color(&color).ok()),
1117 warning_background: self
1118 .warning_background
1119 .as_ref()
1120 .and_then(|color| try_parse_color(&color).ok()),
1121 warning_border: self
1122 .warning_border
1123 .as_ref()
1124 .and_then(|color| try_parse_color(&color).ok()),
1125 }
1126 }
1127}
1128
1129#[derive(Debug, Clone, Default, Serialize, Deserialize, JsonSchema)]
1130#[serde(default)]
1131pub struct HighlightStyleContent {
1132 pub color: Option<String>,
1133}