1mod theme_registry;
2
3use gpui::{
4 color::Color,
5 elements::{ContainerStyle, ImageStyle, LabelStyle, TooltipStyle},
6 fonts::{HighlightStyle, TextStyle},
7 Border, MouseState,
8};
9use serde::{de::DeserializeOwned, Deserialize};
10use serde_json::Value;
11use std::{collections::HashMap, sync::Arc};
12
13pub use theme_registry::*;
14
15#[derive(Deserialize, Default)]
16pub struct Theme {
17 #[serde(default)]
18 pub meta: ThemeMeta,
19 pub workspace: Workspace,
20 pub context_menu: ContextMenu,
21 pub chat_panel: ChatPanel,
22 pub contacts_popover: ContactsPopover,
23 pub contact_list: ContactList,
24 pub contact_finder: ContactFinder,
25 pub project_panel: ProjectPanel,
26 pub command_palette: CommandPalette,
27 pub picker: Picker,
28 pub editor: Editor,
29 pub search: Search,
30 pub project_diagnostics: ProjectDiagnostics,
31 pub breadcrumbs: ContainedText,
32 pub contact_notification: ContactNotification,
33 pub update_notification: UpdateNotification,
34 pub project_shared_notification: ProjectSharedNotification,
35 pub incoming_call_notification: IncomingCallNotification,
36 pub tooltip: TooltipStyle,
37 pub terminal: TerminalStyle,
38}
39
40#[derive(Deserialize, Default, Clone)]
41pub struct ThemeMeta {
42 pub name: String,
43 pub is_light: bool,
44}
45
46#[derive(Deserialize, Default)]
47pub struct Workspace {
48 pub background: Color,
49 pub titlebar: Titlebar,
50 pub tab_bar: TabBar,
51 pub pane_divider: Border,
52 pub leader_border_opacity: f32,
53 pub leader_border_width: f32,
54 pub sidebar: Sidebar,
55 pub status_bar: StatusBar,
56 pub toolbar: Toolbar,
57 pub disconnected_overlay: ContainedText,
58 pub modal: ContainerStyle,
59 pub notification: ContainerStyle,
60 pub notifications: Notifications,
61 pub joining_project_avatar: ImageStyle,
62 pub joining_project_message: ContainedText,
63 pub external_location_message: ContainedText,
64 pub dock: Dock,
65}
66
67#[derive(Clone, Deserialize, Default)]
68pub struct Titlebar {
69 #[serde(flatten)]
70 pub container: ContainerStyle,
71 pub height: f32,
72 pub title: TextStyle,
73 pub avatar_width: f32,
74 pub avatar_margin: f32,
75 pub avatar_ribbon: AvatarRibbon,
76 pub offline_icon: OfflineIcon,
77 pub avatar: ImageStyle,
78 pub inactive_avatar: ImageStyle,
79 pub sign_in_prompt: Interactive<ContainedText>,
80 pub outdated_warning: ContainedText,
81 pub share_button: Interactive<ContainedText>,
82 pub toggle_contacts_button: Interactive<IconButton>,
83 pub toggle_contacts_badge: ContainerStyle,
84}
85
86#[derive(Deserialize, Default)]
87pub struct ContactsPopover {
88 #[serde(flatten)]
89 pub container: ContainerStyle,
90 pub height: f32,
91 pub width: f32,
92}
93
94#[derive(Deserialize, Default)]
95pub struct ContactList {
96 pub user_query_editor: FieldEditor,
97 pub user_query_editor_height: f32,
98 pub add_contact_button: IconButton,
99 pub header_row: Interactive<ContainedText>,
100 pub leave_call: Interactive<ContainedText>,
101 pub contact_row: Interactive<ContainerStyle>,
102 pub row_height: f32,
103 pub project_row: Interactive<ProjectRow>,
104 pub tree_branch: Interactive<TreeBranch>,
105 pub contact_avatar: ImageStyle,
106 pub contact_status_free: ContainerStyle,
107 pub contact_status_busy: ContainerStyle,
108 pub contact_username: ContainedText,
109 pub contact_button: Interactive<IconButton>,
110 pub contact_button_spacing: f32,
111 pub disabled_button: IconButton,
112 pub section_icon_size: f32,
113 pub invite_row: Interactive<ContainedLabel>,
114 pub calling_indicator: ContainedText,
115}
116
117#[derive(Deserialize, Default)]
118pub struct ProjectRow {
119 #[serde(flatten)]
120 pub container: ContainerStyle,
121 pub name: ContainedText,
122}
123
124#[derive(Deserialize, Default, Clone, Copy)]
125pub struct TreeBranch {
126 pub width: f32,
127 pub color: Color,
128}
129
130#[derive(Deserialize, Default)]
131pub struct ContactFinder {
132 pub picker: Picker,
133 pub row_height: f32,
134 pub contact_avatar: ImageStyle,
135 pub contact_username: ContainerStyle,
136 pub contact_button: IconButton,
137 pub disabled_contact_button: IconButton,
138}
139
140#[derive(Clone, Deserialize, Default)]
141pub struct TabBar {
142 #[serde(flatten)]
143 pub container: ContainerStyle,
144 pub pane_button: Interactive<IconButton>,
145 pub pane_button_container: ContainerStyle,
146 pub active_pane: TabStyles,
147 pub inactive_pane: TabStyles,
148 pub dragged_tab: Tab,
149 pub height: f32,
150 pub drop_target_overlay_color: Color,
151}
152
153impl TabBar {
154 pub fn tab_style(&self, pane_active: bool, tab_active: bool) -> &Tab {
155 let tabs = if pane_active {
156 &self.active_pane
157 } else {
158 &self.inactive_pane
159 };
160
161 if tab_active {
162 &tabs.active_tab
163 } else {
164 &tabs.inactive_tab
165 }
166 }
167}
168
169#[derive(Clone, Deserialize, Default)]
170pub struct TabStyles {
171 pub active_tab: Tab,
172 pub inactive_tab: Tab,
173}
174
175#[derive(Clone, Deserialize, Default)]
176pub struct AvatarRibbon {
177 #[serde(flatten)]
178 pub container: ContainerStyle,
179 pub width: f32,
180 pub height: f32,
181}
182
183#[derive(Clone, Deserialize, Default)]
184pub struct OfflineIcon {
185 #[serde(flatten)]
186 pub container: ContainerStyle,
187 pub width: f32,
188 pub color: Color,
189}
190
191#[derive(Clone, Deserialize, Default)]
192pub struct Tab {
193 pub height: f32,
194 #[serde(flatten)]
195 pub container: ContainerStyle,
196 #[serde(flatten)]
197 pub label: LabelStyle,
198 pub description: ContainedText,
199 pub spacing: f32,
200 pub icon_width: f32,
201 pub icon_close: Color,
202 pub icon_close_active: Color,
203 pub icon_dirty: Color,
204 pub icon_conflict: Color,
205}
206
207#[derive(Clone, Deserialize, Default)]
208pub struct Toolbar {
209 #[serde(flatten)]
210 pub container: ContainerStyle,
211 pub height: f32,
212 pub item_spacing: f32,
213 pub nav_button: Interactive<IconButton>,
214}
215
216#[derive(Clone, Deserialize, Default)]
217pub struct Dock {
218 pub initial_size_right: f32,
219 pub initial_size_bottom: f32,
220 pub wash_color: Color,
221 pub panel: ContainerStyle,
222 pub maximized: ContainerStyle,
223}
224
225#[derive(Clone, Deserialize, Default)]
226pub struct Notifications {
227 #[serde(flatten)]
228 pub container: ContainerStyle,
229 pub width: f32,
230}
231
232#[derive(Clone, Deserialize, Default)]
233pub struct Search {
234 #[serde(flatten)]
235 pub container: ContainerStyle,
236 pub editor: FindEditor,
237 pub invalid_editor: ContainerStyle,
238 pub option_button_group: ContainerStyle,
239 pub option_button: Interactive<ContainedText>,
240 pub match_background: Color,
241 pub match_index: ContainedText,
242 pub results_status: TextStyle,
243 pub tab_icon_width: f32,
244 pub tab_icon_spacing: f32,
245}
246
247#[derive(Clone, Deserialize, Default)]
248pub struct FindEditor {
249 #[serde(flatten)]
250 pub input: FieldEditor,
251 pub min_width: f32,
252 pub max_width: f32,
253}
254
255#[derive(Deserialize, Default)]
256pub struct StatusBar {
257 #[serde(flatten)]
258 pub container: ContainerStyle,
259 pub height: f32,
260 pub item_spacing: f32,
261 pub cursor_position: TextStyle,
262 pub auto_update_progress_message: TextStyle,
263 pub auto_update_done_message: TextStyle,
264 pub lsp_status: Interactive<StatusBarLspStatus>,
265 pub feedback: Interactive<TextStyle>,
266 pub sidebar_buttons: StatusBarSidebarButtons,
267 pub diagnostic_summary: Interactive<StatusBarDiagnosticSummary>,
268 pub diagnostic_message: Interactive<ContainedText>,
269}
270
271#[derive(Deserialize, Default)]
272pub struct StatusBarSidebarButtons {
273 pub group_left: ContainerStyle,
274 pub group_right: ContainerStyle,
275 pub item: Interactive<SidebarItem>,
276 pub badge: ContainerStyle,
277}
278
279#[derive(Deserialize, Default)]
280pub struct StatusBarDiagnosticSummary {
281 pub container_ok: ContainerStyle,
282 pub container_warning: ContainerStyle,
283 pub container_error: ContainerStyle,
284 pub text: TextStyle,
285 pub icon_color_ok: Color,
286 pub icon_color_warning: Color,
287 pub icon_color_error: Color,
288 pub height: f32,
289 pub icon_width: f32,
290 pub icon_spacing: f32,
291 pub summary_spacing: f32,
292}
293
294#[derive(Deserialize, Default)]
295pub struct StatusBarLspStatus {
296 #[serde(flatten)]
297 pub container: ContainerStyle,
298 pub height: f32,
299 pub icon_spacing: f32,
300 pub icon_color: Color,
301 pub icon_width: f32,
302 pub message: TextStyle,
303}
304
305#[derive(Deserialize, Default)]
306pub struct Sidebar {
307 pub initial_size: f32,
308 #[serde(flatten)]
309 pub container: ContainerStyle,
310}
311
312#[derive(Clone, Copy, Deserialize, Default)]
313pub struct SidebarItem {
314 #[serde(flatten)]
315 pub container: ContainerStyle,
316 pub icon_color: Color,
317 pub icon_size: f32,
318}
319
320#[derive(Deserialize, Default)]
321pub struct ChatPanel {
322 #[serde(flatten)]
323 pub container: ContainerStyle,
324 pub message: ChatMessage,
325 pub pending_message: ChatMessage,
326 pub channel_select: ChannelSelect,
327 pub input_editor: FieldEditor,
328 pub sign_in_prompt: TextStyle,
329 pub hovered_sign_in_prompt: TextStyle,
330}
331
332#[derive(Deserialize, Default)]
333pub struct ProjectPanel {
334 #[serde(flatten)]
335 pub container: ContainerStyle,
336 pub entry: Interactive<ProjectPanelEntry>,
337 pub cut_entry_fade: f32,
338 pub ignored_entry_fade: f32,
339 pub filename_editor: FieldEditor,
340 pub indent_width: f32,
341}
342
343#[derive(Clone, Debug, Deserialize, Default)]
344pub struct ProjectPanelEntry {
345 pub height: f32,
346 #[serde(flatten)]
347 pub container: ContainerStyle,
348 pub text: TextStyle,
349 pub icon_color: Color,
350 pub icon_size: f32,
351 pub icon_spacing: f32,
352}
353
354#[derive(Clone, Debug, Deserialize, Default)]
355pub struct ContextMenu {
356 #[serde(flatten)]
357 pub container: ContainerStyle,
358 pub item: Interactive<ContextMenuItem>,
359 pub keystroke_margin: f32,
360 pub separator: ContainerStyle,
361}
362
363#[derive(Clone, Debug, Deserialize, Default)]
364pub struct ContextMenuItem {
365 #[serde(flatten)]
366 pub container: ContainerStyle,
367 pub label: TextStyle,
368 pub keystroke: ContainedText,
369 pub icon_width: f32,
370 pub icon_spacing: f32,
371}
372
373#[derive(Debug, Deserialize, Default)]
374pub struct CommandPalette {
375 pub key: Interactive<ContainedLabel>,
376 pub keystroke_spacing: f32,
377}
378
379#[derive(Deserialize, Default)]
380pub struct InviteLink {
381 #[serde(flatten)]
382 pub container: ContainerStyle,
383 #[serde(flatten)]
384 pub label: LabelStyle,
385 pub icon: Icon,
386}
387
388#[derive(Deserialize, Default)]
389pub struct Icon {
390 #[serde(flatten)]
391 pub container: ContainerStyle,
392 pub color: Color,
393 pub width: f32,
394 pub path: String,
395}
396
397#[derive(Deserialize, Clone, Copy, Default)]
398pub struct IconButton {
399 #[serde(flatten)]
400 pub container: ContainerStyle,
401 pub color: Color,
402 pub icon_width: f32,
403 pub button_width: f32,
404}
405
406#[derive(Deserialize, Default)]
407pub struct ChatMessage {
408 #[serde(flatten)]
409 pub container: ContainerStyle,
410 pub body: TextStyle,
411 pub sender: ContainedText,
412 pub timestamp: ContainedText,
413}
414
415#[derive(Deserialize, Default)]
416pub struct ChannelSelect {
417 #[serde(flatten)]
418 pub container: ContainerStyle,
419 pub header: ChannelName,
420 pub item: ChannelName,
421 pub active_item: ChannelName,
422 pub hovered_item: ChannelName,
423 pub hovered_active_item: ChannelName,
424 pub menu: ContainerStyle,
425}
426
427#[derive(Deserialize, Default)]
428pub struct ChannelName {
429 #[serde(flatten)]
430 pub container: ContainerStyle,
431 pub hash: ContainedText,
432 pub name: TextStyle,
433}
434
435#[derive(Deserialize, Default)]
436pub struct Picker {
437 #[serde(flatten)]
438 pub container: ContainerStyle,
439 pub empty: ContainedLabel,
440 pub input_editor: FieldEditor,
441 pub item: Interactive<ContainedLabel>,
442}
443
444#[derive(Clone, Debug, Deserialize, Default)]
445pub struct ContainedText {
446 #[serde(flatten)]
447 pub container: ContainerStyle,
448 #[serde(flatten)]
449 pub text: TextStyle,
450}
451
452#[derive(Clone, Debug, Deserialize, Default)]
453pub struct ContainedLabel {
454 #[serde(flatten)]
455 pub container: ContainerStyle,
456 #[serde(flatten)]
457 pub label: LabelStyle,
458}
459
460#[derive(Clone, Deserialize, Default)]
461pub struct ProjectDiagnostics {
462 #[serde(flatten)]
463 pub container: ContainerStyle,
464 pub empty_message: TextStyle,
465 pub tab_icon_width: f32,
466 pub tab_icon_spacing: f32,
467 pub tab_summary_spacing: f32,
468}
469
470#[derive(Deserialize, Default)]
471pub struct ContactNotification {
472 pub header_avatar: ImageStyle,
473 pub header_message: ContainedText,
474 pub header_height: f32,
475 pub body_message: ContainedText,
476 pub button: Interactive<ContainedText>,
477 pub dismiss_button: Interactive<IconButton>,
478}
479
480#[derive(Deserialize, Default)]
481pub struct UpdateNotification {
482 pub message: ContainedText,
483 pub action_message: Interactive<ContainedText>,
484 pub dismiss_button: Interactive<IconButton>,
485}
486
487#[derive(Deserialize, Default)]
488pub struct ProjectSharedNotification {
489 pub window_height: f32,
490 pub window_width: f32,
491 #[serde(default)]
492 pub background: Color,
493 pub owner_container: ContainerStyle,
494 pub owner_avatar: ImageStyle,
495 pub owner_metadata: ContainerStyle,
496 pub owner_username: ContainedText,
497 pub message: ContainedText,
498 pub worktree_roots: ContainedText,
499 pub button_width: f32,
500 pub open_button: ContainedText,
501 pub dismiss_button: ContainedText,
502}
503
504#[derive(Deserialize, Default)]
505pub struct IncomingCallNotification {
506 pub window_height: f32,
507 pub window_width: f32,
508 #[serde(default)]
509 pub background: Color,
510 pub caller_container: ContainerStyle,
511 pub caller_avatar: ImageStyle,
512 pub caller_metadata: ContainerStyle,
513 pub caller_username: ContainedText,
514 pub caller_message: ContainedText,
515 pub worktree_roots: ContainedText,
516 pub button_width: f32,
517 pub accept_button: ContainedText,
518 pub decline_button: ContainedText,
519}
520
521#[derive(Clone, Deserialize, Default)]
522pub struct Editor {
523 pub text_color: Color,
524 #[serde(default)]
525 pub background: Color,
526 pub selection: SelectionStyle,
527 pub gutter_background: Color,
528 pub gutter_padding_factor: f32,
529 pub active_line_background: Color,
530 pub highlighted_line_background: Color,
531 pub rename_fade: f32,
532 pub document_highlight_read_background: Color,
533 pub document_highlight_write_background: Color,
534 pub diff: DiffStyle,
535 pub line_number: Color,
536 pub line_number_active: Color,
537 pub guest_selections: Vec<SelectionStyle>,
538 pub syntax: Arc<SyntaxTheme>,
539 pub diagnostic_path_header: DiagnosticPathHeader,
540 pub diagnostic_header: DiagnosticHeader,
541 pub error_diagnostic: DiagnosticStyle,
542 pub invalid_error_diagnostic: DiagnosticStyle,
543 pub warning_diagnostic: DiagnosticStyle,
544 pub invalid_warning_diagnostic: DiagnosticStyle,
545 pub information_diagnostic: DiagnosticStyle,
546 pub invalid_information_diagnostic: DiagnosticStyle,
547 pub hint_diagnostic: DiagnosticStyle,
548 pub invalid_hint_diagnostic: DiagnosticStyle,
549 pub autocomplete: AutocompleteStyle,
550 pub code_actions: CodeActions,
551 pub unnecessary_code_fade: f32,
552 pub hover_popover: HoverPopover,
553 pub link_definition: HighlightStyle,
554 pub composition_mark: HighlightStyle,
555 pub jump_icon: Interactive<IconButton>,
556}
557
558#[derive(Clone, Deserialize, Default)]
559pub struct DiagnosticPathHeader {
560 #[serde(flatten)]
561 pub container: ContainerStyle,
562 pub filename: ContainedText,
563 pub path: ContainedText,
564 pub text_scale_factor: f32,
565}
566
567#[derive(Clone, Deserialize, Default)]
568pub struct DiagnosticHeader {
569 #[serde(flatten)]
570 pub container: ContainerStyle,
571 pub message: ContainedLabel,
572 pub code: ContainedText,
573 pub text_scale_factor: f32,
574 pub icon_width_factor: f32,
575}
576
577#[derive(Clone, Deserialize, Default)]
578pub struct DiagnosticStyle {
579 pub message: LabelStyle,
580 #[serde(default)]
581 pub header: ContainerStyle,
582 pub text_scale_factor: f32,
583}
584
585#[derive(Clone, Deserialize, Default)]
586pub struct AutocompleteStyle {
587 #[serde(flatten)]
588 pub container: ContainerStyle,
589 pub item: ContainerStyle,
590 pub selected_item: ContainerStyle,
591 pub hovered_item: ContainerStyle,
592 pub match_highlight: HighlightStyle,
593}
594
595#[derive(Clone, Copy, Default, Deserialize)]
596pub struct SelectionStyle {
597 pub cursor: Color,
598 pub selection: Color,
599}
600
601#[derive(Clone, Deserialize, Default)]
602pub struct FieldEditor {
603 #[serde(flatten)]
604 pub container: ContainerStyle,
605 pub text: TextStyle,
606 #[serde(default)]
607 pub placeholder_text: Option<TextStyle>,
608 pub selection: SelectionStyle,
609}
610
611#[derive(Clone, Deserialize, Default)]
612pub struct CodeActions {
613 #[serde(default)]
614 pub indicator: Color,
615 pub vertical_scale: f32,
616}
617
618#[derive(Clone, Deserialize, Default)]
619pub struct DiffStyle {
620 pub inserted: Color,
621 pub modified: Color,
622 pub deleted: Color,
623 pub removed_width_em: f32,
624 pub width_em: f32,
625 pub corner_radius: f32,
626}
627
628#[derive(Debug, Default, Clone, Copy)]
629pub struct Interactive<T> {
630 pub default: T,
631 pub hover: Option<T>,
632 pub clicked: Option<T>,
633 pub active: Option<T>,
634 pub disabled: Option<T>,
635}
636
637impl<T> Interactive<T> {
638 pub fn style_for(&self, state: MouseState, active: bool) -> &T {
639 if active {
640 self.active.as_ref().unwrap_or(&self.default)
641 } else if state.clicked == Some(gpui::MouseButton::Left) && self.clicked.is_some() {
642 self.clicked.as_ref().unwrap()
643 } else if state.hovered {
644 self.hover.as_ref().unwrap_or(&self.default)
645 } else {
646 &self.default
647 }
648 }
649
650 pub fn disabled_style(&self) -> &T {
651 self.disabled.as_ref().unwrap_or(&self.default)
652 }
653}
654
655impl<'de, T: DeserializeOwned> Deserialize<'de> for Interactive<T> {
656 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
657 where
658 D: serde::Deserializer<'de>,
659 {
660 #[derive(Deserialize)]
661 struct Helper {
662 #[serde(flatten)]
663 default: Value,
664 hover: Option<Value>,
665 clicked: Option<Value>,
666 active: Option<Value>,
667 disabled: Option<Value>,
668 }
669
670 let json = Helper::deserialize(deserializer)?;
671
672 let deserialize_state = |state_json: Option<Value>| -> Result<Option<T>, D::Error> {
673 if let Some(mut state_json) = state_json {
674 if let Value::Object(state_json) = &mut state_json {
675 if let Value::Object(default) = &json.default {
676 for (key, value) in default {
677 if !state_json.contains_key(key) {
678 state_json.insert(key.clone(), value.clone());
679 }
680 }
681 }
682 }
683 Ok(Some(
684 serde_json::from_value::<T>(state_json).map_err(serde::de::Error::custom)?,
685 ))
686 } else {
687 Ok(None)
688 }
689 };
690
691 let hover = deserialize_state(json.hover)?;
692 let clicked = deserialize_state(json.clicked)?;
693 let active = deserialize_state(json.active)?;
694 let disabled = deserialize_state(json.disabled)?;
695 let default = serde_json::from_value(json.default).map_err(serde::de::Error::custom)?;
696
697 Ok(Interactive {
698 default,
699 hover,
700 clicked,
701 active,
702 disabled,
703 })
704 }
705}
706
707impl Editor {
708 pub fn replica_selection_style(&self, replica_id: u16) -> &SelectionStyle {
709 let style_ix = replica_id as usize % (self.guest_selections.len() + 1);
710 if style_ix == 0 {
711 &self.selection
712 } else {
713 &self.guest_selections[style_ix - 1]
714 }
715 }
716}
717
718#[derive(Default)]
719pub struct SyntaxTheme {
720 pub highlights: Vec<(String, HighlightStyle)>,
721}
722
723impl SyntaxTheme {
724 pub fn new(highlights: Vec<(String, HighlightStyle)>) -> Self {
725 Self { highlights }
726 }
727}
728
729impl<'de> Deserialize<'de> for SyntaxTheme {
730 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
731 where
732 D: serde::Deserializer<'de>,
733 {
734 let syntax_data: HashMap<String, HighlightStyle> = Deserialize::deserialize(deserializer)?;
735
736 let mut result = Self::new(Vec::new());
737 for (key, style) in syntax_data {
738 match result
739 .highlights
740 .binary_search_by(|(needle, _)| needle.cmp(&key))
741 {
742 Ok(i) | Err(i) => {
743 result.highlights.insert(i, (key, style));
744 }
745 }
746 }
747
748 Ok(result)
749 }
750}
751
752#[derive(Clone, Deserialize, Default)]
753pub struct HoverPopover {
754 pub container: ContainerStyle,
755 pub info_container: ContainerStyle,
756 pub warning_container: ContainerStyle,
757 pub error_container: ContainerStyle,
758 pub block_style: ContainerStyle,
759 pub prose: TextStyle,
760 pub highlight: Color,
761}
762
763#[derive(Clone, Deserialize, Default)]
764pub struct TerminalStyle {
765 pub colors: TerminalColors,
766 pub modal_container: ContainerStyle,
767}
768
769#[derive(Clone, Deserialize, Default)]
770pub struct TerminalColors {
771 pub black: Color,
772 pub red: Color,
773 pub green: Color,
774 pub yellow: Color,
775 pub blue: Color,
776 pub magenta: Color,
777 pub cyan: Color,
778 pub white: Color,
779 pub bright_black: Color,
780 pub bright_red: Color,
781 pub bright_green: Color,
782 pub bright_yellow: Color,
783 pub bright_blue: Color,
784 pub bright_magenta: Color,
785 pub bright_cyan: Color,
786 pub bright_white: Color,
787 pub foreground: Color,
788 pub background: Color,
789 pub modal_background: Color,
790 pub cursor: Color,
791 pub dim_black: Color,
792 pub dim_red: Color,
793 pub dim_green: Color,
794 pub dim_yellow: Color,
795 pub dim_blue: Color,
796 pub dim_magenta: Color,
797 pub dim_cyan: Color,
798 pub dim_white: Color,
799 pub bright_foreground: Color,
800 pub dim_foreground: Color,
801}