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 {
63 let _ = builder.write_str(&format!("{italic}<Overview move disabled>{reset}\n"));
64 }
65 }
66
67 builder.push('\n');
68
69 if let Some(windows) = &config.windows {
70 if let Some(switch) = &windows.switch {
71 let _ = builder.write_str(&format!(
72 "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",
73 switch.modifier,
74 switch.modifier,
75 switch.modifier,
76 ));
77 } else {
78 let _ = builder.write_str(&format!("{italic}<Switch mode disabled>{reset}\n"));
79 }
80 }
81
82 builder
83}
84
85#[cfg(test)]
86mod tests {
87 use super::*;
88 use crate::structs::*;
89 use std::path::PathBuf;
90
91 fn create_test_config() -> Config {
92 Config {
93 windows: Some(Windows {
94 overview: Some(Overview::default()),
95 switch: Some(Switch::default()),
96 ..Default::default()
97 }),
98 ..Default::default()
99 }
100 }
101
102 #[test]
103 fn test_explain_with_overview() {
104 const CONFIG: &str = r"Config is valid (/test/config.ron)
105Explanation (blue are keys, bold blue keys can be configured in config):
106Use Super + super_l to open the Overview. Use tab and grave / shift + tab to select a different window, press return to switch
107You can also use the arrow keys to navigate the workspaces. Use Esc to close the overview.
108After opening the Overview the Launcher is available:
109 - 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.
110 - Press Ctrl + t to run the typed command in a terminal.
111 - Press Ctrl + <key> to search the typed text in any of the configured SearchEngines: Google, Wikipedia.
112 - Typing a mathematical expression will calculate it and display the result in the launcher.
113 - Paths (starting with ~ or /) can be open in default file-manager.
114
115Press 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.
116";
117 let config = create_test_config();
118 let path = PathBuf::from("/test/config.ron");
119 let result = explain(&config, &path, false);
120 assert_eq!(result, CONFIG);
121 }
122
123 #[test]
124 fn test_explain_without_overview() {
125 const CONFIG: &str = r"Config is valid (/test/config.ron)
126Explanation (blue are keys, bold blue keys can be configured in config):
127<Overview move disabled>
128
129Press 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.
130";
131 let mut config = create_test_config();
132 config.windows.as_mut().unwrap().overview = None;
133 let path = PathBuf::from("/test/config.ron");
134 let result = explain(&config, &path, false);
135 assert_eq!(result, CONFIG);
136 }
137
138 #[test]
139 fn test_explain_without_switch() {
140 const CONFIG: &str = r"Config is valid (/test/config.ron)
141Explanation (blue are keys, bold blue keys can be configured in config):
142Use Super + super_l to open the Overview. Use tab and grave / shift + tab to select a different window, press return to switch
143You can also use the arrow keys to navigate the workspaces. Use Esc to close the overview.
144After opening the Overview the Launcher is available:
145 - 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.
146 - Press Ctrl + t to run the typed command in a terminal.
147 - Press Ctrl + <key> to search the typed text in any of the configured SearchEngines: Google, Wikipedia.
148 - Typing a mathematical expression will calculate it and display the result in the launcher.
149 - Paths (starting with ~ or /) can be open in default file-manager.
150
151<Switch mode disabled>
152";
153 let mut config = create_test_config();
154 config.windows.as_mut().unwrap().switch = None;
155 let path = PathBuf::from("/test/config.ron");
156 let result = explain(&config, &path, false);
157 assert_eq!(result, CONFIG);
158 }
159
160 #[test]
161 fn test_explain_without_plugins() {
162 const CONFIG: &str = r"Config is valid (/test/config.ron)
163Explanation (blue are keys, bold blue keys can be configured in config):
164Use Super + super_l to open the Overview. Use tab and grave / shift + tab to select a different window, press return to switch
165You can also use the arrow keys to navigate the workspaces. Use Esc to close the overview.
166After opening the Overview the Launcher is available:
167
168Press 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.
169";
170 let mut config = create_test_config();
171 config
172 .windows
173 .as_mut()
174 .unwrap()
175 .overview
176 .as_mut()
177 .unwrap()
178 .launcher
179 .plugins = Plugins {
180 applications: None,
181 terminal: None,
182 shell: None,
183 websearch: None,
184 calc: None,
185 path: None,
186 };
187 let path = PathBuf::from("/test/config.ron");
188 let result = explain(&config, &path, false);
189 assert_eq!(result, CONFIG);
190 }
191}