Add shell handling

This commit is contained in:
Austen Adler 2022-12-17 11:25:15 -05:00
parent 7c1c78728c
commit 2b11951166
2 changed files with 56 additions and 20 deletions

View File

@ -25,32 +25,46 @@ impl Default for CommandResult {
} }
pub fn run(app: &mut App) { pub fn run(app: &mut App) {
app.command_result = match run_inner(app) { match run_inner(app) {
Ok(c) => c, Ok(c) => {
Err(e) => CommandResult { // If there was no stdout and the command failed, don't touch stdout
status_success: false, if !c.status_success && c.stdout.is_empty() {
stdout: vec![], app.command_result.stderr = c.stderr;
stderr: format!("{e:?}").as_bytes().to_vec(), app.command_result.status_success = c.status_success;
}, } else {
}; app.command_result = c;
}
}
Err(e) => {
println!("asdf");
app.command_result.status_success = false;
app.command_result.stderr = e.to_string().as_bytes().to_vec();
}
}
} }
fn run_inner(app: &mut App) -> Result<CommandResult> { fn run_inner(app: &mut App) -> Result<CommandResult> {
let args = match shellwords::split(&app.cmdline) { let mut command = Command::new(&app.command);
Ok(a) => a, command
Err(e) => {
bail!("Argument error: {e:?}");
}
};
let mut child = Command::new(&app.command)
.args(&app.hidden_options)
.args(args)
.stdin(Stdio::piped()) .stdin(Stdio::piped())
.stdout(Stdio::piped()) .stdout(Stdio::piped())
.stderr(Stdio::piped()) .stderr(Stdio::piped())
.spawn() .args(&app.hidden_options);
.context("Could not spawn child process")?;
if app.wordsplit {
match shellwords::split(&app.cmdline) {
Ok(a) => {
command.args(a);
}
Err(e) => {
bail!("Argument error: {e:?}");
}
}
} else {
// TODO: Avoid cloning here
command.arg(&app.cmdline);
}
let mut child = command.spawn().context("Could not spawn child process")?;
let mut stdin = child.stdin.take().context("Could not take stdin")?; let mut stdin = child.stdin.take().context("Could not take stdin")?;
let text_orig_clone = app.text_orig.clone(); let text_orig_clone = app.text_orig.clone();

View File

@ -52,6 +52,9 @@ pub struct App {
/// Should every keystroke transform the original text? /// Should every keystroke transform the original text?
autorun: bool, autorun: bool,
/// Should wordsplitting be enabled
wordsplit: bool,
} }
impl App { impl App {
@ -61,6 +64,7 @@ impl App {
let command_result = CommandResult::default(); let command_result = CommandResult::default();
let command = template.command(); let command = template.command();
let cmdline_position = 0; let cmdline_position = 0;
let wordsplit = true;
match template { match template {
Template::Awk | Template::Generic(_) => Self { Template::Awk | Template::Generic(_) => Self {
@ -71,6 +75,17 @@ impl App {
autorun: true, autorun: true,
command, command,
hidden_options: vec![], hidden_options: vec![],
wordsplit,
},
Template::Sh(_) => Self {
cmdline: String::from(""),
cmdline_position: 0,
text_orig,
command_result,
autorun: true,
command,
hidden_options: vec!["-c"],
wordsplit: false,
}, },
Template::Jq => Self { Template::Jq => Self {
cmdline: String::from("'.'"), cmdline: String::from("'.'"),
@ -80,6 +95,7 @@ impl App {
autorun: true, autorun: true,
command, command,
hidden_options: vec!["-C"], hidden_options: vec!["-C"],
wordsplit,
}, },
Template::Grep | Template::Rg => Self { Template::Grep | Template::Rg => Self {
cmdline: String::from("''"), cmdline: String::from("''"),
@ -89,6 +105,7 @@ impl App {
autorun: true, autorun: true,
command, command,
hidden_options: vec!["--color=always"], hidden_options: vec!["--color=always"],
wordsplit,
}, },
Template::Sed => Self { Template::Sed => Self {
cmdline: String::from("'s///g'"), cmdline: String::from("'s///g'"),
@ -98,6 +115,7 @@ impl App {
autorun: true, autorun: true,
command, command,
hidden_options: vec![], hidden_options: vec![],
wordsplit,
}, },
Template::Perl => Self { Template::Perl => Self {
cmdline: String::from("-p -e 's///'"), cmdline: String::from("-p -e 's///'"),
@ -107,6 +125,7 @@ impl App {
autorun: true, autorun: true,
command, command,
hidden_options: vec![], hidden_options: vec![],
wordsplit,
}, },
} }
} }
@ -114,6 +133,7 @@ impl App {
pub enum Template { pub enum Template {
Generic(String), Generic(String),
Sh(String),
Jq, Jq,
Grep, Grep,
Rg, Rg,
@ -132,6 +152,7 @@ impl Template {
"sed" => Self::Sed, "sed" => Self::Sed,
"awk" => Self::Awk, "awk" => Self::Awk,
"perl" => Self::Perl, "perl" => Self::Perl,
s @ "sh" | s @ "bash" | s @ "zsh" | s @ "dash" => Self::Sh(s.to_string()),
c => Self::Generic(c.to_string()), c => Self::Generic(c.to_string()),
} }
} }
@ -140,6 +161,7 @@ impl Template {
pub fn command(&self) -> String { pub fn command(&self) -> String {
match self { match self {
Self::Generic(c) => c.to_string(), Self::Generic(c) => c.to_string(),
Self::Sh(s) => s.to_string(),
Self::Jq => String::from("jq"), Self::Jq => String::from("jq"),
Self::Grep => String::from("grep"), Self::Grep => String::from("grep"),
Self::Rg => String::from("rg"), Self::Rg => String::from("rg"),