1#![allow(missing_docs)]
2
3use gpui::{FontStyle, FontWeight, HighlightStyle, Hsla, WindowBackgroundAppearance};
4use indexmap::IndexMap;
5use palette::FromColor;
6use schemars::{JsonSchema, JsonSchema_repr};
7use serde::{Deserialize, Serialize};
8use serde_repr::{Deserialize_repr, Serialize_repr};
9use settings::{AccentContent, PlayerColorContent};
10
11use crate::{StatusColorsRefinement, ThemeColorsRefinement};
12
13fn ensure_non_opaque(color: Hsla) -> Hsla {
14 const MAXIMUM_OPACITY: f32 = 0.7;
15 if color.a <= MAXIMUM_OPACITY {
16 color
17 } else {
18 Hsla {
19 a: MAXIMUM_OPACITY,
20 ..color
21 }
22 }
23}
24
25fn ensure_opaque(color: Hsla) -> Hsla {
26 Hsla { a: 1.0, ..color }
27}
28
29#[derive(Debug, PartialEq, Clone, Copy, Serialize, Deserialize, JsonSchema)]
30#[serde(rename_all = "snake_case")]
31pub enum AppearanceContent {
32 Light,
33 Dark,
34}
35
36/// The background appearance of the window.
37#[derive(Debug, PartialEq, Clone, Copy, Serialize, Deserialize, JsonSchema)]
38#[serde(rename_all = "snake_case")]
39pub enum WindowBackgroundContent {
40 Opaque,
41 Transparent,
42 Blurred,
43}
44
45impl From<WindowBackgroundContent> for WindowBackgroundAppearance {
46 fn from(value: WindowBackgroundContent) -> Self {
47 match value {
48 WindowBackgroundContent::Opaque => WindowBackgroundAppearance::Opaque,
49 WindowBackgroundContent::Transparent => WindowBackgroundAppearance::Transparent,
50 WindowBackgroundContent::Blurred => WindowBackgroundAppearance::Blurred,
51 }
52 }
53}
54
55/// The content of a serialized theme family.
56#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
57pub struct ThemeFamilyContent {
58 pub name: String,
59 pub author: String,
60 pub themes: Vec<ThemeContent>,
61}
62
63/// The content of a serialized theme.
64#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
65pub struct ThemeContent {
66 pub name: String,
67 pub appearance: AppearanceContent,
68 pub style: settings::ThemeStyleContent,
69}
70
71/// The content of a serialized theme.
72#[derive(Debug, Clone, Default, Serialize, Deserialize, JsonSchema, PartialEq)]
73#[serde(default)]
74pub struct ThemeStyleContent {
75 #[serde(default, rename = "background.appearance")]
76 pub window_background_appearance: Option<WindowBackgroundContent>,
77
78 #[serde(default)]
79 pub accents: Vec<AccentContent>,
80
81 #[serde(flatten, default)]
82 pub colors: settings::ThemeColorsContent,
83
84 #[serde(flatten, default)]
85 pub status: settings::StatusColorsContent,
86
87 #[serde(default)]
88 pub players: Vec<PlayerColorContent>,
89
90 /// The styles for syntax nodes.
91 #[serde(default)]
92 pub syntax: IndexMap<String, settings::HighlightStyleContent>,
93}
94
95/// Returns the syntax style overrides in the [`ThemeContent`].
96pub fn syntax_overrides(this: &settings::ThemeStyleContent) -> Vec<(String, HighlightStyle)> {
97 this.syntax
98 .iter()
99 .map(|(key, style)| {
100 (
101 key.clone(),
102 HighlightStyle {
103 color: style
104 .color
105 .as_ref()
106 .and_then(|color| try_parse_color(color).ok()),
107 background_color: style
108 .background_color
109 .as_ref()
110 .and_then(|color| try_parse_color(color).ok()),
111 font_style: style.font_style.map(FontStyle::from),
112 font_weight: style.font_weight.map(FontWeight::from),
113 ..Default::default()
114 },
115 )
116 })
117 .collect()
118}
119
120pub fn status_colors_refinement(colors: &settings::StatusColorsContent) -> StatusColorsRefinement {
121 StatusColorsRefinement {
122 conflict: colors
123 .conflict
124 .as_ref()
125 .and_then(|color| try_parse_color(color).ok()),
126 conflict_background: colors
127 .conflict_background
128 .as_ref()
129 .and_then(|color| try_parse_color(color).ok()),
130 conflict_border: colors
131 .conflict_border
132 .as_ref()
133 .and_then(|color| try_parse_color(color).ok()),
134 created: colors
135 .created
136 .as_ref()
137 .and_then(|color| try_parse_color(color).ok()),
138 created_background: colors
139 .created_background
140 .as_ref()
141 .and_then(|color| try_parse_color(color).ok()),
142 created_border: colors
143 .created_border
144 .as_ref()
145 .and_then(|color| try_parse_color(color).ok()),
146 deleted: colors
147 .deleted
148 .as_ref()
149 .and_then(|color| try_parse_color(color).ok()),
150 deleted_background: colors
151 .deleted_background
152 .as_ref()
153 .and_then(|color| try_parse_color(color).ok()),
154 deleted_border: colors
155 .deleted_border
156 .as_ref()
157 .and_then(|color| try_parse_color(color).ok()),
158 error: colors
159 .error
160 .as_ref()
161 .and_then(|color| try_parse_color(color).ok()),
162 error_background: colors
163 .error_background
164 .as_ref()
165 .and_then(|color| try_parse_color(color).ok()),
166 error_border: colors
167 .error_border
168 .as_ref()
169 .and_then(|color| try_parse_color(color).ok()),
170 hidden: colors
171 .hidden
172 .as_ref()
173 .and_then(|color| try_parse_color(color).ok()),
174 hidden_background: colors
175 .hidden_background
176 .as_ref()
177 .and_then(|color| try_parse_color(color).ok()),
178 hidden_border: colors
179 .hidden_border
180 .as_ref()
181 .and_then(|color| try_parse_color(color).ok()),
182 hint: colors
183 .hint
184 .as_ref()
185 .and_then(|color| try_parse_color(color).ok()),
186 hint_background: colors
187 .hint_background
188 .as_ref()
189 .and_then(|color| try_parse_color(color).ok()),
190 hint_border: colors
191 .hint_border
192 .as_ref()
193 .and_then(|color| try_parse_color(color).ok()),
194 ignored: colors
195 .ignored
196 .as_ref()
197 .and_then(|color| try_parse_color(color).ok()),
198 ignored_background: colors
199 .ignored_background
200 .as_ref()
201 .and_then(|color| try_parse_color(color).ok()),
202 ignored_border: colors
203 .ignored_border
204 .as_ref()
205 .and_then(|color| try_parse_color(color).ok()),
206 info: colors
207 .info
208 .as_ref()
209 .and_then(|color| try_parse_color(color).ok()),
210 info_background: colors
211 .info_background
212 .as_ref()
213 .and_then(|color| try_parse_color(color).ok()),
214 info_border: colors
215 .info_border
216 .as_ref()
217 .and_then(|color| try_parse_color(color).ok()),
218 modified: colors
219 .modified
220 .as_ref()
221 .and_then(|color| try_parse_color(color).ok()),
222 modified_background: colors
223 .modified_background
224 .as_ref()
225 .and_then(|color| try_parse_color(color).ok()),
226 modified_border: colors
227 .modified_border
228 .as_ref()
229 .and_then(|color| try_parse_color(color).ok()),
230 predictive: colors
231 .predictive
232 .as_ref()
233 .and_then(|color| try_parse_color(color).ok()),
234 predictive_background: colors
235 .predictive_background
236 .as_ref()
237 .and_then(|color| try_parse_color(color).ok()),
238 predictive_border: colors
239 .predictive_border
240 .as_ref()
241 .and_then(|color| try_parse_color(color).ok()),
242 renamed: colors
243 .renamed
244 .as_ref()
245 .and_then(|color| try_parse_color(color).ok()),
246 renamed_background: colors
247 .renamed_background
248 .as_ref()
249 .and_then(|color| try_parse_color(color).ok()),
250 renamed_border: colors
251 .renamed_border
252 .as_ref()
253 .and_then(|color| try_parse_color(color).ok()),
254 success: colors
255 .success
256 .as_ref()
257 .and_then(|color| try_parse_color(color).ok()),
258 success_background: colors
259 .success_background
260 .as_ref()
261 .and_then(|color| try_parse_color(color).ok()),
262 success_border: colors
263 .success_border
264 .as_ref()
265 .and_then(|color| try_parse_color(color).ok()),
266 unreachable: colors
267 .unreachable
268 .as_ref()
269 .and_then(|color| try_parse_color(color).ok()),
270 unreachable_background: colors
271 .unreachable_background
272 .as_ref()
273 .and_then(|color| try_parse_color(color).ok()),
274 unreachable_border: colors
275 .unreachable_border
276 .as_ref()
277 .and_then(|color| try_parse_color(color).ok()),
278 warning: colors
279 .warning
280 .as_ref()
281 .and_then(|color| try_parse_color(color).ok()),
282 warning_background: colors
283 .warning_background
284 .as_ref()
285 .and_then(|color| try_parse_color(color).ok()),
286 warning_border: colors
287 .warning_border
288 .as_ref()
289 .and_then(|color| try_parse_color(color).ok()),
290 }
291}
292
293#[derive(Debug, Clone, Copy, Serialize_repr, Deserialize_repr, JsonSchema_repr, PartialEq)]
294#[repr(u16)]
295pub enum FontWeightContent {
296 Thin = 100,
297 ExtraLight = 200,
298 Light = 300,
299 Normal = 400,
300 Medium = 500,
301 Semibold = 600,
302 Bold = 700,
303 ExtraBold = 800,
304 Black = 900,
305}
306
307pub fn theme_colors_refinement(
308 this: &settings::ThemeColorsContent,
309 status_colors: &StatusColorsRefinement,
310) -> ThemeColorsRefinement {
311 let border = this
312 .border
313 .as_ref()
314 .and_then(|color| try_parse_color(color).ok());
315 let editor_document_highlight_read_background = this
316 .editor_document_highlight_read_background
317 .as_ref()
318 .and_then(|color| try_parse_color(color).ok());
319 let scrollbar_thumb_background = this
320 .scrollbar_thumb_background
321 .as_ref()
322 .and_then(|color| try_parse_color(color).ok())
323 .or_else(|| {
324 this.deprecated_scrollbar_thumb_background
325 .as_ref()
326 .and_then(|color| try_parse_color(color).ok())
327 });
328 let scrollbar_thumb_hover_background = this
329 .scrollbar_thumb_hover_background
330 .as_ref()
331 .and_then(|color| try_parse_color(color).ok());
332 let scrollbar_thumb_active_background = this
333 .scrollbar_thumb_active_background
334 .as_ref()
335 .and_then(|color| try_parse_color(color).ok())
336 .or(scrollbar_thumb_background);
337 let scrollbar_thumb_border = this
338 .scrollbar_thumb_border
339 .as_ref()
340 .and_then(|color| try_parse_color(color).ok());
341 let element_hover = this
342 .element_hover
343 .as_ref()
344 .and_then(|color| try_parse_color(color).ok());
345 let panel_background = this
346 .panel_background
347 .as_ref()
348 .and_then(|color| try_parse_color(color).ok());
349 ThemeColorsRefinement {
350 border,
351 border_variant: this
352 .border_variant
353 .as_ref()
354 .and_then(|color| try_parse_color(color).ok()),
355 border_focused: this
356 .border_focused
357 .as_ref()
358 .and_then(|color| try_parse_color(color).ok()),
359 border_selected: this
360 .border_selected
361 .as_ref()
362 .and_then(|color| try_parse_color(color).ok()),
363 border_transparent: this
364 .border_transparent
365 .as_ref()
366 .and_then(|color| try_parse_color(color).ok()),
367 border_disabled: this
368 .border_disabled
369 .as_ref()
370 .and_then(|color| try_parse_color(color).ok()),
371 elevated_surface_background: this
372 .elevated_surface_background
373 .as_ref()
374 .and_then(|color| try_parse_color(color).ok()),
375 surface_background: this
376 .surface_background
377 .as_ref()
378 .and_then(|color| try_parse_color(color).ok()),
379 background: this
380 .background
381 .as_ref()
382 .and_then(|color| try_parse_color(color).ok()),
383 element_background: this
384 .element_background
385 .as_ref()
386 .and_then(|color| try_parse_color(color).ok()),
387 element_hover,
388 element_active: this
389 .element_active
390 .as_ref()
391 .and_then(|color| try_parse_color(color).ok()),
392 element_selected: this
393 .element_selected
394 .as_ref()
395 .and_then(|color| try_parse_color(color).ok()),
396 element_disabled: this
397 .element_disabled
398 .as_ref()
399 .and_then(|color| try_parse_color(color).ok()),
400 element_selection_background: this
401 .element_selection_background
402 .as_ref()
403 .and_then(|color| try_parse_color(color).ok()),
404 drop_target_background: this
405 .drop_target_background
406 .as_ref()
407 .and_then(|color| try_parse_color(color).ok()),
408 drop_target_border: this
409 .drop_target_border
410 .as_ref()
411 .and_then(|color| try_parse_color(color).ok()),
412 ghost_element_background: this
413 .ghost_element_background
414 .as_ref()
415 .and_then(|color| try_parse_color(color).ok()),
416 ghost_element_hover: this
417 .ghost_element_hover
418 .as_ref()
419 .and_then(|color| try_parse_color(color).ok()),
420 ghost_element_active: this
421 .ghost_element_active
422 .as_ref()
423 .and_then(|color| try_parse_color(color).ok()),
424 ghost_element_selected: this
425 .ghost_element_selected
426 .as_ref()
427 .and_then(|color| try_parse_color(color).ok()),
428 ghost_element_disabled: this
429 .ghost_element_disabled
430 .as_ref()
431 .and_then(|color| try_parse_color(color).ok()),
432 text: this
433 .text
434 .as_ref()
435 .and_then(|color| try_parse_color(color).ok()),
436 text_muted: this
437 .text_muted
438 .as_ref()
439 .and_then(|color| try_parse_color(color).ok()),
440 text_placeholder: this
441 .text_placeholder
442 .as_ref()
443 .and_then(|color| try_parse_color(color).ok()),
444 text_disabled: this
445 .text_disabled
446 .as_ref()
447 .and_then(|color| try_parse_color(color).ok()),
448 text_accent: this
449 .text_accent
450 .as_ref()
451 .and_then(|color| try_parse_color(color).ok()),
452 icon: this
453 .icon
454 .as_ref()
455 .and_then(|color| try_parse_color(color).ok()),
456 icon_muted: this
457 .icon_muted
458 .as_ref()
459 .and_then(|color| try_parse_color(color).ok()),
460 icon_disabled: this
461 .icon_disabled
462 .as_ref()
463 .and_then(|color| try_parse_color(color).ok()),
464 icon_placeholder: this
465 .icon_placeholder
466 .as_ref()
467 .and_then(|color| try_parse_color(color).ok()),
468 icon_accent: this
469 .icon_accent
470 .as_ref()
471 .and_then(|color| try_parse_color(color).ok()),
472 debugger_accent: this
473 .debugger_accent
474 .as_ref()
475 .and_then(|color| try_parse_color(color).ok()),
476 status_bar_background: this
477 .status_bar_background
478 .as_ref()
479 .and_then(|color| try_parse_color(color).ok()),
480 title_bar_background: this
481 .title_bar_background
482 .as_ref()
483 .and_then(|color| try_parse_color(color).ok()),
484 title_bar_inactive_background: this
485 .title_bar_inactive_background
486 .as_ref()
487 .and_then(|color| try_parse_color(color).ok()),
488 toolbar_background: this
489 .toolbar_background
490 .as_ref()
491 .and_then(|color| try_parse_color(color).ok()),
492 tab_bar_background: this
493 .tab_bar_background
494 .as_ref()
495 .and_then(|color| try_parse_color(color).ok()),
496 tab_inactive_background: this
497 .tab_inactive_background
498 .as_ref()
499 .and_then(|color| try_parse_color(color).ok()),
500 tab_active_background: this
501 .tab_active_background
502 .as_ref()
503 .and_then(|color| try_parse_color(color).ok()),
504 search_match_background: this
505 .search_match_background
506 .as_ref()
507 .and_then(|color| try_parse_color(color).ok()),
508 panel_background,
509 panel_focused_border: this
510 .panel_focused_border
511 .as_ref()
512 .and_then(|color| try_parse_color(color).ok()),
513 panel_indent_guide: this
514 .panel_indent_guide
515 .as_ref()
516 .and_then(|color| try_parse_color(color).ok()),
517 panel_indent_guide_hover: this
518 .panel_indent_guide_hover
519 .as_ref()
520 .and_then(|color| try_parse_color(color).ok()),
521 panel_indent_guide_active: this
522 .panel_indent_guide_active
523 .as_ref()
524 .and_then(|color| try_parse_color(color).ok()),
525 panel_overlay_background: this
526 .panel_overlay_background
527 .as_ref()
528 .and_then(|color| try_parse_color(color).ok())
529 .or(panel_background.map(ensure_opaque)),
530 panel_overlay_hover: this
531 .panel_overlay_hover
532 .as_ref()
533 .and_then(|color| try_parse_color(color).ok())
534 .or(panel_background
535 .zip(element_hover)
536 .map(|(panel_bg, hover_bg)| panel_bg.blend(hover_bg))
537 .map(ensure_opaque)),
538 pane_focused_border: this
539 .pane_focused_border
540 .as_ref()
541 .and_then(|color| try_parse_color(color).ok()),
542 pane_group_border: this
543 .pane_group_border
544 .as_ref()
545 .and_then(|color| try_parse_color(color).ok())
546 .or(border),
547 scrollbar_thumb_background,
548 scrollbar_thumb_hover_background,
549 scrollbar_thumb_active_background,
550 scrollbar_thumb_border,
551 scrollbar_track_background: this
552 .scrollbar_track_background
553 .as_ref()
554 .and_then(|color| try_parse_color(color).ok()),
555 scrollbar_track_border: this
556 .scrollbar_track_border
557 .as_ref()
558 .and_then(|color| try_parse_color(color).ok()),
559 minimap_thumb_background: this
560 .minimap_thumb_background
561 .as_ref()
562 .and_then(|color| try_parse_color(color).ok())
563 .or(scrollbar_thumb_background.map(ensure_non_opaque)),
564 minimap_thumb_hover_background: this
565 .minimap_thumb_hover_background
566 .as_ref()
567 .and_then(|color| try_parse_color(color).ok())
568 .or(scrollbar_thumb_hover_background.map(ensure_non_opaque)),
569 minimap_thumb_active_background: this
570 .minimap_thumb_active_background
571 .as_ref()
572 .and_then(|color| try_parse_color(color).ok())
573 .or(scrollbar_thumb_active_background.map(ensure_non_opaque)),
574 minimap_thumb_border: this
575 .minimap_thumb_border
576 .as_ref()
577 .and_then(|color| try_parse_color(color).ok())
578 .or(scrollbar_thumb_border),
579 editor_foreground: this
580 .editor_foreground
581 .as_ref()
582 .and_then(|color| try_parse_color(color).ok()),
583 editor_background: this
584 .editor_background
585 .as_ref()
586 .and_then(|color| try_parse_color(color).ok()),
587 editor_gutter_background: this
588 .editor_gutter_background
589 .as_ref()
590 .and_then(|color| try_parse_color(color).ok()),
591 editor_subheader_background: this
592 .editor_subheader_background
593 .as_ref()
594 .and_then(|color| try_parse_color(color).ok()),
595 editor_active_line_background: this
596 .editor_active_line_background
597 .as_ref()
598 .and_then(|color| try_parse_color(color).ok()),
599 editor_highlighted_line_background: this
600 .editor_highlighted_line_background
601 .as_ref()
602 .and_then(|color| try_parse_color(color).ok()),
603 editor_debugger_active_line_background: this
604 .editor_debugger_active_line_background
605 .as_ref()
606 .and_then(|color| try_parse_color(color).ok()),
607 editor_line_number: this
608 .editor_line_number
609 .as_ref()
610 .and_then(|color| try_parse_color(color).ok()),
611 editor_hover_line_number: this
612 .editor_hover_line_number
613 .as_ref()
614 .and_then(|color| try_parse_color(color).ok()),
615 editor_active_line_number: this
616 .editor_active_line_number
617 .as_ref()
618 .and_then(|color| try_parse_color(color).ok()),
619 editor_invisible: this
620 .editor_invisible
621 .as_ref()
622 .and_then(|color| try_parse_color(color).ok()),
623 editor_wrap_guide: this
624 .editor_wrap_guide
625 .as_ref()
626 .and_then(|color| try_parse_color(color).ok()),
627 editor_active_wrap_guide: this
628 .editor_active_wrap_guide
629 .as_ref()
630 .and_then(|color| try_parse_color(color).ok()),
631 editor_indent_guide: this
632 .editor_indent_guide
633 .as_ref()
634 .and_then(|color| try_parse_color(color).ok()),
635 editor_indent_guide_active: this
636 .editor_indent_guide_active
637 .as_ref()
638 .and_then(|color| try_parse_color(color).ok()),
639 editor_document_highlight_read_background,
640 editor_document_highlight_write_background: this
641 .editor_document_highlight_write_background
642 .as_ref()
643 .and_then(|color| try_parse_color(color).ok()),
644 editor_document_highlight_bracket_background: this
645 .editor_document_highlight_bracket_background
646 .as_ref()
647 .and_then(|color| try_parse_color(color).ok())
648 // Fall back to `editor.document_highlight.read_background`, for backwards compatibility.
649 .or(editor_document_highlight_read_background),
650 terminal_background: this
651 .terminal_background
652 .as_ref()
653 .and_then(|color| try_parse_color(color).ok()),
654 terminal_ansi_background: this
655 .terminal_ansi_background
656 .as_ref()
657 .and_then(|color| try_parse_color(color).ok()),
658 terminal_foreground: this
659 .terminal_foreground
660 .as_ref()
661 .and_then(|color| try_parse_color(color).ok()),
662 terminal_bright_foreground: this
663 .terminal_bright_foreground
664 .as_ref()
665 .and_then(|color| try_parse_color(color).ok()),
666 terminal_dim_foreground: this
667 .terminal_dim_foreground
668 .as_ref()
669 .and_then(|color| try_parse_color(color).ok()),
670 terminal_ansi_black: this
671 .terminal_ansi_black
672 .as_ref()
673 .and_then(|color| try_parse_color(color).ok()),
674 terminal_ansi_bright_black: this
675 .terminal_ansi_bright_black
676 .as_ref()
677 .and_then(|color| try_parse_color(color).ok()),
678 terminal_ansi_dim_black: this
679 .terminal_ansi_dim_black
680 .as_ref()
681 .and_then(|color| try_parse_color(color).ok()),
682 terminal_ansi_red: this
683 .terminal_ansi_red
684 .as_ref()
685 .and_then(|color| try_parse_color(color).ok()),
686 terminal_ansi_bright_red: this
687 .terminal_ansi_bright_red
688 .as_ref()
689 .and_then(|color| try_parse_color(color).ok()),
690 terminal_ansi_dim_red: this
691 .terminal_ansi_dim_red
692 .as_ref()
693 .and_then(|color| try_parse_color(color).ok()),
694 terminal_ansi_green: this
695 .terminal_ansi_green
696 .as_ref()
697 .and_then(|color| try_parse_color(color).ok()),
698 terminal_ansi_bright_green: this
699 .terminal_ansi_bright_green
700 .as_ref()
701 .and_then(|color| try_parse_color(color).ok()),
702 terminal_ansi_dim_green: this
703 .terminal_ansi_dim_green
704 .as_ref()
705 .and_then(|color| try_parse_color(color).ok()),
706 terminal_ansi_yellow: this
707 .terminal_ansi_yellow
708 .as_ref()
709 .and_then(|color| try_parse_color(color).ok()),
710 terminal_ansi_bright_yellow: this
711 .terminal_ansi_bright_yellow
712 .as_ref()
713 .and_then(|color| try_parse_color(color).ok()),
714 terminal_ansi_dim_yellow: this
715 .terminal_ansi_dim_yellow
716 .as_ref()
717 .and_then(|color| try_parse_color(color).ok()),
718 terminal_ansi_blue: this
719 .terminal_ansi_blue
720 .as_ref()
721 .and_then(|color| try_parse_color(color).ok()),
722 terminal_ansi_bright_blue: this
723 .terminal_ansi_bright_blue
724 .as_ref()
725 .and_then(|color| try_parse_color(color).ok()),
726 terminal_ansi_dim_blue: this
727 .terminal_ansi_dim_blue
728 .as_ref()
729 .and_then(|color| try_parse_color(color).ok()),
730 terminal_ansi_magenta: this
731 .terminal_ansi_magenta
732 .as_ref()
733 .and_then(|color| try_parse_color(color).ok()),
734 terminal_ansi_bright_magenta: this
735 .terminal_ansi_bright_magenta
736 .as_ref()
737 .and_then(|color| try_parse_color(color).ok()),
738 terminal_ansi_dim_magenta: this
739 .terminal_ansi_dim_magenta
740 .as_ref()
741 .and_then(|color| try_parse_color(color).ok()),
742 terminal_ansi_cyan: this
743 .terminal_ansi_cyan
744 .as_ref()
745 .and_then(|color| try_parse_color(color).ok()),
746 terminal_ansi_bright_cyan: this
747 .terminal_ansi_bright_cyan
748 .as_ref()
749 .and_then(|color| try_parse_color(color).ok()),
750 terminal_ansi_dim_cyan: this
751 .terminal_ansi_dim_cyan
752 .as_ref()
753 .and_then(|color| try_parse_color(color).ok()),
754 terminal_ansi_white: this
755 .terminal_ansi_white
756 .as_ref()
757 .and_then(|color| try_parse_color(color).ok()),
758 terminal_ansi_bright_white: this
759 .terminal_ansi_bright_white
760 .as_ref()
761 .and_then(|color| try_parse_color(color).ok()),
762 terminal_ansi_dim_white: this
763 .terminal_ansi_dim_white
764 .as_ref()
765 .and_then(|color| try_parse_color(color).ok()),
766 link_text_hover: this
767 .link_text_hover
768 .as_ref()
769 .and_then(|color| try_parse_color(color).ok()),
770 version_control_added: this
771 .version_control_added
772 .as_ref()
773 .and_then(|color| try_parse_color(color).ok())
774 // Fall back to `created`, for backwards compatibility.
775 .or(status_colors.created),
776 version_control_deleted: this
777 .version_control_deleted
778 .as_ref()
779 .and_then(|color| try_parse_color(color).ok())
780 // Fall back to `deleted`, for backwards compatibility.
781 .or(status_colors.deleted),
782 version_control_modified: this
783 .version_control_modified
784 .as_ref()
785 .and_then(|color| try_parse_color(color).ok())
786 // Fall back to `modified`, for backwards compatibility.
787 .or(status_colors.modified),
788 version_control_renamed: this
789 .version_control_renamed
790 .as_ref()
791 .and_then(|color| try_parse_color(color).ok())
792 // Fall back to `modified`, for backwards compatibility.
793 .or(status_colors.modified),
794 version_control_conflict: this
795 .version_control_conflict
796 .as_ref()
797 .and_then(|color| try_parse_color(color).ok())
798 // Fall back to `ignored`, for backwards compatibility.
799 .or(status_colors.ignored),
800 version_control_ignored: this
801 .version_control_ignored
802 .as_ref()
803 .and_then(|color| try_parse_color(color).ok())
804 // Fall back to `conflict`, for backwards compatibility.
805 .or(status_colors.ignored),
806 #[allow(deprecated)]
807 version_control_conflict_marker_ours: this
808 .version_control_conflict_marker_ours
809 .as_ref()
810 .or(this.version_control_conflict_ours_background.as_ref())
811 .and_then(|color| try_parse_color(color).ok()),
812 #[allow(deprecated)]
813 version_control_conflict_marker_theirs: this
814 .version_control_conflict_marker_theirs
815 .as_ref()
816 .or(this.version_control_conflict_theirs_background.as_ref())
817 .and_then(|color| try_parse_color(color).ok()),
818 }
819}
820
821pub(crate) fn try_parse_color(color: &str) -> anyhow::Result<Hsla> {
822 let rgba = gpui::Rgba::try_from(color)?;
823 let rgba = palette::rgb::Srgba::from_components((rgba.r, rgba.g, rgba.b, rgba.a));
824 let hsla = palette::Hsla::from_color(rgba);
825
826 let hsla = gpui::hsla(
827 hsla.hue.into_positive_degrees() / 360.,
828 hsla.saturation,
829 hsla.lightness,
830 hsla.alpha,
831 );
832
833 Ok(hsla)
834}