Compare commits

...

2 Commits

3 changed files with 76 additions and 33 deletions

View File

@ -6,27 +6,16 @@ use std::{
path::{Path, PathBuf},
};
use crate::MapDisplay;
use crate::{rc::History, MapDisplay};
enum ValidStatus {
NoRootFolder,
TryExists(io::Error)
}
trait PathBufIsValid {
fn is_valid(&self) -> Result<PathBuf, ValidStatus>;
fn is_valid_or_home(&self) -> Option<PathBuf>;
}
trait ChangeDirectory {
fn change_directory(&self, args: SplitWhitespace) -> Option<PathBuf>;
fn set_current_dir(&self, new_path: &Path) -> Option<PathBuf>;
fn specific_user_dir(&self, user: String) -> Option<PathBuf>;
fn cd_args(&self, vec_args: Vec<String>) -> Option<PathBuf>;
fn previous_dir(&self) -> Option<PathBuf>;
fn home_dir(&self) -> Option<PathBuf>;
}
impl PathBufIsValid for PathBuf {
fn is_valid(&self) -> Result<PathBuf, ValidStatus> {
match self.try_exists() {
@ -50,6 +39,14 @@ impl PathBufIsValid for PathBuf {
}
}
trait ChangeDirectory {
fn change_directory(&self, args: SplitWhitespace) -> Option<PathBuf>;
fn set_current_dir(&self, new_path: &Path) -> Option<PathBuf>;
fn specific_user_dir(&self, user: String) -> Option<PathBuf>;
fn cd_args(&self, vec_args: Vec<String>) -> Option<PathBuf>;
fn previous_dir(&self) -> Option<PathBuf>;
fn home_dir(&self) -> Option<PathBuf>;
}
impl ChangeDirectory for Command {
fn set_current_dir(&self, new_path: &Path) -> Option<PathBuf> {
std::env::set_current_dir(new_path).map_or_display_none(|()| Some(new_path.to_path_buf()))
@ -117,26 +114,35 @@ impl ChangeDirectory for Command {
}
}
pub struct Command(String);
pub struct Command {
input: String,
history: Option<History>
}
impl Command {
pub fn new(input: String) -> Self {
Self(input)
Self {
history: History::init(),
input
}
}
pub fn spawn(&self, command_process: io::Result<process::Child>) {
command_process.map_or_display_none(|mut child| Some(child.wait()));
pub fn spawn_handle(&mut self, command_process: io::Result<process::Child>) {
if let Ok(mut child) = command_process {
if let Some(history_file) = self.history.as_mut() {
history_file.write(&self.input);
};
child.wait().ok();
} else {
println!("Unknown command: {}", self.input)
}
}
pub fn exec(&self) {
let mut args = self.0.split_whitespace();
pub fn exec(&mut self) {
let mut args = self.input.split_whitespace();
if let Some(command) = args.next() {
match command {
"cd" => {
self.change_directory(args);
},
command => {
self.spawn(process::Command::new(command).args(args).spawn());
}
"cd" => { self.change_directory(args); },
command => { self.spawn_handle(process::Command::new(command).args(args).spawn()); }
}
}
}

View File

@ -1,7 +1,7 @@
use std::{path::PathBuf, fs::{self, File}, io::{self, Write}};
use std::{fs::{self, File, OpenOptions}, io::{self, BufRead, BufReader, Write}, path::PathBuf};
use thiserror::Error;
use crate::MapDisplay;
use crate::{shell_error, MapDisplay};
pub const DEFAULT_CONFIG_CONTENT: &str = r#"--!strict
@ -95,9 +95,47 @@ pub fn config_file() -> Option<PathBuf> {
config_file.is_valid_file_or_create(DEFAULT_CONFIG_CONTENT.as_bytes())
}
// TODO: history.rs
pub fn history_file() -> Option<PathBuf> {
let mut config_file = config_dir()?;
config_file.push(".history");
config_file.is_valid_file_or_create(b"")
pub struct History {
history_file: PathBuf,
checked_empty: bool
}
impl History {
pub fn init() -> Option<Self> {
config_dir().map(|mut config| {
config.push(".history");
config.is_valid_file_or_create(b"");
Self {
history_file: config,
checked_empty: false
}
})
}
pub fn is_empty(&mut self) -> bool {
match self.checked_empty {
true => true,
false => self.read().map_or(false, |history_l| {
self.checked_empty = true;
history_l.is_empty()
})
}
}
pub fn write<S: AsRef<str>>(&mut self, content: S) {
OpenOptions::new().append(true).open(self.history_file.as_path()).map_or_display(|mut file| {
let write_data = match self.is_empty() {
true => content.as_ref().to_owned(),
false => format!("\n{}", content.as_ref()),
};
if let Err(write_err) = file.write_all(write_data.as_bytes()) {
shell_error(write_err);
};
});
}
pub fn read(&self) -> Option<Vec<String>> {
File::open(&self.history_file).map_or_display_none(|file| {
Some(BufReader::new(file).lines().map_while(Result::ok).collect::<Vec<String>>())
})
}
}

View File

@ -2,7 +2,7 @@ use std::{cell::RefCell, fs, io::{self}, rc::Rc};
use core::fmt;
use crate::{
commands, ps::{self, Ps}, rc, shell_error, vm::{self, LuauVm}, MapDisplay
commands, ps::{self, Ps}, rc::{self}, shell_error, vm::{self, LuauVm}, MapDisplay
};
#[derive(Debug, Clone)]
@ -48,7 +48,6 @@ impl LambdaShell {
fs::read_to_string(conf_file).map_or_display(|luau_conf| self.vm_exec(luau_conf));
}
}
self.ps.borrow().display();
loop {
if self.terminate { break } else {