forked from mars/breed
1
0
Fork 0

basic file handling

This commit is contained in:
Emma Tebibyte 2023-04-12 01:22:16 -04:00
parent 9c633b4c72
commit aee17365c6
1 changed files with 52 additions and 13 deletions

View File

@ -19,7 +19,8 @@
use std::{
env::args,
fs::File,
ffi::OsString,
fs::{ File, write },
io::{
Read,
stdout,
@ -27,6 +28,7 @@ use std::{
Write,
},
os::fd::FromRawFd,
path::{ Path }
};
use crossterm::{
@ -194,22 +196,24 @@ enum Direction {
struct State {
pub buffer: Buffer,
pub cursor: Cursor,
pub file: Option<OsString>,
pub mode: Mode,
pub scroll: Cursor,
pub size: (usize, usize),
pub mode: Mode,
pub quit: bool,
}
impl State {
pub fn from_str(text: &str) -> Result<Self> {
pub fn from_str(file_name: Option<OsString>, text: &str) -> Result<Self> {
let (cols, rows) = terminal::size()?;
Ok(Self {
buffer: Buffer::from_str(text),
cursor: Cursor::default(),
file: file_name,
mode: Mode::default(),
scroll: Cursor::default(),
size: (cols as usize, rows as usize),
mode: Mode::default(),
quit: false,
})
}
@ -410,12 +414,40 @@ impl State {
}
}
fn write_buffer(&mut self, file: OsString) -> std::result::Result<(), String> {
let out = self.buffer.text.bytes().collect::<Vec<u8>>();
let handle = file
.clone()
.into_string()
.map_err(|err| {
format!("{:?}", err)
})?;
write(handle, out.as_slice())
.map_err(|err| {
format!("{:?}", err)
})?;
Ok(())
}
fn execute_command(&mut self, command: &str) -> std::result::Result<(), String> {
match command {
"q" => self.quit = true,
command => return Err(format!("unrecognized command {:?}", command)),
}
"w" => {
let handle = self.file.clone().unwrap_or_else(|| {
OsString::from("file")
});
self.write_buffer(handle)?;
},
command => {
return Err(
format!("{:?}: Unrecognized command.", command)
);
},
}
Ok(())
}
@ -449,21 +481,28 @@ fn screen_main(stdout: &mut Stdout, mut state: State) -> Result<()> {
fn main() -> Result<()> {
let argv = args().collect::<Vec<String>>();
let mut buf = Vec::new();
let file_name: Option<OsString>;
match argv.get(1).map(|s| s.as_str()) {
Some("-") | None => {
file_name = None;
let stdin = 0; // get stdin as a file descriptor
if unsafe { libc::isatty(stdin) } == 0 {
unsafe { File::from_raw_fd(stdin) }
} else { File::open("/dev/null").unwrap() }
},
Some(path) => {
std::fs::File::open(path).unwrap_or_else(|_| {
eprintln!(
"{}: {}: No such file or directory.",
argv[0],
argv[1]
);
let input_file = Path::new(path);
file_name = input_file.clone().file_name().map(|f| f.to_owned());
File::open(input_file).unwrap_or_else(|_| {
let mut err = String::new();
if !input_file.exists() {
err = "No such file or directory.".to_string();
} else if input_file.is_dir() {
err = "Is a directory.".to_string();
}
eprintln!("{}: {}: {}", argv[0], path, err);
exit(EX_UNAVAILABLE);
})
},
@ -476,7 +515,7 @@ fn main() -> Result<()> {
exit(EX_DATAERR);
});
let state = State::from_str(&text)?;
let state = State::from_str(file_name, &text)?;
let mut stdout = stdout();
terminal::enable_raw_mode()?;
stdout.execute(terminal::EnterAlternateScreen)?;