Oregami
Repositories/oxedyne/fe2o3

oxedyne/fe2o3/fe2o3_tui/src/lib_tui/text/highlight.rs

5.5 KiB, 7 runs

created by r1870400018:1207, which is this file's identity for as long as the history lasts, whatever it is later renamed to

download · who wrote it · its history

1//! Highlights are intended to be non-verlapping spans of text within lines that can be styled and
2//! navigated using a focus. They are stored with the text lines themselves and so may need to be
3//! updated when the text changes.
4//!
5use crate::lib_tui::{
6 text::{
7 typ::{
8 HighlightType,
9 TextType,
10 },
11 },
12};
13
14use oxedyne_fe2o3_core::prelude::*;
15use oxedyne_fe2o3_text::{
16 Text,
17 highlight::Highlight,
18 lines::LineRange,
19};
20
21
22#[derive(Clone, Debug)]
23pub enum HighlightBuilder {
24 FullLine,
25 IgnoreWhiteSpace,
26 Marked(String, String), // Start marker, end marker.
27}
28
29impl Default for HighlightBuilder {
30 fn default() -> Self {
31 Self::FullLine
32 }
33}
34
35impl HighlightBuilder {
36
37 pub fn build(
38 &self,
39 pairs: Vec<(Text<TextType>, Option<HighlightType>)>,
40 )
41 -> Outcome<Vec<Highlight<HighlightType>>>
42 {
43 let mut result = Vec::new();
44 match &self {
45 Self::FullLine => {
46 for (i, (text, data)) in pairs.into_iter().enumerate() {
47 match text.typ {
48 TextType::Plain |
49 TextType::MenuItem => {
50 result.push(Highlight::new(
51 LineRange::new(i, (0, text.len() - 1)),
52 0,
53 data,
54 ));
55 }
56 _ => {}
57 }
58 }
59 }
60 Self::IgnoreWhiteSpace => {
61 for (i, (text, data)) in pairs.into_iter().enumerate() {
62 match text.typ {
63 TextType::Plain |
64 TextType::MenuItem => {
65 let trimmed = text.txt.trim();
66 let mut iter = trimmed.chars();
67 // Find the start index of the first non-whitespace character.
68 let start = iter.next().and_then(|first_non_white| {
69 text.txt.find(first_non_white)
70 });
71
72 // Find the end index of the last non-whitespace character.
73 let end = iter.last().and_then(|last_non_white| {
74 text.txt.rfind(last_non_white)
75 });
76 if let Some(start) = start {
77 if let Some(end) = end {
78 result.push(Highlight::new(
79 LineRange::new(i, (start, end + 1)),
80 0,
81 data,
82 ));
83 }
84 }
85 }
86 _ => {}
87 }
88 }
89 }
90 Self::Marked(prefix, suffix) => {
91 for (i, (text, data)) in pairs.into_iter().enumerate() {
92 let mut prefix_index = 0;
93 while let Some(start) = text.txt[prefix_index..].find(prefix) {
94 let start = prefix_index + start + prefix.len();
95 if let Some(end) = text.txt[start..].find(suffix) {
96 let end = start + end;
97 result.push(Highlight::new(
98 LineRange::new(i, (start, end - start)),
99 0,
100 data.clone(),
101 ));
102 prefix_index = end + suffix.len();
103 } else {
104 result.push(Highlight::new(
105 LineRange::new(i, (start, text.len() - 1)),
106 0,
107 data.clone(),
108 ));
109 break;
110 }
111 }
112 if prefix_index == 0 && !text.is_empty() {
113 result.push(Highlight::new(
114 LineRange::new(i, (0, text.len() - 1)),
115 0,
116 data.clone(),
117 ));
118 }
119 }
120 }
121 //_ => {}
122 }
123 Ok(result)
124 }
125}
126
127//#[derive(Clone, Debug, Default)]
128//pub struct StyledHighlighter {
129// pub highlighter: Highlighter<HighlightType>,
130// pub build_typ: BuilderType,
131// pub styles: Vec<Style>,
132//}
133//
134//impl StyledHighlighter {
135// pub fn new(
136// build_typ: BuilderType,
137// styles: Vec<Style>,
138// )
139// -> Self
140// {
141// Self {
142// build_typ,
143// styles,
144// ..Default::default()
145// }
146// }
147//
148// pub fn is_empty(&self) -> bool {
149// self.highlighter.is_empty()
150// }
151//
152// pub fn get_focus(&self) -> usize {
153// self.highlighter.get_focus()
154// }
155//
156// pub fn get_highlighted(&self) -> Option<&Highlight<HighlightType>> {
157// self.highlighter.get_highlighted()
158// }
159//
160// pub fn get_highlighted_data(&self) -> Option<&HighlightType> {
161// self.highlighter.get_highlighted()
162// }
163//
164// pub fn inc_focus(&mut self) {
165// self.highlighter.inc_focus()
166// }
167//
168// pub fn dec_focus(&mut self) {
169// self.highlighter.dec_focus()
170// }
171//
172//}