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