hyprshell_config_lib/
explain.rs

1use 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}