Skip to repository content133 lines · 4.0 KB · rust
tenant.openagents/omega
No repository description is available.
OpenAgents Git authority 2026-07-28T04:46:23.507Z Public web read
NIP-34 coordinate
30617:7649603503856e5148d571eac2766b288a8ff1e9e35d380337a1d2b0015b4f92:omegaMaintainersHidden in public view
References2 branches · 1 tag
Read-only clone
git clone https://openagents.com/git/tenant.openagents/omega.gitBrowse files
highlighted_match_with_paths.rs
1use ui::{HighlightedLabel, prelude::*};
2
3#[derive(Clone)]
4pub struct HighlightedMatchWithPaths {
5 pub prefix: Option<SharedString>,
6 pub match_label: HighlightedMatch,
7 pub paths: Vec<HighlightedMatch>,
8 pub active: bool,
9}
10
11#[derive(Debug, Clone, IntoElement)]
12pub struct HighlightedMatch {
13 pub text: String,
14 pub highlight_positions: Vec<usize>,
15 pub color: Color,
16}
17
18impl HighlightedMatch {
19 pub fn join(components: impl Iterator<Item = Self>, separator: &str) -> Self {
20 // Track a running byte offset and insert separators between parts.
21 let mut first = true;
22 let mut byte_offset = 0;
23 let mut text = String::new();
24 let mut highlight_positions = Vec::new();
25 for component in components {
26 if !first {
27 text.push_str(separator);
28 byte_offset += separator.len();
29 }
30 first = false;
31
32 highlight_positions.extend(
33 component
34 .highlight_positions
35 .iter()
36 .map(|position| position + byte_offset),
37 );
38 text.push_str(&component.text);
39 byte_offset += component.text.len();
40 }
41
42 Self {
43 text,
44 highlight_positions,
45 color: Color::Default,
46 }
47 }
48
49 pub fn color(self, color: Color) -> Self {
50 Self { color, ..self }
51 }
52}
53impl RenderOnce for HighlightedMatch {
54 fn render(self, _window: &mut Window, _: &mut App) -> impl IntoElement {
55 HighlightedLabel::new(self.text, self.highlight_positions)
56 .color(self.color)
57 .truncate()
58 }
59}
60
61impl HighlightedMatchWithPaths {
62 pub fn render_paths_children(&mut self, element: Div) -> Div {
63 element.children(self.paths.clone().into_iter().map(|path| {
64 HighlightedLabel::new(path.text, path.highlight_positions)
65 .size(LabelSize::Small)
66 .color(Color::Muted)
67 }))
68 }
69
70 pub fn is_active(mut self, active: bool) -> Self {
71 self.active = active;
72 self
73 }
74}
75
76impl RenderOnce for HighlightedMatchWithPaths {
77 fn render(mut self, _window: &mut Window, _: &mut App) -> impl IntoElement {
78 v_flex()
79 .min_w_0()
80 .child(
81 h_flex()
82 .gap_1()
83 .child(self.match_label.clone())
84 .when_some(self.prefix.as_ref(), |this, prefix| {
85 this.child(Label::new(format!("({})", prefix)).color(Color::Muted))
86 })
87 .when(self.active, |this| {
88 this.child(
89 Icon::new(IconName::Check)
90 .size(IconSize::Small)
91 .color(Color::Accent),
92 )
93 }),
94 )
95 .when(!self.paths.is_empty(), |this| {
96 self.render_paths_children(this)
97 })
98 }
99}
100
101#[cfg(test)]
102mod tests {
103 use super::*;
104
105 #[test]
106 fn join_offsets_positions_by_bytes_not_chars() {
107 // "αβγ" is 3 Unicode scalar values, 6 bytes in UTF-8.
108 let left_text = "αβγ".to_string();
109 let right_text = "label".to_string();
110 let left = HighlightedMatch {
111 text: left_text,
112 highlight_positions: vec![],
113 color: Color::Default,
114 };
115 let right = HighlightedMatch {
116 text: right_text,
117 highlight_positions: vec![0, 1],
118 color: Color::Default,
119 };
120 let joined = HighlightedMatch::join([left, right].into_iter(), "");
121
122 assert!(
123 joined
124 .highlight_positions
125 .iter()
126 .all(|&p| joined.text.is_char_boundary(p)),
127 "join produced non-boundary positions {:?} for text {:?}",
128 joined.highlight_positions,
129 joined.text
130 );
131 }
132}
133