Terminal userdata

This commit is contained in:
rhpidfyre 2025-01-10 22:24:24 -05:00
parent e578f408c5
commit fb2d79c35c
4 changed files with 74 additions and 90 deletions

View File

@ -6,9 +6,12 @@ use crate::MapDisplay;
pub const DEFAULT_CONFIG_CONTENT: &str = r#"--!strict pub const DEFAULT_CONFIG_CONTENT: &str = r#"--!strict
local cyan = TERMINAL.OUT.FOREGROUND.CYAN local cyan = TERMINAL.OUT.FOREGROUND.CYAN
local red = TERMINAL.OUT.FOREGROUND.RED
local username = cyan(SHELL.SYSTEM.USERNAME)
local hostname = SHELL.SYSTEM.HOSTNAME local hostname = SHELL.SYSTEM.HOSTNAME
local username = SHELL.SYSTEM.USERNAME
username = if username == "root" then red(username) else cyan(username)
SHELL.PROMPT = `{username}@{hostname} λ `"#; SHELL.PROMPT = `{username}@{hostname} λ `"#;

View File

@ -1,10 +1,11 @@
use mlua::{Function, Lua as Luau, MultiValue, Result as lResult, Table, Value}; use mlua::{Function, Lua as Luau, MultiValue, Result as lResult, Table, Value};
use color_print::{cformat, ceprintln}; use color_print::{cformat, ceprintln};
use terminal::TerminalGlobal;
use std::{cell::RefCell, rc::Rc}; use std::{cell::RefCell, rc::Rc};
use core::fmt; use core::fmt;
use shell::Shell; use shell::ShellGlobal;
use crate::{ps::Ps, vm::terminal::Terminal, MapDisplay}; use crate::{ps::Ps, MapDisplay};
mod shell; mod shell;
mod terminal; mod terminal;

View File

