shell: Move changes outside so we can properly handle errors

pull/689/head
Blaž Hrastnik 3 years ago
parent e772808a5b
commit 4a76ea8f88

@ -4346,9 +4346,10 @@ fn shell(cx: &mut Context, prompt: &str, behavior: ShellBehavior) {
if event == PromptEvent::Validate { if event == PromptEvent::Validate {
let (view, doc) = current!(cx.editor); let (view, doc) = current!(cx.editor);
let selection = doc.selection(view.id); let selection = doc.selection(view.id);
let mut error: Option<&str> = None;
let transaction = let mut changes = Vec::with_capacity(selection.len());
Transaction::change_by_selection(doc.text(), selection, |range| {
for range in selection.ranges() {
let mut process; let mut process;
match Command::new(&shell[0]) match Command::new(&shell[0])
.args(&shell[1..]) .args(&shell[1..])
@ -4361,8 +4362,8 @@ fn shell(cx: &mut Context, prompt: &str, behavior: ShellBehavior) {
Ok(p) => process = p, Ok(p) => process = p,
Err(e) => { Err(e) => {
log::error!("Failed to start shell: {}", e); log::error!("Failed to start shell: {}", e);
error = Some("Failed to start shell"); cx.editor.set_error("Failed to start shell".to_owned());
return (0, 0, None); return;
} }
} }
if pipe { if pipe {
@ -4376,21 +4377,19 @@ fn shell(cx: &mut Context, prompt: &str, behavior: ShellBehavior) {
if !output.status.success() { if !output.status.success() {
let stderr = output.stderr; let stderr = output.stderr;
if !stderr.is_empty() { if !stderr.is_empty() {
log::error!( log::error!("Shell error: {}", String::from_utf8_lossy(&stderr));
"Shell error: {}",
String::from_utf8_lossy(&stderr)
);
} }
error = Some("Command failed"); cx.editor.set_error("Command failed".to_owned());
return (0, 0, None); return;
} }
let stdout = output.stdout; let stdout = output.stdout;
let tendril; let tendril;
match Tendril::try_from_byte_slice(&stdout) { match Tendril::try_from_byte_slice(&stdout) {
Ok(t) => tendril = t, Ok(t) => tendril = t,
Err(_) => { Err(_) => {
error = Some("Process did not output valid UTF-8"); cx.editor
return (0, 0, None); .set_error("Process did not output valid UTF-8".to_owned());
return;
} }
} }
let (from, to) = match behavior { let (from, to) = match behavior {
@ -4399,21 +4398,21 @@ fn shell(cx: &mut Context, prompt: &str, behavior: ShellBehavior) {
ShellBehavior::Append => (range.to(), range.to()), ShellBehavior::Append => (range.to(), range.to()),
_ => (range.from(), range.from()), _ => (range.from(), range.from()),
}; };
(from, to, Some(tendril)) changes.push((from, to, Some(tendril)));
} else { } else {
// if the process exits successfully, keep the selection, otherwise delete it. // if the process exits successfully, keep the selection, otherwise delete it.
let keep = output.status.success(); let keep = output.status.success();
( changes.push((
range.from(), range.from(),
if keep { range.from() } else { range.to() }, if keep { range.from() } else { range.to() },
None, None,
) ));
} }
}); }
let transaction = Transaction::change(doc.text(), changes.into_iter());
if let Some(error) = error { if behavior != ShellBehavior::Ignore {
cx.editor.set_error(error.to_owned());
} else if behavior != ShellBehavior::Ignore {
doc.apply(&transaction, view.id); doc.apply(&transaction, view.id);
doc.append_changes_to_history(view.id); doc.append_changes_to_history(view.id);
} }

Loading…
Cancel
Save