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) {
app.command_result = match run_inner(app) {
Ok(c) => c,
Err(e) => CommandResult {
status_success: false,
stdout: vec![],
stderr: format!("{e:?}").as_bytes().to_vec(),
},
};
match run_inner(app) {
Ok(c) => {
// If there was no stdout and the command failed, don't touch stdout
if !c.status_success && c.stdout.is_empty() {
app.command_result.stderr = c.stderr;
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> {
let args = match shellwords::split(&app.cmdline) {
Ok(a) => a,
Err(e) => {
bail!("Argument error: {e:?}");
}
};
let mut child = Command::new(&app.command)
.args(&app.hidden_options)
.args(args)
let mut command = Command::new(&app.command);
command
.stdin(Stdio::piped())
.stdout(Stdio::piped())
.stderr(Stdio::piped())
.spawn()
.context("Could not spawn child process")?;
.args(&app.hidden_options);
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 text_orig_clone = app.text_orig.clone();

View File

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