1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
//! High-level REPL controller for managing terminal state, prompts, and input flow.
//!
//! [`Repl`] orchestrates an interactive command-line session by tying together
//! terminal management, input handling, and prompt configuration into a single,
//! easy-to-use interface.
//!
//! # Key Features
//! - Safe terminal lifecycle management with alternate screen, hidden cursor, and cleanup.
//! - Clean separation between user logic and terminal/REPL infrastructure.
//! - Extensibility via custom prompts (`Prompt`) and keyword highlighting (`KeywordStyle`).
//!
//! # Example
//! ```no_run
//! use rusty_repl::{Repl, ReplConfig, CleanPrompt, KeywordStyle};
//! use nu_ansi_term::Color;
//!
//! fn main() -> std::io::Result<()> {
//! // Configure keyword highlighting
//! let kw_style = KeywordStyle {
//! keywords: vec!["help".into(), "exit".into()],
//! foreground: Color::Green,
//! };
//!
//! // Create default prompt
//! let default_prompt = CleanPrompt::default();
//!
//! // Build configuration using builder-style methods
//! let config = ReplConfig::default()
//! .with_title("Demo REPL")
//! .with_kw_style(kw_style)
//! .with_prompt(default_prompt);
//!
//! let repl = Repl::from(config);
//!
//! // Start the REPL loop
//! repl.run(|line| {
//! if line.trim() == "exit" {
//! return true;
//! }
//! println!("You typed: {line}");
//! false
//! })
//! }
//! ```
//!
//! # Lifecycle
//! 1. [`Repl::run`] creates a [`TerminalManager`] instance, entering the alternate screen.
//! 2. An [`InputHandler`] is initialized with the configured prompt and optional keyword highlighting.
//! 3. The input loop reads each line and passes it to your closure.
//! 4. Returning `true` from the closure exits the REPL and restores the terminal.
//!
//! # Notes
//! - Avoid calling `std::process::exit` inside your closure; it bypasses cleanup.
//! - Terminal setup/teardown errors are propagated as `std::io::Result`.
//! - Custom prompts are wrapped in `Arc` automatically, so ownership and borrowing are handled safely.
use crate;
use ;
/// Top-level REPL manager that orchestrates terminal setup and user input.