[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH] Added the 'builtin' built-in command


Specifically run one of dwvsh's built-in commands, rather than whatever
command spellcheck() finds on the $PATH.
---
 src/poem/anthology.rs         |  6 ++-
 src/poem/anthology/builtin.rs | 82 +++++++++++++++++++++++++++++++++++
 2 files changed, 86 insertions(+), 2 deletions(-)
 create mode 100644 src/poem/anthology/builtin.rs

diff --git a/src/poem/anthology.rs b/src/poem/anthology.rs
index 0026b8d..7f13e77 100644
--- a/src/poem/anthology.rs
+++ b/src/poem/anthology.rs
@@ -1,4 +1,5 @@
 mod alias;
+mod builtin;
 mod cd;
 mod exit;
 mod export;
@@ -9,8 +10,8 @@ use std::io;
 use std::process::{Output, Stdio};
 
 /// A static list of all the built-in commands
-static INDEX: [&str; 8] = [
-    "alias", "cd", "exit", "export", "source", "unalias", "unset", "which",
+static INDEX: [&str; 9] = [
+    "alias", "builtin", "cd", "exit", "export", "source", "unalias", "unset", "which",
 ];
 
 /// Lookup the index of a built-in command
@@ -170,6 +171,7 @@ impl Anthology {
         // Incant the built-in and set the output
         self.output = Some(match self.verb.as_str() {
             "alias" => alias::incant(&self.clause, self.uout, &mut env.aliases),
+            "builtin" => builtin::incant(&self.clause, self.uout, self.uerr, env),
             "cd" => cd::incant(&self.clause, self.uerr),
             "exit" => exit::incant(),
             "export" => export::incant(&self.clause, self.uout),
diff --git a/src/poem/anthology/builtin.rs b/src/poem/anthology/builtin.rs
new file mode 100644
index 0000000..25ec3c2
--- /dev/null
+++ b/src/poem/anthology/builtin.rs
@@ -0,0 +1,82 @@
+use crate::poem::anthology::alias;
+use crate::poem::anthology::cd;
+use crate::poem::anthology::exit;
+use crate::poem::anthology::export;
+use crate::poem::anthology::source;
+use crate::poem::anthology::which;
+use crate::Environment;
+use std::os::unix::process::ExitStatusExt;
+use std::process::{ExitStatus, Output};
+
+pub fn incant(
+    clause: &Option<Vec<String>>,
+    uout: bool,
+    uerr: bool,
+    env: &mut Environment,
+) -> Output {
+    let out: Vec<u8> = Vec::new();
+    let mut err: Vec<u8> = Vec::new();
+
+    let clause = match clause {
+        Some(clause) => clause.clone(),
+        None => {
+            if uerr {
+                err.append(
+                    &mut "builtin: must provide a builtin shell function to call"
+                        .as_bytes()
+                        .to_vec(),
+                );
+            } else {
+                eprintln!("builtin: must provide a builtin shell function to call");
+            }
+
+            return Output {
+                status: ExitStatus::from_raw(1),
+                stdout: out,
+                stderr: err,
+            };
+        }
+    };
+
+    let verb = match clause.first() {
+        Some(verb) => verb.as_str(),
+        None => {
+            if uerr {
+                err.append(
+                    &mut "builtin: must provide a builtin shell function to call"
+                        .as_bytes()
+                        .to_vec(),
+                );
+            } else {
+                eprintln!("builtin: must provide a builtin shell function to call");
+            }
+
+            return Output {
+                status: ExitStatus::from_raw(1),
+                stdout: out,
+                stderr: err,
+            };
+        }
+    };
+
+    let clause = if clause.is_empty() || clause.len() == 1 {
+        None
+    } else {
+        let mut c = clause.clone();
+        c.remove(0);
+        Some(clause.clone())
+    };
+
+    match verb {
+        "alias" => alias::incant(&clause, uout, &mut env.aliases),
+        "builtin" => incant(&clause, uout, uerr, env),
+        "cd" => cd::incant(&clause, uerr),
+        "exit" => exit::incant(),
+        "export" => export::incant(&clause, uout),
+        "source" => source::incant(&clause, uout, uerr, env),
+        "unalias" => alias::unincant(&clause, uerr, &mut env.aliases),
+        "unset" => export::unincant(&clause, uerr),
+        "which" => which::incant(&clause, uout, uerr, env),
+        _ => unreachable!(),
+    }
+}
-- 
cheers!~
Rory




Archive administrator: postmaster AT dwarvish DOT org