diff --git a/Cargo.toml b/Cargo.toml index f22b793..b3a28c0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,4 +4,4 @@ version = "0.1.0" edition = "2024" [dependencies] -libc = "0.2.181" +libc = { version = "0.2.181", features = ["extra_traits"] } diff --git a/src/main.rs b/src/main.rs index 37cbc51..d4f639a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,18 +1,25 @@ pub mod reader; +use std::sync::{Arc, Mutex}; + use reader::ReaderState; fn main() { - let mut state = ReaderState::new("uwu> "); - assert!(ReaderState::init_tty().is_ok()); + let state = Arc::new(Mutex::new(ReaderState::new("uwu> "))); + let state_r = state.clone(); + assert!(state.lock().unwrap().init_tty().is_ok()); + std::panic::set_hook(Box::new(move |_| { + let _ = state_r.lock().unwrap().restore_tty(); + })); loop { - let line = state.read_line(); + let line = state.lock().unwrap().read_line(); match line { Ok(s) => println!("{}", s), Err(e) => { - eprintln!("Error: {:?}", e); + eprintln!("\nError: {:?}", e); break; } } } + let _ = state.lock().unwrap().restore_tty(); } diff --git a/src/reader/mod.rs b/src/reader/mod.rs index 0b9af78..95a3077 100644 --- a/src/reader/mod.rs +++ b/src/reader/mod.rs @@ -8,6 +8,7 @@ pub mod esc_parse; #[derive(Default)] pub struct ReaderState { + saved_termios: Option, prompt: String, line: String, cursor: usize, @@ -63,7 +64,7 @@ impl ReaderState { pub fn empty(&mut self) { self.set_line(String::from("")); } - pub fn init_tty() -> Result<(), InitTTYError> { + pub fn init_tty(&mut self) -> Result<(), InitTTYError> { unsafe { use libc::{isatty, termios, ECHO, ICANON, INPCK, TCSANOW, tcgetattr, tcsetattr}; if !(isatty(0) == 1) { @@ -71,12 +72,26 @@ impl ReaderState { } let mut termios: termios = MaybeUninit::zeroed().assume_init(); tcgetattr(0, &mut termios); + self.saved_termios = Some(termios.clone()); termios.c_lflag &= !(ECHO | ICANON); termios.c_iflag &= !(INPCK); tcsetattr(0, TCSANOW, &termios); return Ok(()); } } + + pub fn restore_tty(&self) -> Result<(), ()> { + unsafe { + use libc::{tcsetattr, TCSANOW}; + if self.saved_termios.is_none() { + Err(()) + } else { + tcsetattr(0, TCSANOW, &self.saved_termios.unwrap()); + Ok(()) + } + } + } + pub fn insert_at_cursor(&mut self, txt: String) { self.line.insert_str(self.cursor, txt.as_str()); self.cursor += txt.len(); @@ -187,6 +202,7 @@ impl ReaderState { NewLine => { let line = self.line.clone(); self.submit_line(line.clone()); + println!("{}", line); return Ok(line) }, CursorBack => {