REPL API
The REPL (Read-Eval-Print Loop) module provides the interactive terminal interface.
Main Function
run_repl
Starts the interactive REPL session.
pub async fn run_repl(client: MoonrakerClient) -> Result<()>Parameters:
client- ConnectedMoonrakerClientinstance
Returns:
Result<()>- Success when user exits, or error
Features:
- Command history (saved to
~/.moonriver_history) - Tab completion for G-code and macros
- Syntax highlighting
- Arrow key navigation
- Ctrl+R history search
Example:
use moonriver::moonraker::MoonrakerClient;
use moonriver::repl::run_repl;
#[tokio::main]
async fn main() -> anyhow::Result<()> {
let client = MoonrakerClient::connect("ws://localhost:7125/websocket").await?;
run_repl(client).await?;
Ok(())
}Internal Components
MoonriverHelper
Internal struct that implements rustyline traits for enhanced functionality.
struct MoonriverHelper {
macros: HashSet<String>,
gcode_commands: HashSet<String>,
}Implements:
Completer- Tab completionHighlighter- Syntax highlightingHinter- Command hints (future)Validator- Input validation (future)Helper- Combines all traits
Completion
The REPL provides intelligent tab completion:
G-code Commands
Pre-populated with common G-code commands:
- Movement: G0, G1, G2, G3, G28, etc.
- Temperature: M104, M105, M109, M140, M190, etc.
- Configuration: M500, M501, M502, M503, etc.
- And many more...
Klipper Macros
Dynamically loaded from the connected printer:
- Custom user macros
- Built-in Klipper commands
- Configuration-specific commands
Case Insensitive
Completion works regardless of input case:
> g28<Tab> → G28
> m105<Tab> → M105Syntax Highlighting
Commands are highlighted as you type:
- Bright Green: Recognized G-code commands
- Bright Cyan: Klipper macros
- White: Unrecognized commands
Command History
Storage
History is automatically saved to:
~/.moonriver_historyNavigation
↑/Ctrl+P- Previous command↓/Ctrl+N- Next commandCtrl+R- Search history backward
Persistence
- History loaded on startup
- Saved on exit
- Survives across sessions
Input Handling
Special Commands
Exit
> exit
> quitOr press Ctrl+D
Emergency Stop
> M112Immediately sends emergency stop
Multiple Commands
Separate commands with commas:
> G28, M105, GET_POSITIONCommand Processing
- User input captured via rustyline
- Input trimmed and validated
- Commands split by comma
- Each command sent via MoonrakerClient
- Responses processed and displayed
Error Handling
The REPL handles various errors gracefully:
Connection Errors
Err(ReadlineError::Interrupted) => {
// Ctrl+C pressed, continue
}
Err(ReadlineError::Eof) => {
// Ctrl+D pressed, exit
break;
}Command Errors
Errors are displayed in red but don't crash the REPL:
if let Err(e) = client.send_gcode(cmd).await {
eprintln!("{}", format!("Error: {}", e).red());
}Message Processing
The REPL continuously checks for messages:
loop {
// Check for incoming messages
while let Some(msg) = client.try_receive_message() {
format_response(&msg);
}
// Get user input
let line = rl.readline("> ")?;
// Process command...
}Customization
Prompt
The prompt is customizable:
let prompt = format!("{} ", ">".bright_blue().bold());
rl.readline(&prompt)?;Welcome Message
Displayed on startup:
println!("🌙 Moonriver - Klipper Console 🌙");
println!("Type commands or 'exit' to quit.");Integration Example
Complete example showing REPL integration:
use moonriver::moonraker::MoonrakerClient;
use moonriver::repl::run_repl;
use anyhow::Result;
#[tokio::main]
async fn main() -> Result<()> {
// Parse CLI args (not shown)
let host = "192.168.1.100";
let port = 7125;
// Build URL
let url = format!("ws://{}:{}/websocket", host, port);
// Connect
let client = MoonrakerClient::connect(&url).await?;
// Start REPL
run_repl(client).await?;
Ok(())
}Dependencies
The REPL module uses:
- rustyline - Line editing and history
- colored - Terminal colors
- tokio - Async runtime
Future Enhancements
Planned features:
- Command hints as you type
- Custom color schemes
- Configurable keybindings
- Multi-line command support
- Command aliases
Next Steps
- MoonrakerClient API - WebSocket client
- Interactive Mode Guide - User guide
- Tab Completion - Completion details