# ๐ฆ rusty_repl
<p align="center">
<img src="https://gitlab.com/amad3v/rusty-repl/-/raw/main/assets/logo.svg" alt="Rusty REPL" width="240">
</p>
A lightweight, modular framework for building **interactive REPLs** in Rust โ with clean prompts, terminal isolation, and customisable input handling.
---
## โจ Features
- ๐ฅ๏ธ **Alternate screen mode** โ clean, isolated terminal workspace
- ๐ฌ **Custom prompts** โ easily define your own `Prompt` style via `CleanPrompt`
- โก **Input handling loop** โ powered by [`reedline`](https://crates.io/crates/reedline)
- ๐งน **Automatic cleanup** โ restores cursor, title, and screen on exit
- ๐จ **Keyword highlighting** โ built-in highlighter with custom color schemes (`KeywordStyle`)
- ๐งฉ **Extensible design** โ drop in new highlighters, prompts, or REPL logic
- ๐ ๏ธ **Config builder** โ safely construct REPL configuration with `ReplConfig::new().with_title(...).with_prompt(...).with_kw_style(...)`
---
## ๐ Quick Start
Add to your `Cargo.toml`:
```toml
[dependencies]
rusty_repl = "0.3.0"
```
Then in your project:
```rust,ignore
use rusty_repl::Repl;
fn input_handler(cmd: String) -> bool {
match cmd.as_str() {
"e" | "q" | "quit" | "exit" => {
return true;
}
val => println!("{val}"),
};
false
}
fn main() {
// Use default configuration
let repl_manager = Repl::new();
// Run REPL loop
let _ = repl_manager.run(run);
}
```
Or
```rust,ignore
use rusty_repl::{CleanPrompt, Color, DefaultPromptSegment, KeywordStyle, Repl, ReplConfig};
fn input_handler(cmd: String) -> bool {
match cmd.as_str() {
"e" | "q" | "quit" | "exit" => {
return true;
}
val => println!("{val}"),
};
false
}
fn main() {
// Configure keywords
let ks = KeywordStyle::new(
vec!["ls", "pwd", "cd", "e", "q", "quit", "exit"],
Color::Red,
);
// Configure prompt
let default_prompt = CleanPrompt::from(
DefaultPromptSegment::Basic("โฏโฏโฏ ".to_string()),
DefaultPromptSegment::Empty,
);
// Build REPL configuration
let cfg = ReplConfig::new("REPL")
.with_kw_style(ks)
.with_prompt(default_prompt);
let repl_manager = Repl::from(cfg);
// Run REPL loop
let _ = repl_manager.run(run);
}
```
This opens an alternate terminal screen with a minimal prompt.
Type `exit` to leave the session.
## ๐งฉ Architecture
| `repl::input` | Handles user input with `reedline` |
| `repl::terminal` | Manages terminal (alternate screen, cursor, cleanup) |
| `repl::prompt` | Defines a cleaner, customisable prompt |
| `repl::highlighter` | Highlights configured keywords during input |
| `repl::style` | Configures keyword styles (colors, word list) |
| `repl::repl` | Connects all components into a cohesive REPL session |
## ๐ง Future Enhancements
- ๐พ Persistent command history
- ๐ง Syntax-aware input completion
- ๐ Theming and multi-color highlighting
## ๐ License
Licensed under the [MIT License](https://gitlab.com/amad3v/rusty-repl/-/raw/main/LICENSE)
## ๐ Changelog
### 0.3.0
- Introduced `ReplConfig` builder with `.with_title()`, `.with_prompt()`, `.with_kw_style()`
- REPL prompt now uses `Arc<dyn Prompt>` to avoid ownership/move issues
- InputHandler stores the prompt internally; run no longer requires external prompt
- Updated all modules to consume `Arc<ReplConfig>` instead of cloning individual fields
- Documentation updated for builder pattern, prompt handling, and `Arc` usage
- Example code updated to reflect new API
### 0.2.0
- Added keyword highlighting support
- Introduced `KeywordHighlighter` for basic keyword-based styling.
- Exposed `KeywordStyle` as part of the public API.
- Updated `Repl::new` to accept an optional `KeywordStyle` argument.