history tweaks and begin working on up and down arrows
This commit is contained in:
parent
c91b486214
commit
cde80eccad
@ -96,10 +96,10 @@ impl Command for Pse {
|
|||||||
if let Some(command) = args.next() {
|
if let Some(command) = args.next() {
|
||||||
match command {
|
match command {
|
||||||
"cd" => if ChangeDirectory(None).change_directory(args).is_some() {
|
"cd" => if ChangeDirectory(None).change_directory(args).is_some() {
|
||||||
self.history.add(self.rt.input.literal.as_str())
|
self.rt.history.add(self.rt.input.literal.as_str())
|
||||||
},
|
},
|
||||||
command => if let Ok(mut child) = process::Command::new(command).args(args).spawn() {
|
command => if let Ok(mut child) = process::Command::new(command).args(args).spawn() {
|
||||||
self.history.add(self.rt.input.literal.as_str());
|
self.rt.history.add(self.rt.input.literal.as_str());
|
||||||
child.wait().ok();
|
child.wait().ok();
|
||||||
} else {
|
} else {
|
||||||
println!("pse: Unknown command: {}", self.rt.input.literal)
|
println!("pse: Unknown command: {}", self.rt.input.literal)
|
||||||
|
@ -4,38 +4,36 @@ use crate::{rc::{self}, session::{self, MapDisplay}, valid_pbuf::IsValid};
|
|||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct History {
|
pub struct History {
|
||||||
fs_history: Option<Vec<String>>,
|
pub history: Vec<String>,
|
||||||
history: Vec<String>,
|
pub index: isize,
|
||||||
file: Option<PathBuf>,
|
file: Option<PathBuf>,
|
||||||
}
|
}
|
||||||
impl History {
|
impl History {
|
||||||
pub fn init() -> Self {
|
pub fn init() -> Self {
|
||||||
|
let mut history = Vec::new();
|
||||||
let file = rc::config_dir().map(|mut config_dir| {
|
let file = rc::config_dir().map(|mut config_dir| {
|
||||||
config_dir.push(".history");
|
config_dir.push(".history");
|
||||||
config_dir.is_valid_file_or_create(b"");
|
config_dir.is_valid_file_or_create(b"");
|
||||||
config_dir
|
config_dir
|
||||||
});
|
});
|
||||||
let fs_history = file.as_ref().and_then(|file| {
|
file.as_ref().and_then(|file| {
|
||||||
File::open(file).map_or_display_none(|file| {
|
File::open(file).map_or_display_none(|file| {
|
||||||
Some(BufReader::new(file).lines().map_while(Result::ok).collect::<Vec<String>>())
|
Some(BufReader::new(file).lines().map_while(Result::ok).collect::<Vec<String>>())
|
||||||
})
|
})
|
||||||
});
|
}).inspect(|fs_history_vec| history = fs_history_vec.clone());
|
||||||
Self {
|
|
||||||
history: Vec::new(),
|
Self { history, file, index: -1 }
|
||||||
fs_history,
|
|
||||||
file,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn write_to_file_fallible(&mut self) {
|
pub fn write_to_file_fallible(&mut self) {
|
||||||
if self.history.is_empty() { return; }
|
if self.history.is_empty() { return; }
|
||||||
|
|
||||||
if let (Some(history_file), Some(fs_history)) = (&self.file, &self.fs_history) {
|
if let Some(history_file) = &self.file {
|
||||||
OpenOptions::new()
|
OpenOptions::new()
|
||||||
.append(true)
|
.append(true)
|
||||||
.open(history_file.as_path())
|
.open(history_file.as_path())
|
||||||
.map_or_display(|mut file| {
|
.map_or_display(|mut file| {
|
||||||
let newline_maybe = if fs_history.is_empty() { "" } else { "\n" };
|
let newline_maybe = if self.history.is_empty() { "" } else { "\n" };
|
||||||
let formatted = format!("{newline_maybe}{}", self.history.join("\n"));
|
let formatted = format!("{newline_maybe}{}", self.history.join("\n"));
|
||||||
file.write_all(formatted.as_bytes()).unwrap_or_else(session::shell_error)
|
file.write_all(formatted.as_bytes()).unwrap_or_else(session::shell_error)
|
||||||
});
|
});
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use mlua::Lua as Luau;
|
use mlua::Lua as Luau;
|
||||||
use std::{cell::RefCell, fs, rc::Rc, usize};
|
use std::{cell::RefCell, fs, rc::Rc};
|
||||||
use core::fmt;
|
use core::fmt;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
@ -50,10 +50,10 @@ pub struct Rt {
|
|||||||
pub input: Input,
|
pub input: Input,
|
||||||
pub ps: Rc<RefCell<String>>,
|
pub ps: Rc<RefCell<String>>,
|
||||||
pub vm: Luau,
|
pub vm: Luau,
|
||||||
|
pub history: History,
|
||||||
}
|
}
|
||||||
pub struct Pse {
|
pub struct Pse {
|
||||||
pub config: Config,
|
pub config: Config,
|
||||||
pub history: History,
|
|
||||||
pub rt: Rt
|
pub rt: Rt
|
||||||
}
|
}
|
||||||
impl Pse {
|
impl Pse {
|
||||||
@ -63,13 +63,14 @@ impl Pse {
|
|||||||
let rt = Rt {
|
let rt = Rt {
|
||||||
ps: Rc::new(RefCell::new(Self::DEFAULT_PS.to_owned())),
|
ps: Rc::new(RefCell::new(Self::DEFAULT_PS.to_owned())),
|
||||||
vm: Luau::new(),
|
vm: Luau::new(),
|
||||||
|
history: History::init(),
|
||||||
input: Input {
|
input: Input {
|
||||||
literal: String::new(),
|
literal: String::new(),
|
||||||
cursor: usize::MIN,
|
cursor: usize::MIN,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
Self { rt, config, history: History::init() }
|
Self { rt, config }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn start(&mut self) {
|
pub fn start(&mut self) {
|
||||||
@ -78,6 +79,6 @@ impl Pse {
|
|||||||
fs::read_to_string(conf_file).map_or_display(|luau_conf| self.vm_exec(luau_conf));
|
fs::read_to_string(conf_file).map_or_display(|luau_conf| self.vm_exec(luau_conf));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
self.term_input_processor().map_or_display(|()| self.history.write_to_file_fallible())
|
self.term_input_processor().map_or_display(|()| self.rt.history.write_to_file_fallible())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use crossterm::{cursor, event::{self, Event, KeyCode, KeyEvent, KeyModifiers}, execute, terminal};
|
use crossterm::{cursor, event::{self, Event, KeyCode, KeyEvent, KeyModifiers}, execute, terminal};
|
||||||
use core::fmt;
|
use core::fmt;
|
||||||
use std::io::{self, Write};
|
use std::{io::{self, Write}, mem};
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
use crate::{commands::Command, session::{self, Pse}};
|
use crate::{commands::Command, session::{self, Pse}};
|
||||||
@ -40,6 +40,8 @@ trait SpecificKeybinds {
|
|||||||
fn key_backspace(&mut self) -> InputResult<()>;
|
fn key_backspace(&mut self) -> InputResult<()>;
|
||||||
fn key_arrow_right(&mut self) -> InputResult<()>;
|
fn key_arrow_right(&mut self) -> InputResult<()>;
|
||||||
fn key_arrow_left(&mut self) -> InputResult<()>;
|
fn key_arrow_left(&mut self) -> InputResult<()>;
|
||||||
|
fn key_arrow_up(&mut self) -> InputResult<()>;
|
||||||
|
fn key_arrow_down(&mut self) -> InputResult<()>;
|
||||||
}
|
}
|
||||||
impl SpecificKeybinds for Pse {
|
impl SpecificKeybinds for Pse {
|
||||||
const EXIT_1: &str = "exit";
|
const EXIT_1: &str = "exit";
|
||||||
@ -81,10 +83,8 @@ impl SpecificKeybinds for Pse {
|
|||||||
terminal::Clear(terminal::ClearType::UntilNewLine)
|
terminal::Clear(terminal::ClearType::UntilNewLine)
|
||||||
).map_err(InputHandleError::Flush)?;
|
).map_err(InputHandleError::Flush)?;
|
||||||
self.rt.input.cursor-=1;
|
self.rt.input.cursor-=1;
|
||||||
Ok(())
|
|
||||||
} else {
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn key_arrow_right(&mut self) -> InputResult<()> {
|
fn key_arrow_right(&mut self) -> InputResult<()> {
|
||||||
@ -100,6 +100,18 @@ impl SpecificKeybinds for Pse {
|
|||||||
None => Ok(())
|
None => Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn key_arrow_up(&mut self) -> InputResult<()> {
|
||||||
|
if self.rt.input.literal.is_empty() {
|
||||||
|
self.rt.history.index += 1;
|
||||||
|
// if self.rt.history_index == self.history.fs_history
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn key_arrow_down(&mut self) -> InputResult<()> {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait TermInputCursor {
|
pub trait TermInputCursor {
|
||||||
@ -110,10 +122,7 @@ impl TermInputCursor for Pse {
|
|||||||
fn term_input_cursor_move_left(&mut self) -> Option<()> {
|
fn term_input_cursor_move_left(&mut self) -> Option<()> {
|
||||||
if self.rt.input.cursor == usize::MIN { None } else {
|
if self.rt.input.cursor == usize::MIN { None } else {
|
||||||
match self.rt.input.cursor>usize::MIN {
|
match self.rt.input.cursor>usize::MIN {
|
||||||
true => {
|
true => { self.rt.input.cursor-=1; Some(()) }
|
||||||
self.rt.input.cursor-=1;
|
|
||||||
Some(())
|
|
||||||
},
|
|
||||||
false => None
|
false => None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -122,10 +131,7 @@ impl TermInputCursor for Pse {
|
|||||||
fn term_input_cursor_move_right(&mut self) -> Option<()> {
|
fn term_input_cursor_move_right(&mut self) -> Option<()> {
|
||||||
if self.rt.input.cursor == usize::MAX { None } else {
|
if self.rt.input.cursor == usize::MAX { None } else {
|
||||||
match self.rt.input.cursor<self.rt.input.literal.chars().count() {
|
match self.rt.input.cursor<self.rt.input.literal.chars().count() {
|
||||||
true => {
|
true => { self.rt.input.cursor+=1; Some(()) },
|
||||||
self.rt.input.cursor+=1;
|
|
||||||
Some(())
|
|
||||||
},
|
|
||||||
false => None
|
false => None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -140,13 +146,15 @@ pub trait TermProcessor {
|
|||||||
fn term_input_processor(&mut self) -> io::Result<()>;
|
fn term_input_processor(&mut self) -> io::Result<()>;
|
||||||
}
|
}
|
||||||
impl TermProcessor for Pse {
|
impl TermProcessor for Pse {
|
||||||
fn term_render(&mut self, def_string: String) -> InputResult<()> {
|
fn term_render(&mut self, text: String) -> InputResult<()> {
|
||||||
self.rt.input.literal.insert_str(self.rt.input.cursor, &def_string);
|
self.rt.input.literal.insert_str(self.rt.input.cursor, &text);
|
||||||
self.rt.input.cursor+=1;
|
self.rt.input.cursor+=1;
|
||||||
if self.rt.input.cursor != self.rt.input.literal.chars().count() {
|
if self.rt.input.cursor != self.rt.input.literal.chars().count() {
|
||||||
|
execute!(io::stdout(), terminal::Clear(terminal::ClearType::UntilNewLine)).map_err(InputHandleError::Flush)?;
|
||||||
|
let slice = &self.rt.input.literal[self.rt.input.cursor..];
|
||||||
|
write!(io::stdout(), "{text}{slice}").map_err(InputHandleError::Write)?;
|
||||||
} else {
|
} else {
|
||||||
write!(io::stdout(), "{}", def_string).map_err(InputHandleError::Write)?;
|
write!(io::stdout(), "{text}").map_err(InputHandleError::Write)?;
|
||||||
}
|
}
|
||||||
io::stdout().flush().map_err(InputHandleError::Flush)
|
io::stdout().flush().map_err(InputHandleError::Flush)
|
||||||
}
|
}
|
||||||
@ -163,8 +171,8 @@ impl TermProcessor for Pse {
|
|||||||
KeyCode::Tab => todo!(),
|
KeyCode::Tab => todo!(),
|
||||||
KeyCode::Right => self.key_arrow_right(),
|
KeyCode::Right => self.key_arrow_right(),
|
||||||
KeyCode::Left => self.key_arrow_left(),
|
KeyCode::Left => self.key_arrow_left(),
|
||||||
KeyCode::Up => todo!(),
|
KeyCode::Up => self.key_arrow_up(),
|
||||||
KeyCode::Down => todo!(),
|
KeyCode::Down => self.key_arrow_down(),
|
||||||
keycode => self.key_ctrl(input_key, keycode)
|
keycode => self.key_ctrl(input_key, keycode)
|
||||||
};
|
};
|
||||||
input_handle.map_or_else(|inp_err| match inp_err {
|
input_handle.map_or_else(|inp_err| match inp_err {
|
||||||
|
@ -29,13 +29,8 @@ impl UserData for Shell {
|
|||||||
fn add_methods<M: UserDataMethods<Self>>(methods: &mut M) {
|
fn add_methods<M: UserDataMethods<Self>>(methods: &mut M) {
|
||||||
methods.add_meta_method_mut(MetaMethod::NewIndex, |_, this, (t_index, t_value): (String, String)| -> lResult<()> {
|
methods.add_meta_method_mut(MetaMethod::NewIndex, |_, this, (t_index, t_value): (String, String)| -> lResult<()> {
|
||||||
if t_index == "PROMPT" {
|
if t_index == "PROMPT" {
|
||||||
match t_value.len() as u16 >= u16::MAX {
|
let mut prompt = this.0.borrow_mut();
|
||||||
true => { mlua::Error::runtime(format!("SHELL.PROMPT's length exceeded or equals the max size. ({})", u16::MAX)); },
|
*prompt = t_value;
|
||||||
false => {
|
|
||||||
let mut prompt = this.0.borrow_mut();
|
|
||||||
*prompt = t_value;
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
});
|
});
|
||||||
|
Loading…
x
Reference in New Issue
Block a user