- Updated markdown rendering logic to use more concise methods for obtaining vector lengths. - Changed review status display to use the correct flag from settings. - Cleaned up sidebar rendering code for better formatting and readability. - Enhanced status bar rendering with improved string formatting and consistent style application. - Refined workflow panel rendering, ensuring consistent style usage and improved readability. - Added architecture overview and detailed documentation for backend, data, dependencies, and frontend structures.
88 lines
2.7 KiB
Rust
88 lines
2.7 KiB
Rust
//! Slash-command parser that maps TUI `/foo` input lines into `Command`
|
|
//! variants for the action dispatch system.
|
|
|
|
/// A parsed slash command from the TUI input buffer.
|
|
#[derive(Debug, Clone, PartialEq)]
|
|
pub enum Command {
|
|
Help,
|
|
Quit,
|
|
McpOpen,
|
|
Clear,
|
|
ClearConfirm,
|
|
Login { provider: String },
|
|
Edit(String),
|
|
McpAdd { name: String, command: String },
|
|
ModelList,
|
|
Compact,
|
|
TodoOpen,
|
|
UsageOpen,
|
|
Unknown(String),
|
|
}
|
|
|
|
/// Parse a slash-prefixed input line into a `Command` value.
|
|
///
|
|
/// Flow: trim -> check for leading `/` -> split on space (max 3 parts) ->
|
|
/// match the first token against known commands -> extract arguments from
|
|
/// the remaining parts.
|
|
///
|
|
/// Why: early return `Unknown` for non-slash lines so the caller can treat
|
|
/// them as regular chat input.
|
|
pub fn parse_command(text: &str) -> Command {
|
|
let text = text.trim();
|
|
if !text.starts_with('/') {
|
|
return Command::Unknown(text.to_string());
|
|
}
|
|
let parts: Vec<&str> = text.splitn(3, ' ').collect();
|
|
let cmd = parts[0];
|
|
let arg1 = parts.get(1).copied().unwrap_or("");
|
|
let arg2 = parts.get(2).copied().unwrap_or("");
|
|
match cmd {
|
|
"/help" => Command::Help,
|
|
"/quit" => Command::Quit,
|
|
"/clear" if arg1.is_empty() => Command::ClearConfirm,
|
|
"/clear" => Command::Clear,
|
|
"/login" if arg1.is_empty() => Command::Login {
|
|
provider: String::new(),
|
|
},
|
|
"/login" if !arg1.is_empty() => Command::Login {
|
|
provider: arg1.to_string(),
|
|
},
|
|
"/edit" if !arg1.is_empty() => Command::Edit(arg1.to_string()),
|
|
"/edit" => Command::Edit(".".to_string()),
|
|
"/mcp" if arg1.is_empty() => Command::McpOpen,
|
|
"/mcp" if arg1 == "add" && !arg2.is_empty() => {
|
|
let rest = arg2.trim();
|
|
if let Some(space) = rest.find(' ') {
|
|
let name = rest[..space].to_string();
|
|
let command = rest[space + 1..].trim().to_string();
|
|
Command::McpAdd { name, command }
|
|
} else {
|
|
Command::McpAdd {
|
|
name: rest.to_string(),
|
|
command: String::new(),
|
|
}
|
|
}
|
|
}
|
|
"/model" => Command::ModelList,
|
|
"/compact" => Command::Compact,
|
|
"/todo" => Command::TodoOpen,
|
|
"/usage" => Command::UsageOpen,
|
|
_ => Command::Unknown(cmd.to_string()),
|
|
}
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
|
|
#[test]
|
|
fn parses_todo_open() {
|
|
assert_eq!(parse_command("/todo"), Command::TodoOpen);
|
|
}
|
|
|
|
#[test]
|
|
fn parses_usage_open() {
|
|
assert_eq!(parse_command("/usage"), Command::UsageOpen);
|
|
}
|
|
}
|