diff --git a/Cargo.toml b/Cargo.toml index 5c36965..7969df8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,6 +15,7 @@ path = "src/main.rs" [dependencies] evalexpr = "11.0.0" pico-args = "0.5.0" +rustyline = "14.0.0" termion = "1.5.6" [profile.release] diff --git a/src/main.rs b/src/main.rs index 241157f..289bd08 100644 --- a/src/main.rs +++ b/src/main.rs @@ -5,6 +5,7 @@ use std::{ stdout, IsTerminal, + Read, Write }, process::exit @@ -18,6 +19,7 @@ use evalexpr::{ Value }; use pico_args::Arguments; +use rustyline::DefaultEditor; use termion::{ color, style @@ -43,7 +45,8 @@ fn main() { } let mut context = context::build(&mut args); - let quiet = args.contains(flag::QUIET) || !stdout().is_terminal(); + let is_terminal = stdin().is_terminal() && stdout().is_terminal(); + let quiet = args.contains(flag::QUIET) || !is_terminal; // collect args and evaluate if present let expressions = args.finish(); @@ -53,24 +56,27 @@ fn main() { eval(&expression, &mut context, quiet); } } else { - // enter interactive mode if no args are given - version_text(); - println!("{}Interactive Mode{}", style::Faint, style::Reset); - loop { - print!("> "); - stdout().flush().unwrap(); - let mut i_line = String::new(); - let line_result = stdin().read_line(&mut i_line); - if line_result.is_err() { - break; + if !is_terminal { + let mut buffer = String::with_capacity(0); + if let Ok(_) = stdin().read_to_string(&mut buffer) { + for expression in buffer.lines() { + eval(&expression.to_string(), &mut context, quiet); + } } - let line = i_line.trim().to_string(); - match line.as_str() { - "" | - "exit" => break, - _ => eval(&line, &mut context, quiet) + } else if let Ok(mut rl) = DefaultEditor::new() { + // enter interactive mode if no args are given + version_text(); + println!("{}Interactive Mode{}", style::Faint, style::Reset); + loop { + if let Ok(line) = rl.readline("> ") { + match line.as_str() { + "" | + "exit" => break, + _ => eval(&line, &mut context, quiet) + } + } + reset(); } - reset(); } } }