summaryrefslogtreecommitdiffstats
path: root/src/poem/anthology
diff options
context:
space:
mode:
Diffstat (limited to 'src/poem/anthology')
-rw-r--r--src/poem/anthology/alias.rs56
-rw-r--r--src/poem/anthology/cd.rs53
-rw-r--r--src/poem/anthology/exit.rs3
-rw-r--r--src/poem/anthology/export.rs47
-rw-r--r--src/poem/anthology/source.rs98
-rw-r--r--src/poem/anthology/which.rs44
6 files changed, 238 insertions, 63 deletions
diff --git a/src/poem/anthology/alias.rs b/src/poem/anthology/alias.rs
index 45ee7f2..0746b59 100644
--- a/src/poem/anthology/alias.rs
+++ b/src/poem/anthology/alias.rs
@@ -1,6 +1,7 @@
-use crate::poem::Verse;
use std::collections::BTreeMap;
use std::collections::HashMap;
+use std::os::unix::process::ExitStatusExt;
+use std::process::{ExitStatus, Output};
/// alias
///
@@ -11,8 +12,15 @@ use std::collections::HashMap;
/// ```sh
/// alias vim=nvim
/// ```
-pub fn incant(verse: &Verse, out: &mut Vec<u8>, aliases: &mut HashMap<String, String>) -> i32 {
- match verse.clause() {
+pub fn incant(
+ clause: &Option<Vec<String>>,
+ uout: bool,
+ aliases: &mut HashMap<String, String>,
+) -> Output {
+ let status = 0;
+ let mut out: Vec<u8> = Vec::new();
+ let err: Vec<u8> = Vec::new();
+ match clause {
Some(clause) => {
for stanza in clause {
let (key, val) = match stanza.split_once("=") {
@@ -24,7 +32,7 @@ pub fn incant(verse: &Verse, out: &mut Vec<u8>, aliases: &mut HashMap<String, St
}
None => {
let mut lines = Vec::new();
- let sorted: BTreeMap<_, _> = aliases.into_iter().collect();
+ let sorted: BTreeMap<_, _> = aliases.iter().collect();
for (key, val) in sorted {
let line = if key.contains(' ') && val.contains(' ') {
format!("'{}'='{}'", key, val)
@@ -40,14 +48,19 @@ pub fn incant(verse: &Verse, out: &mut Vec<u8>, aliases: &mut HashMap<String, St
lines.push(line);
}
- if verse.couplet > 0 {
- *out = format!("{}\n", lines.join("\n")).as_bytes().to_vec();
+ if uout {
+ out.append(&mut format!("{}\n", lines.join("\n")).as_bytes().to_vec());
} else {
println!("{}", lines.join("\n"));
}
}
}
- 0
+
+ Output {
+ status: ExitStatus::from_raw(status),
+ stdout: out,
+ stderr: err,
+ }
}
/// unalias
@@ -59,17 +72,34 @@ pub fn incant(verse: &Verse, out: &mut Vec<u8>, aliases: &mut HashMap<String, St
/// ```sh
/// unalias vim
/// ```
-pub fn unincant(verse: &Verse, aliases: &mut HashMap<String, String>) -> i32 {
- match verse.clause() {
+pub fn unincant(
+ clause: &Option<Vec<String>>,
+ uerr: bool,
+ aliases: &mut HashMap<String, String>,
+) -> Output {
+ let out: Vec<u8> = Vec::new();
+ let mut err: Vec<u8> = Vec::new();
+
+ let status = match clause {
Some(clause) => {
for stanza in clause {
- aliases.remove(&stanza);
+ aliases.remove(stanza);
}
+ 0
}
None => {
- eprintln!("unalias: not enough arguments");
- return 1;
+ if uerr {
+ err.append(&mut "unalias: not enough arguments".as_bytes().to_vec());
+ } else {
+ eprintln!("unalias: not enough arguments");
+ }
+ 1
}
+ };
+
+ Output {
+ status: ExitStatus::from_raw(status),
+ stdout: out,
+ stderr: err,
}
- 0
}
diff --git a/src/poem/anthology/cd.rs b/src/poem/anthology/cd.rs
index 5b39359..bdf04f6 100644
--- a/src/poem/anthology/cd.rs
+++ b/src/poem/anthology/cd.rs
@@ -1,5 +1,6 @@
-use crate::poem::Verse;
use std::env;
+use std::os::unix::process::ExitStatusExt;
+use std::process::{ExitStatus, Output};
/// cd
///
@@ -12,27 +13,57 @@ use std::env;
/// ```sh
/// cd ~/.config # Change into /home/<user>/.config
/// ```
-pub fn incant(verse: &Verse) -> i32 {
- let path = match verse.clause() {
+pub fn incant(clause: &Option<Vec<String>>, uerr: bool) -> Output {
+ let status;
+ let out: Vec<u8> = Vec::new();
+ let mut err: Vec<u8> = Vec::new();
+ let path = match clause {
Some(path) => path[0].to_string(),
None => match env::var("HOME") {
Ok(val) => val,
Err(_) => {
- eprintln!("cd: unknown home, staying in pwd");
- return 1;
+ status = 1;
+ if uerr {
+ err.append(&mut "cd: unknown home, staying in pwd\n".as_bytes().to_vec());
+ } else {
+ eprintln!("cd: unknown home, staying in pwd");
+ }
+ return Output {
+ status: ExitStatus::from_raw(status),
+ stdout: out,
+ stderr: err,
+ };
}
},
};
- match std::env::set_current_dir(&path) {
+ status = match std::env::set_current_dir(&path) {
Ok(_) => 0,
Err(e) => {
- eprintln!(
- "cd: unable to change into {}: {}",
- path,
- e.to_string().to_lowercase()
- );
+ if uerr {
+ err.append(
+ &mut format!(
+ "cd: unable to change into {}: {}\n",
+ path,
+ e.to_string().to_lowercase()
+ )
+ .as_bytes()
+ .to_vec(),
+ );
+ } else {
+ eprintln!(
+ "cd: unable to change into {}: {}",
+ path,
+ e.to_string().to_lowercase()
+ );
+ }
1
}
+ };
+
+ Output {
+ status: ExitStatus::from_raw(status),
+ stdout: out,
+ stderr: err,
}
}
diff --git a/src/poem/anthology/exit.rs b/src/poem/anthology/exit.rs
index 46fe13c..6bbaa33 100644
--- a/src/poem/anthology/exit.rs
+++ b/src/poem/anthology/exit.rs
@@ -1,4 +1,5 @@
use std::process::exit;
+use std::process::Output;
/// exit
///
@@ -7,6 +8,6 @@ use std::process::exit;
/// # Aliases
/// * exit
/// * quit
-pub fn incant() -> i32 {
+pub fn incant() -> Output {
exit(0);
}
diff --git a/src/poem/anthology/export.rs b/src/poem/anthology/export.rs
index aa5a894..35a24ae 100644
--- a/src/poem/anthology/export.rs
+++ b/src/poem/anthology/export.rs
@@ -1,6 +1,7 @@
-use crate::poem::Verse;
use std::collections::BTreeMap;
use std::env;
+use std::os::unix::process::ExitStatusExt;
+use std::process::{ExitStatus, Output};
/// export
///
@@ -15,8 +16,11 @@ use std::env;
/// ```sh
/// export FOO=BAR
/// ```
-pub fn incant(verse: &Verse) -> i32 {
- match verse.clause() {
+pub fn incant(clause: &Option<Vec<String>>, uout: bool) -> Output {
+ let status = 0;
+ let mut out: Vec<u8> = Vec::new();
+ let err: Vec<u8> = Vec::new();
+ match clause {
Some(clause) => {
for stanza in clause {
let (key, val) = match stanza.split_once("=") {
@@ -27,14 +31,25 @@ pub fn incant(verse: &Verse) -> i32 {
}
}
None => {
+ let mut lines = Vec::new();
let sorted: BTreeMap<_, _> = env::vars().into_iter().collect();
for (key, val) in sorted {
- println!("{}={}", key, val);
+ lines.push(format!("{}={}", key, val));
+ }
+
+ if uout {
+ out.append(&mut format!("{}\n", lines.join("\n")).as_bytes().to_vec());
+ } else {
+ println!("{}", lines.join("\n"));
}
}
}
- 0
+ Output {
+ status: ExitStatus::from_raw(status),
+ stdout: out,
+ stderr: err,
+ }
}
/// unset
@@ -47,17 +62,29 @@ pub fn incant(verse: &Verse) -> i32 {
/// ```sh
/// unset FOO
/// ```
-pub fn unincant(verse: &Verse) -> i32 {
- match verse.clause() {
+pub fn unincant(clause: &Option<Vec<String>>, uerr: bool) -> Output {
+ let mut status = 0;
+ let out: Vec<u8> = Vec::new();
+ let mut err: Vec<u8> = Vec::new();
+ match clause {
Some(clause) => {
for stanza in clause {
env::remove_var(stanza);
}
}
None => {
- eprintln!("unset: not enough arguments");
- return 1;
+ status = 1;
+ if uerr {
+ err.append(&mut "unset: not enough arguments\n".as_bytes().to_vec());
+ } else {
+ eprintln!("unset: not enough arguments");
+ }
}
}
- 0
+
+ Output {
+ status: ExitStatus::from_raw(status),
+ stdout: out,
+ stderr: err,
+ }
}
diff --git a/src/poem/anthology/source.rs b/src/poem/anthology/source.rs
index 3c81110..0ed759c 100644
--- a/src/poem/anthology/source.rs
+++ b/src/poem/anthology/source.rs
@@ -1,7 +1,8 @@
use crate::compose::Environment;
-use crate::poem::Verse;
use crate::poem::{read::Readable, recite::Reciteable, Poem};
use std::fs;
+use std::os::unix::process::ExitStatusExt;
+use std::process::{ExitStatus, Output};
/// source
///
@@ -12,12 +13,29 @@ use std::fs;
/// ```sh
/// source ~/.dwvshrc
/// ```
-pub fn incant(verse: &Verse, out: &mut Vec<u8>, env: &mut Environment) -> i32 {
- let files = match verse.clause() {
+pub fn incant(
+ clause: &Option<Vec<String>>,
+ uout: bool,
+ uerr: bool,
+ env: &mut Environment,
+) -> Output {
+ let mut status = 0;
+ let mut out: Vec<u8> = Vec::new();
+ let mut err: Vec<u8> = Vec::new();
+ let files = match clause {
Some(clause) => clause,
None => {
- eprintln!("source: not enough arguments");
- return 1;
+ status = 1;
+ if uerr {
+ err.append(&mut "source: not enough arguments\n".as_bytes().to_vec());
+ } else {
+ eprintln!("source: not enough arguments");
+ }
+ return Output {
+ status: ExitStatus::from_raw(status),
+ stdout: out,
+ stderr: err,
+ };
}
};
@@ -25,31 +43,77 @@ pub fn incant(verse: &Verse, out: &mut Vec<u8>, env: &mut Environment) -> i32 {
let poetry = match fs::read_to_string(&file) {
Ok(poetry) => poetry,
Err(e) => {
- eprintln!(
- "source: could not load {}: {}",
- file,
- e.to_string().to_lowercase()
- );
- return 127;
+ status = 127;
+ if uerr {
+ err.append(
+ &mut format!(
+ "source: could not load {}: {}\n",
+ file,
+ e.to_string().to_lowercase()
+ )
+ .as_bytes()
+ .to_vec(),
+ );
+ } else {
+ eprintln!(
+ "source: could not load {}: {}",
+ file,
+ e.to_string().to_lowercase()
+ );
+ }
+ return Output {
+ status: ExitStatus::from_raw(status),
+ stdout: out,
+ stderr: err,
+ };
}
};
let poem = match Poem::read(poetry, env) {
Ok(poem) => poem,
Err(e) => {
- eprintln!("dwvsh: {}", e.to_string().to_lowercase());
+ if uerr {
+ err.append(
+ &mut format!("dwvsh: {}", e.to_string().to_lowercase())
+ .as_bytes()
+ .to_vec(),
+ );
+ } else {
+ eprintln!("dwvsh: {}", e.to_string().to_lowercase());
+ }
continue;
}
};
- *out = match poem.recite(env) {
- Ok(out) => out,
+ status = match poem.recite(env) {
+ Ok(mut sout) => {
+ if uout {
+ out.append(&mut sout);
+ } else {
+ if !sout.is_empty() {
+ println!("{}", String::from_utf8_lossy(&sout));
+ }
+ }
+ 0
+ }
Err(e) => {
- eprintln!("dwvsh: {}", e.to_string().to_lowercase());
- continue;
+ if uerr {
+ err.append(
+ &mut format!("dwvsh: {}", e.to_string().to_lowercase())
+ .as_bytes()
+ .to_vec(),
+ );
+ } else {
+ eprintln!("dwvsh: {}", e.to_string().to_lowercase());
+ }
+ 1
}
};
}
- 0
+ Output {
+ status: ExitStatus::from_raw(status),
+ stdout: out,
+ stderr: err,
+ }
}
diff --git a/src/poem/anthology/which.rs b/src/poem/anthology/which.rs
index 515b52e..6fe709c 100644
--- a/src/poem/anthology/which.rs
+++ b/src/poem/anthology/which.rs
@@ -1,16 +1,20 @@
use crate::compose::Environment;
use crate::poem::Verse;
+use std::os::unix::process::ExitStatusExt;
+use std::process::{ExitStatus, Output};
-pub fn incant(verse: &Verse, out: &mut Vec<u8>, env: &Environment) -> i32 {
+pub fn incant(clause: &Option<Vec<String>>, uout: bool, uerr: bool, env: &Environment) -> Output {
let mut status = 0;
- match verse.clause() {
+ let mut out: Vec<u8> = Vec::new();
+ let mut err: Vec<u8> = Vec::new();
+ match clause {
Some(clause) => {
let mut output: String;
for word in clause {
// Check if it's an alias
- if env.aliases.contains_key(&word) {
- output = format!("{}: aliased to {}\n", word, env.aliases.get(&word).unwrap());
- if verse.couplet > 0 {
+ if env.aliases.contains_key(word) {
+ output = format!("{}: aliased to {}\n", word, env.aliases.get(word).unwrap());
+ if uout {
out.append(&mut output.as_bytes().to_vec());
} else {
print!("{}", output);
@@ -22,7 +26,7 @@ pub fn incant(verse: &Verse, out: &mut Vec<u8>, env: &Environment) -> i32 {
match super::lookup(&word) {
Some(_) => {
output = format!("{}: shell built-in command\n", word);
- if verse.couplet > 0 {
+ if uout {
out.append(&mut output.as_bytes().to_vec());
} else {
print!("{}", output);
@@ -38,7 +42,7 @@ pub fn incant(verse: &Verse, out: &mut Vec<u8>, env: &Environment) -> i32 {
match verb.spellcheck(&env.bins) {
Some(i) => {
output = format!("{}\n", env.bins[i]);
- if verse.couplet > 0 {
+ if uout {
out.append(&mut output.as_bytes().to_vec());
} else {
print!("{}", output);
@@ -47,15 +51,33 @@ pub fn incant(verse: &Verse, out: &mut Vec<u8>, env: &Environment) -> i32 {
None => {
output = format!("{} not found\n", word);
status = 1;
- eprint!("{}", output);
+ if uerr {
+ err.append(&mut output.as_bytes().to_vec());
+ } else {
+ eprint!("{}", output);
+ }
}
}
}
}
None => {
- eprintln!("which: not enough arguments");
- return 1;
+ status = 1;
+ if uerr {
+ err.append(&mut "which: not enough arguments".as_bytes().to_vec());
+ } else {
+ eprintln!("which: not enough arguments");
+ }
+ return Output {
+ status: ExitStatus::from_raw(status),
+ stdout: out,
+ stderr: err,
+ };
}
}
- status
+
+ Output {
+ status: ExitStatus::from_raw(status),
+ stdout: out,
+ stderr: err,
+ }
}