From 1600b7a497e9f7544aaadf8ae6ac7f5b6aaced14 Mon Sep 17 00:00:00 2001 From: Jordan Orelli Date: Sun, 5 Mar 2023 14:02:39 -0600 Subject: [PATCH] unicode logging like a pro --- src/input.rs | 5 ++- src/key.rs | 9 +++- src/main.rs | 115 +++++++++++++++++++++++++++++++-------------------- 3 files changed, 81 insertions(+), 48 deletions(-) diff --git a/src/input.rs b/src/input.rs index 4e0c625..92e7950 100644 --- a/src/input.rs +++ b/src/input.rs @@ -3,6 +3,7 @@ use anyhow::{Context, Result}; use windows::Win32::Foundation::HANDLE; use windows::Win32::System::Console; +#[allow(dead_code)] fn log_input_mode(mode: Console::CONSOLE_MODE) { // Characters read by the ReadFile or ReadConsole function are written to the active screen // buffer as they are typed into the console. This mode can be used only if the @@ -118,8 +119,8 @@ fn setup_stdin() -> Result<()> { Error::check(Console::SetConsoleMode(handle, mode))?; Error::check(Console::GetConsoleMode(handle, &mut mode))?; - debug!("Stdin details:"); - log_input_mode(mode); + // debug!("Stdin details:"); + // log_input_mode(mode); } Ok(()) } diff --git a/src/key.rs b/src/key.rs index 23ee3ca..8390f37 100644 --- a/src/key.rs +++ b/src/key.rs @@ -36,7 +36,14 @@ pub struct Event { impl fmt::Display for Event { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let down = if self.down { '↓' } else { '↑' }; - write!(f, "{} {}", down, self.code.val) + let sym = match self.code.sym { + Some(c) => c, + None => '∅', + }; + let ctrl = if self.ctrl { '⎈' } else { '·' }; + let alt = if self.alt { '⎇' } else { '·' }; + let shift = if self.shift { '⇧'} else { '·' }; + write!(f, "{} {} {} {} {: >2} {}", down, ctrl, alt, shift, self.code.val, sym) } } diff --git a/src/main.rs b/src/main.rs index 6f8fa1a..9328bd8 100644 --- a/src/main.rs +++ b/src/main.rs @@ -18,6 +18,7 @@ use anyhow::{Context, Result}; use crate::{error::Error, log::*}; +#[allow(dead_code)] fn log_output_mode(mode: Console::CONSOLE_MODE) { // Characters written by the WriteFile or WriteConsole function or echoed by the ReadFile or // ReadConsole function are parsed for ASCII control sequences, and the correct action is @@ -122,8 +123,8 @@ fn setup_stdout() -> Result<()> { unsafe { let handle = stdout_handle()?; if Console::GetConsoleMode(handle, &mut mode).as_bool() { - debug!("Stdout details:"); - log_output_mode(mode); + // debug!("Stdout details:"); + // log_output_mode(mode); } else { return Err(Error::last_error().into()); } @@ -143,58 +144,61 @@ fn newline(stdout: HANDLE) -> Result<()> { Ok(()) } -fn eval(line: String) -> Result<()> { - let parts: Vec<&str> = line.split_whitespace().collect(); - if parts.len() == 0 { - return Ok(()); - } - - let cmd = parts[0]; - match cmd { +fn eval(cmd: String, args: Vec<&str>) -> Result { + match cmd.as_str() { "pwd" => { let pb = std::env::current_dir()?; println!("{}", pb.as_path().as_os_str().to_str().unwrap()); - return Ok(()); + return Ok(true); } "cd" => { let cwd = std::env::current_dir()?; - if parts.len() > 1 { - let target = cwd.join(parts[1]); + if args.len() > 0 { + let target = cwd.join(args[0]); std::env::set_current_dir(target)?; - return Ok(()); } + return Ok(true); } "printenv" => { - if parts.len() > 1 { - let name = parts[1]; + if args.len() > 0 { + let name = args[0]; match std::env::var(name) { - Ok(val) => println!("{}", val), - Err(e) => println!("ERROR {}", e), + Ok(val) => { + println!("{}", val); + return Ok(true); + } + Err(e) => { + println!("ERROR {}", e); + return Ok(false); + } } } else { println!("which variable you fucking dork"); + return Ok(false); } - return Ok(()); } "which" => { - if parts.len() > 1 { + if args.len() > 0 { let path = std::env::var("path").unwrap(); let dirs: Vec<&str> = path.split(";").collect(); for d in dirs { let dir = std::path::Path::new(d); - let fname = dir.join(parts[1]).with_extension("exe"); + let fname = dir.join(args[0]).with_extension("exe"); if fname.exists() && fname.is_file() { println!("{}", fname.to_str().unwrap()); - return Ok(()); + return Ok(true); } } - println!("not found: {}", parts[1]); - return Ok(()); + println!("not found: {}", args[0]); + return Ok(false); + } else { + println!("what do you want to look for?"); + return Ok(false); } } "tail" => { - if parts.len() > 1 { - let fname = parts[1]; + if args.len() > 0 { + let fname = args[0]; let stdout = stdout_handle()?; match File::options().read(true).open(fname) { Ok(mut f) => { @@ -218,37 +222,40 @@ fn eval(line: String) -> Result<()> { } } } - Err(e) => { println!("failed to open file: {}", e); } + Err(e) => { + println!("failed to open file: {}", e); + return Err(e.into()); + } } } else { println!("need a file name"); + return Ok(false); } } "echo" => { - let rest: Vec<&str> = parts[1..].to_vec(); - println!("{:?}", rest); + println!("{}", args.join(" ")); + return Ok(true); } _ => { let mut proc = std::process::Command::new(cmd); - if parts.len() > 1 { - let args = parts[1..].to_vec(); + if args.len() > 0 { proc.args(args); } match proc.spawn() { Ok(mut child) => { if let Err(e) = child.wait() { - println!("error: {}", e) + println!("error: {}", e); + return Err(e.into()); } } Err(e) => { - println!("error: {}", e) + println!("error: {}", e); + return Ok(false); } } - return Ok(()); + return Ok(true); } } - // println!("Error: no such command: {}", cmd); - Ok(()) } fn main() -> Result<()> { @@ -270,24 +277,36 @@ fn main() -> Result<()> { let mut input = input::Reader::new()?; prompt.print()?; + info!("» enter"); loop { - // debug!("----------------------------------------"); match input.next()? { input::Event::Key(event) => { if event.down { if event.code.val == 0 { - debug!("{}", event); + debug!(" {}", event); } else { - warn!("{}", event); + warn!(" {}", event); } continue; } - info!("{}", event); + info!(" {}", event); if event.code == key::ENTER { newline(stdout)?; - if let Err(e) = eval(line.pop()) { - println!("error: {}", e); + let s = line.pop(); + let parts: Vec<&str> = s.split_whitespace().collect(); + if parts.len() > 0 { + let cmd = parts[0].to_string(); + let args = if parts.len() > 1 { parts[1..].to_vec() } else { vec![] }; + debug!("◇ {}", cmd.clone()); + match eval(cmd.clone(), args) { + Ok(true) => info!("▷ {}", cmd), + Ok(false) => warn!("▷ {}", cmd), + Err(e) => { + error!("▷ {}: {}", cmd, e); + println!("error: {}", e); + }, + } } prompt.print()?; continue; @@ -321,7 +340,7 @@ fn main() -> Result<()> { } if event.ctrl && event.code == key::D { - debug!("⎈ d: exit"); + info!("» exit"); unsafe { CloseHandle(stdout); } @@ -381,6 +400,7 @@ fn main() -> Result<()> { warn!("‽ {}", event); } input::Event::Left => { + debug!("⛬ ←"); if line.back() { unsafe { let text = "\x1b[D"; // lol this sucks @@ -389,6 +409,7 @@ fn main() -> Result<()> { } }, input::Event::Right => { + debug!("⛬ →"); if line.forward() { unsafe { let text = "\x1b[C"; // lol this sucks @@ -396,8 +417,12 @@ fn main() -> Result<()> { } } } - input::Event::Up => {}, - input::Event::Down => {}, + input::Event::Up => { + debug!("⛬ ↑"); + }, + input::Event::Down => { + debug!("⛬ ↓"); + }, input::Event::Home => {}, input::Event::End => {}, input::Event::Focus(true) => {},