limbo/cli/main.rs
2025-04-20 17:03:43 -03:00

78 lines
2.2 KiB
Rust

#![allow(clippy::arc_with_non_send_sync)]
mod app;
mod commands;
mod helper;
mod input;
mod opcodes_dictionary;
use nix::unistd::isatty;
use rustyline::{error::ReadlineError, Config, Editor};
use std::{
path::PathBuf,
sync::{atomic::Ordering, LazyLock},
};
fn rustyline_config() -> Config {
Config::builder()
.completion_type(rustyline::CompletionType::List)
.auto_add_history(true)
.build()
}
pub static HOME_DIR: LazyLock<PathBuf> =
LazyLock::new(|| dirs::home_dir().expect("Could not determine home directory"));
pub static HISTORY_FILE: LazyLock<PathBuf> = LazyLock::new(|| HOME_DIR.join(".limbo_history"));
fn main() -> anyhow::Result<()> {
let mut app = app::Limbo::new()?;
let _guard = app.init_tracing()?;
if is_a_tty() {
let mut rl = Editor::with_config(rustyline_config())?;
if HISTORY_FILE.exists() {
rl.load_history(HISTORY_FILE.as_path())?;
}
app = app.with_readline(rl);
} else {
tracing::debug!("not in tty");
}
loop {
let readline = app.readline();
match readline {
Ok(line) => match app.handle_input_line(line.trim()) {
Ok(_) => {}
Err(e) => {
eprintln!("{}", e);
}
},
Err(ReadlineError::Interrupted) => {
// At prompt, increment interrupt count
if app.interrupt_count.fetch_add(1, Ordering::SeqCst) >= 1 {
eprintln!("Interrupted. Exiting...");
let _ = app.close_conn();
break;
}
println!("Use .quit to exit or press Ctrl-C again to force quit.");
app.reset_input();
continue;
}
Err(ReadlineError::Eof) => {
app.handle_remaining_input();
let _ = app.close_conn();
break;
}
Err(err) => {
let _ = app.close_conn();
anyhow::bail!(err)
}
}
}
Ok(())
}
/// Return whether or not STDIN is a TTY
fn is_a_tty() -> bool {
isatty(libc::STDIN_FILENO).unwrap_or(false)
}