hyprshell_config_lib/
explain.rs1use crate::Config;
2use std::fmt::Write;
3use std::path::Path;
4
5const BOLD: &str = "\x1b[1m";
6const ITALIC: &str = "\x1b[3m";
7const BLUE: &str = "\x1b[34m";
8const GREEN: &str = "\x1b[32m";
9const RESET: &str = "\x1b[0m";
10
11#[must_use]
12pub fn explain(config: &Config, config_path: &Path, enable_color: bool) -> String {
13 let (bold, italic, blue, green, reset) = if enable_color {
14 (BOLD, ITALIC, BLUE, GREEN, RESET)
15 } else {
16 ("", "", "", "", "")
17 };
18
19 let config_path_display = config_path.display();
20 let mut builder = format!(
21 "{bold}{green}Config is valid{reset} ({config_path_display})\n{bold}Explanation{reset} ({blue}blue{reset} are keys, {bold}{blue}bold blue{reset} keys can be configured in config):{reset}\n",
22 );
23
24 if let Some(windows) = &config.windows {
25 if let Some(overview) = &windows.overview {
26 let _ = builder.write_str(&format!(
27 "Use {bold}{blue}{}{reset} + {bold}{blue}{}{reset} to open the Overview. Use {blue}tab{reset} and {blue}grave{reset} / {blue}shift{reset} + {blue}tab{reset} to select a different window, press {blue}return{reset} to switch\n\
28 You can also use the {blue}arrow keys{reset} to navigate the workspaces. Use {blue}Esc{reset} to close the overview.\n",
29 overview.modifier,
30 overview.key,
31 ));
32 let _ = builder.write_str(&format!(
33 "After opening the Overview the {bold}Launcher{reset} is available:\n"
34 ));
35 if let Some(_applications) = overview.launcher.plugins.applications.as_ref() {
36 let _ = builder.write_str(&format!("\t- Start typing to search through applications (sorted by how often they were opened). Press {blue}return{reset} to launch the first app, use {blue}Ctrl{reset} + {blue}1{reset}/{blue}2{reset}/{blue}3{reset}/... to open the second, third, etc.\n"));
37 }
38 if overview.launcher.plugins.terminal.is_some() {
39 let _ = builder.write_str(&format!(
40 "\t- Press {blue}Ctrl{reset} + {blue}t{reset} to run the typed command in a terminal.\n"
41 ));
42 }
43 if overview.launcher.plugins.shell.is_some() {
44 let _ = builder.write_str(&format!(
45 "\t- Press {blue}Ctrl{reset} + {blue}r{reset} to run the typed command in the background.\n",
46 ));
47 }
48 if let Some(engines) = &overview.launcher.plugins.websearch {
49 let _ = builder.write_str(&format!("\t- Press {blue}Ctrl{reset} + {bold}{blue}<key>{reset} to search the typed text in any of the configured SearchEngines: {}.\n",
50 engines.engines.iter().map(|e| e.name.to_string()).collect::<Vec<_>>().join(", ")));
51 }
52 if overview.launcher.plugins.calc.is_some() {
53 let _ = builder.write_str(
54 "\t- Typing a mathematical expression will calculate it and display the result in the launcher.\n",
55 );
56 }
57 if overview.launcher.plugins.path.is_some() {
58 let _ = builder.write_str(
59 "\t- Paths (starting with ~ or /) can be open in default file-manager.\n",
60 );
61 }
62 } else {
69 let _ = builder.write_str(&format!("{italic}<Overview move disabled>{reset}\n"));
70 }
71 }
72
73 builder.push('\n');
74
75 if let Some(windows) = &config.windows {
76 if let Some(switch) = &windows.switch {
77 let _ = builder.write_str(&format!(
78 "Press {bold}{blue}{}{reset} + {blue}tab{reset} and hold {bold}{blue}{}{reset} to view recently used applications. Press {blue}tab{reset} and {blue}grave{reset} / {blue}shift{reset} + {blue}tab{reset} to select a different window, release {bold}{blue}{}{reset} to close the window.\n",
79 switch.modifier,
80 switch.modifier,
81 switch.modifier,
82 ));
83 } else {
84 let _ = builder.write_str(&format!("{italic}<Switch mode disabled>{reset}\n"));
85 }
86 }
87
88 builder
89}
90
91#[cfg(test)]
92mod tests {
93 use super::*;
94 use crate::structs::*;
95 use std::path::PathBuf;
96
97 fn create_test_config() -> Config {
98 Config {
99 windows: Some(Windows {
100 overview: Some(Overview::default()),
101 switch: Some(Switch::default()),
102 ..Default::default()
103 }),
104 ..Default::default()
105 }
106 }
107
108 #[test]
109 fn test_explain_with_overview() {
110 const CONFIG: &str = r"Config is valid (/test/config.ron)
111Explanation (blue are keys, bold blue keys can be configured in config):
112Use Super + super_l to open the Overview. Use tab and grave / shift + tab to select a different window, press return to switch
113You can also use the arrow keys to navigate the workspaces. Use Esc to close the overview.
114After opening the Overview the Launcher is available:
115 - Start typing to search through applications (sorted by how often they were opened). Press return to launch the first app, use Ctrl + 1/2/3/... to open the second, third, etc.
116 - Press Ctrl + t to run the typed command in a terminal.
117 - Press Ctrl + <key> to search the typed text in any of the configured SearchEngines: Google, Wikipedia.
118 - Typing a mathematical expression will calculate it and display the result in the launcher.
119 - Paths (starting with ~ or /) can be open in default file-manager.
120
121Press Alt + tab and hold Alt to view recently used applications. Press tab and grave / shift + tab to select a different window, release Alt to close the window.
122";
123 let config = create_test_config();
124 let path = PathBuf::from("/test/config.ron");
125 let result = explain(&config, &path, false);
126 assert_eq!(result, CONFIG);
127 }
128
129 #[test]
130 fn test_explain_without_overview() {
131 const CONFIG: &str = r"Config is valid (/test/config.ron)
132Explanation (blue are keys, bold blue keys can be configured in config):
133<Overview move disabled>
134
135Press Alt + tab and hold Alt to view recently used applications. Press tab and grave / shift + tab to select a different window, release Alt to close the window.
136";
137 let mut config = create_test_config();
138 config.windows.as_mut().unwrap().overview = None;
139 let path = PathBuf::from("/test/config.ron");
140 let result = explain(&config, &path, false);
141 assert_eq!(result, CONFIG);
142 }
143
144 #[test]
145 fn test_explain_without_switch() {
146 const CONFIG: &str = r"Config is valid (/test/config.ron)
147Explanation (blue are keys, bold blue keys can be configured in config):
148Use Super + super_l to open the Overview. Use tab and grave / shift + tab to select a different window, press return to switch
149You can also use the arrow keys to navigate the workspaces. Use Esc to close the overview.
150After opening the Overview the Launcher is available:
151 - Start typing to search through applications (sorted by how often they were opened). Press return to launch the first app, use Ctrl + 1/2/3/... to open the second, third, etc.
152 - Press Ctrl + t to run the typed command in a terminal.
153 - Press Ctrl + <key> to search the typed text in any of the configured SearchEngines: Google, Wikipedia.
154 - Typing a mathematical expression will calculate it and display the result in the launcher.
155 - Paths (starting with ~ or /) can be open in default file-manager.
156
157<Switch mode disabled>
158";
159 let mut config = create_test_config();
160 config.windows.as_mut().unwrap().switch = None;
161 let path = PathBuf::from("/test/config.ron");
162 let result = explain(&config, &path, false);
163 assert_eq!(result, CONFIG);
164 }
165
166 #[test]
167 fn test_explain_without_plugins() {
168 const CONFIG: &str = r"Config is valid (/test/config.ron)
169Explanation (blue are keys, bold blue keys can be configured in config):
170Use Super + super_l to open the Overview. Use tab and grave / shift + tab to select a different window, press return to switch
171You can also use the arrow keys to navigate the workspaces. Use Esc to close the overview.
172After opening the Overview the Launcher is available:
173
174Press Alt + tab and hold Alt to view recently used applications. Press tab and grave / shift + tab to select a different window, release Alt to close the window.
175";
176 let mut config = create_test_config();
177 config
178 .windows
179 .as_mut()
180 .unwrap()
181 .overview
182 .as_mut()
183 .unwrap()
184 .launcher
185 .plugins = Plugins {
186 applications: None,
187 terminal: None,
188 shell: None,
189 websearch: None,
190 calc: None,
191 path: None,
192 };
193 let path = PathBuf::from("/test/config.ron");
194 let result = explain(&config, &path, false);
195 assert_eq!(result, CONFIG);
196 }
197}