1use std::sync::{OnceLock, RwLock, RwLockReadGuard};
3
4use FormType::*;
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
17pub trait ColorScheme: Send + Sync + 'static {
19 fn apply(&self);
27
28 fn name(&self) -> &'static str;
30}
31
32static SENDER: OnceLock<DuatSender> = OnceLock::new();
33static BASE_FORMS: &[(&str, Form, FormType)] = &[
34 ("default", Form::new().0, Normal),
35 ("accent", Form::bold().0, Normal),
36 ("caret.main", Form::reverse().0, Normal),
37 ("caret.extra", Form::reverse().0, Ref(2)),
38 ("selection.main", Form::white().on_dark_grey().0, Normal),
39 ("selection.extra", Form::white().on_grey().0, Ref(5)),
40 ("cloak", Form::grey().on_black().0, Normal),
41 ("character.control", Form::grey().0, Normal),
42 ("param.path", Form::yellow().0, Normal),
43 ("param.path.open", Form::yellow().0, Ref(8)),
44 ("param.path.exists", Form::yellow().underlined().0, Normal),
45];
46
47mod global {
49 use std::{
50 any::TypeId,
51 collections::HashMap,
52 sync::{LazyLock, Mutex, OnceLock},
53 };
54
55 use super::{BASE_FORMS, BuiltForm, ColorScheme, CursorShape, Form, FormId, Painter, Palette};
56 #[doc(inline)]
57 pub use crate::{
58 __id_of__ as id_of, __set_many__ as set_many, __set_many_weak__ as set_many_weak,
59 };
60 use crate::{
61 context,
62 hook::{self, ColorSchemeSet},
63 };
64
65 static PALETTE: OnceLock<&'static Palette> = OnceLock::new();
66 static FORMS: OnceLock<&'static Mutex<Vec<&str>>> = OnceLock::new();
67 static COLORSCHEMES: LazyLock<Mutex<Vec<Box<dyn ColorScheme>>>> = LazyLock::new(Mutex::default);
68
69 #[doc(hidden)]
79 pub trait FormFmt {
80 fn kind(&self) -> Kind;
82 }
83 impl FormFmt for Form {
84 fn kind(&self) -> Kind {
85 Kind::Form(*self)
86 }
87 }
88
89 impl FormFmt for BuiltForm {
90 fn kind(&self) -> Kind {
91 Kind::Form(self.0)
92 }
93 }
94
95 impl FormFmt for &str {
96 fn kind(&self) -> Kind {
97 Kind::Ref(self.to_string())
98 }
99 }
100
101 impl FormFmt for &mut str {
102 fn kind(&self) -> Kind {
103 Kind::Ref(self.to_string())
104 }
105 }
106
107 impl FormFmt for String {
108 fn kind(&self) -> Kind {
109 Kind::Ref(self.clone())
110 }
111 }
112
113 pub fn set(name: impl ToString, form: impl FormFmt) -> FormId {
138 let name = name.to_string();
139 let cloned_name = name.clone();
140
141 match form.kind() {
142 Kind::Form(form) => PALETTE.get().unwrap().set_form(cloned_name, form),
143 Kind::Ref(refed) => PALETTE.get().unwrap().set_ref(cloned_name, refed),
144 };
145
146 let mut forms = FORMS.get().unwrap().lock().unwrap();
147 if let Kind::Ref(refed) = form.kind() {
148 position_of_name(&mut forms, refed);
149 }
150 FormId(position_of_name(&mut forms, name) as u16)
151 }
152
153 pub fn set_weak(name: impl ToString, form: impl FormFmt) -> FormId {
181 let name = name.to_string();
182 let cloned_name = name.clone();
183
184 match form.kind() {
185 Kind::Form(form) => PALETTE.get().unwrap().set_weak_form(cloned_name, form),
186 Kind::Ref(refed) => PALETTE.get().unwrap().set_weak_ref(cloned_name, refed),
187 };
188
189 let mut forms = FORMS.get().unwrap().lock().unwrap();
190 if let Kind::Ref(refed) = form.kind() {
191 position_of_name(&mut forms, refed);
192 }
193 FormId(position_of_name(&mut forms, name) as u16)
194 }
195
196 pub fn from_id(id: FormId) -> Form {
198 PALETTE
199 .get()
200 .unwrap()
201 .form_from_id(id)
202 .unwrap_or(Form::new().0)
203 }
204
205 pub fn main_cursor() -> (Form, Option<CursorShape>) {
207 PALETTE.get().unwrap().main_cursor()
208 }
209
210 pub fn extra_cursor() -> (Form, Option<CursorShape>) {
212 PALETTE.get().unwrap().extra_cursor()
213 }
214
215 pub fn set_main_cursor(shape: CursorShape) {
241 PALETTE.get().unwrap().set_main_cursor(shape);
242 }
243
244 pub fn set_extra_cursor(shape: CursorShape) {
270 PALETTE.get().unwrap().set_extra_cursor(shape);
271 }
272
273 pub fn unset_main_cursor() {
284 PALETTE.get().unwrap().unset_main_cursor();
285 }
286
287 pub fn unset_extra_cursor() {
301 PALETTE.get().unwrap().unset_extra_cursor();
302 }
303
304 pub fn unset_cursors() {
311 PALETTE.get().unwrap().unset_main_cursor();
312 PALETTE.get().unwrap().unset_extra_cursor();
313 }
314
315 pub fn painter_with_mask(mask: &'static str) -> Painter {
330 PALETTE.get().unwrap().painter(super::DEFAULT_ID, mask)
331 }
332
333 pub(crate) fn painter_with_widget_and_mask<W: ?Sized + 'static>(mask: &'static str) -> Painter {
335 PALETTE.get().unwrap().painter(
336 default_id(TypeId::of::<W>(), crate::utils::duat_name::<W>()),
337 mask,
338 )
339 }
340
341 pub fn enable_mask(mask: impl AsRef<str> + Send + Sync + 'static) {
401 let mask = mask.as_ref();
402 let mut inner = PALETTE.get().unwrap().0.write().unwrap();
403 if !inner.masks.iter().any(|(m, _)| *m == mask) {
404 let mut remaps: Vec<u16> = (0..inner.forms.len() as u16).collect();
405
406 for (i, (name, ..)) in inner.forms.iter().enumerate() {
407 if let Some((pref, suf)) = name.rsplit_once('.')
408 && suf == mask
409 && let Some(j) = inner.forms.iter().position(|(name, ..)| *name == pref)
410 {
411 remaps[j] = i as u16;
412 }
413 }
414
415 inner.masks.push((mask.to_string().leak(), remaps));
416 }
417 }
418
419 #[macro_export]
453 #[doc(hidden)]
454 macro_rules! __id_of__ {
455 ($form:expr) => {{
456 use $crate::form::{_set_many, DEFAULT_ID, FormId};
457
458 static mut WAS_SET: bool = false;
459 static mut ID: FormId = DEFAULT_ID;
460 if unsafe { WAS_SET } {
461 unsafe { ID }
462 } else {
463 let name = $form.to_string();
464 let id = _set_many(true, vec![(name, None)])[0];
465 unsafe {
466 ID = id;
467 WAS_SET = true;
468 }
469 id
470 }
471 }};
472 }
473
474 pub fn id_of_non_static(name: impl ToString) -> FormId {
481 let name = name.to_string();
482 _set_many(true, vec![(name, None)])[0]
483 }
484
485 pub fn ids_of_non_static(names: impl IntoIterator<Item = impl ToString>) -> Vec<FormId> {
492 let names: Vec<(String, Option<Kind>)> =
493 names.into_iter().map(|n| (n.to_string(), None)).collect();
494 _set_many(true, names)
495 }
496
497 #[doc(hidden)]
499 pub fn _set_many<S: AsRef<str> + Send + Sync + 'static>(
500 weak: bool,
501 sets: Vec<(S, Option<Kind>)>,
502 ) -> Vec<FormId> {
503 let mut ids = Vec::new();
504 let mut forms = FORMS.get().unwrap().lock().unwrap();
505 for (name, _) in sets.iter() {
506 ids.push(FormId(position_of_name(&mut forms, name) as u16));
507 }
508
509 PALETTE.get().unwrap().set_many(weak, &sets);
510
511 ids
512 }
513
514 pub fn add_colorscheme(cs: impl ColorScheme) {
525 let mut colorschemes = COLORSCHEMES.lock().unwrap();
526 let name = cs.name();
527 if let Some(i) = colorschemes.iter().position(|cs| cs.name() == name) {
528 colorschemes[i] = Box::new(cs);
529 } else {
530 colorschemes.push(Box::new(cs));
531 }
532 }
533
534 pub fn set_colorscheme(name: &str) {
541 let name = name.to_string();
542 let colorschemes = COLORSCHEMES.lock().unwrap();
543 if let Some(cs) = colorschemes.iter().find(|cs| cs.name() == name) {
544 cs.apply();
545 let name = cs.name();
546 context::queue(move |pa| _ = hook::trigger(pa, ColorSchemeSet(name)));
547 } else {
548 context::error!("The colorscheme [a]{name}[] was not found");
549 }
550 }
551
552 #[macro_export]
561 #[doc(hidden)]
562 macro_rules! __set_many__ {
563 ($(($name:literal, $form:expr)),+ $(,)?) => {{
564 use $crate::form::FormFmt;
565 $crate::form::_set_many(false, vec![$( ($name, Some($form.kind())) ),+]);
566 }}
567 }
568
569 #[macro_export]
583 #[doc(hidden)]
584 macro_rules! __set_many_weak__ {
585 ($(($name:literal, $form:expr)),+ $(,)?) => {{
586 use $crate::form::FormFmt;
587 $crate::form::_set_many(true, vec![$( ($name, Some($form.kind())) ),+]);
588 }}
589 }
590
591 pub(crate) fn exists(name: &str) -> bool {
593 FORMS.get().unwrap().lock().unwrap().contains(&name)
594 }
595
596 pub(crate) fn colorscheme_exists(name: &str) -> bool {
598 COLORSCHEMES
599 .lock()
600 .unwrap()
601 .iter()
602 .any(|cs| cs.name() == name)
603 }
604
605 pub(super) fn name_of(id: FormId) -> &'static str {
607 FORMS.get().unwrap().lock().unwrap()[id.0 as usize]
608 }
609
610 fn default_id(type_id: TypeId, type_name: &'static str) -> FormId {
611 static IDS: LazyLock<Mutex<HashMap<TypeId, FormId>>> = LazyLock::new(Mutex::default);
612 let mut ids = IDS.lock().unwrap();
613
614 if let Some(id) = ids.get(&type_id) {
615 *id
616 } else {
617 let name = format!("default.{type_name}");
618 let id = _set_many(true, vec![(name, None)])[0];
619 ids.insert(type_id, id);
620 id
621 }
622 }
623
624 fn position_of_name(names: &mut Vec<&'static str>, name: impl AsRef<str>) -> usize {
625 let name = name.as_ref();
626 if let Some((i, _)) = names.iter().enumerate().find(|(_, rhs)| **rhs == name) {
627 i
628 } else if let Some((refed, _)) = name.rsplit_once('.') {
629 position_of_name(names, refed);
630 names.push(name.to_string().leak());
631 names.len() - 1
632 } else {
633 names.push(name.to_string().leak());
634 names.len() - 1
635 }
636 }
637
638 #[doc(hidden)]
642 pub fn get_initial() -> (&'static Mutex<Vec<&'static str>>, &'static Palette) {
643 let forms = Box::leak(Box::new(Mutex::new(
644 BASE_FORMS.iter().map(|(n, ..)| *n).collect(),
645 )));
646 let palette = Box::leak(Box::new(Palette::new()));
647 (forms, palette)
648 }
649
650 #[doc(hidden)]
654 pub fn set_initial((forms, palette): (&'static Mutex<Vec<&'static str>>, &'static Palette)) {
655 FORMS.set(forms).expect("Forms setup ran twice");
656 PALETTE.set(palette).expect("Forms setup ran twice");
657 }
658
659 #[doc(hidden)]
661 pub enum Kind {
662 Form(Form),
663 Ref(String),
664 }
665}
666
667#[derive(Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord)]
681pub struct FormId(u16);
682
683impl FormId {
684 pub const fn to_tag(self, prio: u8) -> FormTag {
693 FormTag(self, prio)
694 }
695
696 pub const fn to_u16(self) -> u16 {
700 self.0
701 }
702
703 pub fn name(self) -> &'static str {
705 name_of(self)
706 }
707}
708
709impl std::fmt::Debug for FormId {
710 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
711 write!(f, "FormId({})", name_of(*self))
712 }
713}
714
715macro_rules! mimic_method_new {
717 (#[$attr:meta] $method:ident $attrib:expr) => {
718 #[$attr]
720 pub const fn $method() -> BuiltForm {
722 let mut built = Form::new();
723 built.0.style.attributes = built.0.style.attributes.with($attrib);
724 built
725 }
726 };
727 (#[$attr:meta] $fg:ident $bg:ident $ul:ident $color:expr) => {
728 #[$attr]
730 pub const fn $fg() -> BuiltForm {
732 let mut built = Form::new();
733 built.0.style.foreground_color = Some($color);
734 built
735 }
736
737 #[$attr]
739 pub const fn $bg() -> BuiltForm {
741 let mut built = Form::new();
742 built.0.style.background_color = Some($color);
743 built
744 }
745
746 #[$attr]
748 pub const fn $ul() -> BuiltForm {
757 let mut built = Form::new();
758 built.0.style.underline_color = Some($color);
759 built
760 }
761 };
762}
763
764macro_rules! mimic_method_mod {
765 (#[$attr:meta] $method:ident $attrib:expr) => {
766 #[$attr]
768 pub const fn $method(mut self) -> Self {
770 self.0.style.attributes = self.0.style.attributes.with($attrib);
771 self
772 }
773 };
774 (#[$attr:meta] $fg:ident $bg:ident $ul:ident $color:expr) => {
775 #[$attr]
777 pub const fn $fg(mut self) -> Self {
778 self.0.style.foreground_color = Some($color);
779 self
780 }
781
782 #[$attr]
784 pub const fn $bg(mut self) -> Self {
785 self.0.style.background_color = Some($color);
786 self
787 }
788
789 #[$attr]
791 pub const fn $ul(mut self) -> Self {
798 self.0.style.underline_color = Some($color);
799 self
800 }
801 };
802}
803#[derive(Clone, Copy, PartialEq, Eq)]
805pub struct Form {
806 pub style: ContentStyle,
808}
809
810#[rustfmt::skip]
811impl Form {
812 mimic_method_new!(bold Attribute::Bold);
813 mimic_method_new!(dim Attribute::Dim);
814 mimic_method_new!(italic Attribute::Italic);
815 mimic_method_new!(underlined Attribute::Underlined);
816 mimic_method_new!(double_underlined Attribute::DoubleUnderlined);
817 mimic_method_new!(undercurled Attribute::Undercurled);
818 mimic_method_new!(underdashed Attribute::Underdashed);
819 mimic_method_new!(reverse Attribute::Reverse);
820 mimic_method_new!(crossed_out Attribute::CrossedOut);
821 mimic_method_new!(black on_black underline_black Color::Black);
822 mimic_method_new!(dark_grey on_dark_grey underline_dark_grey Color::DarkGrey);
823 mimic_method_new!(red on_red underline_red Color::Red);
824 mimic_method_new!(dark_red on_dark_red underline_dark_red Color::DarkRed);
825 mimic_method_new!(green on_green underline_green Color::Green);
826 mimic_method_new!(
827 dark_green on_dark_green underline_dark_green Color::DarkGreen
828 );
829 mimic_method_new!(yellow on_yellow underline_yellow Color::Yellow);
830 mimic_method_new!(
831 dark_yellow on_dark_yellow underline_dark_yellow Color::DarkYellow
832 );
833 mimic_method_new!(blue on_blue underline_blue Color::Blue);
834 mimic_method_new!(dark_blue on_dark_blue underline_dark_blue Color::DarkBlue);
835 mimic_method_new!(magenta on_magenta underline_magenta Color::Magenta);
836 mimic_method_new!(
837 dark_magenta on_dark_magenta underline_dark_magenta Color::DarkMagenta
838 );
839 mimic_method_new!(cyan on_cyan underline_cyan Color::Cyan);
840 mimic_method_new!(dark_cyan on_dark_cyan underline_dark_cyan Color::DarkCyan);
841 mimic_method_new!(white on_white underline_white Color::White);
842 mimic_method_new!(grey on_grey underline_grey Color::Grey);
843}
844
845impl Form {
846 #[allow(clippy::new_ret_no_self)]
850 pub const fn new() -> BuiltForm {
851 let style = ContentStyle {
852 foreground_color: None,
853 background_color: None,
854 underline_color: None,
855 attributes: Attributes::none(),
856 };
857 BuiltForm(Self { style })
858 }
859
860 pub const fn reset() -> BuiltForm {
867 let mut built = Form::new();
868 built.0.style.attributes = built.0.style.attributes.with(Attribute::Reset);
869 built
870 }
871
872 pub const fn with(str: &str) -> BuiltForm {
882 let mut built = Form::new();
883 built.0.style.foreground_color = match str_to_color(str) {
884 Ok(color) => Some(color),
885 Err(err) => panic!("{}", err),
886 };
887 built
888 }
889
890 pub const fn on(str: &str) -> BuiltForm {
900 let mut built = Form::new();
901 built.0.style.background_color = match str_to_color(str) {
902 Ok(color) => Some(color),
903 Err(err) => panic!("{}", err),
904 };
905 built
906 }
907
908 pub const fn underline(str: &str) -> BuiltForm {
918 let mut built = Form::new();
919 built.0.style.underline_color = match str_to_color(str) {
920 Ok(color) => Some(color),
921 Err(err) => panic!("{}", err),
922 };
923 built
924 }
925
926 pub const fn fg(&self) -> Option<Color> {
928 self.style.foreground_color
929 }
930
931 pub const fn bg(&self) -> Option<Color> {
933 self.style.background_color
934 }
935
936 pub const fn ul(&self) -> Option<Color> {
938 self.style.underline_color
939 }
940
941 pub const fn attrs(&self) -> Attributes {
943 self.style.attributes
944 }
945}
946
947#[derive(Clone, Copy, Debug)]
956pub struct BuiltForm(Form);
957
958#[rustfmt::skip]
959impl BuiltForm {
960 mimic_method_mod!(bold Attribute::Bold);
961 mimic_method_mod!(dim Attribute::Dim);
962 mimic_method_mod!(italic Attribute::Italic);
963 mimic_method_mod!(underlined Attribute::Underlined);
964 mimic_method_mod!(double_underlined Attribute::DoubleUnderlined);
965 mimic_method_mod!(undercurled Attribute::Undercurled);
966 mimic_method_mod!(underdashed Attribute::Underdashed);
967 mimic_method_mod!(reverse Attribute::Reverse);
968 mimic_method_mod!(crossed_out Attribute::CrossedOut);
969 mimic_method_mod!(overlined Attribute::OverLined);
970 mimic_method_mod!(black on_black underline_black Color::Black);
971 mimic_method_mod!(dark_grey on_dark_grey underline_dark_grey Color::DarkGrey);
972 mimic_method_mod!(red on_red underline_red Color::Red);
973 mimic_method_mod!(dark_red on_dark_red underline_dark_red Color::DarkRed);
974 mimic_method_mod!(green on_green underline_green Color::Green);
975 mimic_method_mod!(
976 dark_green on_dark_green underline_dark_green Color::DarkGreen
977 );
978 mimic_method_mod!(yellow on_yellow underline_yellow Color::Yellow);
979 mimic_method_mod!(
980 dark_yellow on_dark_yellow underline_dark_yellow Color::DarkYellow
981 );
982 mimic_method_mod!(blue on_blue underline_blue Color::Blue);
983 mimic_method_mod!(dark_blue on_dark_blue underline_dark_blue Color::DarkBlue);
984 mimic_method_mod!(magenta on_magenta underline_magenta Color::Magenta);
985 mimic_method_mod!(
986 dark_magenta on_dark_magenta underline_dark_magenta Color::DarkMagenta
987 );
988 mimic_method_mod!(cyan on_cyan underline_cyan Color::Cyan);
989 mimic_method_mod!(dark_cyan on_dark_cyan underline_dark_cyan Color::DarkCyan);
990 mimic_method_mod!(white on_white underline_white Color::White);
991 mimic_method_mod!(grey on_grey underline_grey Color::Grey);
992}
993
994impl BuiltForm {
995 pub const fn reset(mut self) -> BuiltForm {
1002 self.0.style.attributes = self.0.style.attributes.with(Attribute::Reset);
1003 self
1004 }
1005
1006 pub const fn with(mut self, str: &str) -> Self {
1016 self.0.style.foreground_color = match str_to_color(str) {
1017 Ok(color) => Some(color),
1018 Err(err) => panic!("{}", err),
1019 };
1020 self
1021 }
1022
1023 pub const fn on(mut self, str: &str) -> Self {
1033 self.0.style.background_color = match str_to_color(str) {
1034 Ok(color) => Some(color),
1035 Err(err) => panic!("{}", err),
1036 };
1037 self
1038 }
1039
1040 pub const fn underline(mut self, str: &str) -> Self {
1050 self.0.style.underline_color = match str_to_color(str) {
1051 Ok(color) => Some(color),
1052 Err(err) => panic!("{}", err),
1053 };
1054 self
1055 }
1056}
1057
1058impl std::ops::Deref for BuiltForm {
1059 type Target = Form;
1060
1061 fn deref(&self) -> &Self::Target {
1062 &self.0
1063 }
1064}
1065
1066impl std::ops::DerefMut for BuiltForm {
1067 fn deref_mut(&mut self) -> &mut Self::Target {
1068 &mut self.0
1069 }
1070}
1071
1072impl From<BuiltForm> for Form {
1073 fn from(value: BuiltForm) -> Self {
1074 value.0
1075 }
1076}
1077
1078pub const DEFAULT_ID: FormId = FormId(0);
1080pub const ACCENT_ID: FormId = FormId(1);
1082pub const M_CAR_ID: FormId = FormId(2);
1084pub const E_CAR_ID: FormId = FormId(3);
1086pub const M_SEL_ID: FormId = FormId(4);
1088pub const E_SEL_ID: FormId = FormId(5);
1090pub const CONTROL_CHAR_ID: FormId = FormId(7);
1092
1093#[derive(Debug)]
1097#[doc(hidden)]
1098pub struct Palette(RwLock<InnerPalette>);
1099
1100impl Palette {
1101 fn new() -> Self {
1103 let main_cursor = Some(CursorShape::DefaultUserShape);
1104 Self(RwLock::new(InnerPalette {
1105 main_cursor,
1106 extra_cursor: main_cursor,
1107 forms: BASE_FORMS.to_vec(),
1108 masks: vec![(
1109 "".to_string().leak(),
1110 (0..BASE_FORMS.len() as u16).collect(),
1111 )],
1112 }))
1113 }
1114
1115 fn set_form(&self, name: impl AsRef<str>, form: Form) {
1117 let name = name.as_ref();
1118 self.0.write().unwrap().set_form(name, form);
1119 }
1120
1121 fn set_weak_form(&self, name: impl AsRef<str>, form: Form) {
1123 let name = name.as_ref();
1124 self.0.write().unwrap().set_weak_form(name, form);
1125 }
1126
1127 fn set_ref(&self, name: impl AsRef<str>, refed: impl AsRef<str>) {
1129 let (name, refed) = (name.as_ref(), refed.as_ref());
1130 self.0.write().unwrap().set_ref(name, refed);
1131 }
1132
1133 fn set_weak_ref(&self, name: impl AsRef<str>, refed: impl AsRef<str>) {
1135 let (name, refed) = (name.as_ref(), refed.as_ref());
1136 self.0.write().unwrap().set_weak_ref(name, refed);
1137 }
1138
1139 fn set_many<S: AsRef<str>>(&self, weak: bool, sets: &[(S, Option<self::global::Kind>)]) {
1141 let mut inner = self.0.write().unwrap();
1142 for (name, kind) in sets {
1143 match (weak, kind) {
1144 (false, Some(Kind::Form(form))) => inner.set_form(name.as_ref(), *form),
1145 (false, Some(Kind::Ref(refed))) => inner.set_ref(name.as_ref(), refed),
1146 (true, Some(Kind::Form(form))) => inner.set_weak_form(name.as_ref(), *form),
1147 (true, Some(Kind::Ref(refed))) => inner.set_weak_ref(name.as_ref(), refed),
1148 (_, None) => {
1149 position_and_form(&mut inner.forms, name);
1150 }
1151 }
1152 }
1153 }
1154
1155 fn form_from_id(&self, id: FormId) -> Option<Form> {
1157 let inner = self.0.read().unwrap();
1158 inner.forms.get(id.0 as usize).map(|(_, form, _)| *form)
1159 }
1160
1161 fn main_cursor(&self) -> (Form, Option<CursorShape>) {
1163 let form = self.form_from_id(M_CAR_ID).unwrap();
1164 (form, self.0.read().unwrap().main_cursor)
1165 }
1166
1167 fn extra_cursor(&self) -> (Form, Option<CursorShape>) {
1169 let form = self.form_from_id(E_CAR_ID).unwrap();
1170 (form, self.0.read().unwrap().extra_cursor)
1171 }
1172
1173 fn set_main_cursor(&self, shape: CursorShape) {
1175 self.0.write().unwrap().main_cursor = Some(shape);
1176 if let Some(sender) = SENDER.get() {
1177 sender.send(DuatEvent::FormChange);
1178 }
1179 }
1180
1181 fn set_extra_cursor(&self, shape: CursorShape) {
1183 self.0.write().unwrap().extra_cursor = Some(shape);
1184 if let Some(sender) = SENDER.get() {
1185 sender.send(DuatEvent::FormChange);
1186 }
1187 }
1188
1189 fn unset_main_cursor(&self) {
1191 self.0.write().unwrap().main_cursor = None;
1192 if let Some(sender) = SENDER.get() {
1193 sender.send(DuatEvent::FormChange);
1194 }
1195 }
1196
1197 fn unset_extra_cursor(&self) {
1199 self.0.write().unwrap().extra_cursor = None;
1200 if let Some(sender) = SENDER.get() {
1201 sender.send(DuatEvent::FormChange);
1202 }
1203 }
1204
1205 fn painter(&'static self, default_id: FormId, mask: &str) -> Painter {
1207 let inner = self.0.read().unwrap();
1208 let mask_i = inner
1209 .masks
1210 .iter()
1211 .position(|(m, _)| *m == mask)
1212 .unwrap_or_default();
1213
1214 let default = inner
1215 .forms
1216 .get(match inner.masks[mask_i].1.get(default_id.0 as usize) {
1217 Some(i) => *i as usize,
1218 None => default_id.0 as usize,
1219 })
1220 .map(|(_, f, _)| *f)
1221 .unwrap_or(Form::new().0);
1222
1223 Painter {
1224 inner,
1225 mask_i,
1226 default,
1227 forms: Vec::new(),
1228 set_fg: true,
1229 set_bg: true,
1230 set_ul: true,
1231 reset_attrs: false,
1232 prev_style: None,
1233 }
1234 }
1235}
1236
1237struct InnerPalette {
1238 main_cursor: Option<CursorShape>,
1239 extra_cursor: Option<CursorShape>,
1240 forms: Vec<(&'static str, Form, FormType)>,
1241 masks: Vec<(&'static str, Vec<u16>)>,
1242}
1243
1244impl InnerPalette {
1245 fn set_form(&mut self, name: &str, form: Form) {
1247 let (i, _) = position_and_form(&mut self.forms, name);
1248
1249 self.forms[i].1 = form;
1250 self.forms[i].2 = FormType::Normal;
1251
1252 for refed in refs_of(self, i) {
1253 self.forms[refed].1 = form;
1254 }
1255
1256 if let Some(sender) = SENDER.get() {
1257 sender.send(DuatEvent::FormChange);
1258 }
1259
1260 mask_form(name, i, self);
1261
1262 let form_set = FormSet((self.forms[i].0, FormId(i as u16), form));
1263 context::queue(move |pa| _ = hook::trigger(pa, form_set));
1264 }
1265
1266 fn set_weak_form(&mut self, name: &str, form: Form) {
1268 let (i, _) = position_and_form(&mut self.forms, name);
1269
1270 let (_, f, f_ty) = &mut self.forms[i];
1271 if let FormType::Weakest | FormType::WeakestRef(_) = f_ty {
1272 *f = form;
1273 *f_ty = FormType::Normal;
1274
1275 if let Some(sender) = SENDER.get() {
1276 sender.send(DuatEvent::FormChange);
1277 }
1278 for refed in refs_of(self, i) {
1279 self.forms[refed].1 = form;
1280 }
1281
1282 mask_form(name, i, self);
1283 }
1284 }
1285
1286 fn set_ref(&mut self, name: &str, refed: &str) {
1288 let (refed, form) = position_and_form(&mut self.forms, refed);
1289 let (i, _) = position_and_form(&mut self.forms, name);
1290
1291 self.forms[i].1 = form;
1292 for refed in refs_of(self, i) {
1293 self.forms[refed].1 = form;
1294 }
1295
1296 if would_be_circular(self, i, refed) {
1298 self.forms[i].2 = FormType::Normal;
1299 } else {
1300 self.forms[i].2 = FormType::Ref(refed);
1301 }
1302
1303 if let Some(sender) = SENDER.get() {
1304 sender.send(DuatEvent::FormChange);
1305 }
1306
1307 mask_form(name, i, self);
1308 let form_set = FormSet((self.forms[i].0, FormId(i as u16), form));
1309 context::queue(move |pa| _ = hook::trigger(pa, form_set));
1310 }
1311
1312 fn set_weak_ref(&mut self, name: &str, refed: &str) {
1314 let (refed, form) = position_and_form(&mut self.forms, refed);
1315 let (i, _) = position_and_form(&mut self.forms, name);
1316
1317 let (_, f, f_ty) = &mut self.forms[i];
1320 if let FormType::Weakest | FormType::WeakestRef(_) = f_ty {
1321 *f = form;
1322 *f_ty = FormType::WeakestRef(refed);
1323
1324 if let Some(sender) = SENDER.get() {
1325 sender.send(DuatEvent::FormChange);
1326 }
1327 for refed in refs_of(self, i) {
1328 self.forms[refed].1 = form;
1329 }
1330
1331 mask_form(name, i, self);
1332 }
1333 }
1334}
1335
1336fn mask_form(name: &str, form_i: usize, inner: &mut InnerPalette) {
1338 if inner.masks[0].1.len() < inner.forms.len() {
1339 for (_, remaps) in inner.masks.iter_mut() {
1340 remaps.extend(remaps.len() as u16..inner.forms.len() as u16);
1341 }
1342 }
1343
1344 if let Some((pref, mask)) = name.rsplit_once(".")
1345 && let Some((_, remaps)) = inner.masks.iter_mut().find(|(m, _)| *m == mask)
1346 && let Some(j) = inner.forms.iter().position(|(name, ..)| *name == pref)
1347 {
1348 remaps[j] = form_i as u16;
1349 }
1350}
1351
1352pub struct Painter {
1412 inner: RwLockReadGuard<'static, InnerPalette>,
1413 mask_i: usize,
1414 default: Form,
1415 forms: Vec<(Form, FormId, u8)>,
1416 set_fg: bool,
1417 set_bg: bool,
1418 set_ul: bool,
1419 reset_attrs: bool,
1420 prev_style: Option<ContentStyle>,
1421}
1422
1423impl Painter {
1424 #[inline(always)]
1432 pub fn apply(&mut self, id: FormId, prio: u8) {
1433 let (_, mask) = &self.inner.masks[self.mask_i];
1434 let id = FormId(mask.get(id.0 as usize).copied().unwrap_or(id.0));
1435
1436 let forms = &self.inner.forms;
1437 let form = forms
1438 .get(id.0 as usize)
1439 .map(|(_, f, _)| *f)
1440 .unwrap_or(Form::new().0);
1441
1442 let gt = |(.., p): &&(_, _, u8)| *p > prio;
1443 let i = self.forms.len() - self.forms.iter().rev().take_while(gt).count();
1444 self.forms.insert(i, (form, id, prio));
1445
1446 self.set_fg |= form.fg().is_some();
1447 self.set_bg |= form.bg().is_some();
1448 self.set_ul |= form.ul().is_some();
1449 self.reset_attrs |= form.attrs().has(Attribute::Reset);
1450 }
1451
1452 #[inline(always)]
1455 pub fn remove(&mut self, id: FormId) {
1456 let mask = &self.inner.masks[self.mask_i].1;
1457 let id = FormId(mask.get(id.0 as usize).copied().unwrap_or(id.0));
1458
1459 let mut applied_forms = self.forms.iter().enumerate();
1460 if let Some((i, &(form, ..))) = applied_forms.rfind(|(_, (_, lhs, _))| *lhs == id) {
1461 self.forms.remove(i);
1462
1463 self.set_fg |= form.fg().is_some();
1464 self.set_bg |= form.bg().is_some();
1465 self.set_ul |= form.ul().is_some();
1466 self.reset_attrs |= !form.attrs().is_empty();
1467 };
1468 }
1469
1470 #[inline(always)]
1476 pub fn reset(&mut self) -> ContentStyle {
1477 self.forms.clear();
1478 self.absolute_style()
1479 }
1480
1481 #[inline(always)]
1486 pub fn absolute_style(&self) -> ContentStyle {
1487 let mut style = self.default.style;
1488
1489 for &(form, ..) in &self.forms {
1490 style.foreground_color = form.fg().or(style.foreground_color);
1491 style.background_color = form.bg().or(style.background_color);
1492 style.underline_color = form.ul().or(style.underline_color);
1493 style.attributes = if form.attrs().has(Attribute::Reset) {
1494 form.attrs()
1495 } else {
1496 form.attrs() | style.attributes
1497 }
1498 }
1499
1500 style
1501 }
1502
1503 #[inline(always)]
1515 pub fn relative_style(&mut self) -> Option<ContentStyle> {
1516 let abs_style = self.absolute_style();
1517 let mut style = abs_style;
1518
1519 if style.attributes.has(Attribute::Reset) || self.reset_attrs {
1520 style.attributes.set(Attribute::Reset);
1521 } else {
1525 style.foreground_color = self
1526 .set_fg
1527 .then_some(style.foreground_color.unwrap_or(Color::Reset))
1528 .filter(|fg| Some(*fg) != self.prev_style.and_then(|s| s.foreground_color));
1529 style.background_color = self
1530 .set_bg
1531 .then_some(style.background_color.unwrap_or(Color::Reset))
1532 .filter(|bg| Some(*bg) != self.prev_style.and_then(|s| s.background_color));
1533 style.underline_color = self
1534 .set_ul
1535 .then_some(style.underline_color.unwrap_or(Color::Reset))
1536 .filter(|ul| Some(*ul) != self.prev_style.and_then(|s| s.underline_color));
1537 }
1538
1539 self.set_fg = false;
1540 self.set_bg = false;
1541 self.set_ul = false;
1542 self.reset_attrs = false;
1543
1544 if let Some(prev_style) = self.prev_style.replace(abs_style) {
1545 (style != prev_style && style != Default::default()).then_some(style)
1546 } else {
1547 Some(style)
1548 }
1549 }
1550
1551 pub fn reset_prev_style(&mut self) {
1557 self.prev_style = None;
1558 self.set_fg = true;
1559 self.set_bg = true;
1560 self.set_ul = true;
1561 self.reset_attrs = true;
1562 }
1563
1564 #[inline(always)]
1566 pub fn apply_main_cursor(&mut self) {
1567 self.apply(M_CAR_ID, 100);
1568 }
1569
1570 #[inline(always)]
1572 pub fn remove_main_caret(&mut self) {
1573 self.remove(M_CAR_ID);
1574 }
1575
1576 #[inline(always)]
1578 pub fn apply_extra_cursor(&mut self) {
1579 self.apply(E_CAR_ID, 100);
1580 }
1581
1582 #[inline(always)]
1584 pub fn remove_extra_caret(&mut self) {
1585 self.remove(E_CAR_ID);
1586 }
1587
1588 pub fn main_cursor(&self) -> Option<CursorShape> {
1590 self.inner.main_cursor
1591 }
1592
1593 pub fn extra_cursor(&self) -> Option<CursorShape> {
1595 self.inner.extra_cursor
1596 }
1597
1598 pub fn get_default(&self) -> Form {
1600 self.default
1601 }
1602}
1603
1604pub(crate) fn set_sender(sender: DuatSender) {
1605 SENDER
1606 .set(sender)
1607 .unwrap_or_else(|_| panic!("Sender set more than once"));
1608}
1609
1610#[derive(Clone)]
1612enum FormType {
1613 Normal,
1614 Ref(usize),
1615 Weakest,
1616 WeakestRef(usize),
1617}
1618
1619fn refs_of(inner: &InnerPalette, refed: usize) -> Vec<usize> {
1621 let mut refs = Vec::new();
1622 for (i, (.., f_ty)) in inner.forms.iter().enumerate() {
1623 if let FormType::Ref(ref_id) | FormType::WeakestRef(ref_id) = f_ty
1624 && *ref_id == refed
1625 {
1626 refs.push(i);
1627 refs.extend(refs_of(inner, i));
1628 }
1629 }
1630 refs
1631}
1632
1633fn would_be_circular(inner: &InnerPalette, referee: usize, refed: usize) -> bool {
1635 if let (.., FormType::Ref(refed_ref) | FormType::WeakestRef(refed_ref)) = inner.forms[refed] {
1636 match refed_ref == referee {
1637 true => true,
1638 false => would_be_circular(inner, referee, refed_ref),
1639 }
1640 } else {
1641 false
1642 }
1643}
1644
1645fn position_and_form(
1646 forms: &mut Vec<(&str, Form, FormType)>,
1647 name: impl AsRef<str>,
1648) -> (usize, Form) {
1649 let name = name.as_ref();
1650 if let Some((i, (_, form, _))) = forms.iter().enumerate().find(|(_, (lhs, ..))| *lhs == name) {
1651 (i, *form)
1652 } else if let Some((refed, _)) = name.rsplit_once('.') {
1653 let (i, form) = position_and_form(forms, refed);
1654 forms.push((name.to_string().leak(), form, FormType::WeakestRef(i)));
1655 (forms.len() - 1, form)
1656 } else {
1657 forms.push((name.to_string().leak(), Form::new().0, FormType::Weakest));
1658 (forms.len() - 1, Form::new().0)
1659 }
1660}
1661
1662const fn str_to_color(str: &str) -> std::result::Result<Color, &'static str> {
1664 const fn strip_prefix<'a>(prefix: &str, str: &'a str) -> Option<&'a str> {
1665 let prefix = prefix.as_bytes();
1666
1667 let mut i = 0;
1668 while i < prefix.len() {
1669 if str.as_bytes()[i] != prefix[i] {
1670 return None;
1671 }
1672 i += 1;
1673 }
1674
1675 Some(str.split_at(prefix.len()).1)
1676 }
1677 const fn strip_suffix<'a>(suffix: &str, str: &'a str) -> Option<&'a str> {
1678 let prefix = suffix.as_bytes();
1679
1680 let mut i = str.len() - 1;
1681 while i >= str.len() - prefix.len() {
1682 if str.as_bytes()[i] != prefix[i - (str.len() - prefix.len())] {
1683 return None;
1684 }
1685 i += 1;
1686 }
1687
1688 Some(str.split_at(str.len() - suffix.len()).0)
1689 }
1690 const fn split_space(str: &str) -> Option<(&str, &str)> {
1691 if str.is_empty() {
1692 return None;
1693 }
1694
1695 let mut i = 0;
1696 while i < str.len() {
1697 if str.as_bytes()[i] == b' ' {
1698 break;
1699 }
1700 i += 1;
1701 }
1702
1703 let (cut, rest) = str.split_at(i);
1704 let (_, rest) = rest.split_at(if rest.is_empty() { 0 } else { 1 });
1705 Some((cut, rest))
1706 }
1707 const fn hue_to_rgb(p: f32, q: f32, mut t: f32) -> f32 {
1708 t = if t < 0.0 { t + 1.0 } else { t };
1709 t = if t > 1.0 { t - 1.0 } else { t };
1710 if t < 1.0 / 6.0 {
1711 p + (q - p) * 6.0 * t
1712 } else if t < 1.0 / 2.0 {
1713 q
1714 } else if t < 2.0 / 3.0 {
1715 p + (q - p) * (2.0 / 3.0 - t) * 6.0
1716 } else {
1717 p
1718 }
1719 }
1720
1721 if let Some(hex) = strip_prefix("#", str) {
1723 let total = match u32::from_str_radix(hex, 16) {
1724 Ok(total) if hex.len() == 6 => total,
1725 _ => return Err("Hexcode does not contain 6 hex values"),
1726 };
1727 let r = (total >> 16) as u8;
1728 let g = (total >> 8) as u8;
1729 let b = total as u8;
1730
1731 Ok(Color::Rgb { r, g, b })
1732 } else if let Some(mut rgb) = strip_prefix("rgb ", str) {
1734 let mut values = [0, 0, 0];
1735 let mut i = 0;
1736
1737 while i < values.len() {
1738 if let Some((cut, rest)) = split_space(rgb) {
1739 rgb = rest;
1740 values[i] = match u8::from_str_radix(cut, 10) {
1741 Ok(value) => value,
1742 Err(_) => return Err("Rgb format value could not be parsed"),
1743 }
1744 } else {
1745 return Err("Missing value in rgb format");
1746 }
1747 i += 1;
1748 }
1749
1750 let [r, g, b] = values;
1751 Ok(Color::Rgb { r, g, b })
1752 } else if let Some(mut hsl) = strip_prefix("hsl ", str) {
1754 let mut values = [0.0, 0.0, 0.0];
1755 let mut i = 0;
1756 while i < values.len() {
1757 if let Some((cut, rest)) = split_space(hsl) {
1758 hsl = rest;
1759 let (num, div) = match strip_suffix("%", cut) {
1760 Some(perc) => (perc, 100),
1761 None => (cut, 255),
1762 };
1763 values[i] = match u8::from_str_radix(num, 10) {
1764 Ok(value) if value <= div => value as f32 / div as f32,
1765 _ => return Err("Hsl format property could not be parsed"),
1766 }
1767 } else {
1768 return Err("Missing value in hsl format");
1769 }
1770 i += 1;
1771 }
1772 let [hue, sat, lit] = values;
1773
1774 let (r, g, b) = if sat == 0.0 {
1775 (lit, lit, lit)
1776 } else {
1777 let q = if lit < 0.5 {
1778 lit * (1.0 + sat)
1779 } else {
1780 lit + sat - lit * sat
1781 };
1782 let p = 2.0 * lit - q;
1783 let r = hue_to_rgb(p, q, hue + 1.0 / 3.0);
1784 let g = hue_to_rgb(p, q, hue);
1785 let b = hue_to_rgb(p, q, hue - 1.0 / 3.0);
1786 (r, g, b)
1787 };
1788
1789 let r = (0.5 + r * 255.0) as u8;
1791 let g = (0.5 + g * 255.0) as u8;
1792 let b = (0.5 + b * 255.0) as u8;
1793 Ok(Color::Rgb { r, g, b })
1794 } else {
1795 Err("Color format was not recognized")
1796 }
1797}
1798
1799impl std::fmt::Debug for Form {
1800 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1801 struct DebugColor(Option<Color>);
1802 impl std::fmt::Debug for DebugColor {
1803 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1804 match self.0 {
1805 Some(Color::Rgb { r, g, b }) => write!(f, "Some(Rgb({r}, {g}, {b}))"),
1806 Some(Color::AnsiValue(ansi)) => write!(f, "Some(Ansi({ansi}))"),
1807 Some(color) => write!(f, "Some({color:?})"),
1808 None => f.write_str("None"),
1809 }
1810 }
1811 }
1812
1813 struct DebugAttributes(Attributes);
1814 impl std::fmt::Debug for DebugAttributes {
1815 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1816 if self.0.is_empty() {
1817 f.write_str("None")
1818 } else {
1819 let mut is_first = true;
1820 for attr in Attribute::iterator() {
1821 if self.0.has(attr) {
1822 if !is_first {
1823 f.write_str(" | ")?;
1824 }
1825 is_first = false;
1826 write!(f, "{attr:?}")?;
1827 }
1828 }
1829 Ok(())
1830 }
1831 }
1832 }
1833
1834 f.debug_struct("Form")
1835 .field("fg", &DebugColor(self.style.foreground_color))
1836 .field("bg", &DebugColor(self.style.background_color))
1837 .field("ul", &DebugColor(self.style.underline_color))
1838 .field("attr", &DebugAttributes(self.style.attributes))
1839 .finish()
1840 }
1841}
1842
1843impl std::fmt::Debug for InnerPalette {
1844 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1845 struct DebugForms<'a>(&'a [(&'static str, Form, FormType)]);
1846 impl std::fmt::Debug for DebugForms<'_> {
1847 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1848 if f.alternate() {
1849 f.write_str("[\n")?;
1850 let max = self.0.len().ilog10() as usize + 3;
1851 for (n, (name, form, ty)) in self.0.iter().enumerate() {
1852 let num = format!("{n}:");
1853 writeln!(f, "{num:<max$}({name}, {ty:?}, {form:#?})")?;
1854 }
1855 f.write_str("]")
1856 } else {
1857 write!(f, "{:?}", self.0)
1858 }
1859 }
1860 }
1861
1862 struct DebugCursorShape(CursorShape);
1863 impl std::fmt::Debug for DebugCursorShape {
1864 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1865 match self.0 {
1866 CursorShape::DefaultUserShape => f.write_str("DefaultUserShape"),
1867 CursorShape::BlinkingBlock => f.write_str("BlinkingBlock"),
1868 CursorShape::SteadyBlock => f.write_str("SteadyBlock"),
1869 CursorShape::BlinkingUnderScore => f.write_str("BlinkingUnderScore"),
1870 CursorShape::SteadyUnderScore => f.write_str("SteadyUnderScore"),
1871 CursorShape::BlinkingBar => f.write_str("BlinkingBar"),
1872 CursorShape::SteadyBar => f.write_str("SteadyBar"),
1873 }
1874 }
1875 }
1876
1877 f.debug_struct("InnerPalette")
1878 .field("main_cursor", &self.main_cursor.map(DebugCursorShape))
1879 .field("extra_cursor", &self.extra_cursor.map(DebugCursorShape))
1880 .field("forms", &DebugForms(&self.forms))
1881 .field("masks", &self.masks)
1882 .finish()
1883 }
1884}
1885
1886impl std::fmt::Debug for FormType {
1887 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1888 match self {
1889 Self::Normal => write!(f, "Normal"),
1890 Self::Ref(refed) => write!(f, "Ref({refed})"),
1891 Self::Weakest => write!(f, "Weakest"),
1892 Self::WeakestRef(refed) => write!(f, "WeakestRef({refed})"),
1893 }
1894 }
1895}