@ -19,8 +19,8 @@ fn luau_sys_details(luau: &Luau) -> lResult<Table> {
Ok(system) Ok(system)
} }
struct ShellUserdata(Rc<RefCell<Ps>>); struct Shell(Rc<RefCell<Ps>>);
impl UserData for ShellUserdata { impl UserData for Shell {
fn add_fields<F: UserDataFields<Self>>(fields: &mut F) { fn add_fields<F: UserDataFields<Self>>(fields: &mut F) {
fields.add_field_method_get("PROMPT", |_, this| Ok(this.0.borrow().get().to_owned())); fields.add_field_method_get("PROMPT", |_, this| Ok(this.0.borrow().get().to_owned()));
fields.add_field_method_get("SYSTEM", |luau, _| luau_sys_details(luau)); fields.add_field_method_get("SYSTEM", |luau, _| luau_sys_details(luau));
@ -36,15 +36,12 @@ impl UserData for ShellUserdata {
} }
} }
pub trait Shell { pub trait ShellGlobal {
fn global_shell(&self, luau_globals: &Table) -> lResult<()>; fn global_shell(&self, luau_globals: &Table) -> lResult<()>;
} }
impl Shell for LuauVm { impl ShellGlobal for LuauVm {
fn global_shell(&self, luau_globals: &Table) -> lResult<()> { fn global_shell(&self, luau_globals: &Table) -> lResult<()> {
// let shell = self.vm.create_table()?; luau_globals.set("SHELL", Shell(Rc::clone(&self.ps)))?;
// shell.set("SYSTEM", self.sys_details()?)?;
// shell.set("PROMPT", self.ps_prompt()?)?;
luau_globals.set("SHELL", ShellUserdata(Rc::clone(&self.ps)))?;
Ok(()) Ok(())
} }
} }

View File

@ -1,110 +1,93 @@
use mlua::{Function, Result as lResult, Table}; use mlua::{UserDataFields, Lua as Luau, Result as lResult, Table, UserData};
use const_format::str_split; use const_format::str_split;
use crossterm::style::Stylize; use crossterm::style::Stylize;
use crate::vm::LuauVm; use crate::vm::LuauVm;
macro_rules! foreground_styles_luau { macro_rules! foreground_styles_luau {
($self:expr, $style_table:expr, $($color:ident)+) => { ($luau:expr, $style_table:expr, $($color:ident)+) => {
$( $(
$style_table.raw_set(stringify!($color).to_ascii_uppercase(), $self.vm.create_function(|_, text: String| -> lResult<String> { $style_table.raw_set(stringify!($color).to_ascii_uppercase(), $luau.create_function(|_, text: String| -> lResult<String> {
Ok(text.$color().to_string()) Ok(text.$color().to_string())
})?)?; })?)?;
)+ )+
}; };
} }
macro_rules! background_styles_luau { macro_rules! background_styles_luau {
($self:expr, $style_table:expr, $($color:ident)+) => { ($luau:expr, $style_table:expr, $($color:ident)+) => {
$( $(
$style_table.raw_set( $style_table.raw_set(
str_split!(stringify!($color), "_")[1..].join("_").to_ascii_uppercase(), str_split!(stringify!($color), "_")[1..].join("_").to_ascii_uppercase(),
$self.vm.create_function(|_, text: String| -> lResult<String> { $luau.create_function(|_, text: String| -> lResult<String> {
Ok(text.$color().to_string()) Ok(text.$color().to_string())
})?)?; })?)?;
)+ )+
}; };
} }
trait Colors { fn text_styles_funcs(luau: &Luau) -> lResult<(Table, Table)> {
fn background(&self, term_out_table: &Table) -> lResult<()>; let foreground_table = luau.create_table()?;
fn foreground(&self, term_out_table: &Table) -> lResult<()>; let background_table = luau.create_table()?;
} foreground_styles_luau!(luau, foreground_table,
impl Colors for LuauVm { dark_grey dark_red dark_green dark_cyan
fn background(&self, term_out_table: &Table) -> lResult<()> { dark_yellow dark_magenta dark_blue
let foreground_table = self.vm.create_table()?; red grey black green yellow
foreground_styles_luau!(self, foreground_table, blue magenta cyan white
dark_grey dark_red dark_green dark_cyan underlined
dark_yellow dark_magenta dark_blue underline_dark_grey underline_dark_red underline_dark_green underline_dark_cyan
red grey black green yellow underline_dark_yellow underline_dark_magenta underline_dark_blue underline_red
blue magenta cyan white underline_grey underline_black underline_green underline_yellow
underlined underline_blue underline_magenta underline_cyan underline_white
underline_dark_grey underline_dark_red underline_dark_green underline_dark_cyan bold
underline_dark_yellow underline_dark_magenta underline_dark_blue underline_red );
underline_grey underline_black underline_green underline_yellow background_styles_luau!(luau, background_table,
underline_blue underline_magenta underline_cyan underline_white on_dark_grey on_dark_red on_dark_green on_dark_cyan
bold on_dark_yellow on_dark_magenta on_dark_blue
); on_red on_grey on_black
term_out_table.raw_set("FOREGROUND", foreground_table) on_green on_yellow
} on_blue on_magenta
on_cyan on_white
fn foreground(&self, term_out_table: &Table) -> lResult<()> { );
let background_table = self.vm.create_table()?; Ok((foreground_table, background_table))
background_styles_luau!(self, background_table,
on_dark_grey on_dark_red on_dark_green on_dark_cyan
on_dark_yellow on_dark_magenta on_dark_blue
on_red on_grey on_black
on_green on_yellow
on_blue on_magenta
on_cyan on_white
);
term_out_table.raw_set("BACKGROUND", background_table)
}
} }
trait Write { fn fields_write_funcs<F: UserDataFields<Terminal>>(fields: &mut F) {
fn write(&self) -> lResult<Function>; fields.add_field_method_get("WRITE", |luau, _| luau.create_function(|_, s: String| -> lResult<()> {
fn write_error(&self) -> lResult<Function>; print!("{s}");
fn write_error_ln(&self) -> lResult<Function>; Ok(())
} }));
impl Write for LuauVm { fields.add_field_method_get("WRITE_ERROR", |luau, _| luau.create_function(|_, s: String| -> lResult<()> {
fn write(&self) -> lResult<Function> { eprint!("{s}");
self.vm.create_function(|_, s: String| -> lResult<()> { Ok(())
print!("{s}"); }));
Ok(()) fields.add_field_method_get("WRITE_ERROR_LN", |luau, _| luau.create_function(|_, s: String| -> lResult<()> {
}) eprintln!("{s}");
} Ok(())
fn write_error(&self) -> lResult<Function> { }));
self.vm.create_function(|_, s: String| -> lResult<()> {
eprint!("{s}");
Ok(())
})
}
fn write_error_ln(&self) -> lResult<Function> {
self.vm.create_function(|_, s: String| -> lResult<()> {
eprintln!("{s}");
Ok(())
})
}
} }
pub trait Terminal { struct Terminal;
fn out(&self) -> lResult<Table>; impl UserData for Terminal {
fn add_fields<F: UserDataFields<Self>>(fields: &mut F) {
fields_write_funcs(fields);
fields.add_field_method_get("OUT", |luau, _| {
let (foreground, background) = text_styles_funcs(luau)?;
let out_table = luau.create_table()?;
out_table.raw_set("FOREGROUND", foreground)?;
out_table.raw_set("BACKGROUND", background)?;
Ok(out_table)
});
}
// fn add_methods<M: UserDataMethods<Self>>(methods: &mut M) {
// }
}
pub trait TerminalGlobal {
fn global_terminal(&self, luau_globals: &Table) -> lResult<()>; fn global_terminal(&self, luau_globals: &Table) -> lResult<()>;
} }
impl Terminal for LuauVm { impl TerminalGlobal for LuauVm {
fn out(&self) -> lResult<Table> {
let term_out_table = self.vm.create_table()?;
self.background(&term_out_table)?;
self.foreground(&term_out_table)?;
Ok(term_out_table)
}
fn global_terminal(&self, luau_globals: &Table) -> lResult<()> { fn global_terminal(&self, luau_globals: &Table) -> lResult<()> {
let term_table = self.vm.create_table()?; luau_globals.raw_set("TERMINAL", Terminal)
term_table.raw_set("OUT", self.out()?)?;
term_table.raw_set("WRITE", self.write()?)?;
term_table.raw_set("WRITE_ERROR", self.write_error()?)?;
term_table.raw_set("WRITE_ERROR_LN", self.write_error_ln()?)?;
luau_globals.raw_set("TERMINAL", term_table)
} }
} }