1use std::sync::{OnceLock, RwLock, RwLockReadGuard};
3
4use FormKind::*;
5use crossterm::style::{Attribute, Attributes, ContentStyle};
6pub use crossterm::{cursor::SetCursorStyle as CursorShape, style::Color};
7
8pub use self::global::*;
9pub(crate) use self::global::{colorscheme_exists, exists};
10use crate::{
11 context::{self, DuatSender},
12 hook::{self, FormSet},
13 session::DuatEvent,
14 text::FormTag,
15};
16
17static SENDER: OnceLock<DuatSender> = OnceLock::new();
18static BASE_FORMS: &[(&str, Form)] = &[
19 ("default", Form::new()),
20 ("accent", Form::new().bold()),
21 ("caret.main", Form::new().reverse()),
22 ("caret.extra", Form {
23 kind: Ref(2, default_style()),
24 ..Form::new().reverse()
25 }),
26 ("selection.main", Form::new().white().on_dark_grey()),
27 ("selection.extra", Form::new().white().on_grey()),
28 ("cloak", Form::new().grey().on_black()),
29 ("character.control", Form::new().grey()),
30 ("param.path", Form::new().yellow()),
31 ("param.path.exists", Form {
32 kind: Ref(8, ContentStyle {
33 attributes: Attributes::none().with(Attribute::Underlined),
34 ..default_style()
35 }),
36 ..Form::new().yellow().underlined()
37 }),
38 ("replace", Form::new().grey()),
39];
40
41mod global {
43 use std::{
44 any::TypeId,
45 collections::HashMap,
46 sync::{Arc, LazyLock, Mutex, OnceLock},
47 };
48
49 use super::{BASE_FORMS, CursorShape, Form, FormId, Painter, Palette};
50 #[doc(inline)]
51 pub use crate::__id_of__ as id_of;
52 use crate::{
53 context,
54 form::FormKind,
55 hook::{self, ColorSchemeSet},
56 };
57
58 static PALETTE: OnceLock<&Palette> = OnceLock::new();
59 static FORMS: OnceLock<&Mutex<Vec<Arc<str>>>> = OnceLock::new();
60 static COLORSCHEMES: LazyLock<Mutex<HashMap<Arc<str>, ColorschemeFn>>> =
61 LazyLock::new(Mutex::default);
62
63 pub fn set(name: impl ToString, form: Form) -> FormId {
88 let name = name.to_string();
89 let cloned_name = name.clone();
90
91 match form.kind {
92 FormKind::Normal => PALETTE.get().unwrap().set_form(cloned_name, form),
93 FormKind::Ref(refed, style) => {
94 PALETTE.get().unwrap().set_ref(cloned_name, refed, style)
95 }
96 _ => unreachable!(),
97 };
98
99 let mut forms = FORMS.get().unwrap().lock().unwrap();
100 FormId(position_of_name(&mut forms, name) as u16)
101 }
102
103 pub fn set_weak(name: impl ToString, form: Form) -> FormId {
131 let name = name.to_string();
132 let cloned_name = name.clone();
133
134 match form.kind {
135 FormKind::Normal => PALETTE.get().unwrap().set_weak_form(cloned_name, form),
136 FormKind::Ref(refed, style) => {
137 PALETTE
138 .get()
139 .unwrap()
140 .set_weak_ref(cloned_name, refed, style)
141 }
142 _ => unreachable!(),
143 };
144
145 let mut forms = FORMS.get().unwrap().lock().unwrap();
146 FormId(position_of_name(&mut forms, name) as u16)
147 }
148
149 pub fn from_id(id: FormId) -> Form {
151 PALETTE.get().unwrap().form_from_id(id).unwrap_or_default()
152 }
153
154 pub fn main_cursor() -> (Form, Option<CursorShape>) {
156 PALETTE.get().unwrap().main_cursor()
157 }
158
159 pub fn extra_cursor() -> (Form, Option<CursorShape>) {
161 PALETTE.get().unwrap().extra_cursor()
162 }
163
164 pub fn set_main_cursor(shape: CursorShape) {
190 PALETTE.get().unwrap().set_main_cursor(shape);
191 }
192
193 pub fn set_extra_cursor(shape: CursorShape) {
219 PALETTE.get().unwrap().set_extra_cursor(shape);
220 }
221
222 pub fn unset_main_cursor() {
233 PALETTE.get().unwrap().unset_main_cursor();
234 }
235
236 pub fn unset_extra_cursor() {
250 PALETTE.get().unwrap().unset_extra_cursor();
251 }
252
253 pub fn unset_cursors() {
260 PALETTE.get().unwrap().unset_main_cursor();
261 PALETTE.get().unwrap().unset_extra_cursor();
262 }
263
264 pub fn painter_with_mask(mask: &'static str) -> Painter {
279 PALETTE.get().unwrap().painter(super::DEFAULT_ID, mask)
280 }
281
282 pub(crate) fn painter_with_widget_and_mask<W: ?Sized + 'static>(mask: &'static str) -> Painter {
284 PALETTE.get().unwrap().painter(
285 default_id(TypeId::of::<W>(), crate::utils::duat_name::<W>()),
286 mask,
287 )
288 }
289
290 pub fn enable_mask(mask: impl AsRef<str> + Send + Sync + 'static) {
350 let mask = mask.as_ref();
351 let mut inner = PALETTE.get().unwrap().0.write().unwrap();
352 if !inner.masks.iter().any(|(m, _)| *m == mask) {
353 let mut remaps: Vec<u16> = (0..inner.forms.len() as u16).collect();
354
355 for (i, (name, ..)) in inner.forms.iter().enumerate() {
356 if let Some((pref, suf)) = name.rsplit_once('.')
357 && suf == mask
358 && let Some(j) = inner.forms.iter().position(|(name, ..)| *name == pref)
359 {
360 remaps[j] = i as u16;
361 }
362 }
363
364 inner.masks.push((mask.to_string(), remaps));
365 }
366 }
367
368 #[macro_export]
402 #[doc(hidden)]
403 macro_rules! __id_of__ {
404 ($form:expr) => {{
405 use $crate::form::{DEFAULT_ID, FormId, set_many};
406
407 static mut WAS_SET: bool = false;
408 static mut ID: FormId = DEFAULT_ID;
409 if unsafe { WAS_SET } {
410 unsafe { ID }
411 } else {
412 let name = $form.to_string();
413 let id = set_many([(name, None)])[0];
414 unsafe {
415 ID = id;
416 WAS_SET = true;
417 }
418 id
419 }
420 }};
421 }
422
423 pub fn id_of_non_static(name: impl ToString) -> FormId {
430 let name = name.to_string();
431 set_many([(name, None)])[0]
432 }
433
434 pub fn ids_of_non_static(names: impl IntoIterator<Item = impl ToString>) -> Vec<FormId> {
441 set_many(names.into_iter().map(|n| (n.to_string(), None)))
442 }
443
444 #[doc(hidden)]
446 pub fn set_many<S: AsRef<str>>(
447 sets: impl IntoIterator<Item = (S, Option<Form>)>,
448 ) -> Vec<FormId> {
449 let mut ids = Vec::new();
450 let mut forms = FORMS.get().unwrap().lock().unwrap();
451 let sets: Vec<_> = sets.into_iter().collect();
452 for (name, _) in &sets {
453 ids.push(FormId(position_of_name(&mut forms, name) as u16));
454 }
455
456 PALETTE.get().unwrap().set_many(&sets);
457
458 ids
459 }
460
461 pub fn add_colorscheme(
474 name: impl ToString,
475 pairs: impl FnMut() -> Vec<(String, Form)> + Send + 'static,
476 ) {
477 let name = name.to_string();
478 COLORSCHEMES
479 .lock()
480 .unwrap()
481 .insert(Arc::from(name), Box::new(pairs));
482 }
483
484 pub fn set_colorscheme(name: &str) {
491 let name = name.to_string();
492 let mut colorschemes = COLORSCHEMES.lock().unwrap();
493 if let Some(pairs) = colorschemes.get_mut(name.as_str()) {
494 let pairs = pairs();
495 set_many(pairs.iter().cloned().map(|(name, form)| (name, Some(form))));
496 context::queue(move |pa| {
497 _ = hook::trigger(pa, ColorSchemeSet((name.to_string(), pairs)))
498 });
499 } else {
500 context::error!("The colorscheme [a]{name}[] was not found");
501 }
502 }
503
504 pub fn colorscheme_list() -> Vec<String> {
506 COLORSCHEMES
507 .lock()
508 .unwrap()
509 .keys()
510 .map(|name| name.to_string())
511 .collect()
512 }
513
514 pub(crate) fn exists(name: &str) -> bool {
516 FORMS
517 .get()
518 .unwrap()
519 .lock()
520 .unwrap()
521 .iter()
522 .any(|fname| fname.as_ref() == name)
523 }
524
525 pub(crate) fn colorscheme_exists(name: &str) -> bool {
527 COLORSCHEMES.lock().unwrap().contains_key(name)
528 }
529
530 pub(super) fn name_of(id: FormId) -> Arc<str> {
532 FORMS.get().unwrap().lock().unwrap()[id.0 as usize].clone()
533 }
534
535 fn default_id(type_id: TypeId, type_name: &'static str) -> FormId {
536 static IDS: LazyLock<Mutex<HashMap<TypeId, FormId>>> = LazyLock::new(Mutex::default);
537 let mut ids = IDS.lock().unwrap();
538
539 if let Some(id) = ids.get(&type_id) {
540 *id
541 } else {
542 let name = format!("default.{type_name}");
543 let id = set_many(vec![(name, None)])[0];
544 ids.insert(type_id, id);
545 id
546 }
547 }
548
549 fn position_of_name(names: &mut Vec<Arc<str>>, name: impl AsRef<str>) -> usize {
550 let name = name.as_ref();
551 if let Some((i, _)) = names
552 .iter()
553 .enumerate()
554 .find(|(_, rhs)| rhs.as_ref() == name)
555 {
556 i
557 } else if let Some((refed, _)) = name.rsplit_once('.') {
558 position_of_name(names, refed);
559 names.push(name.into());
560 names.len() - 1
561 } else {
562 names.push(name.into());
563 names.len() - 1
564 }
565 }
566
567 #[doc(hidden)]
571 pub fn get_initial() -> (&'static Mutex<Vec<Arc<str>>>, &'static Palette) {
572 let forms = Box::leak(Box::new(Mutex::new(
573 BASE_FORMS.iter().map(|(n, ..)| Arc::from(*n)).collect(),
574 )));
575 let palette = Box::leak(Box::new(Palette::new()));
576 (forms, palette)
577 }
578
579 #[doc(hidden)]
583 pub fn set_initial((forms, palette): (&'static Mutex<Vec<Arc<str>>>, &'static Palette)) {
584 FORMS.set(forms).expect("Forms setup ran twice");
585 PALETTE.set(palette).expect("Forms setup ran twice");
586 }
587
588 type ColorschemeFn = Box<dyn FnMut() -> Vec<(String, Form)> + Send>;
589}
590
591#[derive(Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord)]
605pub struct FormId(u16);
606
607impl FormId {
608 pub const fn to_tag(self, prio: u8) -> FormTag {
617 FormTag(self, prio)
618 }
619
620 pub const fn to_u16(self) -> u16 {
624 self.0
625 }
626
627 pub fn name(self) -> std::sync::Arc<str> {
629 name_of(self)
630 }
631}
632
633impl std::fmt::Debug for FormId {
634 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
635 write!(f, "FormId({}: {})", self.0, name_of(*self))
636 }
637}
638
639macro_rules! mimic_method {
641 (#[$attr:meta] $method:ident $attrib:expr) => {
642 #[$attr]
644 pub const fn $method(mut self) -> Form {
646 self.style.attributes = self.style.attributes.with($attrib);
647 self
648 }
649 };
650 (#[$attr:meta] $fg:ident $bg:ident $ul:ident $color:expr) => {
651 #[$attr]
653 pub const fn $fg(mut self) -> Form {
655 self.style.foreground_color = Some($color);
656 self
657 }
658
659 #[$attr]
661 pub const fn $bg(mut self) -> Form {
663 self.style.background_color = Some($color);
664 self
665 }
666
667 #[$attr]
669 pub const fn $ul(mut self) -> Form {
678 self.style.underline_color = Some($color);
679 self
680 }
681 };
682}
683
684#[derive(Default, Clone, Copy)]
686pub struct Form {
687 pub style: ContentStyle,
689 kind: FormKind,
690}
691
692#[rustfmt::skip]
693impl Form {
694 mimic_method!(bold Attribute::Bold);
695 mimic_method!(dim Attribute::Dim);
696 mimic_method!(italic Attribute::Italic);
697 mimic_method!(underlined Attribute::Underlined);
698 mimic_method!(double_underlined Attribute::DoubleUnderlined);
699 mimic_method!(undercurled Attribute::Undercurled);
700 mimic_method!(underdashed Attribute::Underdashed);
701 mimic_method!(reverse Attribute::Reverse);
702 mimic_method!(crossed_out Attribute::CrossedOut);
703 mimic_method!(black on_black underline_black Color::Black);
704 mimic_method!(dark_grey on_dark_grey underline_dark_grey Color::DarkGrey);
705 mimic_method!(red on_red underline_red Color::Red);
706 mimic_method!(dark_red on_dark_red underline_dark_red Color::DarkRed);
707 mimic_method!(green on_green underline_green Color::Green);
708 mimic_method!(
709 dark_green on_dark_green underline_dark_green Color::DarkGreen
710 );
711 mimic_method!(yellow on_yellow underline_yellow Color::Yellow);
712 mimic_method!(
713 dark_yellow on_dark_yellow underline_dark_yellow Color::DarkYellow
714 );
715 mimic_method!(blue on_blue underline_blue Color::Blue);
716 mimic_method!(dark_blue on_dark_blue underline_dark_blue Color::DarkBlue);
717 mimic_method!(magenta on_magenta underline_magenta Color::Magenta);
718 mimic_method!(
719 dark_magenta on_dark_magenta underline_dark_magenta Color::DarkMagenta
720 );
721 mimic_method!(cyan on_cyan underline_cyan Color::Cyan);
722 mimic_method!(dark_cyan on_dark_cyan underline_dark_cyan Color::DarkCyan);
723 mimic_method!(white on_white underline_white Color::White);
724 mimic_method!(grey on_grey underline_grey Color::Grey);
725}
726
727impl Form {
728 pub const fn new() -> Form {
730 Self {
731 style: default_style(),
732 kind: FormKind::Normal,
733 }
734 }
735
736 pub fn of(form_name: impl AsRef<str>) -> Form {
738 let mut form = from_id(id_of_non_static(form_name.as_ref()));
739 form.kind = FormKind::Normal;
740 form
741 }
742
743 pub fn mimic(form_name: impl AsRef<str>) -> Form {
759 let id = id_of_non_static(form_name.as_ref());
760 let mut form = from_id(id);
761 form.kind = FormKind::Ref(id.0, default_style());
762 form
763 }
764
765 pub const fn reset(mut self) -> Form {
772 self.style.attributes = self.style.attributes.with(Attribute::Reset);
773
774 if let FormKind::Ref(_, style) = &mut self.kind {
775 style.attributes = style.attributes.with(Attribute::Reset);
776 }
777
778 self
779 }
780
781 #[track_caller]
794 pub const fn with(mut self, color: &str) -> Form {
795 self.style.foreground_color = match str_to_color(color) {
796 Ok(color) => Some(color),
797 Err(_) => panic!("Ill-formed color"),
798 };
799
800 if let FormKind::Ref(_, style) = &mut self.kind {
801 style.foreground_color = self.style.foreground_color;
802 }
803
804 self
805 }
806
807 pub const fn on(mut self, color: &str) -> Form {
820 self.style.background_color = match str_to_color(color) {
821 Ok(color) => Some(color),
822 Err(_) => panic!("Ill-formed color"),
823 };
824
825 if let FormKind::Ref(_, style) = &mut self.kind {
826 style.background_color = self.style.background_color;
827 }
828
829 self
830 }
831
832 pub fn underline(mut self, color: &str) -> Form {
849 self.style.background_color = match str_to_color(color) {
850 Ok(color) => Some(color),
851 Err(_) => panic!("Ill-formed color"),
852 };
853
854 if let FormKind::Ref(_, style) = &mut self.kind {
855 style.background_color = self.style.background_color;
856 }
857
858 self
859 }
860
861 const fn fg(&self) -> Option<Color> {
863 self.style.foreground_color
864 }
865
866 const fn bg(&self) -> Option<Color> {
868 self.style.background_color
869 }
870
871 const fn ul(&self) -> Option<Color> {
873 self.style.underline_color
874 }
875
876 const fn attrs(&self) -> Attributes {
878 self.style.attributes
879 }
880}
881
882impl PartialEq for Form {
883 fn eq(&self, other: &Self) -> bool {
884 self.style == other.style
885 }
886}
887
888impl Eq for Form {}
889
890#[derive(Debug)]
894#[doc(hidden)]
895pub struct Palette(RwLock<InnerPalette>);
896
897impl Palette {
898 fn new() -> Self {
900 let main_cursor = Some(CursorShape::DefaultUserShape);
901 Self(RwLock::new(InnerPalette {
902 main_cursor,
903 extra_cursor: main_cursor,
904 forms: BASE_FORMS
905 .iter()
906 .map(|(str, form)| (str.to_string(), *form))
907 .collect(),
908 masks: vec![("".to_string(), (0..BASE_FORMS.len() as u16).collect())],
909 }))
910 }
911
912 fn set_form(&self, name: impl AsRef<str>, form: Form) {
914 let name = name.as_ref();
915 self.0.write().unwrap().set_form(name, form);
916 }
917
918 fn set_weak_form(&self, name: impl AsRef<str>, form: Form) {
920 let name = name.as_ref();
921 self.0.write().unwrap().set_weak_form(name, form);
922 }
923
924 fn set_ref(&self, name: impl AsRef<str>, refed: u16, override_style: ContentStyle) {
926 let name = name.as_ref();
927 self.0.write().unwrap().set_ref(name, refed, override_style);
928 }
929
930 fn set_weak_ref(&self, name: impl AsRef<str>, refed: u16, override_style: ContentStyle) {
932 let name = name.as_ref();
933 let mut inner_palette = self.0.write().unwrap();
934 inner_palette.set_weak_ref(name, refed, override_style);
935 }
936
937 fn set_many<S: AsRef<str>>(&self, sets: &[(S, Option<Form>)]) {
939 let mut inner = self.0.write().unwrap();
940 for (name, form) in sets {
941 let Some(form) = *form else {
942 position_and_form(&mut inner.forms, name);
943 continue;
944 };
945
946 match form.kind {
947 FormKind::Normal => inner.set_form(name.as_ref(), form),
948 FormKind::Ref(refed, style) => inner.set_ref(name.as_ref(), refed, style),
949 FormKind::Weakest => inner.set_weak_form(name.as_ref(), form),
950 FormKind::WeakestRef(refed, style) => {
951 inner.set_weak_ref(name.as_ref(), refed, style)
952 }
953 }
954 }
955 }
956
957 fn form_from_id(&self, id: FormId) -> Option<Form> {
959 let inner = self.0.read().unwrap();
960 inner.forms.get(id.0 as usize).map(|(_, form)| *form)
961 }
962
963 fn main_cursor(&self) -> (Form, Option<CursorShape>) {
965 let form = self.form_from_id(M_CAR_ID).unwrap();
966 (form, self.0.read().unwrap().main_cursor)
967 }
968
969 fn extra_cursor(&self) -> (Form, Option<CursorShape>) {
971 let form = self.form_from_id(E_CAR_ID).unwrap();
972 (form, self.0.read().unwrap().extra_cursor)
973 }
974
975 fn set_main_cursor(&self, shape: CursorShape) {
977 self.0.write().unwrap().main_cursor = Some(shape);
978 if let Some(sender) = SENDER.get() {
979 sender.send(DuatEvent::FormChange);
980 }
981 }
982
983 fn set_extra_cursor(&self, shape: CursorShape) {
985 self.0.write().unwrap().extra_cursor = Some(shape);
986 if let Some(sender) = SENDER.get() {
987 sender.send(DuatEvent::FormChange);
988 }
989 }
990
991 fn unset_main_cursor(&self) {
993 self.0.write().unwrap().main_cursor = None;
994 if let Some(sender) = SENDER.get() {
995 sender.send(DuatEvent::FormChange);
996 }
997 }
998
999 fn unset_extra_cursor(&self) {
1001 self.0.write().unwrap().extra_cursor = None;
1002 if let Some(sender) = SENDER.get() {
1003 sender.send(DuatEvent::FormChange);
1004 }
1005 }
1006
1007 fn painter(&'static self, default_id: FormId, mask: &str) -> Painter {
1009 let inner = self.0.read().unwrap();
1010 let mask_i = inner
1011 .masks
1012 .iter()
1013 .position(|(m, _)| *m == mask)
1014 .unwrap_or_default();
1015
1016 let default = inner
1017 .forms
1018 .get(match inner.masks[mask_i].1.get(default_id.0 as usize) {
1019 Some(i) => *i as usize,
1020 None => default_id.0 as usize,
1021 })
1022 .map(|(_, f)| *f)
1023 .unwrap_or(Form::new());
1024
1025 Painter {
1026 inner,
1027 mask_i,
1028 default,
1029 parts: PainterParts::default(),
1030 main_parts: None,
1031 }
1032 }
1033}
1034
1035struct InnerPalette {
1036 main_cursor: Option<CursorShape>,
1037 extra_cursor: Option<CursorShape>,
1038 forms: Vec<(String, Form)>,
1039 masks: Vec<(String, Vec<u16>)>,
1040}
1041
1042impl InnerPalette {
1043 fn set_form(&mut self, name: &str, form: Form) {
1045 let (i, _) = position_and_form(&mut self.forms, name);
1046
1047 self.forms[i].1 = form;
1048
1049 for (referee, override_style) in refs_of(self, i) {
1050 mimic_form_to_referee(&mut self.forms[referee].1, form, override_style);
1051 }
1052
1053 if let Some(sender) = SENDER.get() {
1054 sender.send(DuatEvent::FormChange);
1055 }
1056
1057 mask_form(name, i, self);
1058
1059 let form_set = FormSet((self.forms[i].0.clone(), FormId(i as u16), form));
1060 context::queue(move |pa| _ = hook::trigger(pa, form_set));
1061 }
1062
1063 fn set_weak_form(&mut self, name: &str, form: Form) {
1065 let (i, _) = position_and_form(&mut self.forms, name);
1066
1067 let (_, f) = &mut self.forms[i];
1068 if let FormKind::Weakest | FormKind::WeakestRef(..) = f.kind {
1069 *f = form;
1070 f.kind = FormKind::Normal;
1071
1072 if let Some(sender) = SENDER.get() {
1073 sender.send(DuatEvent::FormChange);
1074 }
1075 for (referee, override_style) in refs_of(self, i) {
1076 mimic_form_to_referee(&mut self.forms[referee].1, form, override_style);
1077 }
1078
1079 mask_form(name, i, self);
1080 }
1081 }
1082
1083 fn set_ref(&mut self, name: &str, refed: u16, override_style: ContentStyle) {
1085 let (_, form) = self.forms[refed as usize];
1086 let (i, _) = position_and_form(&mut self.forms, name);
1087
1088 self.forms[i].1 = form;
1089 for (referee, override_style) in refs_of(self, i) {
1090 mimic_form_to_referee(&mut self.forms[referee].1, form, override_style);
1091 }
1092
1093 if would_be_circular(self, i, refed as usize) {
1095 self.forms[i].1.kind = FormKind::Normal;
1096 } else {
1097 self.forms[i].1.kind = FormKind::Ref(refed, override_style);
1098 }
1099
1100 if let Some(sender) = SENDER.get() {
1101 sender.send(DuatEvent::FormChange);
1102 }
1103
1104 mask_form(name, i, self);
1105 let form_set = FormSet((self.forms[i].0.clone(), FormId(i as u16), form));
1106 context::queue(move |pa| _ = hook::trigger(pa, form_set));
1107 }
1108
1109 fn set_weak_ref(&mut self, name: &str, refed: u16, override_style: ContentStyle) {
1111 let (_, form) = self.forms[refed as usize];
1112 let (i, _) = position_and_form(&mut self.forms, name);
1113
1114 let (_, f) = &mut self.forms[i];
1117 if let FormKind::Weakest | FormKind::WeakestRef(..) = f.kind {
1118 *f = form;
1119 f.kind = FormKind::WeakestRef(refed, override_style);
1120
1121 if let Some(sender) = SENDER.get() {
1122 sender.send(DuatEvent::FormChange);
1123 }
1124 for (referee, override_style) in refs_of(self, i) {
1125 mimic_form_to_referee(&mut self.forms[referee].1, form, override_style);
1126 }
1127
1128 mask_form(name, i, self);
1129 }
1130 }
1131}
1132
1133fn mimic_form_to_referee(referee: &mut Form, form: Form, override_style: ContentStyle) {
1134 referee.style = form.style;
1135 referee.style.attributes.extend(override_style.attributes);
1136 if let Some(color) = override_style.foreground_color {
1137 referee.style.foreground_color = Some(color);
1138 }
1139 if let Some(color) = override_style.background_color {
1140 referee.style.background_color = Some(color);
1141 }
1142 if let Some(color) = override_style.underline_color {
1143 referee.style.underline_color = Some(color);
1144 }
1145}
1146
1147fn mask_form(name: &str, form_i: usize, inner: &mut InnerPalette) {
1149 if inner.masks[0].1.len() < inner.forms.len() {
1150 for (_, remaps) in inner.masks.iter_mut() {
1151 remaps.extend(remaps.len() as u16..inner.forms.len() as u16);
1152 }
1153 }
1154
1155 if let Some((pref, mask)) = name.rsplit_once(".")
1156 && let Some((_, remaps)) = inner.masks.iter_mut().find(|(m, _)| *m == mask)
1157 && let Some(j) = inner.forms.iter().position(|(name, ..)| *name == pref)
1158 {
1159 remaps[j] = form_i as u16;
1160 }
1161}
1162
1163pub struct Painter {
1223 inner: RwLockReadGuard<'static, InnerPalette>,
1224 mask_i: usize,
1225 default: Form,
1226 parts: PainterParts,
1227 main_parts: Option<PainterParts>,
1228}
1229
1230impl Painter {
1231 #[inline(always)]
1239 pub fn apply(&mut self, id: FormId, prio: u8) {
1240 let (_, mask) = &self.inner.masks[self.mask_i];
1241 let id = FormId(mask.get(id.0 as usize).copied().unwrap_or(id.0));
1242
1243 let forms = &self.inner.forms;
1244 let form = unsafe { forms.get(id.0 as usize).map(|(_, f)| *f).unwrap_unchecked() };
1247
1248 let gt = |(.., p): &&(_, _, u8)| *p > prio;
1249 let i = self.parts.forms.len() - self.parts.forms.iter().rev().take_while(gt).count();
1250 self.parts.forms.insert(i, (form, id, prio));
1251
1252 self.parts.set_fg |= form.fg().is_some();
1253 self.parts.set_bg |= form.bg().is_some();
1254 self.parts.set_ul |= form.ul().is_some();
1255 self.parts.reset_attrs |= form.attrs().has(Attribute::Reset);
1256 }
1257
1258 #[inline(always)]
1261 pub fn remove(&mut self, id: FormId) {
1262 let mask = &self.inner.masks[self.mask_i].1;
1263 let id = FormId(mask.get(id.0 as usize).copied().unwrap_or(id.0));
1264
1265 let mut applied_forms = self.parts.forms.iter().enumerate();
1266 if let Some((i, &(form, ..))) = applied_forms.rfind(|(_, (_, lhs, _))| *lhs == id) {
1267 self.parts.forms.remove(i);
1268
1269 self.parts.set_fg |= form.fg().is_some();
1270 self.parts.set_bg |= form.bg().is_some();
1271 self.parts.set_ul |= form.ul().is_some();
1272 self.parts.reset_attrs |= !form.attrs().is_empty();
1273 };
1274 }
1275
1276 #[inline(always)]
1282 pub fn reset(&mut self) -> ContentStyle {
1283 self.parts.forms.clear();
1284 self.absolute_style()
1285 }
1286
1287 #[inline(always)]
1292 pub fn absolute_style(&self) -> ContentStyle {
1293 let mut style = self.default.style;
1294
1295 for &(form, ..) in &self.parts.forms {
1296 style.foreground_color = form.fg().or(style.foreground_color);
1297 style.background_color = form.bg().or(style.background_color);
1298 style.underline_color = form.ul().or(style.underline_color);
1299 style.attributes = if form.attrs().has(Attribute::Reset) {
1300 form.attrs()
1301 } else {
1302 form.attrs() | style.attributes
1303 }
1304 }
1305
1306 style
1307 }
1308
1309 #[inline(always)]
1321 pub fn relative_style(&mut self) -> Option<ContentStyle> {
1322 let abs_style = self.absolute_style();
1323 let mut style = abs_style;
1324
1325 if style.attributes.has(Attribute::Reset) || self.parts.reset_attrs {
1326 style.attributes.set(Attribute::Reset);
1327 } else {
1331 style.foreground_color = self
1332 .parts
1333 .set_fg
1334 .then_some(style.foreground_color.unwrap_or(Color::Reset))
1335 .filter(|fg| Some(*fg) != self.parts.prev_style.and_then(|s| s.foreground_color));
1336 style.background_color = self
1337 .parts
1338 .set_bg
1339 .then_some(style.background_color.unwrap_or(Color::Reset))
1340 .filter(|bg| Some(*bg) != self.parts.prev_style.and_then(|s| s.background_color));
1341 style.underline_color = self
1342 .parts
1343 .set_ul
1344 .then_some(style.underline_color.unwrap_or(Color::Reset))
1345 .filter(|ul| Some(*ul) != self.parts.prev_style.and_then(|s| s.underline_color));
1346 }
1347
1348 self.parts.set_fg = false;
1349 self.parts.set_bg = false;
1350 self.parts.set_ul = false;
1351 self.parts.reset_attrs = false;
1352
1353 if let Some(prev_style) = self.parts.prev_style.replace(abs_style) {
1354 (style != prev_style && style != Default::default()).then_some(style)
1355 } else {
1356 Some(style)
1357 }
1358 }
1359
1360 pub fn reset_prev_style(&mut self) {
1366 self.parts.prev_style = None;
1367 self.parts.set_fg = true;
1368 self.parts.set_bg = true;
1369 self.parts.set_ul = true;
1370 self.parts.reset_attrs = true;
1371 }
1372
1373 #[inline(always)]
1375 pub fn apply_main_selection(&mut self, is_caret: bool, start_range: bool) {
1376 if is_caret {
1377 self.apply(M_CAR_ID, 100);
1378 }
1379 if start_range {
1380 self.apply(M_SEL_ID, 95);
1381 }
1382 }
1383
1384 #[inline(always)]
1386 pub fn remove_main_selection(&mut self, is_caret: bool, end_range: bool) {
1387 if is_caret {
1388 self.remove(M_CAR_ID);
1389 }
1390 if end_range {
1391 self.remove(M_SEL_ID);
1392 }
1393 }
1394
1395 #[inline(always)]
1397 pub fn apply_extra_selection(&mut self, is_caret: bool, start_range: bool) {
1398 if is_caret {
1399 self.apply(E_CAR_ID, 100);
1400 }
1401 if start_range {
1402 self.apply(E_SEL_ID, 95);
1403 }
1404 }
1405
1406 #[inline(always)]
1408 pub fn remove_extra_selection(&mut self, is_caret: bool, end_range: bool) {
1409 if is_caret {
1410 self.remove(E_CAR_ID);
1411 }
1412 if end_range {
1413 self.remove(E_SEL_ID);
1414 }
1415 }
1416
1417 pub fn prepare_for_inlay(&mut self) {
1421 self.main_parts = Some(std::mem::take(&mut self.parts));
1422 }
1423
1424 #[track_caller]
1434 pub fn return_from_inlay(&mut self) {
1435 self.parts = self.main_parts.take().unwrap();
1436 }
1437
1438 pub fn main_cursor(&self) -> Option<CursorShape> {
1440 self.inner.main_cursor
1441 }
1442
1443 pub fn extra_cursor(&self) -> Option<CursorShape> {
1445 self.inner.extra_cursor
1446 }
1447
1448 pub fn get_default(&self) -> Form {
1450 self.default
1451 }
1452}
1453
1454struct PainterParts {
1455 forms: Vec<(Form, FormId, u8)>,
1456 set_fg: bool,
1457 set_bg: bool,
1458 set_ul: bool,
1459 reset_attrs: bool,
1460 prev_style: Option<ContentStyle>,
1461}
1462
1463impl Default for PainterParts {
1464 fn default() -> Self {
1465 Self {
1466 forms: Vec::new(),
1467 set_fg: true,
1468 set_bg: true,
1469 set_ul: true,
1470 reset_attrs: true,
1471 prev_style: None,
1472 }
1473 }
1474}
1475
1476pub(crate) fn set_sender(sender: DuatSender) {
1477 SENDER
1478 .set(sender)
1479 .unwrap_or_else(|_| panic!("Sender set more than once"));
1480}
1481
1482#[derive(Default, Clone, Copy)]
1484enum FormKind {
1485 #[default]
1486 Normal,
1487 Ref(u16, ContentStyle),
1488 Weakest,
1489 WeakestRef(u16, ContentStyle),
1490}
1491
1492fn refs_of(inner: &InnerPalette, refed: usize) -> Vec<(usize, ContentStyle)> {
1494 let mut refs = Vec::new();
1495 for (i, (_, form)) in inner.forms.iter().enumerate() {
1496 if let FormKind::Ref(id, style) | FormKind::WeakestRef(id, style) = form.kind
1497 && id as usize == refed
1498 {
1499 refs.push((i, style));
1500 refs.extend(refs_of(inner, i));
1501 }
1502 }
1503 refs
1504}
1505
1506fn would_be_circular(inner: &InnerPalette, referee: usize, refed: usize) -> bool {
1508 if let FormKind::Ref(id, _) | FormKind::WeakestRef(id, _) = inner.forms[refed].1.kind {
1509 match id as usize == referee {
1510 true => true,
1511 false => would_be_circular(inner, referee, id as usize),
1512 }
1513 } else {
1514 false
1515 }
1516}
1517
1518fn position_and_form(forms: &mut Vec<(String, Form)>, name: impl AsRef<str>) -> (usize, Form) {
1519 let name = name.as_ref();
1520 if let Some((i, (_, form))) = forms.iter().enumerate().find(|(_, (lhs, _))| *lhs == name) {
1521 (i, *form)
1522 } else if let Some((refed, _)) = name.rsplit_once('.') {
1523 let (i, mut form) = position_and_form(forms, refed);
1524 form.kind = FormKind::WeakestRef(i as u16, default_style());
1525 forms.push((name.to_string(), form));
1526 (forms.len() - 1, form)
1527 } else {
1528 let mut form = Form::new();
1529 form.kind = FormKind::Weakest;
1530 forms.push((name.to_string(), form));
1531 (forms.len() - 1, form)
1532 }
1533}
1534
1535const fn str_to_color(str: &str) -> std::result::Result<Color, &'static str> {
1537 const fn strip_prefix<'a>(prefix: &str, str: &'a str) -> Option<&'a str> {
1538 let prefix = prefix.as_bytes();
1539
1540 let mut i = 0;
1541 while i < prefix.len() {
1542 if str.as_bytes()[i] != prefix[i] {
1543 return None;
1544 }
1545 i += 1;
1546 }
1547
1548 Some(str.split_at(prefix.len()).1)
1549 }
1550 const fn strip_suffix<'a>(suffix: &str, str: &'a str) -> Option<&'a str> {
1551 let prefix = suffix.as_bytes();
1552
1553 let mut i = str.len() - 1;
1554 while i >= str.len() - prefix.len() {
1555 if str.as_bytes()[i] != prefix[i - (str.len() - prefix.len())] {
1556 return None;
1557 }
1558 i += 1;
1559 }
1560
1561 Some(str.split_at(str.len() - suffix.len()).0)
1562 }
1563 const fn split_space(str: &str) -> Option<(&str, &str)> {
1564 if str.is_empty() {
1565 return None;
1566 }
1567
1568 let mut i = 0;
1569 while i < str.len() {
1570 if str.as_bytes()[i] == b' ' {
1571 break;
1572 }
1573 i += 1;
1574 }
1575
1576 let (cut, rest) = str.split_at(i);
1577 let (_, rest) = rest.split_at(if rest.is_empty() { 0 } else { 1 });
1578 Some((cut, rest))
1579 }
1580 const fn hue_to_rgb(p: f32, q: f32, mut t: f32) -> f32 {
1581 t = if t < 0.0 { t + 1.0 } else { t };
1582 t = if t > 1.0 { t - 1.0 } else { t };
1583 if t < 1.0 / 6.0 {
1584 p + (q - p) * 6.0 * t
1585 } else if t < 1.0 / 2.0 {
1586 q
1587 } else if t < 2.0 / 3.0 {
1588 p + (q - p) * (2.0 / 3.0 - t) * 6.0
1589 } else {
1590 p
1591 }
1592 }
1593
1594 if let Some(hex) = strip_prefix("#", str) {
1596 let total = match u32::from_str_radix(hex, 16) {
1597 Ok(total) if hex.len() == 6 => total,
1598 _ => return Err("Hexcode does not contain 6 hex values"),
1599 };
1600 let r = (total >> 16) as u8;
1601 let g = (total >> 8) as u8;
1602 let b = total as u8;
1603
1604 Ok(Color::Rgb { r, g, b })
1605 } else if let Some(mut hsl) = strip_prefix("hsl ", str) {
1607 let mut values = [0.0, 0.0, 0.0];
1608 let mut i = 0;
1609 while i < values.len() {
1610 if let Some((cut, rest)) = split_space(hsl) {
1611 hsl = rest;
1612 let (num, div) = match strip_suffix("%", cut) {
1613 Some(perc) => (perc, 100),
1614 None => (cut, 255),
1615 };
1616 values[i] = match u8::from_str_radix(num, 10) {
1617 Ok(value) if value <= div => value as f32 / div as f32,
1618 _ => return Err("Hsl format property could not be parsed"),
1619 }
1620 } else {
1621 return Err("Missing value in hsl format");
1622 }
1623 i += 1;
1624 }
1625 let [hue, sat, lit] = values;
1626
1627 let (r, g, b) = if sat == 0.0 {
1628 (lit, lit, lit)
1629 } else {
1630 let q = if lit < 0.5 {
1631 lit * (1.0 + sat)
1632 } else {
1633 lit + sat - lit * sat
1634 };
1635 let p = 2.0 * lit - q;
1636 let r = hue_to_rgb(p, q, hue + 1.0 / 3.0);
1637 let g = hue_to_rgb(p, q, hue);
1638 let b = hue_to_rgb(p, q, hue - 1.0 / 3.0);
1639 (r, g, b)
1640 };
1641
1642 let r = (0.5 + r * 255.0) as u8;
1644 let g = (0.5 + g * 255.0) as u8;
1645 let b = (0.5 + b * 255.0) as u8;
1646 Ok(Color::Rgb { r, g, b })
1647 } else {
1648 Err("Color format was not recognized")
1649 }
1650}
1651
1652const fn default_style() -> ContentStyle {
1654 ContentStyle {
1655 foreground_color: None,
1656 background_color: None,
1657 underline_color: None,
1658 attributes: Attributes::none(),
1659 }
1660}
1661
1662impl std::fmt::Debug for Form {
1663 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1664 struct DebugColor(Option<Color>);
1665 impl std::fmt::Debug for DebugColor {
1666 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1667 match self.0 {
1668 Some(Color::Rgb { r, g, b }) => write!(f, "Some(Rgb({r}, {g}, {b}))"),
1669 Some(Color::AnsiValue(ansi)) => write!(f, "Some(Ansi({ansi}))"),
1670 Some(color) => write!(f, "Some({color:?})"),
1671 None => f.write_str("None"),
1672 }
1673 }
1674 }
1675
1676 struct DebugAttributes(Attributes);
1677 impl std::fmt::Debug for DebugAttributes {
1678 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1679 if self.0.is_empty() {
1680 f.write_str("None")
1681 } else {
1682 let mut is_first = true;
1683 for attr in Attribute::iterator() {
1684 if self.0.has(attr) {
1685 if !is_first {
1686 f.write_str(" | ")?;
1687 }
1688 is_first = false;
1689 write!(f, "{attr:?}")?;
1690 }
1691 }
1692 Ok(())
1693 }
1694 }
1695 }
1696
1697 f.debug_struct("Form")
1698 .field("fg", &DebugColor(self.style.foreground_color))
1699 .field("bg", &DebugColor(self.style.background_color))
1700 .field("ul", &DebugColor(self.style.underline_color))
1701 .field("attr", &DebugAttributes(self.style.attributes))
1702 .finish()
1703 }
1704}
1705
1706impl std::fmt::Debug for InnerPalette {
1707 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1708 struct DebugForms<'a>(&'a [(String, Form)]);
1709 impl std::fmt::Debug for DebugForms<'_> {
1710 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1711 if f.alternate() {
1712 f.write_str("[\n")?;
1713 let max = self.0.len().ilog10() as usize + 3;
1714 for (n, (name, form)) in self.0.iter().enumerate() {
1715 let num = format!("{n}:");
1716 writeln!(f, "{num:<max$}({name}, {form:#?})")?;
1717 }
1718 f.write_str("]")
1719 } else {
1720 write!(f, "{:?}", self.0)
1721 }
1722 }
1723 }
1724
1725 struct DebugCursorShape(CursorShape);
1726 impl std::fmt::Debug for DebugCursorShape {
1727 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1728 match self.0 {
1729 CursorShape::DefaultUserShape => f.write_str("DefaultUserShape"),
1730 CursorShape::BlinkingBlock => f.write_str("BlinkingBlock"),
1731 CursorShape::SteadyBlock => f.write_str("SteadyBlock"),
1732 CursorShape::BlinkingUnderScore => f.write_str("BlinkingUnderScore"),
1733 CursorShape::SteadyUnderScore => f.write_str("SteadyUnderScore"),
1734 CursorShape::BlinkingBar => f.write_str("BlinkingBar"),
1735 CursorShape::SteadyBar => f.write_str("SteadyBar"),
1736 }
1737 }
1738 }
1739
1740 f.debug_struct("InnerPalette")
1741 .field("main_cursor", &self.main_cursor.map(DebugCursorShape))
1742 .field("extra_cursor", &self.extra_cursor.map(DebugCursorShape))
1743 .field("forms", &DebugForms(&self.forms))
1744 .field("masks", &self.masks)
1745 .finish()
1746 }
1747}
1748
1749impl std::fmt::Debug for FormKind {
1750 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1751 match self {
1752 Self::Normal => write!(f, "Normal"),
1753 Self::Ref(refed, _) => write!(f, "Ref({refed})"),
1754 Self::Weakest => write!(f, "Weakest"),
1755 Self::WeakestRef(refed, _) => write!(f, "WeakestRef({refed})"),
1756 }
1757 }
1758}
1759
1760pub const DEFAULT_ID: FormId = FormId(0);
1762pub const ACCENT_ID: FormId = FormId(1);
1764pub const M_CAR_ID: FormId = FormId(2);
1766pub const E_CAR_ID: FormId = FormId(3);
1768pub const M_SEL_ID: FormId = FormId(4);
1770pub const E_SEL_ID: FormId = FormId(5);
1772pub const CONTROL_CHAR_ID: FormId = FormId(7);