modcli/
console.rs

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    // Get shell configuration
11    let sconf = if let Some(sconf) = &config.modcli.shell {
12        sconf
13    } else {
14        panic!("Shell configuration is missing");
15    };
16
17    // Set prompt prefix or default to "Mod > "
18    let prompt = sconf.prompt.as_deref().unwrap_or("Mod > ");
19
20    // Show welcome message, scroll line-by-line with optional delay
21    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    // Show goodbye message, scroll line-by-line with optional delay
28    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    // Initialize ModCLI
37    let mut cli = ModCli::new();
38   
39    // Optionally re-load commands if needed
40    // let source = crate::loader::sources::JsonFileSource::new("examples/commands.json");
41    // cli.registry.load_from(Box::new(source));
42
43    // Loop for shell commands
44    loop {
45        // Get input
46        let input = prompt_text(&prompt);
47        let trimmed = input.trim();
48
49        // Check for exit commands
50        if matches!(trimmed, "exit" | "quit") {
51            break;
52        }
53        
54        // Check internal shell commands
55        if dispatch_shell_command(trimmed, config) {
56            continue;
57        }
58
59        // Check custom shell commands
60        if dispatch(trimmed) {
61            continue;
62        }
63
64        // Parse input into command and args
65        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        // Execute command
78        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}