cl-repl: Terminal pipe support + fun stylistic fixups
This commit is contained in:
parent
9cae7e4eb8
commit
2eade74d3a
@ -1,6 +1,13 @@
|
||||
use cl_repl::cli::run;
|
||||
use cl_repl::{cli::run, tools::is_terminal};
|
||||
use std::error::Error;
|
||||
|
||||
fn main() -> Result<(), Box<dyn Error>> {
|
||||
if is_terminal() {
|
||||
println!(
|
||||
"--- {} v{} 💪🦈 ---",
|
||||
env!("CARGO_BIN_NAME"),
|
||||
env!("CARGO_PKG_VERSION"),
|
||||
);
|
||||
}
|
||||
run(argh::from_env())
|
||||
}
|
||||
|
@ -8,9 +8,9 @@
|
||||
pub mod ansi {
|
||||
// ANSI color escape sequences
|
||||
pub const ANSI_RED: &str = "\x1b[31m";
|
||||
// const ANSI_GREEN: &str = "\x1b[32m"; // the color of type checker mode
|
||||
pub const ANSI_GREEN: &str = "\x1b[32m"; // the color of type checker mode
|
||||
pub const ANSI_CYAN: &str = "\x1b[36m";
|
||||
pub const ANSI_BRIGHT_GREEN: &str = "\x1b[92m";
|
||||
// pub const ANSI_BRIGHT_GREEN: &str = "\x1b[92m";
|
||||
pub const ANSI_BRIGHT_BLUE: &str = "\x1b[94m";
|
||||
pub const ANSI_BRIGHT_MAGENTA: &str = "\x1b[95m";
|
||||
// const ANSI_BRIGHT_CYAN: &str = "\x1b[96m";
|
||||
@ -21,6 +21,7 @@ pub mod ansi {
|
||||
}
|
||||
|
||||
pub mod args {
|
||||
use crate::tools::is_terminal;
|
||||
use argh::FromArgs;
|
||||
use std::{path::PathBuf, str::FromStr};
|
||||
|
||||
@ -39,9 +40,9 @@ pub mod args {
|
||||
#[argh(option, short = 'm', default = "Default::default()")]
|
||||
pub mode: Mode,
|
||||
|
||||
/// whether to start the repl
|
||||
#[argh(switch, short = 'r')]
|
||||
pub no_repl: bool,
|
||||
/// whether to start the repl (`true` or `false`)
|
||||
#[argh(option, short = 'r', default = "is_terminal()")]
|
||||
pub repl: bool,
|
||||
}
|
||||
|
||||
/// The CLI's operating mode
|
||||
@ -187,14 +188,19 @@ pub mod cli {
|
||||
|
||||
/// Run the command line interface
|
||||
pub fn run(args: Args) -> Result<(), Box<dyn Error>> {
|
||||
let Args { file, include, mode, no_repl } = args;
|
||||
let Args { file, include, mode, repl } = args;
|
||||
|
||||
let mut env = Environment::new();
|
||||
for path in include {
|
||||
load_file(&mut env, path)?;
|
||||
}
|
||||
|
||||
if no_repl {
|
||||
if repl {
|
||||
if let Some(file) = file {
|
||||
load_file(&mut env, file)?;
|
||||
}
|
||||
Repl::with_env(mode, env).repl()
|
||||
} else {
|
||||
let code = match &file {
|
||||
Some(file) => std::fs::read_to_string(file)?,
|
||||
None => std::io::read_to_string(std::io::stdin())?,
|
||||
@ -206,11 +212,6 @@ pub mod cli {
|
||||
Mode::Beautify => beautify(code),
|
||||
Mode::Interpret => interpret(code, &mut env),
|
||||
}?;
|
||||
} else {
|
||||
if let Some(file) = file {
|
||||
load_file(&mut env, file)?;
|
||||
}
|
||||
Repl::with_env(mode, env).repl()
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
@ -251,7 +252,10 @@ pub mod cli {
|
||||
ret => println!("{ret}"),
|
||||
}
|
||||
if env.get("main").is_ok() {
|
||||
println!("-> {}", env.call("main", &[])?);
|
||||
match env.call("main", &[])? {
|
||||
ConValue::Empty => {}
|
||||
ret => println!("{ret}"),
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
@ -304,8 +308,8 @@ pub mod repl {
|
||||
println!("{ANSI_CLEAR_LINES}{ANSI_RED}{prompt} {err}{ANSI_RESET}")
|
||||
}
|
||||
pub fn prompt_succs(&self, value: &impl Display) {
|
||||
let Self { prompt_succs: prompt, .. } = self;
|
||||
println!("{ANSI_BRIGHT_GREEN}{prompt}{ANSI_RESET} {value}")
|
||||
let Self { prompt_succs: _prompt, .. } = self;
|
||||
println!("{ANSI_GREEN}{value}{ANSI_RESET}")
|
||||
}
|
||||
/// Resets the cursor to the start of the line, clears the terminal,
|
||||
/// and sets the output color
|
||||
@ -327,6 +331,7 @@ pub mod repl {
|
||||
/// Runs the main REPL loop
|
||||
pub fn repl(&mut self) {
|
||||
use crate::repline::{error::Error, Repline};
|
||||
|
||||
let mut rl = Repline::new(self.mode.ansi_color(), self.prompt_begin, self.prompt_again);
|
||||
fn clear_line() {
|
||||
print!("\x1b[G\x1b[J");
|
||||
@ -437,6 +442,8 @@ pub mod repl {
|
||||
|
||||
pub mod tools {
|
||||
use cl_token::Token;
|
||||
use std::io::IsTerminal;
|
||||
/// Prints a token in the particular way cl-repl does
|
||||
pub fn print_token(t: &Token) {
|
||||
println!(
|
||||
"{:02}:{:02}: {:#19} │{}│",
|
||||
@ -446,6 +453,10 @@ pub mod tools {
|
||||
t.data(),
|
||||
)
|
||||
}
|
||||
/// gets whether stdin AND stdout are a terminal, for pipelining
|
||||
pub fn is_terminal() -> bool {
|
||||
std::io::stdin().is_terminal() && std::io::stdout().is_terminal()
|
||||
}
|
||||
}
|
||||
|
||||
pub mod repline;
|
||||
|
Loading…
Reference in New Issue
Block a user