vtcode_core/ui/
slash.rs

1use once_cell::sync::Lazy;
2
3/// Metadata describing a slash command supported by the chat interface.
4#[derive(Clone, Copy, Debug)]
5pub struct SlashCommandInfo {
6    pub name: &'static str,
7    pub description: &'static str,
8}
9
10/// Collection of slash command definitions in the order they should be displayed.
11pub static SLASH_COMMANDS: Lazy<Vec<SlashCommandInfo>> = Lazy::new(|| {
12    vec![
13        SlashCommandInfo {
14            name: "init",
15            description: "Create vtcode.toml and index the workspace (usage: /init [--force])",
16        },
17        SlashCommandInfo {
18            name: "config",
19            description: "View the effective vtcode.toml configuration",
20        },
21        SlashCommandInfo {
22            name: "theme",
23            description: "Switch UI theme (usage: /theme <theme-id>)",
24        },
25        SlashCommandInfo {
26            name: "list-themes",
27            description: "List all available UI themes",
28        },
29        SlashCommandInfo {
30            name: "command",
31            description: "Run a terminal command (usage: /command <program> [args...])",
32        },
33        SlashCommandInfo {
34            name: "sessions",
35            description: "List recent archived sessions (usage: /sessions [limit])",
36        },
37        SlashCommandInfo {
38            name: "help",
39            description: "Show slash command help",
40        },
41        SlashCommandInfo {
42            name: "exit",
43            description: "Exit the session",
44        },
45    ]
46});
47
48/// Returns slash command metadata that match the provided prefix (case insensitive).
49pub fn suggestions_for(prefix: &str) -> Vec<&'static SlashCommandInfo> {
50    if prefix.is_empty() {
51        return SLASH_COMMANDS.iter().collect();
52    }
53    let query = prefix.to_ascii_lowercase();
54    let mut matches: Vec<&SlashCommandInfo> = SLASH_COMMANDS
55        .iter()
56        .filter(|info| info.name.starts_with(&query))
57        .collect();
58    if matches.is_empty() {
59        SLASH_COMMANDS.iter().collect()
60    } else {
61        matches.sort_by(|a, b| a.name.cmp(b.name));
62        matches
63    }
64}