Using "Editor" for my mental health

Signed-off-by: teo3300 <matteo.rogora@live.it>
This commit is contained in:
teo3300
2023-12-22 09:54:16 +09:00
parent 28af3f8785
commit 7a5ebe5fa1
4 changed files with 336 additions and 30 deletions

View File

@ -4,7 +4,8 @@ use crate::step5_tco::rep;
use crate::types::{MalErr, MalRet, MalType::Nil};
use regex::Regex;
use std::fs::File;
use std::io::{self, BufRead, BufReader};
use std::io::{BufRead, BufReader};
use std::process::exit;
pub fn load_file(filename: &str, env: &Env) -> MalRet {
let file_desc = File::open(filename);
@ -63,38 +64,68 @@ pub fn load_file(filename: &str, env: &Env) -> MalRet {
}
}
use std::io::Write;
use std::process::exit;
extern crate rustyline;
use rustyline::error::ReadlineError;
use rustyline::DefaultEditor;
pub fn interactive(env: Env) {
const HISTORY_PATH: &str = ".mal-history";
// Using "Editor" instead of the standard I/O because I hate myself but not this much
// TODO: remove unwrap and switch to a better error handling
let mut rl = DefaultEditor::new().unwrap();
if rl.load_history(HISTORY_PATH).is_err() {
eprintln!("Failed to load history");
}
let mut num = 0;
let parser = Reader::new();
loop {
parser.clear();
loop {
print!("user> ");
// Flush the prompt to appear before command
let _ = io::stdout().flush();
// // Old reader
// print!("user> ");
// // Flush the prompt to appear before command
// let _ = io::stdout().flush();
// Read line to compose program input
let mut line = String::new();
io::stdin().read_line(&mut line).unwrap();
// // Read line to compose program input
// let mut line = String::new();
// io::stdin().read_line(&mut line).unwrap();
let line = rl.readline("user> ");
parser.push(&line);
match line {
Ok(line) => {
// TODO: should handle this in a different way
rl.add_history_entry(&line).unwrap();
rl.save_history(HISTORY_PATH).unwrap();
// Perform rep on whole available input
match rep(&parser, &env) {
Ok(output) => output.iter().for_each(|el| println!("[{}]> {}", num, el)),
Err(error) => {
if error.is_recoverable() {
// && line != "\n" {
continue;
parser.push(&line);
// Perform rep on whole available input
match rep(&parser, &env) {
Ok(output) => output.iter().for_each(|el| println!("[{}]> {}", num, el)),
Err(error) => {
if error.is_recoverable() {
// && line != "\n" {
continue;
}
println!("; [{}]> Error @ {}", num, error.message());
}
}
println!("; [{}]> Error @ {}", num, error.message());
num += 1;
break;
}
Err(ReadlineError::Interrupted) => {
parser.clear();
eprintln!("; ... Interrupted");
continue;
}
Err(ReadlineError::Eof) => exit(0),
Err(err) => {
eprint!("Error reading lnie: {:?}", err);
break;
}
}
num += 1;
break;
}
}
}