Add descriptions to commands and improve REPL display formatting
This commit is contained in:
parent
cbc7b3a2e2
commit
aa75aa4157
7 changed files with 323 additions and 292 deletions
146
engine/src/core/repl/repl.rs
Normal file
146
engine/src/core/repl/repl.rs
Normal file
|
@ -0,0 +1,146 @@
|
|||
use super::{commands, Callable, COMMAND_LIST};
|
||||
use chrono::Local;
|
||||
use reedline::{Prompt, Reedline, Signal};
|
||||
use regex::Regex;
|
||||
use std::{borrow::Borrow, collections::HashMap, sync::Arc};
|
||||
|
||||
fn register_commands() {
|
||||
COMMAND_LIST.add_command(
|
||||
"hello",
|
||||
Some("Displays \"Hello World\"!"),
|
||||
Callable::Simple(commands::say_hello),
|
||||
None,
|
||||
);
|
||||
|
||||
COMMAND_LIST.add_command(
|
||||
"exit",
|
||||
Some("Exits the application gracefully."),
|
||||
Callable::Simple(commands::exit),
|
||||
None,
|
||||
);
|
||||
|
||||
COMMAND_LIST.add_command(
|
||||
"clear",
|
||||
Some("Clears the terminal screen."),
|
||||
Callable::Simple(commands::clear),
|
||||
None,
|
||||
);
|
||||
|
||||
COMMAND_LIST.add_command(
|
||||
"echo",
|
||||
Some("Prints the provided arguments back to the terminal."),
|
||||
Callable::WithArgs(commands::echo),
|
||||
Some(1), // Requires at least one argument
|
||||
);
|
||||
|
||||
COMMAND_LIST.add_command(
|
||||
"help",
|
||||
Some("Displays a list of all available commands."),
|
||||
Callable::Simple(commands::help),
|
||||
None,
|
||||
);
|
||||
|
||||
// EXAMPLE
|
||||
// Adding aliases for commands
|
||||
COMMAND_LIST.add_alias("cls".to_string(), "clear".to_string()); // Likely unintended; consider removing or renaming.
|
||||
}
|
||||
|
||||
struct ZPrompt {
|
||||
left_text: String,
|
||||
right_text: String,
|
||||
}
|
||||
|
||||
impl Prompt for ZPrompt {
|
||||
fn render_prompt_left(&self) -> std::borrow::Cow<str> {
|
||||
std::borrow::Cow::Borrowed(&self.left_text)
|
||||
}
|
||||
|
||||
fn render_prompt_right(&self) -> std::borrow::Cow<str> {
|
||||
std::borrow::Cow::Borrowed(&self.right_text)
|
||||
}
|
||||
|
||||
fn render_prompt_history_search_indicator(
|
||||
&self,
|
||||
_history_search: reedline::PromptHistorySearch,
|
||||
) -> std::borrow::Cow<str> {
|
||||
std::borrow::Cow::Borrowed("")
|
||||
}
|
||||
|
||||
fn render_prompt_indicator(
|
||||
&self,
|
||||
prompt_mode: reedline::PromptEditMode,
|
||||
) -> std::borrow::Cow<str> {
|
||||
match prompt_mode {
|
||||
reedline::PromptEditMode::Default => std::borrow::Cow::Borrowed(">>"),
|
||||
reedline::PromptEditMode::Emacs => {
|
||||
let timestamp = Local::now().format("[%H:%M:%S.%3f/SHELL] >>\t").to_string();
|
||||
std::borrow::Cow::Owned(timestamp)
|
||||
}
|
||||
reedline::PromptEditMode::Vi(_) => std::borrow::Cow::Borrowed("vi>>"),
|
||||
reedline::PromptEditMode::Custom(_) => std::borrow::Cow::Borrowed("custom>>"),
|
||||
}
|
||||
}
|
||||
|
||||
fn render_prompt_multiline_indicator(&self) -> std::borrow::Cow<str> {
|
||||
std::borrow::Cow::Borrowed("><")
|
||||
}
|
||||
}
|
||||
|
||||
fn evaluate_command(input: &str) {
|
||||
if input.trim().is_empty() {
|
||||
return;
|
||||
}
|
||||
|
||||
let pattern = Regex::new(r"[;|\n]").unwrap();
|
||||
let commands: Vec<&str> = pattern.split(input).collect();
|
||||
|
||||
for command in commands {
|
||||
let command = command.trim();
|
||||
if command.is_empty() {
|
||||
println!("Empty command, skipping.");
|
||||
continue;
|
||||
}
|
||||
|
||||
let tokens: Vec<&str> = command.split_whitespace().collect();
|
||||
if tokens.is_empty() {
|
||||
return;
|
||||
}
|
||||
|
||||
let cmd_name = tokens[0];
|
||||
let args: Vec<String> = tokens[1..].iter().map(|&s| s.to_string()).collect();
|
||||
|
||||
COMMAND_LIST.execute_command(
|
||||
cmd_name.to_string(),
|
||||
if args.is_empty() { None } else { Some(args) },
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn handle_repl() {
|
||||
let mut line_editor = Reedline::create();
|
||||
register_commands();
|
||||
|
||||
loop {
|
||||
let sig = line_editor.read_line(&ZPrompt {
|
||||
left_text: String::new(),
|
||||
right_text: "<<".to_string(),
|
||||
});
|
||||
|
||||
match sig {
|
||||
Ok(Signal::Success(buffer)) => {
|
||||
if buffer == "exit" {
|
||||
std::process::exit(0);
|
||||
} else {
|
||||
evaluate_command(&buffer);
|
||||
}
|
||||
}
|
||||
Ok(Signal::CtrlC) => {
|
||||
println!("\nCONTROL+C RECEIVED, TERMINATING");
|
||||
std::process::exit(0);
|
||||
}
|
||||
err => {
|
||||
eprintln!("Error: {:?}", err);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue