Add shell handling
This commit is contained in:
parent
7c1c78728c
commit
2b11951166
@ -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();
|
||||||
|
22
src/main.rs
22
src/main.rs
@ -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"),
|
||||||
|
Loading…
Reference in New Issue
Block a user