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 #[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 {
136 let name = name.to_string();
137 let cloned_name = name.clone();
138
139 match form.kind() {
140 Kind::Form(form) => queue(move || PALETTE.get().unwrap().set_form(cloned_name, form)),
141 Kind::Ref(refed) => queue(move || PALETTE.get().unwrap().set_ref(cloned_name, refed)),
142 };
143
144 let mut forms = FORMS.get().unwrap().lock().unwrap();
145 if let Kind::Ref(refed) = form.kind() {
146 position_of_name(&mut forms, refed);
147 }
148 FormId(position_of_name(&mut forms, name) as u16)
149 }
150
151 pub fn set_weak(name: impl ToString, form: impl FormFmt) -> FormId {
177 let name = name.to_string();
178 let cloned_name = name.clone();
179
180 match form.kind() {
181 Kind::Form(form) => {
182 queue(move || PALETTE.get().unwrap().set_weak_form(cloned_name, form))
183 }
184 Kind::Ref(refed) => {
185 queue(move || PALETTE.get().unwrap().set_weak_ref(cloned_name, refed))
186 }
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) {
239 queue(move || PALETTE.get().unwrap().set_main_cursor(shape));
240 }
241
242 pub fn set_extra_cursor(shape: CursorShape) {
266 queue(move || PALETTE.get().unwrap().set_extra_cursor(shape));
267 }
268
269 pub fn unset_main_cursor() {
280 queue(move || PALETTE.get().unwrap().unset_main_cursor());
281 }
282
283 pub fn unset_extra_cursor() {
297 queue(move || PALETTE.get().unwrap().unset_extra_cursor());
298 }
299
300 pub fn unset_cursors() {
307 queue(move || {
308 PALETTE.get().unwrap().unset_main_cursor();
309 PALETTE.get().unwrap().unset_extra_cursor();
310 })
311 }
312
313 pub(crate) fn painter_with_mask<W: ?Sized + 'static>(mask: &'static str) -> Painter {
315 PALETTE.get().unwrap().painter(
316 default_id(TypeId::of::<W>(), crate::utils::duat_name::<W>()),
317 mask,
318 )
319 }
320
321 pub fn enable_mask(mask: impl AsRef<str> + Send + Sync + 'static) {
380 queue(move || {
381 let mask = mask.as_ref();
382 let mut inner = PALETTE.get().unwrap().0.write().unwrap();
383 if !inner.masks.iter().any(|(m, _)| *m == mask) {
384 let mut remaps: Vec<u16> = (0..inner.forms.len() as u16).collect();
385
386 for (i, (name, ..)) in inner.forms.iter().enumerate() {
387 if let Some((pref, suf)) = name.rsplit_once('.')
388 && suf == mask
389 && let Some(j) = inner.forms.iter().position(|(name, ..)| *name == pref)
390 {
391 remaps[j] = i as u16;
392 }
393 }
394
395 inner.masks.push((mask.to_string().leak(), remaps));
396 }
397 })
398 }
399
400 #[macro_export]
434 #[doc(hidden)]
435 macro_rules! __id_of__ {
436 ($form:expr) => {{
437 use $crate::form::{_set_many, DEFAULT_ID, FormId};
438
439 static mut WAS_SET: bool = false;
440 static mut ID: FormId = DEFAULT_ID;
441 if unsafe { WAS_SET } {
442 unsafe { ID }
443 } else {
444 let name = $form.to_string();
445 let id = _set_many(true, vec![(name, None)])[0];
446 unsafe {
447 ID = id;
448 WAS_SET = true;
449 }
450 id
451 }
452 }};
453 }
454
455 pub fn id_of_non_static(name: impl ToString) -> FormId {
462 let name = name.to_string();
463 _set_many(true, vec![(name, None)])[0]
464 }
465
466 pub fn ids_of_non_static(names: impl IntoIterator<Item = impl ToString>) -> Vec<FormId> {
473 let names: Vec<(String, Option<Kind>)> =
474 names.into_iter().map(|n| (n.to_string(), None)).collect();
475 _set_many(true, names)
476 }
477
478 #[doc(hidden)]
480 pub fn _set_many<S: AsRef<str> + Send + Sync + 'static>(
481 weak: bool,
482 sets: Vec<(S, Option<Kind>)>,
483 ) -> Vec<FormId> {
484 let mut ids = Vec::new();
485 let mut forms = FORMS.get().unwrap().lock().unwrap();
486 for (name, _) in sets.iter() {
487 ids.push(FormId(position_of_name(&mut forms, name) as u16));
488 }
489
490 queue(move || PALETTE.get().unwrap().set_many(weak, &sets));
491
492 ids
493 }
494
495 pub fn add_colorscheme(cs: impl ColorScheme) {
506 let mut colorschemes = COLORSCHEMES.lock().unwrap();
507 let name = cs.name();
508 if let Some(i) = colorschemes.iter().position(|cs| cs.name() == name) {
509 colorschemes[i] = Box::new(cs);
510 } else {
511 colorschemes.push(Box::new(cs));
512 }
513 }
514
515 pub fn set_colorscheme(name: &str) {
522 let name = name.to_string();
523 let colorschemes = COLORSCHEMES.lock().unwrap();
524 if let Some(cs) = colorschemes.iter().find(|cs| cs.name() == name) {
525 cs.apply();
526 hook::queue(ColorSchemeSet(cs.name()));
527 } else {
528 context::error!("The colorscheme [a]{name}[] was not found");
529 }
530 }
531
532 #[macro_export]
541 #[doc(hidden)]
542 macro_rules! __set_many__ {
543 ($(($name:literal, $form:expr)),+ $(,)?) => {{
544 use $crate::form::FormFmt;
545 $crate::form::_set_many(false, vec![$( ($name, Some($form.kind())) ),+]);
546 }}
547 }
548
549 #[macro_export]
563 #[doc(hidden)]
564 macro_rules! __set_many_weak__ {
565 ($(($name:literal, $form:expr)),+ $(,)?) => {{
566 use $crate::form::FormFmt;
567 $crate::form::_set_many(true, vec![$( ($name, Some($form.kind())) ),+]);
568 }}
569 }
570
571 pub(crate) fn exists(name: &str) -> bool {
573 FORMS.get().unwrap().lock().unwrap().contains(&name)
574 }
575
576 pub(crate) fn colorscheme_exists(name: &str) -> bool {
578 COLORSCHEMES
579 .lock()
580 .unwrap()
581 .iter()
582 .any(|cs| cs.name() == name)
583 }
584
585 pub(super) fn name_of(id: FormId) -> &'static str {
587 FORMS.get().unwrap().lock().unwrap()[id.0 as usize]
588 }
589
590 fn default_id(type_id: TypeId, type_name: &'static str) -> FormId {
591 static IDS: LazyLock<Mutex<HashMap<TypeId, FormId>>> = LazyLock::new(Mutex::default);
592 let mut ids = IDS.lock().unwrap();
593
594 if let Some(id) = ids.get(&type_id) {
595 *id
596 } else {
597 let name = format!("default.{type_name}");
598 let id = _set_many(true, vec![(name, None)])[0];
599 ids.insert(type_id, id);
600 id
601 }
602 }
603
604 fn position_of_name(names: &mut Vec<&'static str>, name: impl AsRef<str>) -> usize {
605 let name = name.as_ref();
606 if let Some((i, _)) = names.iter().enumerate().find(|(_, rhs)| **rhs == name) {
607 i
608 } else if let Some((refed, _)) = name.rsplit_once('.') {
609 position_of_name(names, refed);
610 names.push(name.to_string().leak());
611 names.len() - 1
612 } else {
613 names.push(name.to_string().leak());
614 names.len() - 1
615 }
616 }
617
618 fn queue<R>(f: impl FnOnce() -> R + Send + Sync + 'static) {
619 static SENDER: Mutex<Option<mpsc::Sender<Box<dyn FnOnce() + Send + Sync>>>> =
620 Mutex::new(None);
621
622 if context::will_reload_or_quit() {
623 return;
624 }
625
626 let f = Box::new(move || {
627 f();
628 });
629
630 let mut sender = SENDER.lock().unwrap();
631 let f = if let Some(tx) = sender.as_ref() {
632 let Err(err) = tx.send(f) else {
633 return;
634 };
635 err.0
636 } else {
637 f
638 };
639 let (tx, rx) = mpsc::channel();
640 tx.send(f).unwrap();
641 *sender = Some(tx);
642
643 std::thread::spawn(move || {
644 while let Ok(f) = rx.recv_timeout(Duration::from_micros(500)) {
645 f();
646 }
647 });
648 }
649
650 #[doc(hidden)]
654 pub fn get_initial() -> (&'static Mutex<Vec<&'static str>>, &'static Palette) {
655 let forms = Box::leak(Box::new(Mutex::new(
656 BASE_FORMS.iter().map(|(n, ..)| *n).collect(),
657 )));
658 let palette = Box::leak(Box::new(Palette::new()));
659 (forms, palette)
660 }
661
662 #[doc(hidden)]
666 pub fn set_initial((forms, palette): (&'static Mutex<Vec<&'static str>>, &'static Palette)) {
667 FORMS.set(forms).expect("Forms setup ran twice");
668 PALETTE.set(palette).expect("Forms setup ran twice");
669 }
670
671 #[doc(hidden)]
673 pub enum Kind {
674 Form(Form),
675 Ref(String),
676 }
677}
678
679#[derive(Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord)]
693pub struct FormId(u16);
694
695impl FormId {
696 pub const fn to_tag(self, prio: u8) -> FormTag {
705 FormTag(self, prio)
706 }
707
708 pub const fn to_u16(self) -> u16 {
712 self.0
713 }
714
715 pub fn name(self) -> &'static str {
717 name_of(self)
718 }
719}
720
721impl std::fmt::Debug for FormId {
722 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
723 write!(f, "FormId({})", name_of(*self))
724 }
725}
726
727macro_rules! mimic_method_new {
729 (#[$attr:meta] $method:ident $attrib:expr) => {
730 #[$attr]
732 pub const fn $method() -> BuiltForm {
734 let mut built = Form::new();
735 built.0.style.attributes = built.0.style.attributes.with($attrib);
736 built
737 }
738 };
739 (#[$attr:meta] $fg:ident $bg:ident $ul:ident $color:expr) => {
740 #[$attr]
742 pub const fn $fg() -> BuiltForm {
744 let mut built = Form::new();
745 built.0.style.foreground_color = Some($color);
746 built
747 }
748
749 #[$attr]
751 pub const fn $bg() -> BuiltForm {
753 let mut built = Form::new();
754 built.0.style.background_color = Some($color);
755 built
756 }
757
758 #[$attr]
760 pub const fn $ul() -> BuiltForm {
769 let mut built = Form::new();
770 built.0.style.underline_color = Some($color);
771 built
772 }
773 };
774}
775
776macro_rules! mimic_method_mod {
777 (#[$attr:meta] $method:ident $attrib:expr) => {
778 #[$attr]
780 pub const fn $method(mut self) -> Self {
782 self.0.style.attributes = self.0.style.attributes.with($attrib);
783 self
784 }
785 };
786 (#[$attr:meta] $fg:ident $bg:ident $ul:ident $color:expr) => {
787 #[$attr]
789 pub const fn $fg(mut self) -> Self {
790 self.0.style.foreground_color = Some($color);
791 self
792 }
793
794 #[$attr]
796 pub const fn $bg(mut self) -> Self {
797 self.0.style.background_color = Some($color);
798 self
799 }
800
801 #[$attr]
803 pub const fn $ul(mut self) -> Self {
810 self.0.style.underline_color = Some($color);
811 self
812 }
813 };
814}
815#[derive(Clone, Copy, PartialEq, Eq)]
817pub struct Form {
818 pub style: ContentStyle,
820}
821
822#[rustfmt::skip]
823impl Form {
824 mimic_method_new!(bold Attribute::Bold);
825 mimic_method_new!(dim Attribute::Dim);
826 mimic_method_new!(italic Attribute::Italic);
827 mimic_method_new!(underlined Attribute::Underlined);
828 mimic_method_new!(double_underlined Attribute::DoubleUnderlined);
829 mimic_method_new!(undercurled Attribute::Undercurled);
830 mimic_method_new!(underdashed Attribute::Underdashed);
831 mimic_method_new!(reverse Attribute::Reverse);
832 mimic_method_new!(crossed_out Attribute::CrossedOut);
833 mimic_method_new!(black on_black underline_black Color::Black);
834 mimic_method_new!(dark_grey on_dark_grey underline_dark_grey Color::DarkGrey);
835 mimic_method_new!(red on_red underline_red Color::Red);
836 mimic_method_new!(dark_red on_dark_red underline_dark_red Color::DarkRed);
837 mimic_method_new!(green on_green underline_green Color::Green);
838 mimic_method_new!(
839 dark_green on_dark_green underline_dark_green Color::DarkGreen
840 );
841 mimic_method_new!(yellow on_yellow underline_yellow Color::Yellow);
842 mimic_method_new!(
843 dark_yellow on_dark_yellow underline_dark_yellow Color::DarkYellow
844 );
845 mimic_method_new!(blue on_blue underline_blue Color::Blue);
846 mimic_method_new!(dark_blue on_dark_blue underline_dark_blue Color::DarkBlue);
847 mimic_method_new!(magenta on_magenta underline_magenta Color::Magenta);
848 mimic_method_new!(
849 dark_magenta on_dark_magenta underline_dark_magenta Color::DarkMagenta
850 );
851 mimic_method_new!(cyan on_cyan underline_cyan Color::Cyan);
852 mimic_method_new!(dark_cyan on_dark_cyan underline_dark_cyan Color::DarkCyan);
853 mimic_method_new!(white on_white underline_white Color::White);
854 mimic_method_new!(grey on_grey underline_grey Color::Grey);
855}
856
857impl Form {
858 #[allow(clippy::new_ret_no_self)]
862 pub const fn new() -> BuiltForm {
863 let style = ContentStyle {
864 foreground_color: None,
865 background_color: None,
866 underline_color: None,
867 attributes: Attributes::none(),
868 };
869 BuiltForm(Self { style })
870 }
871
872 pub const fn reset() -> BuiltForm {
879 let mut built = Form::new();
880 built.0.style.attributes = built.0.style.attributes.with(Attribute::Reset);
881 built
882 }
883
884 pub const fn with(str: &str) -> BuiltForm {
894 let mut built = Form::new();
895 built.0.style.foreground_color = match str_to_color(str) {
896 Ok(color) => Some(color),
897 Err(err) => panic!("{}", err),
898 };
899 built
900 }
901
902 pub const fn on(str: &str) -> BuiltForm {
912 let mut built = Form::new();
913 built.0.style.background_color = match str_to_color(str) {
914 Ok(color) => Some(color),
915 Err(err) => panic!("{}", err),
916 };
917 built
918 }
919
920 pub const fn underline(str: &str) -> BuiltForm {
930 let mut built = Form::new();
931 built.0.style.underline_color = match str_to_color(str) {
932 Ok(color) => Some(color),
933 Err(err) => panic!("{}", err),
934 };
935 built
936 }
937
938 pub const fn fg(&self) -> Option<Color> {
940 self.style.foreground_color
941 }
942
943 pub const fn bg(&self) -> Option<Color> {
945 self.style.background_color
946 }
947
948 pub const fn ul(&self) -> Option<Color> {
950 self.style.underline_color
951 }
952
953 pub const fn attrs(&self) -> Attributes {
955 self.style.attributes
956 }
957}
958
959#[derive(Clone, Copy, Debug)]
968pub struct BuiltForm(Form);
969
970#[rustfmt::skip]
971impl BuiltForm {
972 mimic_method_mod!(bold Attribute::Bold);
973 mimic_method_mod!(dim Attribute::Dim);
974 mimic_method_mod!(italic Attribute::Italic);
975 mimic_method_mod!(underlined Attribute::Underlined);
976 mimic_method_mod!(double_underlined Attribute::DoubleUnderlined);
977 mimic_method_mod!(undercurled Attribute::Undercurled);
978 mimic_method_mod!(underdashed Attribute::Underdashed);
979 mimic_method_mod!(reverse Attribute::Reverse);
980 mimic_method_mod!(crossed_out Attribute::CrossedOut);
981 mimic_method_mod!(overlined Attribute::OverLined);
982 mimic_method_mod!(black on_black underline_black Color::Black);
983 mimic_method_mod!(dark_grey on_dark_grey underline_dark_grey Color::DarkGrey);
984 mimic_method_mod!(red on_red underline_red Color::Red);
985 mimic_method_mod!(dark_red on_dark_red underline_dark_red Color::DarkRed);
986 mimic_method_mod!(green on_green underline_green Color::Green);
987 mimic_method_mod!(
988 dark_green on_dark_green underline_dark_green Color::DarkGreen
989 );
990 mimic_method_mod!(yellow on_yellow underline_yellow Color::Yellow);
991 mimic_method_mod!(
992 dark_yellow on_dark_yellow underline_dark_yellow Color::DarkYellow
993 );
994 mimic_method_mod!(blue on_blue underline_blue Color::Blue);
995 mimic_method_mod!(dark_blue on_dark_blue underline_dark_blue Color::DarkBlue);
996 mimic_method_mod!(magenta on_magenta underline_magenta Color::Magenta);
997 mimic_method_mod!(
998 dark_magenta on_dark_magenta underline_dark_magenta Color::DarkMagenta
999 );
1000 mimic_method_mod!(cyan on_cyan underline_cyan Color::Cyan);
1001 mimic_method_mod!(dark_cyan on_dark_cyan underline_dark_cyan Color::DarkCyan);
1002 mimic_method_mod!(white on_white underline_white Color::White);
1003 mimic_method_mod!(grey on_grey underline_grey Color::Grey);
1004}
1005
1006impl BuiltForm {
1007 pub const fn reset(mut self) -> BuiltForm {
1014 self.0.style.attributes = self.0.style.attributes.with(Attribute::Reset);
1015 self
1016 }
1017
1018 pub const fn with(mut self, str: &str) -> Self {
1028 self.0.style.foreground_color = match str_to_color(str) {
1029 Ok(color) => Some(color),
1030 Err(err) => panic!("{}", err),
1031 };
1032 self
1033 }
1034
1035 pub const fn on(mut self, str: &str) -> Self {
1045 self.0.style.background_color = match str_to_color(str) {
1046 Ok(color) => Some(color),
1047 Err(err) => panic!("{}", err),
1048 };
1049 self
1050 }
1051
1052 pub const fn underline(mut self, str: &str) -> Self {
1062 self.0.style.underline_color = match str_to_color(str) {
1063 Ok(color) => Some(color),
1064 Err(err) => panic!("{}", err),
1065 };
1066 self
1067 }
1068}
1069
1070impl std::ops::Deref for BuiltForm {
1071 type Target = Form;
1072
1073 fn deref(&self) -> &Self::Target {
1074 &self.0
1075 }
1076}
1077
1078impl std::ops::DerefMut for BuiltForm {
1079 fn deref_mut(&mut self) -> &mut Self::Target {
1080 &mut self.0
1081 }
1082}
1083
1084impl From<BuiltForm> for Form {
1085 fn from(value: BuiltForm) -> Self {
1086 value.0
1087 }
1088}
1089
1090pub const DEFAULT_ID: FormId = FormId(0);
1092pub const ACCENT_ID: FormId = FormId(1);
1094pub const M_CAR_ID: FormId = FormId(2);
1096pub const E_CAR_ID: FormId = FormId(3);
1098pub const M_SEL_ID: FormId = FormId(4);
1100pub const E_SEL_ID: FormId = FormId(5);
1102pub const CONTROL_CHAR_ID: FormId = FormId(7);
1104
1105#[derive(Debug)]
1109#[doc(hidden)]
1110pub struct Palette(RwLock<InnerPalette>);
1111
1112impl Palette {
1113 fn new() -> Self {
1115 let main_cursor = Some(CursorShape::DefaultUserShape);
1116 Self(RwLock::new(InnerPalette {
1117 main_cursor,
1118 extra_cursor: main_cursor,
1119 forms: BASE_FORMS.to_vec(),
1120 masks: vec![(
1121 "".to_string().leak(),
1122 (0..BASE_FORMS.len() as u16).collect(),
1123 )],
1124 }))
1125 }
1126
1127 fn set_form(&self, name: impl AsRef<str>, form: Form) {
1129 let name = name.as_ref();
1130 self.0.write().unwrap().set_form(name, form);
1131 }
1132
1133 fn set_weak_form(&self, name: impl AsRef<str>, form: Form) {
1135 let name = name.as_ref();
1136 self.0.write().unwrap().set_weak_form(name, form);
1137 }
1138
1139 fn set_ref(&self, name: impl AsRef<str>, refed: impl AsRef<str>) {
1141 let (name, refed) = (name.as_ref(), refed.as_ref());
1142 self.0.write().unwrap().set_ref(name, refed);
1143 }
1144
1145 fn set_weak_ref(&self, name: impl AsRef<str>, refed: impl AsRef<str>) {
1147 let (name, refed) = (name.as_ref(), refed.as_ref());
1148 self.0.write().unwrap().set_weak_ref(name, refed);
1149 }
1150
1151 fn set_many<S: AsRef<str>>(&self, weak: bool, sets: &[(S, Option<self::global::Kind>)]) {
1153 let mut inner = self.0.write().unwrap();
1154 for (name, kind) in sets {
1155 match (weak, kind) {
1156 (false, Some(Kind::Form(form))) => inner.set_form(name.as_ref(), *form),
1157 (false, Some(Kind::Ref(refed))) => inner.set_ref(name.as_ref(), refed),
1158 (true, Some(Kind::Form(form))) => inner.set_weak_form(name.as_ref(), *form),
1159 (true, Some(Kind::Ref(refed))) => inner.set_weak_ref(name.as_ref(), refed),
1160 (_, None) => {
1161 position_and_form(&mut inner.forms, name);
1162 }
1163 }
1164 }
1165 }
1166
1167 fn form_from_id(&self, id: FormId) -> Option<Form> {
1169 let inner = self.0.read().unwrap();
1170 inner.forms.get(id.0 as usize).map(|(_, form, _)| *form)
1171 }
1172
1173 fn main_cursor(&self) -> (Form, Option<CursorShape>) {
1175 let form = self.form_from_id(M_CAR_ID).unwrap();
1176 (form, self.0.read().unwrap().main_cursor)
1177 }
1178
1179 fn extra_cursor(&self) -> (Form, Option<CursorShape>) {
1181 let form = self.form_from_id(E_CAR_ID).unwrap();
1182 (form, self.0.read().unwrap().extra_cursor)
1183 }
1184
1185 fn set_main_cursor(&self, shape: CursorShape) {
1187 self.0.write().unwrap().main_cursor = Some(shape);
1188 if let Some(sender) = SENDER.get() {
1189 sender.send_form_changed().unwrap()
1190 }
1191 }
1192
1193 fn set_extra_cursor(&self, shape: CursorShape) {
1195 self.0.write().unwrap().extra_cursor = Some(shape);
1196 if let Some(sender) = SENDER.get() {
1197 sender.send_form_changed().unwrap()
1198 }
1199 }
1200
1201 fn unset_main_cursor(&self) {
1203 self.0.write().unwrap().main_cursor = None;
1204 if let Some(sender) = SENDER.get() {
1205 sender.send_form_changed().unwrap()
1206 }
1207 }
1208
1209 fn unset_extra_cursor(&self) {
1211 self.0.write().unwrap().extra_cursor = None;
1212 if let Some(sender) = SENDER.get() {
1213 sender.send_form_changed().unwrap()
1214 }
1215 }
1216
1217 fn painter(&'static self, default_id: FormId, mask: &str) -> Painter {
1219 let inner = self.0.read().unwrap();
1220 let mask_i = inner
1221 .masks
1222 .iter()
1223 .position(|(m, _)| *m == mask)
1224 .unwrap_or_default();
1225
1226 let default = inner
1227 .forms
1228 .get(match inner.masks[mask_i].1.get(default_id.0 as usize) {
1229 Some(i) => *i as usize,
1230 None => default_id.0 as usize,
1231 })
1232 .map(|(_, f, _)| *f)
1233 .unwrap_or(Form::new().0);
1234
1235 Painter {
1236 inner,
1237 mask_i,
1238 default,
1239 forms: Vec::new(),
1240 set_fg: true,
1241 set_bg: true,
1242 set_ul: true,
1243 reset_attrs: false,
1244 prev_style: None,
1245 }
1246 }
1247}
1248
1249struct InnerPalette {
1250 main_cursor: Option<CursorShape>,
1251 extra_cursor: Option<CursorShape>,
1252 forms: Vec<(&'static str, Form, FormType)>,
1253 masks: Vec<(&'static str, Vec<u16>)>,
1254}
1255
1256impl InnerPalette {
1257 fn set_form(&mut self, name: &str, form: Form) {
1259 let (i, _) = position_and_form(&mut self.forms, name);
1260
1261 self.forms[i].1 = form;
1262 self.forms[i].2 = FormType::Normal;
1263
1264 for refed in refs_of(self, i) {
1265 self.forms[refed].1 = form;
1266 }
1267
1268 if let Some(sender) = SENDER.get() {
1269 sender.send_form_changed().unwrap()
1270 }
1271
1272 mask_form(name, i, self);
1273 hook::queue(FormSet((self.forms[i].0, FormId(i as u16), form)));
1274 }
1275
1276 fn set_weak_form(&mut self, name: &str, form: Form) {
1278 let (i, _) = position_and_form(&mut self.forms, name);
1279
1280 let (_, f, f_ty) = &mut self.forms[i];
1281 if let FormType::Weakest | FormType::WeakestRef(_) = f_ty {
1282 *f = form;
1283 *f_ty = FormType::Normal;
1284
1285 if let Some(sender) = SENDER.get() {
1286 sender.send_form_changed().unwrap()
1287 }
1288 for refed in refs_of(self, i) {
1289 self.forms[refed].1 = form;
1290 }
1291
1292 mask_form(name, i, self);
1293 }
1294 }
1295
1296 fn set_ref(&mut self, name: &str, refed: &str) {
1298 let (refed, form) = position_and_form(&mut self.forms, refed);
1299 let (i, _) = position_and_form(&mut self.forms, name);
1300
1301 self.forms[i].1 = form;
1302 for refed in refs_of(self, i) {
1303 self.forms[refed].1 = form;
1304 }
1305
1306 if would_be_circular(self, i, refed) {
1308 self.forms[i].2 = FormType::Normal;
1309 } else {
1310 self.forms[i].2 = FormType::Ref(refed);
1311 }
1312
1313 if let Some(sender) = SENDER.get() {
1314 sender.send_form_changed().unwrap()
1315 }
1316
1317 mask_form(name, i, self);
1318 hook::queue(FormSet((self.forms[i].0, FormId(i as u16), form)));
1319 }
1320
1321 fn set_weak_ref(&mut self, name: &str, refed: &str) {
1323 let (refed, form) = position_and_form(&mut self.forms, refed);
1324 let (i, _) = position_and_form(&mut self.forms, name);
1325
1326 let (_, f, f_ty) = &mut self.forms[i];
1329 if let FormType::Weakest | FormType::WeakestRef(_) = f_ty {
1330 *f = form;
1331 *f_ty = FormType::WeakestRef(refed);
1332
1333 if let Some(sender) = SENDER.get() {
1334 sender.send_form_changed().unwrap()
1335 }
1336 for refed in refs_of(self, i) {
1337 self.forms[refed].1 = form;
1338 }
1339
1340 mask_form(name, i, self);
1341 }
1342 }
1343}
1344
1345fn mask_form(name: &str, form_i: usize, inner: &mut InnerPalette) {
1347 if inner.masks[0].1.len() < inner.forms.len() {
1348 for (_, remaps) in inner.masks.iter_mut() {
1349 remaps.extend(remaps.len() as u16..inner.forms.len() as u16);
1350 }
1351 }
1352
1353 if let Some((pref, mask)) = name.rsplit_once(".")
1354 && let Some((_, remaps)) = inner.masks.iter_mut().find(|(m, _)| *m == mask)
1355 && let Some(j) = inner.forms.iter().position(|(name, ..)| *name == pref)
1356 {
1357 remaps[j] = form_i as u16;
1358 }
1359}
1360
1361pub struct Painter {
1421 inner: RwLockReadGuard<'static, InnerPalette>,
1422 mask_i: usize,
1423 default: Form,
1424 forms: Vec<(Form, FormId, u8)>,
1425 set_fg: bool,
1426 set_bg: bool,
1427 set_ul: bool,
1428 reset_attrs: bool,
1429 prev_style: Option<ContentStyle>,
1430}
1431
1432impl Painter {
1433 #[inline(always)]
1441 pub fn apply(&mut self, id: FormId, prio: u8) {
1442 let (_, mask) = &self.inner.masks[self.mask_i];
1443 let id = FormId(mask.get(id.0 as usize).copied().unwrap_or(id.0));
1444
1445 let forms = &self.inner.forms;
1446 let form = forms
1447 .get(id.0 as usize)
1448 .map(|(_, f, _)| *f)
1449 .unwrap_or(Form::new().0);
1450
1451 let gt = |(.., p): &&(_, _, u8)| *p > prio;
1452 let i = self.forms.len() - self.forms.iter().rev().take_while(gt).count();
1453 self.forms.insert(i, (form, id, prio));
1454
1455 self.set_fg |= form.fg().is_some();
1456 self.set_bg |= form.bg().is_some();
1457 self.set_ul |= form.ul().is_some();
1458 self.reset_attrs |= form.attrs().has(Attribute::Reset);
1459 }
1460
1461 #[inline(always)]
1464 pub fn remove(&mut self, id: FormId) {
1465 let mask = &self.inner.masks[self.mask_i].1;
1466 let id = FormId(mask.get(id.0 as usize).copied().unwrap_or(id.0));
1467
1468 let mut applied_forms = self.forms.iter().enumerate();
1469 if let Some((i, &(form, ..))) = applied_forms.rfind(|(_, (_, lhs, _))| *lhs == id) {
1470 self.forms.remove(i);
1471
1472 self.set_fg |= form.fg().is_some();
1473 self.set_bg |= form.bg().is_some();
1474 self.set_ul |= form.ul().is_some();
1475 self.reset_attrs |= !form.attrs().is_empty();
1476 };
1477 }
1478
1479 #[inline(always)]
1485 pub fn reset(&mut self) -> ContentStyle {
1486 self.forms.clear();
1487 self.absolute_style()
1488 }
1489
1490 #[inline(always)]
1495 pub fn absolute_style(&self) -> ContentStyle {
1496 let mut style = self.default.style;
1497
1498 for &(form, ..) in &self.forms {
1499 style.foreground_color = form.fg().or(style.foreground_color);
1500 style.background_color = form.bg().or(style.background_color);
1501 style.underline_color = form.ul().or(style.underline_color);
1502 style.attributes = if form.attrs().has(Attribute::Reset) {
1503 form.attrs()
1504 } else {
1505 form.attrs() | style.attributes
1506 }
1507 }
1508
1509 style
1510 }
1511
1512 #[inline(always)]
1524 pub fn relative_style(&mut self) -> Option<ContentStyle> {
1525 let abs_style = self.absolute_style();
1526 let mut style = abs_style;
1527
1528 if style.attributes.has(Attribute::Reset) || self.reset_attrs {
1529 style.attributes.set(Attribute::Reset);
1530 } else {
1534 style.foreground_color = self
1535 .set_fg
1536 .then_some(style.foreground_color.unwrap_or(Color::Reset))
1537 .filter(|fg| Some(*fg) != self.prev_style.and_then(|s| s.foreground_color));
1538 style.background_color = self
1539 .set_bg
1540 .then_some(style.background_color.unwrap_or(Color::Reset))
1541 .filter(|bg| Some(*bg) != self.prev_style.and_then(|s| s.background_color));
1542 style.underline_color = self
1543 .set_ul
1544 .then_some(style.underline_color.unwrap_or(Color::Reset))
1545 .filter(|ul| Some(*ul) != self.prev_style.and_then(|s| s.underline_color));
1546 }
1547
1548 self.set_fg = false;
1549 self.set_bg = false;
1550 self.set_ul = false;
1551 self.reset_attrs = false;
1552
1553 if let Some(prev_style) = self.prev_style.replace(abs_style) {
1554 (style != prev_style && style != Default::default()).then_some(style)
1555 } else {
1556 Some(style)
1557 }
1558 }
1559
1560 pub fn reset_prev_style(&mut self) {
1566 self.prev_style = None;
1567 self.set_fg = true;
1568 self.set_bg = true;
1569 self.set_ul = true;
1570 self.reset_attrs = true;
1571 }
1572
1573 #[inline(always)]
1575 pub fn apply_main_cursor(&mut self) {
1576 self.apply(M_CAR_ID, 100);
1577 }
1578
1579 #[inline(always)]
1581 pub fn remove_main_caret(&mut self) {
1582 self.remove(M_CAR_ID);
1583 }
1584
1585 #[inline(always)]
1587 pub fn apply_extra_cursor(&mut self) {
1588 self.apply(E_CAR_ID, 100);
1589 }
1590
1591 #[inline(always)]
1593 pub fn remove_extra_caret(&mut self) {
1594 self.remove(E_CAR_ID);
1595 }
1596
1597 pub fn main_cursor(&self) -> Option<CursorShape> {
1599 self.inner.main_cursor
1600 }
1601
1602 pub fn extra_cursor(&self) -> Option<CursorShape> {
1604 self.inner.extra_cursor
1605 }
1606
1607 pub fn get_default(&self) -> Form {
1609 self.default
1610 }
1611}
1612
1613pub(crate) fn set_sender(sender: DuatSender) {
1614 SENDER
1615 .set(sender)
1616 .unwrap_or_else(|_| panic!("Sender set more than once"));
1617}
1618
1619#[derive(Clone)]
1621enum FormType {
1622 Normal,
1623 Ref(usize),
1624 Weakest,
1625 WeakestRef(usize),
1626}
1627
1628fn refs_of(inner: &InnerPalette, refed: usize) -> Vec<usize> {
1630 let mut refs = Vec::new();
1631 for (i, (.., f_ty)) in inner.forms.iter().enumerate() {
1632 if let FormType::Ref(ref_id) | FormType::WeakestRef(ref_id) = f_ty
1633 && *ref_id == refed
1634 {
1635 refs.push(i);
1636 refs.extend(refs_of(inner, i));
1637 }
1638 }
1639 refs
1640}
1641
1642fn would_be_circular(inner: &InnerPalette, referee: usize, refed: usize) -> bool {
1644 if let (.., FormType::Ref(refed_ref) | FormType::WeakestRef(refed_ref)) = inner.forms[refed] {
1645 match refed_ref == referee {
1646 true => true,
1647 false => would_be_circular(inner, referee, refed_ref),
1648 }
1649 } else {
1650 false
1651 }
1652}
1653
1654fn position_and_form(
1655 forms: &mut Vec<(&str, Form, FormType)>,
1656 name: impl AsRef<str>,
1657) -> (usize, Form) {
1658 let name = name.as_ref();
1659 if let Some((i, (_, form, _))) = forms.iter().enumerate().find(|(_, (lhs, ..))| *lhs == name) {
1660 (i, *form)
1661 } else if let Some((refed, _)) = name.rsplit_once('.') {
1662 let (i, form) = position_and_form(forms, refed);
1663 forms.push((name.to_string().leak(), form, FormType::WeakestRef(i)));
1664 (forms.len() - 1, form)
1665 } else {
1666 forms.push((name.to_string().leak(), Form::new().0, FormType::Weakest));
1667 (forms.len() - 1, Form::new().0)
1668 }
1669}
1670
1671const fn str_to_color(str: &str) -> std::result::Result<Color, &'static str> {
1673 const fn strip_prefix<'a>(prefix: &str, str: &'a str) -> Option<&'a str> {
1674 let prefix = prefix.as_bytes();
1675
1676 let mut i = 0;
1677 while i < prefix.len() {
1678 if str.as_bytes()[i] != prefix[i] {
1679 return None;
1680 }
1681 i += 1;
1682 }
1683
1684 Some(str.split_at(prefix.len()).1)
1685 }
1686 const fn strip_suffix<'a>(suffix: &str, str: &'a str) -> Option<&'a str> {
1687 let prefix = suffix.as_bytes();
1688
1689 let mut i = str.len() - 1;
1690 while i >= str.len() - prefix.len() {
1691 if str.as_bytes()[i] != prefix[i - (str.len() - prefix.len())] {
1692 return None;
1693 }
1694 i += 1;
1695 }
1696
1697 Some(str.split_at(str.len() - suffix.len()).0)
1698 }
1699 const fn split_space(str: &str) -> Option<(&str, &str)> {
1700 if str.is_empty() {
1701 return None;
1702 }
1703
1704 let mut i = 0;
1705 while i < str.len() {
1706 if str.as_bytes()[i] == b' ' {
1707 break;
1708 }
1709 i += 1;
1710 }
1711
1712 let (cut, rest) = str.split_at(i);
1713 let (_, rest) = rest.split_at(if rest.is_empty() { 0 } else { 1 });
1714 Some((cut, rest))
1715 }
1716 const fn hue_to_rgb(p: f32, q: f32, mut t: f32) -> f32 {
1717 t = if t < 0.0 { t + 1.0 } else { t };
1718 t = if t > 1.0 { t - 1.0 } else { t };
1719 if t < 1.0 / 6.0 {
1720 p + (q - p) * 6.0 * t
1721 } else if t < 1.0 / 2.0 {
1722 q
1723 } else if t < 2.0 / 3.0 {
1724 p + (q - p) * (2.0 / 3.0 - t) * 6.0
1725 } else {
1726 p
1727 }
1728 }
1729
1730 if let Some(hex) = strip_prefix("#", str) {
1732 let total = match u32::from_str_radix(hex, 16) {
1733 Ok(total) if hex.len() == 6 => total,
1734 _ => return Err("Hexcode does not contain 6 hex values"),
1735 };
1736 let r = (total >> 16) as u8;
1737 let g = (total >> 8) as u8;
1738 let b = total as u8;
1739
1740 Ok(Color::Rgb { r, g, b })
1741 } else if let Some(mut rgb) = strip_prefix("rgb ", str) {
1743 let mut values = [0, 0, 0];
1744 let mut i = 0;
1745
1746 while i < values.len() {
1747 if let Some((cut, rest)) = split_space(rgb) {
1748 rgb = rest;
1749 values[i] = match u8::from_str_radix(cut, 10) {
1750 Ok(value) => value,
1751 Err(_) => return Err("Rgb format value could not be parsed"),
1752 }
1753 } else {
1754 return Err("Missing value in rgb format");
1755 }
1756 i += 1;
1757 }
1758
1759 let [r, g, b] = values;
1760 Ok(Color::Rgb { r, g, b })
1761 } else if let Some(mut hsl) = strip_prefix("hsl ", str) {
1763 let mut values = [0.0, 0.0, 0.0];
1764 let mut i = 0;
1765 while i < values.len() {
1766 if let Some((cut, rest)) = split_space(hsl) {
1767 hsl = rest;
1768 let (num, div) = match strip_suffix("%", cut) {
1769 Some(perc) => (perc, 100),
1770 None => (cut, 255),
1771 };
1772 values[i] = match u8::from_str_radix(num, 10) {
1773 Ok(value) if value <= div => value as f32 / div as f32,
1774 _ => return Err("Hsl format property could not be parsed"),
1775 }
1776 } else {
1777 return Err("Missing value in hsl format");
1778 }
1779 i += 1;
1780 }
1781 let [hue, sat, lit] = values;
1782
1783 let (r, g, b) = if sat == 0.0 {
1784 (lit, lit, lit)
1785 } else {
1786 let q = if lit < 0.5 {
1787 lit * (1.0 + sat)
1788 } else {
1789 lit + sat - lit * sat
1790 };
1791 let p = 2.0 * lit - q;
1792 let r = hue_to_rgb(p, q, hue + 1.0 / 3.0);
1793 let g = hue_to_rgb(p, q, hue);
1794 let b = hue_to_rgb(p, q, hue - 1.0 / 3.0);
1795 (r, g, b)
1796 };
1797
1798 let r = (0.5 + r * 255.0) as u8;
1800 let g = (0.5 + g * 255.0) as u8;
1801 let b = (0.5 + b * 255.0) as u8;
1802 Ok(Color::Rgb { r, g, b })
1803 } else {
1804 Err("Color format was not recognized")
1805 }
1806}
1807
1808impl std::fmt::Debug for Form {
1809 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1810 struct DebugColor(Option<Color>);
1811 impl std::fmt::Debug for DebugColor {
1812 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1813 match self.0 {
1814 Some(Color::Rgb { r, g, b }) => write!(f, "Some(Rgb({r}, {g}, {b}))"),
1815 Some(Color::AnsiValue(ansi)) => write!(f, "Some(Ansi({ansi}))"),
1816 Some(color) => write!(f, "Some({color:?})"),
1817 None => f.write_str("None"),
1818 }
1819 }
1820 }
1821
1822 struct DebugAttributes(Attributes);
1823 impl std::fmt::Debug for DebugAttributes {
1824 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1825 if self.0.is_empty() {
1826 f.write_str("None")
1827 } else {
1828 let mut is_first = true;
1829 for attr in Attribute::iterator() {
1830 if self.0.has(attr) {
1831 if !is_first {
1832 f.write_str(" | ")?;
1833 }
1834 is_first = false;
1835 write!(f, "{attr:?}")?;
1836 }
1837 }
1838 Ok(())
1839 }
1840 }
1841 }
1842
1843 f.debug_struct("Form")
1844 .field("fg", &DebugColor(self.style.foreground_color))
1845 .field("bg", &DebugColor(self.style.background_color))
1846 .field("ul", &DebugColor(self.style.underline_color))
1847 .field("attr", &DebugAttributes(self.style.attributes))
1848 .finish()
1849 }
1850}
1851
1852impl std::fmt::Debug for InnerPalette {
1853 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1854 struct DebugForms<'a>(&'a [(&'static str, Form, FormType)]);
1855 impl std::fmt::Debug for DebugForms<'_> {
1856 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1857 if f.alternate() {
1858 f.write_str("[\n")?;
1859 let max = self.0.len().ilog10() as usize + 3;
1860 for (n, (name, form, ty)) in self.0.iter().enumerate() {
1861 let num = format!("{n}:");
1862 writeln!(f, "{num:<max$}({name}, {ty:?}, {form:#?})")?;
1863 }
1864 f.write_str("]")
1865 } else {
1866 write!(f, "{:?}", self.0)
1867 }
1868 }
1869 }
1870
1871 struct DebugCursorShape(CursorShape);
1872 impl std::fmt::Debug for DebugCursorShape {
1873 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1874 match self.0 {
1875 CursorShape::DefaultUserShape => f.write_str("DefaultUserShape"),
1876 CursorShape::BlinkingBlock => f.write_str("BlinkingBlock"),
1877 CursorShape::SteadyBlock => f.write_str("SteadyBlock"),
1878 CursorShape::BlinkingUnderScore => f.write_str("BlinkingUnderScore"),
1879 CursorShape::SteadyUnderScore => f.write_str("SteadyUnderScore"),
1880 CursorShape::BlinkingBar => f.write_str("BlinkingBar"),
1881 CursorShape::SteadyBar => f.write_str("SteadyBar"),
1882 }
1883 }
1884 }
1885
1886 f.debug_struct("InnerPalette")
1887 .field("main_cursor", &self.main_cursor.map(DebugCursorShape))
1888 .field("extra_cursor", &self.extra_cursor.map(DebugCursorShape))
1889 .field("forms", &DebugForms(&self.forms))
1890 .field("masks", &self.masks)
1891 .finish()
1892 }
1893}
1894
1895impl std::fmt::Debug for FormType {
1896 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1897 match self {
1898 Self::Normal => write!(f, "Normal"),
1899 Self::Ref(refed) => write!(f, "Ref({refed})"),
1900 Self::Weakest => write!(f, "Weakest"),
1901 Self::WeakestRef(refed) => write!(f, "WeakestRef({refed})"),
1902 }
1903 }
1904}