Early implementation of scripting elements

This commit is contained in:
2025-03-05 01:36:58 -05:00
parent cd216ef1cc
commit 83c9c08106
28 changed files with 1384 additions and 371 deletions

61
src/shellenv/input.rs Normal file
View File

@@ -0,0 +1,61 @@
use std::cell::Ref;
use crate::prelude::*;
#[derive(Clone,Debug)]
pub struct InputMan {
input: Option<String>,
spans: Vec<Rc<RefCell<Span>>>,
}
impl InputMan {
pub fn new() -> Self {
Self { input: None, spans: vec![] }
}
pub fn clear(&mut self) {
*self = Self::new();
}
pub fn new_input(&mut self, input: &str) {
self.input = Some(input.to_string())
}
pub fn get_input(&self) -> Option<&String> {
self.input.as_ref()
}
pub fn get_input_mut(&mut self) -> Option<&mut String> {
self.input.as_mut()
}
pub fn new_span(&mut self, start: usize, end: usize) -> Rc<RefCell<Span>> {
if let Some(_input) = &self.input {
let span = Rc::new(RefCell::new(Span::new(start, end)));
self.spans.push(span.clone());
span
} else {
Rc::new(RefCell::new(Span::new(0,0)))
}
}
pub fn spans_mut(&mut self) -> &mut Vec<Rc<RefCell<Span>>> {
&mut self.spans
}
pub fn clamp(&self, span: Rc<RefCell<Span>>) {
let mut span = span.borrow_mut();
if let Some(input) = &self.input {
span.clamp_start(input.len());
span.clamp_end(input.len());
}
}
pub fn clamp_all(&self) {
for span in &self.spans {
self.clamp(span.clone());
}
}
pub fn get_slice(&self, span: Rc<RefCell<Span>>) -> Option<&str> {
let span = span.borrow();
let mut start = span.start();
let end = span.end();
if start > end {
start = end;
}
self.input.as_ref().map(|s| &s[start..end])
}
}

View File

@@ -10,6 +10,7 @@ pub mod exec_ctx;
pub mod meta;
pub mod shenv;
pub mod vars;
pub mod input;
/// Calls attach_tty() on the shell's process group to retake control of the terminal
pub fn take_term() -> ShResult<()> {

View File

@@ -5,6 +5,7 @@ pub struct ShEnv {
vars: shellenv::vars::VarTab,
logic: shellenv::logic::LogTab,
meta: shellenv::meta::MetaTab,
input_man: shellenv::input::InputMan,
ctx: shellenv::exec_ctx::ExecCtx
}
@@ -14,6 +15,7 @@ impl ShEnv {
vars: shellenv::vars::VarTab::new(),
logic: shellenv::logic::LogTab::new(),
meta: shellenv::meta::MetaTab::new(),
input_man: shellenv::input::InputMan::new(),
ctx: shellenv::exec_ctx::ExecCtx::new(),
}
}
@@ -26,6 +28,58 @@ impl ShEnv {
pub fn meta(&self) -> &shellenv::meta::MetaTab {
&self.meta
}
pub fn input_slice(&self, span: Rc<RefCell<Span>>) -> &str {
&self.input_man.get_slice(span).unwrap_or_default()
}
pub fn expand_input(&mut self, new: &str, repl_span: Rc<RefCell<Span>>) -> Vec<Token> {
let saved_spans = self.input_man.spans_mut().clone();
let mut new_tokens = Lexer::new(new.to_string(), self).lex();
*self.input_man.spans_mut() = saved_spans;
let offset = repl_span.borrow().start();
for token in new_tokens.iter_mut() {
token.span().borrow_mut().shift(offset as isize);
}
let repl_start = repl_span.borrow().start();
let repl_end = repl_span.borrow().end();
let range = repl_start..repl_end;
if let Some(ref mut input) = self.input_man.get_input_mut() {
let old = &input[range.clone()];
let delta: isize = new.len() as isize - old.len() as isize;
input.replace_range(range, new);
let expanded = input.clone();
log!(DEBUG, expanded);
for span in self.input_man.spans_mut() {
let mut span_mut = span.borrow_mut();
if span_mut.start() > repl_start {
span_mut.shift(delta);
}
}
for token in &new_tokens {
self.input_man.spans_mut().push(token.span());
}
}
self.input_man.clamp_all();
new_tokens
}
pub fn new_input(&mut self, input: &str) {
self.input_man.clear();
self.input_man.new_input(input);
}
pub fn get_input(&self) -> String {
let input = self.input_man.get_input().map(|s| s.to_string()).unwrap_or_default();
log!(DEBUG, input);
input
}
pub fn inputman(&self) -> &shellenv::input::InputMan {
&self.input_man
}
pub fn inputman_mut(&mut self) -> &mut shellenv::input::InputMan {
&mut self.input_man
}
pub fn meta_mut(&mut self) -> &mut shellenv::meta::MetaTab {
&mut self.meta
}