1use crate::config::CliConfig;
2use crate::output::input::prompt_text;
3use crate::output::print;
4use crate::ModCli;
5use crate::shell_extensions::dispatch_shell_command;
6use crate::shell_commands::dispatch;
7
8pub fn run_shell(config: &CliConfig) {
9
10 let sconf = if let Some(sconf) = &config.modcli.shell {
12 sconf
13 } else {
14 panic!("Shell configuration is missing");
15 };
16
17 let prompt = sconf.prompt.as_deref().unwrap_or("Mod > ");
19
20 if let Some(welcome) = &sconf.welcome {
22 let delay = &config.modcli.delay.unwrap_or(0);
23 let lines: Vec<&str> = welcome.iter().flat_map(|s| s.lines()).collect();
24 print::scroll(&lines, *delay);
25 }
26
27 let goodbye_message = if let Some(goodbye) = &sconf.goodbye {
29 let delay = &config.modcli.delay.unwrap_or(0);
30 let lines: Vec<&str> = goodbye.iter().flat_map(|s| s.lines()).collect();
31 Some((lines, *delay))
32 } else {
33 None
34 };
35
36 let mut cli = ModCli::new();
38
39 loop {
45 let input = prompt_text(&prompt);
47 let trimmed = input.trim();
48
49 if matches!(trimmed, "exit" | "quit") {
51 break;
52 }
53
54 if dispatch_shell_command(trimmed, config) {
56 continue;
57 }
58
59 if dispatch(trimmed) {
61 continue;
62 }
63
64 let parts: Vec<String> = trimmed
66 .split_whitespace()
67 .map(String::from)
68 .collect();
69
70 if parts.is_empty() {
71 continue;
72 }
73
74 let cmd = parts[0].clone();
75 let args = parts[1..].to_vec();
76
77 cli.run([cmd].into_iter().chain(args).collect());
79 }
80
81 if let Some((lines, delay)) = goodbye_message {
82 print::scroll(&lines, delay);
83 }
84}