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 hook::{self, FormSet},
12 session::DuatSender,
13 text::FormTag,
14};
15
16pub trait ColorScheme: Send + Sync + 'static {
18 fn apply(&self);
26
27 fn name(&self) -> &'static str;
29}
30
31static SENDER: OnceLock<DuatSender> = OnceLock::new();
32static BASE_FORMS: &[(&str, Form, FormType)] = &[
33 ("default", Form::new().0, Normal),
34 ("accent", Form::bold().0, Normal),
35 ("caret.main", Form::reverse().0, Normal),
36 ("caret.extra", Form::reverse().0, Ref(2)),
37 ("selection.main", Form::white().on_dark_grey().0, Normal),
38 ("selection.extra", Form::white().on_grey().0, Ref(5)),
39 ("cloak", Form::grey().on_black().0, Normal),
40 ("character.control", Form::grey().0, Normal),
41 ("param.buffer", Form::yellow().0, Normal),
42 ("param.buffer.open", Form::yellow().0, Ref(8)),
43 ("param.buffer.exists", Form::yellow().underlined().0, Normal),
44];
45
46mod global {
48 use std::{
49 any::TypeId,
50 collections::HashMap,
51 sync::{LazyLock, Mutex, OnceLock, mpsc},
52 time::Duration,
53 };
54
55 use super::{BASE_FORMS, BuiltForm, ColorScheme, CursorShape, Form, FormId, Painter, Palette};
56 use crate::{
57 context,
58 hook::{self, ColorSchemeSet},
59 };
60
61 static PALETTE: OnceLock<&'static Palette> = OnceLock::new();
62 static FORMS: OnceLock<&'static Mutex<Vec<&str>>> = OnceLock::new();
63 static COLORSCHEMES: LazyLock<Mutex<Vec<Box<dyn ColorScheme>>>> = LazyLock::new(Mutex::default);
64
65 #[doc(hidden)]
75 pub trait FormFmt {
76 fn kind(&self) -> Kind;
78 }
79 impl FormFmt for Form {
80 fn kind(&self) -> Kind {
81 Kind::Form(*self)
82 }
83 }
84
85 impl FormFmt for BuiltForm {
86 fn kind(&self) -> Kind {
87 Kind::Form(self.0)
88 }
89 }
90
91 impl FormFmt for &str {
92 fn kind(&self) -> Kind {
93 Kind::Ref(self.to_string())
94 }
95 }
96
97 impl FormFmt for &mut str {
98 fn kind(&self) -> Kind {
99 Kind::Ref(self.to_string())
100 }
101 }
102
103 impl FormFmt for String {
104 fn kind(&self) -> Kind {
105 Kind::Ref(self.clone())
106 }
107 }
108
109 pub fn set(name: impl ToString, form: impl FormFmt) -> FormId {
132 let name = name.to_string();
133 let cloned_name = name.clone();
134
135 match form.kind() {
136 Kind::Form(form) => queue(move || PALETTE.get().unwrap().set_form(cloned_name, form)),
137 Kind::Ref(refed) => queue(move || PALETTE.get().unwrap().set_ref(cloned_name, refed)),
138 };
139
140 let mut forms = FORMS.get().unwrap().lock().unwrap();
141 if let Kind::Ref(refed) = form.kind() {
142 position_of_name(&mut forms, refed);
143 }
144 FormId(position_of_name(&mut forms, name) as u16)
145 }
146
147 pub fn set_weak(name: impl ToString, form: impl FormFmt) -> FormId {
173 let name = name.to_string();
174 let cloned_name = name.clone();
175
176 match form.kind() {
177 Kind::Form(form) => {
178 queue(move || PALETTE.get().unwrap().set_weak_form(cloned_name, form))
179 }
180 Kind::Ref(refed) => {
181 queue(move || PALETTE.get().unwrap().set_weak_ref(cloned_name, refed))
182 }
183 };
184
185 let mut forms = FORMS.get().unwrap().lock().unwrap();
186 if let Kind::Ref(refed) = form.kind() {
187 position_of_name(&mut forms, refed);
188 }
189 FormId(position_of_name(&mut forms, name) as u16)
190 }
191
192 pub fn from_id(id: FormId) -> Form {
194 PALETTE
195 .get()
196 .unwrap()
197 .form_from_id(id)
198 .unwrap_or(Form::new().0)
199 }
200
201 pub fn main_cursor() -> (Form, Option<CursorShape>) {
203 PALETTE.get().unwrap().main_cursor()
204 }
205
206 pub fn extra_cursor() -> (Form, Option<CursorShape>) {
208 PALETTE.get().unwrap().extra_cursor()
209 }
210
211 pub fn set_main_cursor(shape: CursorShape) {
235 queue(move || PALETTE.get().unwrap().set_main_cursor(shape));
236 }
237
238 pub fn set_extra_cursor(shape: CursorShape) {
262 queue(move || PALETTE.get().unwrap().set_extra_cursor(shape));
263 }
264
265 pub fn unset_main_cursor() {
276 queue(move || PALETTE.get().unwrap().unset_main_cursor());
277 }
278
279 pub fn unset_extra_cursor() {
293 queue(move || PALETTE.get().unwrap().unset_extra_cursor());
294 }
295
296 pub fn unset_cursors() {
303 queue(move || {
304 PALETTE.get().unwrap().unset_main_cursor();
305 PALETTE.get().unwrap().unset_extra_cursor();
306 })
307 }
308
309 pub(crate) fn painter_with_mask<W: ?Sized + 'static>(mask: &'static str) -> Painter {
311 PALETTE.get().unwrap().painter(
312 default_id(TypeId::of::<W>(), crate::utils::duat_name::<W>()),
313 mask,
314 )
315 }
316
317 pub fn enable_mask(mask: impl AsRef<str> + Send + Sync + 'static) {
377 queue(move || {
378 let mask = mask.as_ref();
379 let mut inner = PALETTE.get().unwrap().0.write().unwrap();
380 if !inner.masks.iter().any(|(m, _)| *m == mask) {
381 let mut remaps: Vec<u16> = (0..inner.forms.len() as u16).collect();
382
383 for (i, (name, ..)) in inner.forms.iter().enumerate() {
384 if let Some((pref, suf)) = name.rsplit_once('.')
385 && suf == mask
386 && let Some(j) = inner.forms.iter().position(|(name, ..)| *name == pref)
387 {
388 remaps[j] = i as u16;
389 }
390 }
391
392 inner.masks.push((mask.to_string().leak(), remaps));
393 }
394 })
395 }
396
397 pub macro id_of($form:expr) {{
431 use $crate::form::{_set_many, DEFAULT_ID, FormId};
432
433 static mut WAS_SET: bool = false;
434 static mut ID: FormId = DEFAULT_ID;
435 if unsafe { WAS_SET } {
436 unsafe { ID }
437 } else {
438 let name = $form.to_string();
439 let id = _set_many(true, vec![(name, None)])[0];
440 unsafe {
441 ID = id;
442 WAS_SET = true;
443 }
444 id
445 }
446 }}
447
448 pub fn id_of_non_static(name: impl ToString) -> FormId {
455 let name = name.to_string();
456 _set_many(true, vec![(name, None)])[0]
457 }
458
459 pub fn ids_of_non_static(names: impl IntoIterator<Item = impl ToString>) -> Vec<FormId> {
466 let names: Vec<(String, Option<Kind>)> =
467 names.into_iter().map(|n| (n.to_string(), None)).collect();
468 _set_many(true, names)
469 }
470
471 #[doc(hidden)]
473 pub fn _set_many<S: AsRef<str> + Send + Sync + 'static>(
474 weak: bool,
475 sets: Vec<(S, Option<Kind>)>,
476 ) -> Vec<FormId> {
477 let mut ids = Vec::new();
478 let mut forms = FORMS.get().unwrap().lock().unwrap();
479 for (name, _) in sets.iter() {
480 ids.push(FormId(position_of_name(&mut forms, name) as u16));
481 }
482
483 queue(move || PALETTE.get().unwrap().set_many(weak, &sets));
484
485 ids
486 }
487
488 pub fn add_colorscheme(cs: impl ColorScheme) {
499 let mut colorschemes = COLORSCHEMES.lock().unwrap();
500 let name = cs.name();
501 if let Some(i) = colorschemes.iter().position(|cs| cs.name() == name) {
502 colorschemes[i] = Box::new(cs);
503 } else {
504 colorschemes.push(Box::new(cs));
505 }
506 }
507
508 pub fn set_colorscheme(name: &str) {
515 let name = name.to_string();
516 let colorschemes = COLORSCHEMES.lock().unwrap();
517 if let Some(cs) = colorschemes.iter().find(|cs| cs.name() == name) {
518 cs.apply();
519 hook::queue(ColorSchemeSet(cs.name()));
520 } else {
521 context::error!("The colorscheme [a]{name}[] was not found");
522 }
523 }
524
525 pub macro set_many($(($name:literal, $form:expr)),+ $(,)?) {{
534 use $crate::form::FormFmt;
535 $crate::form::_set_many(false, vec![$( ($name, Some($form.kind())) ),+]);
536 }}
537
538 pub macro set_many_weak($(($name:literal, $form:expr)),+ $(,)?) {{
552 use $crate::form::FormFmt;
553 $crate::form::_set_many(true, vec![$( ($name, Some($form.kind())) ),+]);
554 }}
555
556 pub(crate) fn exists(name: &str) -> bool {
558 FORMS.get().unwrap().lock().unwrap().contains(&name)
559 }
560
561 pub(crate) fn colorscheme_exists(name: &str) -> bool {
563 COLORSCHEMES
564 .lock()
565 .unwrap()
566 .iter()
567 .any(|cs| cs.name() == name)
568 }
569
570 pub(super) fn name_of(id: FormId) -> &'static str {
572 FORMS.get().unwrap().lock().unwrap()[id.0 as usize]
573 }
574
575 fn default_id(type_id: TypeId, type_name: &'static str) -> FormId {
576 static IDS: LazyLock<Mutex<HashMap<TypeId, FormId>>> = LazyLock::new(Mutex::default);
577 let mut ids = IDS.lock().unwrap();
578
579 if let Some(id) = ids.get(&type_id) {
580 *id
581 } else {
582 let name = format!("default.{type_name}");
583 let id = _set_many(true, vec![(name, None)])[0];
584 ids.insert(type_id, id);
585 id
586 }
587 }
588
589 fn position_of_name(names: &mut Vec<&'static str>, name: impl AsRef<str>) -> usize {
590 let name = name.as_ref();
591 if let Some((i, _)) = names.iter().enumerate().find(|(_, rhs)| **rhs == name) {
592 i
593 } else if let Some((refed, _)) = name.rsplit_once('.') {
594 position_of_name(names, refed);
595 names.push(name.to_string().leak());
596 names.len() - 1
597 } else {
598 names.push(name.to_string().leak());
599 names.len() - 1
600 }
601 }
602
603 fn queue<R>(f: impl FnOnce() -> R + Send + Sync + 'static) {
604 static SENDER: Mutex<Option<mpsc::Sender<Box<dyn FnOnce() + Send + Sync>>>> =
605 Mutex::new(None);
606
607 if context::will_reload_or_quit() {
608 return;
609 }
610
611 let f = Box::new(move || {
612 f();
613 });
614
615 let mut sender = SENDER.lock().unwrap();
616 let f = if let Some(tx) = sender.as_ref() {
617 let Err(err) = tx.send(f) else {
618 return;
619 };
620 err.0
621 } else {
622 f
623 };
624 let (tx, rx) = mpsc::channel();
625 tx.send(f).unwrap();
626 *sender = Some(tx);
627
628 std::thread::spawn(move || {
629 while let Ok(f) = rx.recv_timeout(Duration::from_micros(500)) {
630 f();
631 }
632 });
633 }
634
635 #[doc(hidden)]
639 pub fn get_initial() -> (&'static Mutex<Vec<&'static str>>, &'static Palette) {
640 let forms = Box::leak(Box::new(Mutex::new(
641 BASE_FORMS.iter().map(|(n, ..)| *n).collect(),
642 )));
643 let palette = Box::leak(Box::new(Palette::new()));
644 (forms, palette)
645 }
646
647 #[doc(hidden)]
651 pub fn set_initial((forms, palette): (&'static Mutex<Vec<&'static str>>, &'static Palette)) {
652 FORMS.set(forms).expect("Forms setup ran twice");
653 PALETTE.set(palette).expect("Forms setup ran twice");
654 }
655
656 #[doc(hidden)]
658 pub enum Kind {
659 Form(Form),
660 Ref(String),
661 }
662}
663
664#[derive(Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord)]
678pub struct FormId(u16);
679
680impl FormId {
681 pub const fn to_tag(self, prio: u8) -> FormTag {
690 FormTag(self, prio)
691 }
692
693 pub const fn to_u16(self) -> u16 {
697 self.0
698 }
699
700 pub fn name(self) -> &'static str {
702 name_of(self)
703 }
704}
705
706impl std::fmt::Debug for FormId {
707 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
708 write!(f, "FormId({})", name_of(*self))
709 }
710}
711
712#[derive(Clone, Copy, PartialEq, Eq)]
714pub struct Form {
715 pub style: ContentStyle,
717}
718
719#[rustfmt::skip]
720impl Form {
721 mimic_method_new!(bold Attribute::Bold);
722 mimic_method_new!(dim Attribute::Dim);
723 mimic_method_new!(italic Attribute::Italic);
724 mimic_method_new!(underlined Attribute::Underlined);
725 mimic_method_new!(double_underlined Attribute::DoubleUnderlined);
726 mimic_method_new!(undercurled Attribute::Undercurled);
727 mimic_method_new!(underdashed Attribute::Underdashed);
728 mimic_method_new!(reverse Attribute::Reverse);
729 mimic_method_new!(crossed_out Attribute::CrossedOut);
730 mimic_method_new!(black on_black underline_black Color::Black);
731 mimic_method_new!(dark_grey on_dark_grey underline_dark_grey Color::DarkGrey);
732 mimic_method_new!(red on_red underline_red Color::Red);
733 mimic_method_new!(dark_red on_dark_red underline_dark_red Color::DarkRed);
734 mimic_method_new!(green on_green underline_green Color::Green);
735 mimic_method_new!(
736 dark_green on_dark_green underline_dark_green Color::DarkGreen
737 );
738 mimic_method_new!(yellow on_yellow underline_yellow Color::Yellow);
739 mimic_method_new!(
740 dark_yellow on_dark_yellow underline_dark_yellow Color::DarkYellow
741 );
742 mimic_method_new!(blue on_blue underline_blue Color::Blue);
743 mimic_method_new!(dark_blue on_dark_blue underline_dark_blue Color::DarkBlue);
744 mimic_method_new!(magenta on_magenta underline_magenta Color::Magenta);
745 mimic_method_new!(
746 dark_magenta on_dark_magenta underline_dark_magenta Color::DarkMagenta
747 );
748 mimic_method_new!(cyan on_cyan underline_cyan Color::Cyan);
749 mimic_method_new!(dark_cyan on_dark_cyan underline_dark_cyan Color::DarkCyan);
750 mimic_method_new!(white on_white underline_white Color::White);
751 mimic_method_new!(grey on_grey underline_grey Color::Grey);
752}
753
754impl Form {
755 #[allow(clippy::new_ret_no_self)]
759 pub const fn new() -> BuiltForm {
760 let style = ContentStyle {
761 foreground_color: None,
762 background_color: None,
763 underline_color: None,
764 attributes: Attributes::none(),
765 };
766 BuiltForm(Self { style })
767 }
768
769 pub const fn reset() -> BuiltForm {
776 let mut built = Form::new();
777 built.0.style.attributes = built.0.style.attributes.with(Attribute::Reset);
778 built
779 }
780
781 pub const fn with(str: &str) -> BuiltForm {
791 let mut built = Form::new();
792 built.0.style.foreground_color = match str_to_color(str) {
793 Ok(color) => Some(color),
794 Err(err) => panic!("{}", err),
795 };
796 built
797 }
798
799 pub const fn on(str: &str) -> BuiltForm {
809 let mut built = Form::new();
810 built.0.style.background_color = match str_to_color(str) {
811 Ok(color) => Some(color),
812 Err(err) => panic!("{}", err),
813 };
814 built
815 }
816
817 pub const fn underline(str: &str) -> BuiltForm {
827 let mut built = Form::new();
828 built.0.style.underline_color = match str_to_color(str) {
829 Ok(color) => Some(color),
830 Err(err) => panic!("{}", err),
831 };
832 built
833 }
834
835 pub const fn fg(&self) -> Option<Color> {
837 self.style.foreground_color
838 }
839
840 pub const fn bg(&self) -> Option<Color> {
842 self.style.background_color
843 }
844
845 pub const fn ul(&self) -> Option<Color> {
847 self.style.underline_color
848 }
849
850 pub const fn attrs(&self) -> Attributes {
852 self.style.attributes
853 }
854}
855
856#[derive(Clone, Copy, Debug)]
865pub struct BuiltForm(Form);
866
867#[rustfmt::skip]
868impl BuiltForm {
869 mimic_method_mod!(bold Attribute::Bold);
870 mimic_method_mod!(dim Attribute::Dim);
871 mimic_method_mod!(italic Attribute::Italic);
872 mimic_method_mod!(underlined Attribute::Underlined);
873 mimic_method_mod!(double_underlined Attribute::DoubleUnderlined);
874 mimic_method_mod!(undercurled Attribute::Undercurled);
875 mimic_method_mod!(underdashed Attribute::Underdashed);
876 mimic_method_mod!(reverse Attribute::Reverse);
877 mimic_method_mod!(crossed_out Attribute::CrossedOut);
878 mimic_method_mod!(overlined Attribute::OverLined);
879 mimic_method_mod!(black on_black underline_black Color::Black);
880 mimic_method_mod!(dark_grey on_dark_grey underline_dark_grey Color::DarkGrey);
881 mimic_method_mod!(red on_red underline_red Color::Red);
882 mimic_method_mod!(dark_red on_dark_red underline_dark_red Color::DarkRed);
883 mimic_method_mod!(green on_green underline_green Color::Green);
884 mimic_method_mod!(
885 dark_green on_dark_green underline_dark_green Color::DarkGreen
886 );
887 mimic_method_mod!(yellow on_yellow underline_yellow Color::Yellow);
888 mimic_method_mod!(
889 dark_yellow on_dark_yellow underline_dark_yellow Color::DarkYellow
890 );
891 mimic_method_mod!(blue on_blue underline_blue Color::Blue);
892 mimic_method_mod!(dark_blue on_dark_blue underline_dark_blue Color::DarkBlue);
893 mimic_method_mod!(magenta on_magenta underline_magenta Color::Magenta);
894 mimic_method_mod!(
895 dark_magenta on_dark_magenta underline_dark_magenta Color::DarkMagenta
896 );
897 mimic_method_mod!(cyan on_cyan underline_cyan Color::Cyan);
898 mimic_method_mod!(dark_cyan on_dark_cyan underline_dark_cyan Color::DarkCyan);
899 mimic_method_mod!(white on_white underline_white Color::White);
900 mimic_method_mod!(grey on_grey underline_grey Color::Grey);
901}
902
903impl BuiltForm {
904 pub const fn reset(mut self) -> BuiltForm {
911 self.0.style.attributes = self.0.style.attributes.with(Attribute::Reset);
912 self
913 }
914
915 pub const fn with(mut self, str: &str) -> Self {
925 self.0.style.foreground_color = match str_to_color(str) {
926 Ok(color) => Some(color),
927 Err(err) => panic!("{}", err),
928 };
929 self
930 }
931
932 pub const fn on(mut self, str: &str) -> Self {
942 self.0.style.background_color = match str_to_color(str) {
943 Ok(color) => Some(color),
944 Err(err) => panic!("{}", err),
945 };
946 self
947 }
948
949 pub const fn underline(mut self, str: &str) -> Self {
959 self.0.style.underline_color = match str_to_color(str) {
960 Ok(color) => Some(color),
961 Err(err) => panic!("{}", err),
962 };
963 self
964 }
965}
966
967impl std::ops::Deref for BuiltForm {
968 type Target = Form;
969
970 fn deref(&self) -> &Self::Target {
971 &self.0
972 }
973}
974
975impl std::ops::DerefMut for BuiltForm {
976 fn deref_mut(&mut self) -> &mut Self::Target {
977 &mut self.0
978 }
979}
980
981impl From<BuiltForm> for Form {
982 fn from(value: BuiltForm) -> Self {
983 value.0
984 }
985}
986
987pub const DEFAULT_ID: FormId = FormId(0);
989pub const ACCENT_ID: FormId = FormId(1);
991pub const M_CAR_ID: FormId = FormId(2);
993pub const E_CAR_ID: FormId = FormId(3);
995pub const M_SEL_ID: FormId = FormId(4);
997pub const E_SEL_ID: FormId = FormId(5);
999pub const CONTROL_CHAR_ID: FormId = FormId(7);
1001
1002#[derive(Debug)]
1006#[doc(hidden)]
1007pub struct Palette(RwLock<InnerPalette>);
1008
1009impl Palette {
1010 fn new() -> Self {
1012 let main_cursor = Some(CursorShape::DefaultUserShape);
1013 Self(RwLock::new(InnerPalette {
1014 main_cursor,
1015 extra_cursor: main_cursor,
1016 forms: BASE_FORMS.to_vec(),
1017 masks: vec![(
1018 "".to_string().leak(),
1019 (0..BASE_FORMS.len() as u16).collect(),
1020 )],
1021 }))
1022 }
1023
1024 fn set_form(&self, name: impl AsRef<str>, form: Form) {
1026 let name = name.as_ref();
1027 self.0.write().unwrap().set_form(name, form);
1028 }
1029
1030 fn set_weak_form(&self, name: impl AsRef<str>, form: Form) {
1032 let name = name.as_ref();
1033 self.0.write().unwrap().set_weak_form(name, form);
1034 }
1035
1036 fn set_ref(&self, name: impl AsRef<str>, refed: impl AsRef<str>) {
1038 let (name, refed) = (name.as_ref(), refed.as_ref());
1039 self.0.write().unwrap().set_ref(name, refed);
1040 }
1041
1042 fn set_weak_ref(&self, name: impl AsRef<str>, refed: impl AsRef<str>) {
1044 let (name, refed) = (name.as_ref(), refed.as_ref());
1045 self.0.write().unwrap().set_weak_ref(name, refed);
1046 }
1047
1048 fn set_many<S: AsRef<str>>(&self, weak: bool, sets: &[(S, Option<self::global::Kind>)]) {
1050 let mut inner = self.0.write().unwrap();
1051 for (name, kind) in sets {
1052 match (weak, kind) {
1053 (false, Some(Kind::Form(form))) => inner.set_form(name.as_ref(), *form),
1054 (false, Some(Kind::Ref(refed))) => inner.set_ref(name.as_ref(), refed),
1055 (true, Some(Kind::Form(form))) => inner.set_weak_form(name.as_ref(), *form),
1056 (true, Some(Kind::Ref(refed))) => inner.set_weak_ref(name.as_ref(), refed),
1057 (_, None) => {
1058 position_and_form(&mut inner.forms, name);
1059 }
1060 }
1061 }
1062 }
1063
1064 fn form_from_id(&self, id: FormId) -> Option<Form> {
1066 let inner = self.0.read().unwrap();
1067 inner.forms.get(id.0 as usize).map(|(_, form, _)| *form)
1068 }
1069
1070 fn main_cursor(&self) -> (Form, Option<CursorShape>) {
1072 let form = self.form_from_id(M_CAR_ID).unwrap();
1073 (form, self.0.read().unwrap().main_cursor)
1074 }
1075
1076 fn extra_cursor(&self) -> (Form, Option<CursorShape>) {
1078 let form = self.form_from_id(E_CAR_ID).unwrap();
1079 (form, self.0.read().unwrap().extra_cursor)
1080 }
1081
1082 fn set_main_cursor(&self, shape: CursorShape) {
1084 self.0.write().unwrap().main_cursor = Some(shape);
1085 if let Some(sender) = SENDER.get() {
1086 sender.send_form_changed().unwrap()
1087 }
1088 }
1089
1090 fn set_extra_cursor(&self, shape: CursorShape) {
1092 self.0.write().unwrap().extra_cursor = Some(shape);
1093 if let Some(sender) = SENDER.get() {
1094 sender.send_form_changed().unwrap()
1095 }
1096 }
1097
1098 fn unset_main_cursor(&self) {
1100 self.0.write().unwrap().main_cursor = None;
1101 if let Some(sender) = SENDER.get() {
1102 sender.send_form_changed().unwrap()
1103 }
1104 }
1105
1106 fn unset_extra_cursor(&self) {
1108 self.0.write().unwrap().extra_cursor = None;
1109 if let Some(sender) = SENDER.get() {
1110 sender.send_form_changed().unwrap()
1111 }
1112 }
1113
1114 fn painter(&'static self, default_id: FormId, mask: &str) -> Painter {
1116 let inner = self.0.read().unwrap();
1117 let mask_i = inner
1118 .masks
1119 .iter()
1120 .position(|(m, _)| *m == mask)
1121 .unwrap_or_default();
1122
1123 let default = inner
1124 .forms
1125 .get(match inner.masks[mask_i].1.get(default_id.0 as usize) {
1126 Some(i) => *i as usize,
1127 None => default_id.0 as usize,
1128 })
1129 .map(|(_, f, _)| *f)
1130 .unwrap_or(Form::new().0);
1131
1132 Painter {
1133 inner,
1134 mask_i,
1135 default,
1136 forms: Vec::new(),
1137 set_fg: true,
1138 set_bg: true,
1139 set_ul: true,
1140 reset_attrs: false,
1141 prev_style: None,
1142 }
1143 }
1144}
1145
1146struct InnerPalette {
1147 main_cursor: Option<CursorShape>,
1148 extra_cursor: Option<CursorShape>,
1149 forms: Vec<(&'static str, Form, FormType)>,
1150 masks: Vec<(&'static str, Vec<u16>)>,
1151}
1152
1153impl InnerPalette {
1154 fn set_form(&mut self, name: &str, form: Form) {
1156 let (i, _) = position_and_form(&mut self.forms, name);
1157
1158 self.forms[i].1 = form;
1159 self.forms[i].2 = FormType::Normal;
1160
1161 for refed in refs_of(self, i) {
1162 self.forms[refed].1 = form;
1163 }
1164
1165 if let Some(sender) = SENDER.get() {
1166 sender.send_form_changed().unwrap()
1167 }
1168
1169 mask_form(name, i, self);
1170 hook::queue(FormSet((self.forms[i].0, FormId(i as u16), form)));
1171 }
1172
1173 fn set_weak_form(&mut self, name: &str, form: Form) {
1175 let (i, _) = position_and_form(&mut self.forms, name);
1176
1177 let (_, f, f_ty) = &mut self.forms[i];
1178 if let FormType::Weakest | FormType::WeakestRef(_) = f_ty {
1179 *f = form;
1180 *f_ty = FormType::Normal;
1181
1182 if let Some(sender) = SENDER.get() {
1183 sender.send_form_changed().unwrap()
1184 }
1185 for refed in refs_of(self, i) {
1186 self.forms[refed].1 = form;
1187 }
1188
1189 mask_form(name, i, self);
1190 }
1191 }
1192
1193 fn set_ref(&mut self, name: &str, refed: &str) {
1195 let (refed, form) = position_and_form(&mut self.forms, refed);
1196 let (i, _) = position_and_form(&mut self.forms, name);
1197
1198 self.forms[i].1 = form;
1199 for refed in refs_of(self, i) {
1200 self.forms[refed].1 = form;
1201 }
1202
1203 if would_be_circular(self, i, refed) {
1205 self.forms[i].2 = FormType::Normal;
1206 } else {
1207 self.forms[i].2 = FormType::Ref(refed);
1208 }
1209
1210 if let Some(sender) = SENDER.get() {
1211 sender.send_form_changed().unwrap()
1212 }
1213
1214 mask_form(name, i, self);
1215 hook::queue(FormSet((self.forms[i].0, FormId(i as u16), form)));
1216 }
1217
1218 fn set_weak_ref(&mut self, name: &str, refed: &str) {
1220 let (refed, form) = position_and_form(&mut self.forms, refed);
1221 let (i, _) = position_and_form(&mut self.forms, name);
1222
1223 let (_, f, f_ty) = &mut self.forms[i];
1226 if let FormType::Weakest | FormType::WeakestRef(_) = f_ty {
1227 *f = form;
1228 *f_ty = FormType::WeakestRef(refed);
1229
1230 if let Some(sender) = SENDER.get() {
1231 sender.send_form_changed().unwrap()
1232 }
1233 for refed in refs_of(self, i) {
1234 self.forms[refed].1 = form;
1235 }
1236
1237 mask_form(name, i, self);
1238 }
1239 }
1240}
1241
1242fn mask_form(name: &str, form_i: usize, inner: &mut InnerPalette) {
1244 if inner.masks[0].1.len() < inner.forms.len() {
1245 for (_, remaps) in inner.masks.iter_mut() {
1246 remaps.extend(remaps.len() as u16..inner.forms.len() as u16);
1247 }
1248 }
1249
1250 if let Some((pref, mask)) = name.rsplit_once(".")
1251 && let Some((_, remaps)) = inner.masks.iter_mut().find(|(m, _)| *m == mask)
1252 && let Some(j) = inner.forms.iter().position(|(name, ..)| *name == pref)
1253 {
1254 remaps[j] = form_i as u16;
1255 }
1256}
1257
1258pub struct Painter {
1318 inner: RwLockReadGuard<'static, InnerPalette>,
1319 mask_i: usize,
1320 default: Form,
1321 forms: Vec<(Form, FormId, u8)>,
1322 set_fg: bool,
1323 set_bg: bool,
1324 set_ul: bool,
1325 reset_attrs: bool,
1326 prev_style: Option<ContentStyle>,
1327}
1328
1329impl Painter {
1330 #[inline(always)]
1338 pub fn apply(&mut self, id: FormId, prio: u8) {
1339 let (_, mask) = &self.inner.masks[self.mask_i];
1340 let id = FormId(mask.get(id.0 as usize).copied().unwrap_or(id.0));
1341
1342 let forms = &self.inner.forms;
1343 let form = forms
1344 .get(id.0 as usize)
1345 .map(|(_, f, _)| *f)
1346 .unwrap_or(Form::new().0);
1347
1348 let gt = |(.., p): &&(_, _, u8)| *p > prio;
1349 let i = self.forms.len() - self.forms.iter().rev().take_while(gt).count();
1350 self.forms.insert(i, (form, id, prio));
1351
1352 self.set_fg |= form.fg().is_some();
1353 self.set_bg |= form.bg().is_some();
1354 self.set_ul |= form.ul().is_some();
1355 self.reset_attrs |= form.attrs().has(Attribute::Reset);
1356 }
1357
1358 #[inline(always)]
1361 pub fn remove(&mut self, id: FormId) {
1362 let mask = &self.inner.masks[self.mask_i].1;
1363 let id = FormId(mask.get(id.0 as usize).copied().unwrap_or(id.0));
1364
1365 let mut applied_forms = self.forms.iter().enumerate();
1366 if let Some((i, &(form, ..))) = applied_forms.rfind(|(_, (_, lhs, _))| *lhs == id) {
1367 self.forms.remove(i);
1368
1369 self.set_fg |= form.fg().is_some();
1370 self.set_bg |= form.bg().is_some();
1371 self.set_ul |= form.ul().is_some();
1372 self.reset_attrs |= !form.attrs().is_empty();
1373 };
1374 }
1375
1376 #[inline(always)]
1382 pub fn reset(&mut self) -> ContentStyle {
1383 self.forms.clear();
1384 self.absolute_style()
1385 }
1386
1387 #[inline(always)]
1392 pub fn absolute_style(&self) -> ContentStyle {
1393 let mut style = self.default.style;
1394
1395 for &(form, ..) in &self.forms {
1396 style.foreground_color = form.fg().or(style.foreground_color);
1397 style.background_color = form.bg().or(style.background_color);
1398 style.underline_color = form.ul().or(style.underline_color);
1399 style.attributes = if form.attrs().has(Attribute::Reset) {
1400 form.attrs()
1401 } else {
1402 form.attrs() | style.attributes
1403 }
1404 }
1405
1406 style
1407 }
1408
1409 #[inline(always)]
1421 pub fn relative_style(&mut self) -> Option<ContentStyle> {
1422 let abs_style = self.absolute_style();
1423 let mut style = abs_style;
1424
1425 if style.attributes.has(Attribute::Reset) || self.reset_attrs {
1426 style.attributes.set(Attribute::Reset);
1427 } else {
1431 style.foreground_color = self
1432 .set_fg
1433 .then_some(style.foreground_color.unwrap_or(Color::Reset))
1434 .filter(|fg| Some(*fg) != self.prev_style.and_then(|s| s.foreground_color));
1435 style.background_color = self
1436 .set_bg
1437 .then_some(style.background_color.unwrap_or(Color::Reset))
1438 .filter(|bg| Some(*bg) != self.prev_style.and_then(|s| s.background_color));
1439 style.underline_color = self
1440 .set_ul
1441 .then_some(style.underline_color.unwrap_or(Color::Reset))
1442 .filter(|ul| Some(*ul) != self.prev_style.and_then(|s| s.underline_color));
1443 }
1444
1445 self.set_fg = false;
1446 self.set_bg = false;
1447 self.set_ul = false;
1448 self.reset_attrs = false;
1449
1450 if let Some(prev_style) = self.prev_style.replace(abs_style) {
1451 (style != prev_style && style != Default::default()).then_some(style)
1452 } else {
1453 Some(style)
1454 }
1455 }
1456
1457 pub fn reset_prev_style(&mut self) {
1463 self.prev_style = None;
1464 self.set_fg = true;
1465 self.set_bg = true;
1466 self.set_ul = true;
1467 self.reset_attrs = true;
1468 }
1469
1470 #[inline(always)]
1472 pub fn apply_main_cursor(&mut self) {
1473 self.apply(M_CAR_ID, 100);
1474 }
1475
1476 #[inline(always)]
1478 pub fn remove_main_caret(&mut self) {
1479 self.remove(M_CAR_ID);
1480 }
1481
1482 #[inline(always)]
1484 pub fn apply_extra_cursor(&mut self) {
1485 self.apply(E_CAR_ID, 100);
1486 }
1487
1488 #[inline(always)]
1490 pub fn remove_extra_caret(&mut self) {
1491 self.remove(E_CAR_ID);
1492 }
1493
1494 pub fn main_cursor(&self) -> Option<CursorShape> {
1496 self.inner.main_cursor
1497 }
1498
1499 pub fn extra_cursor(&self) -> Option<CursorShape> {
1501 self.inner.extra_cursor
1502 }
1503
1504 pub fn get_default(&self) -> Form {
1506 self.default
1507 }
1508}
1509
1510pub(crate) fn set_sender(sender: DuatSender) {
1511 SENDER
1512 .set(sender)
1513 .unwrap_or_else(|_| panic!("Sender set more than once"));
1514}
1515
1516#[derive(Clone)]
1518enum FormType {
1519 Normal,
1520 Ref(usize),
1521 Weakest,
1522 WeakestRef(usize),
1523}
1524
1525fn refs_of(inner: &InnerPalette, refed: usize) -> Vec<usize> {
1527 let mut refs = Vec::new();
1528 for (i, (.., f_ty)) in inner.forms.iter().enumerate() {
1529 if let FormType::Ref(ref_id) | FormType::WeakestRef(ref_id) = f_ty
1530 && *ref_id == refed
1531 {
1532 refs.push(i);
1533 refs.extend(refs_of(inner, i));
1534 }
1535 }
1536 refs
1537}
1538
1539fn would_be_circular(inner: &InnerPalette, referee: usize, refed: usize) -> bool {
1541 if let (.., FormType::Ref(refed_ref) | FormType::WeakestRef(refed_ref)) = inner.forms[refed] {
1542 match refed_ref == referee {
1543 true => true,
1544 false => would_be_circular(inner, referee, refed_ref),
1545 }
1546 } else {
1547 false
1548 }
1549}
1550
1551fn position_and_form(
1552 forms: &mut Vec<(&str, Form, FormType)>,
1553 name: impl AsRef<str>,
1554) -> (usize, Form) {
1555 let name = name.as_ref();
1556 if let Some((i, (_, form, _))) = forms.iter().enumerate().find(|(_, (lhs, ..))| *lhs == name) {
1557 (i, *form)
1558 } else if let Some((refed, _)) = name.rsplit_once('.') {
1559 let (i, form) = position_and_form(forms, refed);
1560 forms.push((name.to_string().leak(), form, FormType::WeakestRef(i)));
1561 (forms.len() - 1, form)
1562 } else {
1563 forms.push((name.to_string().leak(), Form::new().0, FormType::Weakest));
1564 (forms.len() - 1, Form::new().0)
1565 }
1566}
1567
1568const fn str_to_color(str: &str) -> std::result::Result<Color, &'static str> {
1570 const fn strip_prefix<'a>(prefix: &str, str: &'a str) -> Option<&'a str> {
1571 let prefix = prefix.as_bytes();
1572
1573 let mut i = 0;
1574 while i < prefix.len() {
1575 if str.as_bytes()[i] != prefix[i] {
1576 return None;
1577 }
1578 i += 1;
1579 }
1580
1581 Some(str.split_at(prefix.len()).1)
1582 }
1583 const fn strip_suffix<'a>(suffix: &str, str: &'a str) -> Option<&'a str> {
1584 let prefix = suffix.as_bytes();
1585
1586 let mut i = str.len() - 1;
1587 while i >= str.len() - prefix.len() {
1588 if str.as_bytes()[i] != prefix[i - (str.len() - prefix.len())] {
1589 return None;
1590 }
1591 i += 1;
1592 }
1593
1594 Some(str.split_at(str.len() - suffix.len()).0)
1595 }
1596 const fn split_space(str: &str) -> Option<(&str, &str)> {
1597 if str.is_empty() {
1598 return None;
1599 }
1600
1601 let mut i = 0;
1602 while i < str.len() {
1603 if str.as_bytes()[i] == b' ' {
1604 break;
1605 }
1606 i += 1;
1607 }
1608
1609 let (cut, rest) = str.split_at(i);
1610 let (_, rest) = rest.split_at(if rest.is_empty() { 0 } else { 1 });
1611 Some((cut, rest))
1612 }
1613 const fn hue_to_rgb(p: f32, q: f32, mut t: f32) -> f32 {
1614 t = if t < 0.0 { t + 1.0 } else { t };
1615 t = if t > 1.0 { t - 1.0 } else { t };
1616 if t < 1.0 / 6.0 {
1617 p + (q - p) * 6.0 * t
1618 } else if t < 1.0 / 2.0 {
1619 q
1620 } else if t < 2.0 / 3.0 {
1621 p + (q - p) * (2.0 / 3.0 - t) * 6.0
1622 } else {
1623 p
1624 }
1625 }
1626
1627 if let Some(hex) = strip_prefix("#", str) {
1629 let total = match u32::from_str_radix(hex, 16) {
1630 Ok(total) if hex.len() == 6 => total,
1631 _ => return Err("Hexcode does not contain 6 hex values"),
1632 };
1633 let r = (total >> 16) as u8;
1634 let g = (total >> 8) as u8;
1635 let b = total as u8;
1636
1637 Ok(Color::Rgb { r, g, b })
1638 } else if let Some(mut rgb) = strip_prefix("rgb ", str) {
1640 let mut values = [0, 0, 0];
1641 let mut i = 0;
1642
1643 while i < values.len() {
1644 if let Some((cut, rest)) = split_space(rgb) {
1645 rgb = rest;
1646 values[i] = match u8::from_str_radix(cut, 10) {
1647 Ok(value) => value,
1648 Err(_) => return Err("Rgb format value could not be parsed"),
1649 }
1650 } else {
1651 return Err("Missing value in rgb format");
1652 }
1653 i += 1;
1654 }
1655
1656 let [r, g, b] = values;
1657 Ok(Color::Rgb { r, g, b })
1658 } else if let Some(mut hsl) = strip_prefix("hsl ", str) {
1660 let mut values = [0.0, 0.0, 0.0];
1661 let mut i = 0;
1662 while i < values.len() {
1663 if let Some((cut, rest)) = split_space(hsl) {
1664 hsl = rest;
1665 let (num, div) = match strip_suffix("%", cut) {
1666 Some(perc) => (perc, 100),
1667 None => (cut, 255),
1668 };
1669 values[i] = match u8::from_str_radix(num, 10) {
1670 Ok(value) if value <= div => value as f32 / div as f32,
1671 _ => return Err("Hsl format property could not be parsed"),
1672 }
1673 } else {
1674 return Err("Missing value in hsl format");
1675 }
1676 i += 1;
1677 }
1678 let [hue, sat, lit] = values;
1679
1680 let (r, g, b) = if sat == 0.0 {
1681 (lit, lit, lit)
1682 } else {
1683 let q = if lit < 0.5 {
1684 lit * (1.0 + sat)
1685 } else {
1686 lit + sat - lit * sat
1687 };
1688 let p = 2.0 * lit - q;
1689 let r = hue_to_rgb(p, q, hue + 1.0 / 3.0);
1690 let g = hue_to_rgb(p, q, hue);
1691 let b = hue_to_rgb(p, q, hue - 1.0 / 3.0);
1692 (r, g, b)
1693 };
1694
1695 let r = (0.5 + r * 255.0) as u8;
1697 let g = (0.5 + g * 255.0) as u8;
1698 let b = (0.5 + b * 255.0) as u8;
1699 Ok(Color::Rgb { r, g, b })
1700 } else {
1701 Err("Color format was not recognized")
1702 }
1703}
1704
1705impl std::fmt::Debug for Form {
1706 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1707 struct DebugColor(Option<Color>);
1708 impl std::fmt::Debug for DebugColor {
1709 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1710 match self.0 {
1711 Some(Color::Rgb { r, g, b }) => write!(f, "Some(Rgb({r}, {g}, {b}))"),
1712 Some(Color::AnsiValue(ansi)) => write!(f, "Some(Ansi({ansi}))"),
1713 Some(color) => write!(f, "Some({color:?})"),
1714 None => f.write_str("None"),
1715 }
1716 }
1717 }
1718
1719 struct DebugAttributes(Attributes);
1720 impl std::fmt::Debug for DebugAttributes {
1721 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1722 if self.0.is_empty() {
1723 f.write_str("None")
1724 } else {
1725 let mut is_first = true;
1726 for attr in Attribute::iterator() {
1727 if self.0.has(attr) {
1728 if !is_first {
1729 f.write_str(" | ")?;
1730 }
1731 is_first = false;
1732 write!(f, "{attr:?}")?;
1733 }
1734 }
1735 Ok(())
1736 }
1737 }
1738 }
1739
1740 f.debug_struct("Form")
1741 .field("fg", &DebugColor(self.style.foreground_color))
1742 .field("bg", &DebugColor(self.style.background_color))
1743 .field("ul", &DebugColor(self.style.underline_color))
1744 .field("attr", &DebugAttributes(self.style.attributes))
1745 .finish()
1746 }
1747}
1748
1749impl std::fmt::Debug for InnerPalette {
1750 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1751 struct DebugForms<'a>(&'a [(&'static str, Form, FormType)]);
1752 impl std::fmt::Debug for DebugForms<'_> {
1753 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1754 if f.alternate() {
1755 f.write_str("[\n")?;
1756 let max = self.0.len().ilog10() as usize + 3;
1757 for (n, (name, form, ty)) in self.0.iter().enumerate() {
1758 let num = format!("{n}:");
1759 writeln!(f, "{num:<max$}({name}, {ty:?}, {form:#?})")?;
1760 }
1761 f.write_str("]")
1762 } else {
1763 write!(f, "{:?}", self.0)
1764 }
1765 }
1766 }
1767
1768 struct DebugCursorShape(CursorShape);
1769 impl std::fmt::Debug for DebugCursorShape {
1770 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1771 match self.0 {
1772 CursorShape::DefaultUserShape => f.write_str("DefaultUserShape"),
1773 CursorShape::BlinkingBlock => f.write_str("BlinkingBlock"),
1774 CursorShape::SteadyBlock => f.write_str("SteadyBlock"),
1775 CursorShape::BlinkingUnderScore => f.write_str("BlinkingUnderScore"),
1776 CursorShape::SteadyUnderScore => f.write_str("SteadyUnderScore"),
1777 CursorShape::BlinkingBar => f.write_str("BlinkingBar"),
1778 CursorShape::SteadyBar => f.write_str("SteadyBar"),
1779 }
1780 }
1781 }
1782
1783 f.debug_struct("InnerPalette")
1784 .field("main_cursor", &self.main_cursor.map(DebugCursorShape))
1785 .field("extra_cursor", &self.extra_cursor.map(DebugCursorShape))
1786 .field("forms", &DebugForms(&self.forms))
1787 .field("masks", &self.masks)
1788 .finish()
1789 }
1790}
1791
1792impl std::fmt::Debug for FormType {
1793 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1794 match self {
1795 Self::Normal => write!(f, "Normal"),
1796 Self::Ref(refed) => write!(f, "Ref({refed})"),
1797 Self::Weakest => write!(f, "Weakest"),
1798 Self::WeakestRef(refed) => write!(f, "WeakestRef({refed})"),
1799 }
1800 }
1801}
1802
1803macro mimic_method_new {
1805 (#[$attr:meta] $method:ident $attrib:expr) => {
1806 #[$attr]
1808 pub const fn $method() -> BuiltForm {
1810 let mut built = Form::new();
1811 built.0.style.attributes = built.0.style.attributes.with($attrib);
1812 built
1813 }
1814 },
1815
1816 (#[$attr:meta] $fg:ident $bg:ident $ul:ident $color:expr) => {
1817 #[$attr]
1819 pub const fn $fg() -> BuiltForm {
1821 let mut built = Form::new();
1822 built.0.style.foreground_color = Some($color);
1823 built
1824 }
1825
1826 #[$attr]
1828 pub const fn $bg() -> BuiltForm {
1830 let mut built = Form::new();
1831 built.0.style.background_color = Some($color);
1832 built
1833 }
1834
1835 #[$attr]
1837 pub const fn $ul() -> BuiltForm {
1846 let mut built = Form::new();
1847 built.0.style.underline_color = Some($color);
1848 built
1849 }
1850 }
1851}
1852
1853macro mimic_method_mod {
1854 (#[$attr:meta] $method:ident $attrib:expr) => {
1855 #[$attr]
1857 pub const fn $method(mut self) -> Self {
1859 self.0.style.attributes = self.0.style.attributes.with($attrib);
1860 self
1861 }
1862 },
1863
1864 (#[$attr:meta] $fg:ident $bg:ident $ul:ident $color:expr) => {
1865 #[$attr]
1867 pub const fn $fg(mut self) -> Self {
1868 self.0.style.foreground_color = Some($color);
1869 self
1870 }
1871
1872 #[$attr]
1874 pub const fn $bg(mut self) -> Self {
1875 self.0.style.background_color = Some($color);
1876 self
1877 }
1878
1879 #[$attr]
1881 pub const fn $ul(mut self) -> Self {
1889 self.0.style.underline_color = Some($color);
1890 self
1891 }
1892 }
1893}