diff options
author | Rory Dudley | 2024-04-04 00:47:24 -0600 |
---|---|---|
committer | Rory Dudley | 2024-04-04 00:47:24 -0600 |
commit | 9b3e4dd71ec1491e3580e079e9be1b42117a74c9 (patch) | |
tree | 6bf49aee7b725e87f34b124eb20def50e475c26c | |
parent | beb11773f6ac17d0b97f908311ac5989e1a0a5ae (diff) | |
download | dwarvish-9b3e4dd71ec1491e3580e079e9be1b42117a74c9.tar.gz |
Add better support for aliases
Make sure to interpret alias values as their own poems, since aliases
can be fairly complex.
Notes
Notes:
Previously, I was doing a simple find and replace for aliases within
each verse. However, aliases can be fairly complex, containing their own
range of meters, commands, and io operations. This could cause problems,
since a verse should never have, for instance, a pipe (`|`) in the
middle of it. This patch fixes it, so that we iterate once through the
poem, generating a new poem based on aliases that are found. In order to
avoid two loops in the recite() function, it might make sense to offload
handling aliases to read().
-rw-r--r-- | src/poem/anthology.rs | 6 | ||||
-rw-r--r-- | src/poem/anthology/alias.rs | 24 | ||||
-rw-r--r-- | src/poem/anthology/source.rs | 10 | ||||
-rw-r--r-- | src/poem/recite.rs | 39 |
4 files changed, 50 insertions, 29 deletions
diff --git a/src/poem/anthology.rs b/src/poem/anthology.rs index e48e6c6..79f48f2 100644 --- a/src/poem/anthology.rs +++ b/src/poem/anthology.rs @@ -43,14 +43,14 @@ pub fn lookup(verb: &str) -> Option<usize> { /// ... /// } /// ``` -pub fn incant(verse: &Verse, index: usize, env: &mut Environment) -> i32 { +pub fn incant(verse: &Verse, out: &mut String, index: usize, env: &mut Environment) -> i32 { let verb = INDEX[index]; match verb { - "alias" => alias::incant(verse, &mut env.aliases), + "alias" => alias::incant(verse, out, &mut env.aliases), "cd" => cd::incant(verse), "exit" => exit::incant(), "export" => export::incant(verse), - "source" => source::incant(verse, env), + "source" => source::incant(verse, out, env), "unalias" => alias::unincant(verse, &mut env.aliases), "unset" => export::unincant(verse), _ => unreachable!(), diff --git a/src/poem/anthology/alias.rs b/src/poem/anthology/alias.rs index 96682db..0183ec2 100644 --- a/src/poem/anthology/alias.rs +++ b/src/poem/anthology/alias.rs @@ -10,7 +10,7 @@ use std::collections::HashMap; /// ```sh /// alias vim=nvim /// ``` -pub fn incant(verse: &Verse, aliases: &mut HashMap<String, String>) -> i32 { +pub fn incant(verse: &Verse, out: &mut String, aliases: &mut HashMap<String, String>) -> i32 { match verse.clause() { Some(clause) => { for stanza in clause { @@ -22,18 +22,26 @@ pub fn incant(verse: &Verse, aliases: &mut HashMap<String, String>) -> i32 { } } None => { + let mut lines = Vec::new(); for (key, val) in aliases { - if key.contains(' ') && val.contains(' ') { - println!("'{}'='{}'", key, val); + let line = if key.contains(' ') && val.contains(' ') { + format!("'{}'='{}'", key, val) } else if key.contains(' ') { - println!("'{}'={}", key, val); + format!("'{}'={}", key, val) } else if val.contains(' ') { - println!("{}='{}'", key, val); + format!("{}='{}'", key, val) } else if val.is_empty() { - println!("{}=''", key); + format!("{}=''", key) } else { - println!("{}={}", key, val); - } + format!("{}={}", key, val) + }; + lines.push(line); + } + + if verse.couplet { + *out = lines.join("\n"); + } else { + println!("{}", lines.join("\n")); } } } diff --git a/src/poem/anthology/source.rs b/src/poem/anthology/source.rs index ed4ed13..77d1330 100644 --- a/src/poem/anthology/source.rs +++ b/src/poem/anthology/source.rs @@ -12,7 +12,7 @@ use std::fs; /// ```sh /// source ~/.dwvshrc /// ``` -pub fn incant(verse: &Verse, env: &mut Environment) -> i32 { +pub fn incant(verse: &Verse, out: &mut String, env: &mut Environment) -> i32 { let files = match verse.clause() { Some(clause) => clause, None => { @@ -42,13 +42,15 @@ pub fn incant(verse: &Verse, env: &mut Environment) -> i32 { } }; - match poem.recite(env, None) { - Ok(_) => {} + let stdout = if verse.couplet { Some(true) } else { None }; + + *out = match poem.recite(env, stdout) { + Ok(out) => out, Err(e) => { eprintln!("dwvsh: {}", e.to_string().to_lowercase()); continue; } - } + }; } 0 diff --git a/src/poem/recite.rs b/src/poem/recite.rs index 45d4d2e..1f24d14 100644 --- a/src/poem/recite.rs +++ b/src/poem/recite.rs @@ -4,6 +4,7 @@ use crate::compose::Environment; use crate::path; use crate::poem::anthology; use crate::poem::elements::rune::Rune; +use crate::poem::read::Readable; use std::env; use std::{ io, @@ -25,8 +26,30 @@ impl Reciteable for Poem { // Keep track of pids for background processes let mut pids: Arc<Mutex<Vec<i32>>> = Arc::new(Mutex::new(Vec::new())); - // Loop through each verse in the poem + // Check for aliases + let mut vv = Poem::new(); for verse in self.iter() { + let alias = match env.aliases.get(&verse.verb()) { + Some(alias) => alias, + None => { + vv.push(verse.clone()); + continue; + } + } + .to_string(); + + let mut poem = Poem::read(alias).unwrap(); + let len = poem.len(); + for (i, new_verse) in poem.iter_mut().enumerate() { + if verse.clause().is_some() && i + 1 == len { + new_verse.stanza.append(&mut verse.clause().unwrap()); + } + vv.push(new_verse.clone()); + } + } + + // Loop through each verse in the poem + for verse in vv.iter() { // Verse may need to be mutable let mut verse = verse.clone(); @@ -59,18 +82,6 @@ impl Reciteable for Poem { *word = word.replace('\x0e', "$"); } - // 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 => {} - }; - // Check if verse is a builtin let index = anthology::lookup(&verse.verb()); @@ -142,7 +153,7 @@ impl Reciteable for Poem { // Incant the verse if it's a built-in let status = if index.is_some() { - anthology::incant(&verse, index.unwrap(), env) + anthology::incant(&verse, &mut out, index.unwrap(), env) } else { // Checking for environment variables and running internal // poems may mean that the verb is empty now, so check it once |