diff options
author | Rory Dudley | 2024-03-30 19:05:23 -0600 |
---|---|---|
committer | Rory Dudley | 2024-03-30 19:05:23 -0600 |
commit | d408624afeb0035217d3d327e21b24a62b803f28 (patch) | |
tree | 891f52eb69f827ca71de157ab67f51606c7b40f0 | |
parent | 491d3fbff384d4b04483b54e5bb78d23bb1181c5 (diff) | |
download | dwarvish-d408624afeb0035217d3d327e21b24a62b803f28.tar.gz |
Add wrapper for global shell environment
Instead of having to pass around a bunch of different data structures
for various shell functions, create the wrapper compose::Environment,
which serves as a global shell state. It is configured via
login/profile/rc scripts initially, but can of course be modified
throughout the lifetime of the shell.
-rw-r--r-- | src/compose.rs | 19 | ||||
-rw-r--r-- | src/compose/environment.rs | 13 | ||||
-rw-r--r-- | src/main.rs | 11 | ||||
-rw-r--r-- | src/poem/anthology.rs | 4 | ||||
-rw-r--r-- | src/poem/anthology/source.rs | 5 | ||||
-rw-r--r-- | src/poem/recite.rs | 15 |
6 files changed, 45 insertions, 22 deletions
diff --git a/src/compose.rs b/src/compose.rs index 8c4b3ea..3d2a2db 100644 --- a/src/compose.rs +++ b/src/compose.rs @@ -1,8 +1,13 @@ use crate::poem::{read::Readable, recite::Reciteable, Poem}; +pub mod environment; +pub use environment::Environment; use std::fs; use std::path::PathBuf; -pub fn env() { +pub fn env() -> Environment { + // Create a new Environment object, to store some extra shell info + let mut env = Environment::new(); + // Use local repo path if running the debug target let global_rc = if cfg!(debug_assertions) { let mut base = PathBuf::from(env!("CARGO_MANIFEST_DIR")); @@ -17,11 +22,14 @@ pub fn env() { local_rc.push(".dwvshrc"); // Read, read, and recite - rrr(global_rc); - rrr(local_rc); + rrr(global_rc, &mut env); + rrr(local_rc, &mut env); + + // Return the new environment + env } -fn rrr(path: PathBuf) { +fn rrr(path: PathBuf, env: &mut Environment) { let poetry = match fs::read_to_string(&path) { Ok(poetry) => poetry, Err(e) => { @@ -47,8 +55,7 @@ fn rrr(path: PathBuf) { } }; - let mut bins = vec![]; - match poem.recite(&mut bins, None) { + match poem.recite(env, None) { Ok(_) => {} Err(e) => { eprintln!("dwvsh: {}", e.to_string().to_lowercase()); diff --git a/src/compose/environment.rs b/src/compose/environment.rs new file mode 100644 index 0000000..219a597 --- /dev/null +++ b/src/compose/environment.rs @@ -0,0 +1,13 @@ +pub struct Environment { + pub aliases: Vec<String>, + pub bins: Vec<String>, +} + +impl Environment { + pub fn new() -> Self { + Environment { + aliases: vec![], + bins: vec![], + } + } +} diff --git a/src/main.rs b/src/main.rs index ce5f611..898d19e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,6 +4,7 @@ mod path; mod poem; use poem::{read::Readable, recite::Reciteable, Poem}; mod compose; +use compose::Environment; /// Starts the main shell loop /// @@ -20,9 +21,9 @@ mod compose; /// repl(prompt, &mut at_prompt); /// } /// ``` -fn repl(prompt: &str, at_prompt: &mut Arc<Mutex<bool>>) { +fn repl(prompt: &str, at_prompt: &mut Arc<Mutex<bool>>, env: &mut Environment) { // Initial path refresh on startup - let mut bins: Vec<String> = path::refresh(); + env.bins = path::refresh(); // Main shell loop loop { @@ -67,7 +68,7 @@ fn repl(prompt: &str, at_prompt: &mut Arc<Mutex<bool>>) { }; // Recite the poem - match poem.recite(&mut bins, None) { + match poem.recite(env, None) { Ok(_) => {} Err(e) => eprintln!("dwvsh: {}", e.to_string().to_lowercase()), } @@ -81,7 +82,7 @@ fn main() { // Compose the environment for dwvsh // TODO: All instances of `env!("HOME")` need to be changed to use env::var // TODO: Will probably need to set $HOME in dwv{profile,login} via passwd - compose::env(); + let mut env = compose::env(); // Set the prompt let prompt = "|> "; @@ -102,5 +103,5 @@ fn main() { }; // Begin evaluating commands - repl(prompt, &mut at_prompt); + repl(prompt, &mut at_prompt, &mut env); } diff --git a/src/poem/anthology.rs b/src/poem/anthology.rs index b9e747c..f1adae7 100644 --- a/src/poem/anthology.rs +++ b/src/poem/anthology.rs @@ -19,13 +19,13 @@ pub fn lookup(verb: &str) -> Option<usize> { INDEX.iter().position(|v| v.to_string() == verb) } -pub fn incant(verse: &Verse, index: usize, bins: &mut Vec<String>) -> i32 { +pub fn incant(verse: &Verse, index: usize, env: &mut Environment) -> i32 { let verb = INDEX[index]; match verb { "cd" => cd::incant(verse), "exit" => exit::incant(), "export" => export::incant(verse), - "source" => source::incant(verse, bins), + "source" => source::incant(verse, env), _ => unreachable!(), } } diff --git a/src/poem/anthology/source.rs b/src/poem/anthology/source.rs index f7b9a0b..b4148cb 100644 --- a/src/poem/anthology/source.rs +++ b/src/poem/anthology/source.rs @@ -1,8 +1,9 @@ +use crate::compose::Environment; use crate::poem::Verse; use crate::poem::{read::Readable, recite::Reciteable, Poem}; use std::fs; -pub fn incant(verse: &Verse, bins: &mut Vec<String>) -> i32 { +pub fn incant(verse: &Verse, env: &mut Environment) -> i32 { let files = match verse.clause() { Some(clause) => clause, None => { @@ -32,7 +33,7 @@ pub fn incant(verse: &Verse, bins: &mut Vec<String>) -> i32 { } }; - match poem.recite(bins, None) { + match poem.recite(env, None) { Ok(_) => {} Err(e) => { eprintln!("dwvsh: {}", e.to_string().to_lowercase()); diff --git a/src/poem/recite.rs b/src/poem/recite.rs index f2af591..e37b7c6 100644 --- a/src/poem/recite.rs +++ b/src/poem/recite.rs @@ -1,5 +1,6 @@ mod ps; use super::Poem; +use crate::compose::Environment; use crate::path; use crate::poem::anthology; use crate::poem::elements::rune::Rune; @@ -10,11 +11,11 @@ use std::{ }; pub trait Reciteable { - fn recite(&self, bins: &mut Vec<String>, stdout: Option<bool>) -> Result<String, io::Error>; + fn recite(&self, env: &mut Environment, stdout: Option<bool>) -> Result<String, io::Error>; } impl Reciteable for Poem { - fn recite(&self, bins: &mut Vec<String>, stdout: Option<bool>) -> Result<String, io::Error> { + fn recite(&self, env: &mut Environment, stdout: Option<bool>) -> Result<String, io::Error> { // Should we print to stdout or always capture it let stdout = stdout.unwrap_or(true); @@ -84,7 +85,7 @@ impl Reciteable for Poem { Some(poem) => poem, None => break, // TODO: Return an error }; - let out = poem.recite(bins, Some(false))?; + let out = poem.recite(env, Some(false))?; if out.contains("\n") { let mut out = out.split("\n"); let next = out.next().unwrap_or("").trim(); @@ -121,16 +122,16 @@ impl Reciteable for Poem { // Incant the verse if it's a built-in let index = anthology::lookup(&verse.verb()); let status = if index.is_some() { - anthology::incant(&verse, index.unwrap(), bins) + anthology::incant(&verse, index.unwrap(), env) } else { // Incant the verse, based on its meter // Check if the verb exists // If it doesn't exist, try refreshing the binary cache, and check // again // If it still doesn't exist, print an error - if !verse.spellcheck(bins) { - *bins = path::refresh(); - if !verse.spellcheck(bins) { + if !verse.spellcheck(&env.bins) { + env.bins = path::refresh(); + if !verse.spellcheck(&env.bins) { eprintln!("dwvsh: {}: command not found", verse.verb()); if verse.meter != Rune::And { |