From ca94a86a24632afc4a4e43b62c6946027586f243 Mon Sep 17 00:00:00 2001 From: Jordan Orelli Date: Sun, 5 Mar 2023 06:53:24 -0600 Subject: [PATCH] a shockingly bad tail implementation the version of tail.exe that exists in coreutils on scoop cannot handle unicode at all, which is really annoying, so I wrote an in-shell tail that handles utf-8 cleanly. It reads one byte at a time and then checks if the whole buffer that it has read is valid utf-8 and then spits it out of it is. There's also no way to stop it lol. It is -terrible- --- src/input.rs | 6 +----- src/key.rs | 9 +++++++-- src/log.rs | 18 +++++++++++++++++- src/main.rs | 40 +++++++++++++++++++++++++++++++++++++++- 4 files changed, 64 insertions(+), 9 deletions(-) diff --git a/src/input.rs b/src/input.rs index 1508130..4e0c625 100644 --- a/src/input.rs +++ b/src/input.rs @@ -167,6 +167,7 @@ impl Reader { &mut self.buf_len, ))?; } + debug!("• {}", self.buf_len); self.buf_idx = 0; } @@ -263,11 +264,6 @@ impl From for Event { let mstate = event.dwControlKeyState; let c = char::from_u32(event.uChar.UnicodeChar as u32).unwrap_or('💀'); - if event.bKeyDown.as_bool() { - debug!("key down {}", event.wVirtualKeyCode); - } else { - debug!("key up {}", event.wVirtualKeyCode); - } Event::Key(key::Event { down: event.bKeyDown.as_bool(), repeats: event.wRepeatCount, diff --git a/src/key.rs b/src/key.rs index a34df14..23ee3ca 100644 --- a/src/key.rs +++ b/src/key.rs @@ -1,4 +1,4 @@ -// type Code = u16; +use std::fmt; #[derive(Debug, PartialEq, Clone, Copy)] pub struct Code { @@ -33,7 +33,12 @@ pub struct Event { pub shift: bool, } -impl 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) + } +} /// CODES contains a lookup table for key codes. Note that this is a sparse array and not all /// values associate to valid key codes. diff --git a/src/log.rs b/src/log.rs index 9292063..5103b78 100644 --- a/src/log.rs +++ b/src/log.rs @@ -46,7 +46,23 @@ where fn log(&self, record: &Record) { if self.enabled(record.metadata()) { if let Ok(out) = self.out.lock().as_deref_mut() { - _ = write!(out, "{} - {}\n", record.level(), record.args()); + match record.level() { + log::Level::Error => { + _ = write!(out, "\x1b[31m{}\x1b[0m\n", record.args()); + }, + log::Level::Warn => { + _ = write!(out, "\x1b[33m{}\x1b[0m\n", record.args()); + }, + log::Level::Info => { + _ = write!(out, "\x1b[37m{}\x1b[0m\n", record.args()); + }, + log::Level::Debug => { + _ = write!(out, "\x1b[90m{}\x1b[0m\n", record.args()); + }, + log::Level::Trace => { + _ = write!(out, "\x1b[36m{}\x1b[0m\n", record.args()); + }, + } } } } diff --git a/src/main.rs b/src/main.rs index d3e0749..9bbda57 100644 --- a/src/main.rs +++ b/src/main.rs @@ -7,6 +7,8 @@ mod prompt; use line::Line; use prompt::Prompt; +use std::fs::File; +use std::io::{Read, Seek, SeekFrom}; use windows::Win32::{ Foundation::{CloseHandle, HANDLE}, System::Console, @@ -190,6 +192,38 @@ fn eval(line: String) -> Result<()> { return Ok(()); } } + "tail" => { + if parts.len() > 1 { + let fname = parts[1]; + let stdout = stdout_handle()?; + match File::options().read(true).open(fname) { + Ok(mut f) => { + _ = f.seek(SeekFrom::End(0)); + let mut one_byte: [u8; 1] = [0 ; 1]; + let mut buf: Vec = vec![]; + loop { + match f.read(&mut one_byte) { + Ok(n) => { + if n == 1 { + buf.push(one_byte[0]); + if let Ok(s) = std::str::from_utf8(&buf) { + unsafe { + Error::check(Console::WriteConsoleA(stdout, s.as_bytes(), None, None))?; + } + buf.clear(); + } + } + }, + Err(_) => {}, + } + } + } + Err(e) => { println!("failed to open file: {}", e); } + } + } else { + println!("need a file name"); + } + } "echo" => { let rest: Vec<&str> = parts[1..].to_vec(); println!("{:?}", rest); @@ -237,8 +271,10 @@ fn main() -> Result<()> { prompt.print()?; loop { + // debug!("----------------------------------------"); match input.next()? { input::Event::Key(event) => { + debug!("{}", event); if event.down { continue; } @@ -280,6 +316,7 @@ fn main() -> Result<()> { } if event.ctrl && event.code == key::D { + debug!("ctrl-d"); unsafe { CloseHandle(stdout); } @@ -287,6 +324,7 @@ fn main() -> Result<()> { } if event.ctrl && event.code == key::J { + debug!("ctrl-j"); unsafe { // red bullet let text = "\x1b[31m\u{2022}\x1b[0m"; @@ -322,7 +360,7 @@ fn main() -> Result<()> { continue; } - debug!("Unhandled Keyboard Event: {:?}", event.code); + warn!("‽ {}", event); } input::Event::Left => { if line.back() {