summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRory Dudley2024-03-30 19:05:23 -0600
committerRory Dudley2024-03-30 19:05:23 -0600
commitd408624afeb0035217d3d327e21b24a62b803f28 (patch)
tree891f52eb69f827ca71de157ab67f51606c7b40f0
parent491d3fbff384d4b04483b54e5bb78d23bb1181c5 (diff)
downloaddwarvish-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.rs19
-rw-r--r--src/compose/environment.rs13
-rw-r--r--src/main.rs11
-rw-r--r--src/poem/anthology.rs4
-rw-r--r--src/poem/anthology/source.rs5
-rw-r--r--src/poem/recite.rs15
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 {