From f902bd547332b9202805dc99b1ddd63c57901f70 Mon Sep 17 00:00:00 2001 From: Ava Affine Date: Wed, 7 Feb 2024 11:13:17 -0800 Subject: [PATCH 1/5] add tab completion for unescaped paths Signed-off-by: Ava Affine --- Readme.org | 3 +-- src/bin/flesh.rs | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/Readme.org b/Readme.org index 07e62fa..89683bc 100644 --- a/Readme.org +++ b/Readme.org @@ -165,9 +165,8 @@ Note: this section only tracks the state of incomplete TODO items. Having everyt - Can pass args to flesh scripts (via command line) - Can pass args to flesh scripts (via interpreter) - Pipe also operates on stderr -- ~ if possible (string replacement? +- ~ if possible (string replacement?) - tab completion for symbols also attempts to complete binaries -- tab completion for symbols also attempts to complete paths - finish basic goals in the [[file:snippets/interactive-devel.f][interactive development library]] - Release CI - Make an icon if you feel like it diff --git a/src/bin/flesh.rs b/src/bin/flesh.rs index 95bfc19..4ca41be 100644 --- a/src/bin/flesh.rs +++ b/src/bin/flesh.rs @@ -106,7 +106,7 @@ impl Completer for CustomCompleter { .expect("current dir bad?"); let (tok, is_str, start) = get_token_to_complete(line, pos); let mut sugg = vec![]; - if !is_str { + if !is_str && !tok.contains('/') { let mut offcenter_match = vec![]; for sym in &self.0 { if sym.starts_with(tok.as_str()) { From 6351ac63d2adef1c9e390a10fae4a7e25dd64b0b Mon Sep 17 00:00:00 2001 From: Ava Affine Date: Tue, 20 Feb 2024 12:45:34 -0800 Subject: [PATCH 2/5] cd now tracks PWD Signed-off-by: Ava Affine --- src/stl/posix.rs | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/src/stl/posix.rs b/src/stl/posix.rs index 0257fad..d8e5230 100644 --- a/src/stl/posix.rs +++ b/src/stl/posix.rs @@ -41,7 +41,7 @@ use { io::Result as IOResult, rc::Rc, fs::{ - File, OpenOptions + File, OpenOptions, canonicalize, }, path::Path, process::{ @@ -715,7 +715,7 @@ fn fg_callback( const CD_DOCSTRING: &str = "Expects 1 argument (a string). Changes to a new directory"; -fn cd_callback(ast: &Seg, _syms: &mut SymTable) -> Result { +fn cd_callback(ast: &Seg, syms: &mut SymTable) -> Result { if let Ctr::String(ref dir) = *ast.car { let dirp = Path::new(dir); if let Err(s) = set_current_dir(dirp) { @@ -723,7 +723,24 @@ fn cd_callback(ast: &Seg, _syms: &mut SymTable) -> Result { ("cd", s.to_string()) .into())) } else { - Ok(Ctr::None) + if let Ok(abs) = canonicalize(dirp) { + syms.insert( + String::from("PWD"), + Symbol::from_ast( + &String::from("PWD"), + &String::from("current working directory"), + &Seg::from_mono(Box::new( + Ctr::String(abs.to_string_lossy().into()))), + None, + )); + + // Run configurable user function + + Ok(Ctr::None) + } else { + Err(start_trace( + ("cd", "cannot make absolute path").into())) + } } } else { Err(start_trace( From 50ebfd2e37ee6298f1e637629bffb6f4b3505587 Mon Sep 17 00:00:00 2001 From: Ava Affine Date: Tue, 20 Feb 2024 14:27:11 -0800 Subject: [PATCH 3/5] configurable cd hook Signed-off-by: Ava Affine --- Readme.org | 12 +++---- Shell.org | 3 ++ src/lib.rs | 1 - src/stl/posix.rs | 90 ++++++++++++++++++++++++++++++++++++------------ 4 files changed, 77 insertions(+), 29 deletions(-) diff --git a/Readme.org b/Readme.org index 89683bc..fd8c6d3 100644 --- a/Readme.org +++ b/Readme.org @@ -68,6 +68,7 @@ Errors during configuration are non-terminal. In such a case any defaults which - CFG_FLESH_L_PROMPT (default 'λ'): a function that is called with no arguments to output the left hand of the prompt - CFG_FLESH_R_PROMPT (default ''): a function that is called with no arguments to output the right hand of the prompt - CFG_FLESH_PROMPT_DELIMITER (default '>'): a function that is called with no arguments to output the delimiter separating prompt from user input +- CFG_FLESH_CD_CB (default None): optional function / lambda that is called with no arguments on every change of CD. See [[file:Shell.org][The Shell Documentation]] for more information. ** Prompt design For an example of prompt design see [[file:snippets/mood-prompt.f][the mood prompt]] @@ -164,18 +165,17 @@ Note: this section only tracks the state of incomplete TODO items. Having everyt ** TODO v1.0 tasks - Can pass args to flesh scripts (via command line) - Can pass args to flesh scripts (via interpreter) -- Pipe also operates on stderr -- ~ if possible (string replacement?) - tab completion for symbols also attempts to complete binaries -- finish basic goals in the [[file:snippets/interactive-devel.f][interactive development library]] +- cd accepts symbols as well as strings (emulate shell) +- declare macros - Release CI - Make an icon if you feel like it - Post release to relevant channels ** TODO v1.1 tasks -- emacs lsp implementation -- finish stretch goals in the [[file:snippets/interactive-devel.f][interactive development library]] +- Pipe also operates on stderr +- better emacs language mode +- finish the [[file:snippets/interactive-devel.f][interactive development library]] - History length configurable (env var?) -- execute configurable function on cd - Post to relevant channels - Implement Compose for lambdas (add to readme) diff --git a/Shell.org b/Shell.org index 1b1cac3..5b15362 100644 --- a/Shell.org +++ b/Shell.org @@ -143,6 +143,9 @@ Flesh also provides a ~cd~ utility to change current working directory: (cd (concat HOME '/repositories')) ;; $ cd ~/repositories #+END_EXAMPLE +This ~cd~ routine will keep the ~PWD~ variable up to date. +Every invokation of ~cd~ will call whatever lambda or function is stored in ~CFG_FLESH_CD_CB~ with no arguments. A function stored in this variable can then perform on the fly reconfiguration or set additional variables based on the directory that the user has entered. + ** Creating bindings for shell commands Daily Flesh users will long for first class shell commands that are accounted for in autocomplete. diff --git a/src/lib.rs b/src/lib.rs index 5eb99fa..579373c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -33,7 +33,6 @@ pub mod ast { } pub mod stdlib { - pub use crate::stl::{}; pub use crate::stl::{ dynamic_stdlib, static_stdlib, load_defaults, load_environment, diff --git a/src/stl/posix.rs b/src/stl/posix.rs index d8e5230..8c9f47b 100644 --- a/src/stl/posix.rs +++ b/src/stl/posix.rs @@ -63,6 +63,7 @@ use { }; pub const POSIX_LOAD_NAME: &str = "load"; +pub const CD_USER_CB: &str = "CFG_FLESH_CD_CB"; pub struct ShellState { pub parent_pid: Pid, @@ -714,38 +715,69 @@ fn fg_callback( } const CD_DOCSTRING: &str = - "Expects 1 argument (a string). Changes to a new directory"; + "Expects 1 argument (a string). Changes to a new directory. +If CFG_RELISH_CD_CB is defined, cd will evaluate it. +cd returns the result that CFG_RELISH_CD_CB returns."; fn cd_callback(ast: &Seg, syms: &mut SymTable) -> Result { - if let Ctr::String(ref dir) = *ast.car { - let dirp = Path::new(dir); - if let Err(s) = set_current_dir(dirp) { - Err(start_trace( - ("cd", s.to_string()) - .into())) - } else { - if let Ok(abs) = canonicalize(dirp) { + let dir: &String; + match *ast.car { + Ctr::String(ref d) => dir = d, + Ctr::Symbol(ref d) => dir = d, + Ctr::Seg(ref s) => { + match eval(s, syms) { + Ok(r) => { + if r == ast.car { + return Err(start_trace(("cd", "innapropriate input.").into())); + } + return cd_callback(&Seg::from_mono(r), syms); + } + Err(e) => { + return Err(e.with_trace(("cd", "couldnt evaluate input").into())); + } + } + }, + _ => return Err(start_trace( + ("cd", "expected input to be a string or symbol") + .into())) + } + + let dirp = Path::new(dir); + match canonicalize(dirp) { + Ok(abs) => { + if let Err(s) = set_current_dir(dirp) { + Err(start_trace( + ("cd", s.to_string()) + .into())) + } else { syms.insert( String::from("PWD"), Symbol::from_ast( &String::from("PWD"), - &String::from("current working directory"), + &String::from("current working directory, set by cd"), &Seg::from_mono(Box::new( Ctr::String(abs.to_string_lossy().into()))), None, )); - // Run configurable user function - - Ok(Ctr::None) - } else { - Err(start_trace( - ("cd", "cannot make absolute path").into())) + match syms.call_symbol( + &CD_USER_CB.to_string(), + &Seg::new(), + true, + ) { + Ok(r) => { + Ok(*r) + }, + Err(s) => { + Err(s.with_trace(("cd", "failed to call callback").into())) + }, + } } + }, + Err(e) => { + Err( + start_trace( ("cd", e.to_string()).into()) + .with_trace(("cd", "could not make absolute path").into())) } - } else { - Err(start_trace( - ("cd", "expected input to be a string") - .into())) } } @@ -948,11 +980,25 @@ pub fn load_posix_shell(syms: &mut SymTable, shell_state: Rc "cd".to_string(), Symbol { name: String::from("cd"), - args: Args::Strict(vec![Type::String]), - conditional_branches: false, + args: Args::Lazy(1), + conditional_branches: true, docs: CD_DOCSTRING.to_string(), value: ValueType::Internal(Rc::new(cd_callback)), ..Default::default() }, ); + + syms.insert( + String::from(CD_USER_CB), + Symbol { + name: String::from(CD_USER_CB), + args: Args::None, + conditional_branches: false, + docs: String::from("lambda called at each invocation of cd"), + value: ValueType::Internal(Rc::new(move |_ast: &Seg, _sym: &mut SymTable| -> Result { + Ok(Ctr::None) + })), + ..Default::default() + }, + ); } From 108e25e336c8d1279fab767bde114f3f1a8dc9f3 Mon Sep 17 00:00:00 2001 From: Ava Affine Date: Tue, 20 Feb 2024 14:32:06 -0800 Subject: [PATCH 4/5] cd path arg can be a symbol (shell ease) Signed-off-by: Ava Affine --- Readme.org | 1 - Shell.org | 4 ++++ src/stl/posix.rs | 7 +++++-- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/Readme.org b/Readme.org index fd8c6d3..5c87a01 100644 --- a/Readme.org +++ b/Readme.org @@ -166,7 +166,6 @@ Note: this section only tracks the state of incomplete TODO items. Having everyt - Can pass args to flesh scripts (via command line) - Can pass args to flesh scripts (via interpreter) - tab completion for symbols also attempts to complete binaries -- cd accepts symbols as well as strings (emulate shell) - declare macros - Release CI - Make an icon if you feel like it diff --git a/Shell.org b/Shell.org index 5b15362..303d90f 100644 --- a/Shell.org +++ b/Shell.org @@ -146,6 +146,10 @@ Flesh also provides a ~cd~ utility to change current working directory: This ~cd~ routine will keep the ~PWD~ variable up to date. Every invokation of ~cd~ will call whatever lambda or function is stored in ~CFG_FLESH_CD_CB~ with no arguments. A function stored in this variable can then perform on the fly reconfiguration or set additional variables based on the directory that the user has entered. +WARNING: Symbols will be taken as strings unless wrapped in a form. + > Example: cd HOME => cd 'HOME' + > Example: cd (eval HOME) => cd /path/to/home/dir + ** Creating bindings for shell commands Daily Flesh users will long for first class shell commands that are accounted for in autocomplete. diff --git a/src/stl/posix.rs b/src/stl/posix.rs index 8c9f47b..6fd6f6a 100644 --- a/src/stl/posix.rs +++ b/src/stl/posix.rs @@ -715,9 +715,12 @@ fn fg_callback( } const CD_DOCSTRING: &str = - "Expects 1 argument (a string). Changes to a new directory. + "Expects 1 argument (a string, symbol, or form). Changes to a directory. +WARNING: Symbols will be taken as strings unless wrapped in a form. + > Example: cd HOME => cd 'HOME' + > Example: cd (eval HOME) => cd /path/to/home/dir If CFG_RELISH_CD_CB is defined, cd will evaluate it. -cd returns the result that CFG_RELISH_CD_CB returns."; +cd returns the result that CFG_RELISH_CD_CB returns, or None"; fn cd_callback(ast: &Seg, syms: &mut SymTable) -> Result { let dir: &String; match *ast.car { From dcb34c9ab15b7777bb66318be828463ffc572446 Mon Sep 17 00:00:00 2001 From: Ava Affine Date: Tue, 20 Feb 2024 14:37:40 -0800 Subject: [PATCH 5/5] note further autocomplete work in Readme Signed-off-by: Ava Affine --- Readme.org | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Readme.org b/Readme.org index 5c87a01..a8cab6a 100644 --- a/Readme.org +++ b/Readme.org @@ -165,12 +165,12 @@ Note: this section only tracks the state of incomplete TODO items. Having everyt ** TODO v1.0 tasks - Can pass args to flesh scripts (via command line) - Can pass args to flesh scripts (via interpreter) -- tab completion for symbols also attempts to complete binaries - declare macros - Release CI - Make an icon if you feel like it - Post release to relevant channels ** TODO v1.1 tasks +- all autocomplete is done via configurable userfunction, default documented with 1:1 functionality - Pipe also operates on stderr - better emacs language mode - finish the [[file:snippets/interactive-devel.f][interactive development library]]