Merge branch 'auto-complete-stuff' into 'main'
add tab completion for unescaped paths See merge request whom/relish!12
This commit is contained in:
commit
13135def5a
5 changed files with 97 additions and 27 deletions
14
Readme.org
14
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_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_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_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
|
** Prompt design
|
||||||
For an example of prompt design see [[file:snippets/mood-prompt.f][the mood prompt]]
|
For an example of prompt design see [[file:snippets/mood-prompt.f][the mood prompt]]
|
||||||
|
|
@ -164,19 +165,16 @@ Note: this section only tracks the state of incomplete TODO items. Having everyt
|
||||||
** TODO v1.0 tasks
|
** TODO v1.0 tasks
|
||||||
- Can pass args to flesh scripts (via command line)
|
- Can pass args to flesh scripts (via command line)
|
||||||
- Can pass args to flesh scripts (via interpreter)
|
- Can pass args to flesh scripts (via interpreter)
|
||||||
- Pipe also operates on stderr
|
- declare macros
|
||||||
- ~ 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
|
- Release CI
|
||||||
- Make an icon if you feel like it
|
- Make an icon if you feel like it
|
||||||
- Post release to relevant channels
|
- Post release to relevant channels
|
||||||
** TODO v1.1 tasks
|
** TODO v1.1 tasks
|
||||||
- emacs lsp implementation
|
- all autocomplete is done via configurable userfunction, default documented with 1:1 functionality
|
||||||
- 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?)
|
- History length configurable (env var?)
|
||||||
- execute configurable function on cd
|
|
||||||
- Post to relevant channels
|
- Post to relevant channels
|
||||||
- Implement Compose for lambdas
|
- Implement Compose for lambdas
|
||||||
(add to readme)
|
(add to readme)
|
||||||
|
|
|
||||||
|
|
@ -143,6 +143,13 @@ Flesh also provides a ~cd~ utility to change current working directory:
|
||||||
(cd (concat HOME '/repositories')) ;; $ cd ~/repositories
|
(cd (concat HOME '/repositories')) ;; $ cd ~/repositories
|
||||||
#+END_EXAMPLE
|
#+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.
|
||||||
|
|
||||||
|
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
|
** Creating bindings for shell commands
|
||||||
Daily Flesh users will long for first class shell commands that are accounted for in autocomplete.
|
Daily Flesh users will long for first class shell commands that are accounted for in autocomplete.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -106,7 +106,7 @@ impl Completer for CustomCompleter {
|
||||||
.expect("current dir bad?");
|
.expect("current dir bad?");
|
||||||
let (tok, is_str, start) = get_token_to_complete(line, pos);
|
let (tok, is_str, start) = get_token_to_complete(line, pos);
|
||||||
let mut sugg = vec![];
|
let mut sugg = vec![];
|
||||||
if !is_str {
|
if !is_str && !tok.contains('/') {
|
||||||
let mut offcenter_match = vec![];
|
let mut offcenter_match = vec![];
|
||||||
for sym in &self.0 {
|
for sym in &self.0 {
|
||||||
if sym.starts_with(tok.as_str()) {
|
if sym.starts_with(tok.as_str()) {
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,6 @@ pub mod ast {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub mod stdlib {
|
pub mod stdlib {
|
||||||
pub use crate::stl::{};
|
|
||||||
pub use crate::stl::{
|
pub use crate::stl::{
|
||||||
dynamic_stdlib, static_stdlib,
|
dynamic_stdlib, static_stdlib,
|
||||||
load_defaults, load_environment,
|
load_defaults, load_environment,
|
||||||
|
|
|
||||||
100
src/stl/posix.rs
100
src/stl/posix.rs
|
|
@ -41,7 +41,7 @@ use {
|
||||||
io::Result as IOResult,
|
io::Result as IOResult,
|
||||||
rc::Rc,
|
rc::Rc,
|
||||||
fs::{
|
fs::{
|
||||||
File, OpenOptions
|
File, OpenOptions, canonicalize,
|
||||||
},
|
},
|
||||||
path::Path,
|
path::Path,
|
||||||
process::{
|
process::{
|
||||||
|
|
@ -63,6 +63,7 @@ use {
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const POSIX_LOAD_NAME: &str = "load";
|
pub const POSIX_LOAD_NAME: &str = "load";
|
||||||
|
pub const CD_USER_CB: &str = "CFG_FLESH_CD_CB";
|
||||||
|
|
||||||
pub struct ShellState {
|
pub struct ShellState {
|
||||||
pub parent_pid: Pid,
|
pub parent_pid: Pid,
|
||||||
|
|
@ -714,22 +715,73 @@ fn fg_callback(
|
||||||
}
|
}
|
||||||
|
|
||||||
const CD_DOCSTRING: &str =
|
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.
|
||||||
fn cd_callback(ast: &Seg, _syms: &mut SymTable) -> Result<Ctr, Traceback> {
|
WARNING: Symbols will be taken as strings unless wrapped in a form.
|
||||||
if let Ctr::String(ref dir) = *ast.car {
|
> Example: cd HOME => cd 'HOME'
|
||||||
let dirp = Path::new(dir);
|
> Example: cd (eval HOME) => cd /path/to/home/dir
|
||||||
if let Err(s) = set_current_dir(dirp) {
|
If CFG_RELISH_CD_CB is defined, cd will evaluate it.
|
||||||
Err(start_trace(
|
cd returns the result that CFG_RELISH_CD_CB returns, or None";
|
||||||
("cd", s.to_string())
|
fn cd_callback(ast: &Seg, syms: &mut SymTable) -> Result<Ctr, Traceback> {
|
||||||
.into()))
|
let dir: &String;
|
||||||
} else {
|
match *ast.car {
|
||||||
Ok(Ctr::None)
|
Ctr::String(ref d) => dir = d,
|
||||||
}
|
Ctr::Symbol(ref d) => dir = d,
|
||||||
} else {
|
Ctr::Seg(ref s) => {
|
||||||
Err(start_trace(
|
match eval(s, syms) {
|
||||||
("cd", "expected input to be a string")
|
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()))
|
.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, set by cd"),
|
||||||
|
&Seg::from_mono(Box::new(
|
||||||
|
Ctr::String(abs.to_string_lossy().into()))),
|
||||||
|
None,
|
||||||
|
));
|
||||||
|
|
||||||
|
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()))
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn load_posix_shell(syms: &mut SymTable, shell_state: Rc<RefCell<ShellState>>) {
|
pub fn load_posix_shell(syms: &mut SymTable, shell_state: Rc<RefCell<ShellState>>) {
|
||||||
|
|
@ -931,11 +983,25 @@ pub fn load_posix_shell(syms: &mut SymTable, shell_state: Rc<RefCell<ShellState>
|
||||||
"cd".to_string(),
|
"cd".to_string(),
|
||||||
Symbol {
|
Symbol {
|
||||||
name: String::from("cd"),
|
name: String::from("cd"),
|
||||||
args: Args::Strict(vec![Type::String]),
|
args: Args::Lazy(1),
|
||||||
conditional_branches: false,
|
conditional_branches: true,
|
||||||
docs: CD_DOCSTRING.to_string(),
|
docs: CD_DOCSTRING.to_string(),
|
||||||
value: ValueType::Internal(Rc::new(cd_callback)),
|
value: ValueType::Internal(Rc::new(cd_callback)),
|
||||||
..Default::default()
|
..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<Ctr, Traceback> {
|
||||||
|
Ok(Ctr::None)
|
||||||
|
})),
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue