use std::{io::Write, sync::atomic::Ordering}; use matrix::{value::Value, vm::Interupt}; use rustyline::{Config, EditMode, ColorMode, Editor, CompletionType}; use crate::{State, helper::MatrixHelper}; pub struct Repl<'a> { state: State<'a> } impl<'a> Repl<'a> { pub fn new(state: State<'a>) -> Self { Self { state } } pub fn run(&mut self) { let interupt = self.state.vm.borrow().interupt(); ctrlc::set_handler(move || { interupt.store(Interupt::KeyboardInterupt as usize, Ordering::SeqCst); }).unwrap(); let config = Config::builder() .check_cursor_position(true) .completion_type(CompletionType::List) .edit_mode(EditMode::Emacs) .color_mode(if self.state.color { ColorMode::Enabled } else { ColorMode::Disabled }) .build(); let helper = MatrixHelper::new(self.state.vm.clone()); let mut rl = Editor::with_config(config).unwrap(); rl.set_helper(Some(helper)); loop { let Ok(line) = rl.readline(">> ") else { break; }; if let Err(_) = rl.add_history_entry(&line) { break; }; match self.state.execute(line) { Err(err) => crate::error(err, &self.state), Ok(val) => { if val != Value::Nil { if self.state.color { println!("{val:#}"); } else { println!("{val}"); } } } } let _ = std::io::stdout().flush(); } } }