reorganizing extension commands

parse-tree
Jordan Orelli 2 years ago
parent 3f6eaa8e61
commit 0a0dfc2ee9

@ -0,0 +1,5 @@
mod tail;
mod command;
pub use tail::Tail;
pub use command::Command;

@ -0,0 +1,7 @@
pub trait Command {
fn name() -> String;
fn create() -> Self;
fn exec(&mut self, args: Vec<&str>) -> anyhow::Result<bool>;
}

@ -0,0 +1,58 @@
use crate::{
ext::Command,
output,
};
use std::{
fs::File,
io::{Seek, SeekFrom, Read, Write},
};
use anyhow::Result;
pub struct Tail { }
impl Command for Tail {
fn name() -> String {
String::from("tail")
}
fn create() -> Self {
Self{ }
}
fn exec(&mut self, args: Vec<&str>) -> Result<bool> {
let mut stdout = output::Writer::stdout()?;
if args.len() > 0 {
let fname = args[0];
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<u8> = 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) {
stdout.write(s.as_bytes())?;
buf.clear();
}
}
}
Err(_) => {}
}
}
}
Err(e) => {
println!("failed to open file: {}", e);
return Err(e.into());
}
}
} else {
println!("need a file name");
return Ok(false);
}
}
}

@ -1,20 +1,21 @@
mod error; mod error;
mod ext;
mod input; mod input;
mod key; mod key;
mod line; mod line;
mod log; mod log;
mod output; mod output;
mod shell;
mod prompt; mod prompt;
mod shell;
use crate::log::*;
use prompt::Prompt; use prompt::Prompt;
use shell::Shell;
use std::io::Write; use std::io::Write;
use anyhow::Result; use anyhow::Result;
use crate::log::*;
use shell::Shell;
fn main() -> Result<()> { fn main() -> Result<()> {
let mut shell = Shell::new()?; let mut shell = Shell::new()?;
let log_path = shell.expand_path("~/wash.log"); let log_path = shell.expand_path("~/wash.log");
@ -99,7 +100,7 @@ fn main() -> Result<()> {
// the tail // the tail
if n > 1 { if n > 1 {
// let text = format!("\x1b[{}D", n - 1); // let text = format!("\x1b[{}D", n - 1);
shell.output.back(n-1)?; shell.output.back(n - 1)?;
// output.write(text.as_bytes())?; // output.write(text.as_bytes())?;
} else { } else {
// honestly I can't remember how I figured this out // honestly I can't remember how I figured this out
@ -120,7 +121,9 @@ fn main() -> Result<()> {
if event.ctrl && event.code == key::J { if event.ctrl && event.code == key::J {
debug!("⎈ j: dot"); debug!("⎈ j: dot");
// red bullet // red bullet
shell.output.write(String::from("\x1b[31m\u{2022}\x1b[0m").as_bytes())?; shell
.output
.write(String::from("\x1b[31m\u{2022}\x1b[0m").as_bytes())?;
continue; continue;
} }
@ -177,7 +180,7 @@ fn main() -> Result<()> {
if n > 1 { if n > 1 {
// if we wrote more than one character, because we weren't at the end, we // if we wrote more than one character, because we weren't at the end, we
// need to rewind the terminal cursor to where it was. // need to rewind the terminal cursor to where it was.
shell.output.back(n-1)?; shell.output.back(n - 1)?;
} }
continue; continue;
} }

@ -94,27 +94,29 @@ fn log_output_mode(mode: Console::CONSOLE_MODE) {
} }
} }
fn stdout_handle() -> Result<HANDLE> {
unsafe {
let handle = Console::GetStdHandle(Console::STD_OUTPUT_HANDLE)
.context("unable to get stdin handle")?;
Ok(handle)
}
}
pub struct Writer { pub struct Writer {
output: HANDLE, output: HANDLE,
} }
impl Writer { impl Writer {
pub fn new() -> Result<Self> { pub fn stdout() -> Result<Self> {
let mut v = Self { unsafe {
output: stdout_handle()?, let handle = Console::GetStdHandle(Console::STD_OUTPUT_HANDLE)
}; .context("unable to get stdin handle")?;
v.reset()?; let mut stdout = Self{output: handle};
Ok(v) stdout.reset()?;
Ok(stdout)
}
} }
// pub fn new() -> Result<Self> {
// let mut v = Self {
// output: stdout_handle()?,
// };
// v.reset()?;
// Ok(v)
// }
pub fn close(&mut self) -> Result<()> { pub fn close(&mut self) -> Result<()> {
unsafe { unsafe {
CloseHandle(self.output); CloseHandle(self.output);

@ -1,4 +1,4 @@
use crate::{input, line::Line, log::*, output}; use crate::{input, line::Line, log::*, output, ext::{Command, Tail}};
use std::{ use std::{
fs::File, fs::File,
@ -19,7 +19,7 @@ impl Shell {
pub fn new() -> Result<Self> { pub fn new() -> Result<Self> {
Ok(Self { Ok(Self {
input: input::Reader::new()?, input: input::Reader::new()?,
output: output::Writer::new()?, output: output::Writer::stdout()?,
line: Line::new(), line: Line::new(),
}) })
} }
@ -145,39 +145,7 @@ impl Shell {
return Ok(false); return Ok(false);
} }
} }
"tail" => { "tail" => Tail::create().exec(args),
if args.len() > 0 {
let fname = args[0];
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<u8> = 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) {
self.output.write(s.as_bytes())?;
buf.clear();
}
}
}
Err(_) => {}
}
}
}
Err(e) => {
println!("failed to open file: {}", e);
return Err(e.into());
}
}
} else {
println!("need a file name");
return Ok(false);
}
}
"echo" => { "echo" => {
println!("{}", args.join(" ")); println!("{}", args.join(" "));
return Ok(true); return Ok(true);

Loading…
Cancel
Save