schema.rs

  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}