From c4cd1e2c165c4f34ebf67fa9350f8732b2aeca13 Mon Sep 17 00:00:00 2001 From: Rory Dudley Date: Tue, 4 Jun 2024 16:25:32 -0600 Subject: Updated the way built-in commands are called/used Previously, built-in commands were fairly primitive, merely outputting STDOUT and STDERR with the print! macros. However, we need them to behave like normal programs, that is: - Acknowledge their verse's meter (forking, piping, etc.), - Ability to capture STDOUT and STDERR (>, 2>), - and Affect the currently running environment. For these reasons, the anthology was reworked, and now contains the Anthology struct, which mimics both std::process::{Child, Command}. The AnthologyStdin helper struct was also created, for built-ins to take input on STDIN, though no built-in is currently using it. Each built-ins' incant functions were updated to return a std::process::Output. It contains output from STDOUT, output from STDERR, and the exit code of the "process". A fix was also implemented for aliases, where the STDOUT and STDERR vectors were not being copied to the newly constructed verse. --- src/poem/recite.rs | 57 +++++++++++++++++++++++++++--------------------------- 1 file changed, 29 insertions(+), 28 deletions(-) (limited to 'src/poem/recite.rs') diff --git a/src/poem/recite.rs b/src/poem/recite.rs index 037906b..b33cc87 100644 --- a/src/poem/recite.rs +++ b/src/poem/recite.rs @@ -1,6 +1,5 @@ use super::Poem; use crate::compose::Environment; -use crate::path; use crate::poem::anthology; use crate::poem::elements::rune::Rune; use crate::poem::elements::stanza::Stanza; @@ -143,33 +142,35 @@ impl Reciteable for Poem { }; // Incant the verse if it's a built-in - let status = if index.is_some() { - 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 - // more - // If it is empty, just continue to the next verse - if !verse.verb().is_empty() { - // Check if the verb exists on the PATH - // 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).is_some() { - env.bins = path::refresh(); - if !verse.spellcheck(&env.bins).is_some() { - eprintln!("dwvsh: {}: command not found", verse.verb()); - - if verse.meter != Rune::And { - continue; - } - } - } - } else { - continue; - } - verse.incant(&mut out, &mut pids)? - }; + let status = + verse.incant(&mut out, &mut pids, env, anthology::lookup(&verse.verb()))?; + // let status = if index.is_some() { + // 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 + // // more + // // If it is empty, just continue to the next verse + // if !verse.verb().is_empty() { + // // Check if the verb exists on the PATH + // // 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).is_some() { + // env.bins = path::refresh(); + // if !verse.spellcheck(&env.bins).is_some() { + // eprintln!("dwvsh: {}: command not found", verse.verb()); + // + // if verse.meter != Rune::And { + // continue; + // } + // } + // } + // } else { + // continue; + // } + // verse.incant(&mut out, &mut pids, anthology::lookup(&verse.verb()))? + // }; // Break from the loop if the meter is not [Rune::Continue], and // if the status is not 0 -- cgit v1.2.3