ghostscope_ui/events/
source_path.rs1#[derive(Debug, Clone)]
3pub struct SourcePathInfo {
4 pub substitutions: Vec<PathSubstitution>,
5 pub search_dirs: Vec<String>,
6 pub runtime_substitution_count: usize,
7 pub runtime_search_dir_count: usize,
8 pub config_substitution_count: usize,
9 pub config_search_dir_count: usize,
10}
11
12impl SourcePathInfo {
13 pub fn format_for_display(&self) -> String {
15 let mut output = String::new();
16
17 output.push_str("šļø Source Path Configuration:\n\n");
18
19 if self.substitutions.is_empty() {
21 output.push_str("Path Substitutions: (none)\n");
22 } else {
23 output.push_str(&format!(
24 "Path Substitutions ({}):\n",
25 self.substitutions.len()
26 ));
27 for (i, sub) in self.substitutions.iter().enumerate() {
28 let marker = if i < self.runtime_substitution_count {
29 "[runtime]"
30 } else {
31 "[config] "
32 };
33 output.push_str(&format!(" {} {} -> {}\n", marker, sub.from, sub.to));
34 }
35 }
36
37 output.push('\n');
38
39 if self.search_dirs.is_empty() {
41 output.push_str("Search Directories: (none)\n");
42 } else {
43 output.push_str(&format!(
44 "Search Directories ({}):\n",
45 self.search_dirs.len()
46 ));
47 for (i, dir) in self.search_dirs.iter().enumerate() {
48 let marker = if i < self.runtime_search_dir_count {
49 "[runtime]"
50 } else {
51 "[config] "
52 };
53 output.push_str(&format!(" {marker} {dir}\n"));
54 }
55 }
56
57 output.push_str("\nš” Runtime rules take precedence over config file rules.\n");
58 output.push_str(
59 "š” Use 'srcpath clear' to remove runtime rules, 'srcpath reset' to reset to config.\n",
60 );
61
62 output
63 }
64
65 pub fn format_for_display_styled(&self) -> Vec<ratatui::text::Line<'static>> {
67 use crate::components::command_panel::style_builder::{StylePresets, StyledLineBuilder};
68 use ratatui::text::Line;
69
70 let mut lines = Vec::new();
71
72 lines.push(
74 StyledLineBuilder::new()
75 .title("šļø Source Path Configuration:")
76 .build(),
77 );
78 lines.push(Line::from(""));
79
80 if self.substitutions.is_empty() {
82 lines.push(
83 StyledLineBuilder::new()
84 .key("Path Substitutions:")
85 .text(" (none)")
86 .build(),
87 );
88 } else {
89 lines.push(
90 StyledLineBuilder::new()
91 .key(format!(
92 "Path Substitutions ({}):",
93 self.substitutions.len()
94 ))
95 .build(),
96 );
97 for (i, sub) in self.substitutions.iter().enumerate() {
98 let marker = if i < self.runtime_substitution_count {
99 "[runtime]"
100 } else {
101 "[config] "
102 };
103 lines.push(
104 StyledLineBuilder::new()
105 .text(" ")
106 .styled(marker, StylePresets::MARKER)
107 .text(" ")
108 .value(&sub.from)
109 .styled(" -> ", StylePresets::TREE)
110 .styled(&sub.to, StylePresets::KEY)
111 .build(),
112 );
113 }
114 }
115
116 lines.push(Line::from(""));
117
118 if self.search_dirs.is_empty() {
120 lines.push(
121 StyledLineBuilder::new()
122 .key("Search Directories:")
123 .text(" (none)")
124 .build(),
125 );
126 } else {
127 lines.push(
128 StyledLineBuilder::new()
129 .key(format!("Search Directories ({}):", self.search_dirs.len()))
130 .build(),
131 );
132 for (i, dir) in self.search_dirs.iter().enumerate() {
133 let marker = if i < self.runtime_search_dir_count {
134 "[runtime]"
135 } else {
136 "[config] "
137 };
138 lines.push(
139 StyledLineBuilder::new()
140 .text(" ")
141 .styled(marker, StylePresets::MARKER)
142 .text(" ")
143 .value(dir)
144 .build(),
145 );
146 }
147 }
148
149 lines.push(Line::from(""));
150 lines.push(
151 StyledLineBuilder::new()
152 .styled(
153 "š” Runtime rules take precedence over config file rules.",
154 StylePresets::TIP,
155 )
156 .build(),
157 );
158 lines.push(
159 StyledLineBuilder::new()
160 .styled(
161 "š” Use 'srcpath clear' to remove runtime rules, 'srcpath reset' to reset to config.",
162 StylePresets::TIP,
163 )
164 .build(),
165 );
166
167 lines
168 }
169}
170
171#[derive(Debug, Clone, PartialEq, Eq)]
173pub struct PathSubstitution {
174 pub from: String,
175 pub to: String,
176}