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: "model",
23            description: "Launch the interactive model picker",
24        },
25        SlashCommandInfo {
26            name: "theme",
27            description: "Switch UI theme (usage: /theme <theme-id>)",
28        },
29        SlashCommandInfo {
30            name: "list-themes",
31            description: "List all available UI themes",
32        },
33        SlashCommandInfo {
34            name: "command",
35            description: "Run a terminal command (usage: /command <program> [args...])",
36        },
37        SlashCommandInfo {
38            name: "sessions",
39            description: "List recent archived sessions (usage: /sessions [limit])",
40        },
41        SlashCommandInfo {
42            name: "help",
43            description: "Show slash command help",
44        },
45        SlashCommandInfo {
46            name: "exit",
47            description: "Exit the session",
48        },
49    ]
50});
51
52/// Returns slash command metadata that match the provided prefix (case insensitive).
53pub fn suggestions_for(prefix: &str) -> Vec<&'static SlashCommandInfo> {
54    if prefix.is_empty() {
55        return SLASH_COMMANDS.iter().collect();
56    }
57    let query = prefix.to_ascii_lowercase();
58    let mut matches: Vec<&SlashCommandInfo> = SLASH_COMMANDS
59        .iter()
60        .filter(|info| info.name.starts_with(&query))
61        .collect();
62    if matches.is_empty() {
63        SLASH_COMMANDS.iter().collect()
64    } else {
65        matches.sort_by(|a, b| a.name.cmp(b.name));
66        matches
67    }
68}