diff options
author | Rory Dudley | 2024-03-30 20:15:12 -0600 |
---|---|---|
committer | Rory Dudley | 2024-03-30 20:15:12 -0600 |
commit | 2439f63a1c0859fd454d4a67dc36b61ad6ab5eb8 (patch) | |
tree | 51926cec235e93eb759eacb5761e398dc50fc7f2 | |
parent | bc64d1917829623cea447871c548950460559232 (diff) | |
download | dwarvish-2439f63a1c0859fd454d4a67dc36b61ad6ab5eb8.tar.gz |
Add the 'alias' built-in command
The shell now has support for aliases (via alias foo=bar). The 'unalias'
command is also available to remove aliases. Finally,
Environment::aliases was changed to be a HashMap<String, String>,
instead of a Vec<String>.
Since the verse's verb might change (for instance, it is an environment
variable, or an alias), add another check in Poem::recite, which simply
continues, instead of running the spellchecker, if the verb is empty.
-rw-r--r-- | src/compose/environment.rs | 8 | ||||
-rw-r--r-- | src/poem/anthology.rs | 13 | ||||
-rw-r--r-- | src/poem/anthology/alias.rs | 47 | ||||
-rw-r--r-- | src/poem/recite.rs | 26 |
4 files changed, 81 insertions, 13 deletions
diff --git a/src/compose/environment.rs b/src/compose/environment.rs index 219a597..df83e4f 100644 --- a/src/compose/environment.rs +++ b/src/compose/environment.rs @@ -1,13 +1,15 @@ +use std::collections::HashMap; + pub struct Environment { - pub aliases: Vec<String>, + pub aliases: HashMap<String, String>, pub bins: Vec<String>, } impl Environment { pub fn new() -> Self { Environment { - aliases: vec![], - bins: vec![], + aliases: HashMap::new(), + bins: Vec::new(), } } } diff --git a/src/poem/anthology.rs b/src/poem/anthology.rs index 7d97ab7..94b5f6b 100644 --- a/src/poem/anthology.rs +++ b/src/poem/anthology.rs @@ -1,12 +1,13 @@ -pub mod cd; -pub mod exit; -pub mod export; -pub mod source; +mod alias; +mod cd; +mod exit; +mod export; +mod source; use crate::compose::Environment; use crate::poem::Verse; /// A static list of all the built-in commands -static INDEX: [&str; 4] = ["cd", "exit", "export", "source"]; +static INDEX: [&str; 6] = ["alias", "cd", "exit", "export", "source", "unalias"]; /// Lookup the index of a built-in command /// @@ -23,10 +24,12 @@ pub fn lookup(verb: &str) -> Option<usize> { pub fn incant(verse: &Verse, index: usize, env: &mut Environment) -> i32 { let verb = INDEX[index]; match verb { + "alias" => alias::incant(verse, &mut env.aliases), "cd" => cd::incant(verse), "exit" => exit::incant(), "export" => export::incant(verse), "source" => source::incant(verse, env), + "unalias" => alias::unincant(verse, &mut env.aliases), _ => unreachable!(), } } diff --git a/src/poem/anthology/alias.rs b/src/poem/anthology/alias.rs new file mode 100644 index 0000000..6a8e739 --- /dev/null +++ b/src/poem/anthology/alias.rs @@ -0,0 +1,47 @@ +use crate::poem::Verse; +use std::collections::HashMap; + +pub fn incant(verse: &Verse, aliases: &mut HashMap<String, String>) -> i32 { + match verse.clause() { + Some(clause) => { + for stanza in clause { + let (key, val) = match stanza.split_once("=") { + Some((key, val)) => (key, val), + None => continue, + }; + aliases.insert(String::from(key), String::from(val)); + } + } + None => { + for (key, val) in aliases { + if key.contains(' ') && val.contains(' ') { + println!("'{}'='{}'", key, val); + } else if key.contains(' ') { + println!("'{}'={}", key, val); + } else if val.contains(' ') { + println!("{}='{}'", key, val); + } else if val.is_empty() { + println!("{}=''", key); + } else { + println!("{}={}", key, val); + } + } + } + } + 0 +} + +pub fn unincant(verse: &Verse, aliases: &mut HashMap<String, String>) -> i32 { + match verse.clause() { + Some(clause) => { + for stanza in clause { + aliases.remove(&stanza); + } + } + None => { + eprintln!("unalias: not enough arguments"); + return 1; + } + } + 0 +} diff --git a/src/poem/recite.rs b/src/poem/recite.rs index e37b7c6..9a425e8 100644 --- a/src/poem/recite.rs +++ b/src/poem/recite.rs @@ -54,6 +54,18 @@ impl Reciteable for Poem { } } + // Check for aliases + match env.aliases.get(&verse.verb()) { + Some(verb) => { + let mut split: Vec<String> = verb.split(" ").map(|s| s.to_string()).collect(); + let mut old_stanza = verse.stanza.clone(); + old_stanza.remove(0); + split.append(&mut old_stanza); + verse.stanza = split; + } + None => {} + }; + // Run interal poems let v = verse.clone(); let mut new_stanza = None; @@ -129,15 +141,19 @@ impl Reciteable for Poem { // 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(&env.bins) { - env.bins = path::refresh(); + if !verse.verb().is_empty() { if !verse.spellcheck(&env.bins) { - eprintln!("dwvsh: {}: command not found", verse.verb()); + env.bins = path::refresh(); + if !verse.spellcheck(&env.bins) { + eprintln!("dwvsh: {}: command not found", verse.verb()); - if verse.meter != Rune::And { - continue; + if verse.meter != Rune::And { + continue; + } } } + } else { + continue; } if stdout { |