usability improvements to env and def
* env prints variables and functions in seperate columns * run/stl seperation of concerns significantly better * def doesnt store lists or lambdas in the environment
This commit is contained in:
parent
825854fd42
commit
6969ea63bc
7 changed files with 309 additions and 131 deletions
|
|
@ -19,11 +19,13 @@ use {
|
|||
relish::{
|
||||
ast::{
|
||||
eval, lex, run,
|
||||
Ctr, Seg, SymTable,
|
||||
load_defaults, load_environment
|
||||
Ctr, Seg, SymTable, Symbol,
|
||||
},
|
||||
stdlib::{
|
||||
static_stdlib, dynamic_stdlib
|
||||
static_stdlib, dynamic_stdlib, load_defaults,
|
||||
load_environment,
|
||||
CONSOLE_XDIM_VNAME, CONSOLE_YDIM_VNAME, CFG_FILE_VNAME,
|
||||
L_PROMPT_VNAME, R_PROMPT_VNAME, PROMPT_DELIM_VNAME,
|
||||
},
|
||||
aux::{ShellState, check_jobs},
|
||||
},
|
||||
|
|
@ -46,6 +48,7 @@ use {
|
|||
nix::unistd,
|
||||
nu_ansi_term::{Color, Style},
|
||||
dirs::home_dir,
|
||||
termion::terminal_size,
|
||||
};
|
||||
|
||||
#[derive(Clone)]
|
||||
|
|
@ -252,7 +255,7 @@ fn main() {
|
|||
// this is a user shell. attempt to load configuration
|
||||
{
|
||||
// scope the below borrow of syms
|
||||
let cfg_file = env::var("RELISH_CFG_FILE").unwrap_or(cfg_file_name);
|
||||
let cfg_file = env::var(CFG_FILE_VNAME).unwrap_or(cfg_file_name);
|
||||
run(cfg_file.clone(), &mut syms)
|
||||
.unwrap_or_else(|err: String| eprintln!("failed to load script {}\n{}", cfg_file, err));
|
||||
}
|
||||
|
|
@ -284,8 +287,11 @@ fn main() {
|
|||
.with_style(Style::new().italic().fg(Color::LightGray)),
|
||||
)).with_validator(Box::new(DefaultValidator));
|
||||
|
||||
let mut xdimension: u16 = 0;
|
||||
let mut ydimension: u16 = 0;
|
||||
loop {
|
||||
{
|
||||
// update state
|
||||
check_jobs(&mut prompt_ss.borrow_mut());
|
||||
}
|
||||
let readline_prompt = make_prompt(&mut syms);
|
||||
|
|
@ -293,6 +299,11 @@ fn main() {
|
|||
// realloc with each loop because syms can change
|
||||
rl = rl.with_completer(Box::new(completer));
|
||||
let user_doc = rl.read_line(&readline_prompt).unwrap();
|
||||
|
||||
// doing this update here prevents needing to update twice before dimensions take effect
|
||||
(xdimension, ydimension) =
|
||||
check_and_update_console_dimensions(&mut syms, xdimension, ydimension);
|
||||
|
||||
match user_doc {
|
||||
Signal::Success(line) => {
|
||||
println!(""); // add a new line before output gets printed
|
||||
|
|
@ -320,19 +331,19 @@ fn main() {
|
|||
|
||||
fn make_prompt(syms: &mut SymTable) -> CustomPrompt {
|
||||
let l_ctr = *syms
|
||||
.call_symbol(&"CFG_RELISH_L_PROMPT".to_string(), &Seg::new(), true)
|
||||
.call_symbol(&L_PROMPT_VNAME.to_string(), &Seg::new(), true)
|
||||
.unwrap_or_else(|err: String| {
|
||||
eprintln!("{}", err);
|
||||
Box::new(Ctr::String("<prompt broken!>".to_string()))
|
||||
});
|
||||
let r_ctr = *syms
|
||||
.call_symbol(&"CFG_RELISH_R_PROMPT".to_string(), &Seg::new(), true)
|
||||
.call_symbol(&R_PROMPT_VNAME.to_string(), &Seg::new(), true)
|
||||
.unwrap_or_else(|err: String| {
|
||||
eprintln!("{}", err);
|
||||
Box::new(Ctr::String("<prompt broken!>".to_string()))
|
||||
});
|
||||
let d_ctr = *syms
|
||||
.call_symbol(&"CFG_RELISH_PROMPT_DELIMITER".to_string(), &Seg::new(), true)
|
||||
.call_symbol(&PROMPT_DELIM_VNAME.to_string(), &Seg::new(), true)
|
||||
.unwrap_or_else(|err: String| {
|
||||
eprintln!("{}", err);
|
||||
Box::new(Ctr::String("<prompt broken!>".to_string()))
|
||||
|
|
@ -397,3 +408,47 @@ fn get_token_to_complete(line: &str, pos: usize) -> (String, bool, usize) {
|
|||
|
||||
return (res, is_str, start_idx)
|
||||
}
|
||||
|
||||
/* It was considered that a SIGWINCH handler would be a more
|
||||
* elegant solution to this. Such a solution would need to
|
||||
* modify the current libc based approach to use a state-enclosing
|
||||
* closure as a signal handler. As of May 2023 there is no clear
|
||||
* way of doing such a thing.
|
||||
*
|
||||
* Luckily this data is only used within Relish, so we can simply
|
||||
* rely on it only being read during the evaluation phase of the REPL.
|
||||
* This method will at least work for that. (ava)
|
||||
*/
|
||||
fn check_and_update_console_dimensions(
|
||||
syms: &mut SymTable,
|
||||
last_xdim: u16,
|
||||
last_ydim: u16
|
||||
) -> (u16, u16) {
|
||||
let (xdim, ydim) = terminal_size().expect("Couldnt get console dimensions");
|
||||
|
||||
if xdim != last_xdim {
|
||||
syms.insert(
|
||||
String::from(CONSOLE_XDIM_VNAME),
|
||||
Symbol::from_ast(
|
||||
&String::from(CONSOLE_XDIM_VNAME),
|
||||
&String::from("Length of current console"),
|
||||
&Seg::from_mono(Box::new(Ctr::Integer(xdim.into()))),
|
||||
None,
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if ydim != last_ydim {
|
||||
syms.insert(
|
||||
String::from(CONSOLE_YDIM_VNAME),
|
||||
Symbol::from_ast(
|
||||
&String::from(CONSOLE_YDIM_VNAME),
|
||||
&String::from("Height of current console"),
|
||||
&Seg::from_mono(Box::new(Ctr::Integer(ydim.into()))),
|
||||
None,
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
(xdim, ydim)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue