mirror of
https://github.com/helix-editor/helix.git
synced 2024-11-22 09:26:19 +04:00
Prevent shell_keep_pipe
from stopping on nonzero exit status code (#9817)
The `shell_impl` and `shell_impl_async` functions no longer return `success` because it was always `true`. If the command didn't succeed both functions would return an `Err`. This was also the reason, why `shell_keep_pipe` didn't work. It relied upon the value of `success` and aborted in case of an `Err`. It now removes any selection for which `shell_impl` returns `Err`. If the command always fails, the selections are preserved and an error message is displayed in the status bar.
This commit is contained in:
parent
485c5cf0b8
commit
5b8bfc5476
@ -5436,16 +5436,9 @@ fn shell_keep_pipe(cx: &mut Context) {
|
||||
|
||||
for (i, range) in selection.ranges().iter().enumerate() {
|
||||
let fragment = range.slice(text);
|
||||
let (_output, success) = match shell_impl(shell, input, Some(fragment.into())) {
|
||||
Ok(result) => result,
|
||||
Err(err) => {
|
||||
cx.editor.set_error(err.to_string());
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
// if the process exits successfully, keep the selection
|
||||
if success {
|
||||
if let Err(err) = shell_impl(shell, input, Some(fragment.into())) {
|
||||
log::debug!("Shell command failed: {}", err);
|
||||
} else {
|
||||
ranges.push(*range);
|
||||
if i >= old_index && index.is_none() {
|
||||
index = Some(ranges.len() - 1);
|
||||
@ -5464,7 +5457,7 @@ fn shell_keep_pipe(cx: &mut Context) {
|
||||
);
|
||||
}
|
||||
|
||||
fn shell_impl(shell: &[String], cmd: &str, input: Option<Rope>) -> anyhow::Result<(Tendril, bool)> {
|
||||
fn shell_impl(shell: &[String], cmd: &str, input: Option<Rope>) -> anyhow::Result<Tendril> {
|
||||
tokio::task::block_in_place(|| helix_lsp::block_on(shell_impl_async(shell, cmd, input)))
|
||||
}
|
||||
|
||||
@ -5472,7 +5465,7 @@ async fn shell_impl_async(
|
||||
shell: &[String],
|
||||
cmd: &str,
|
||||
input: Option<Rope>,
|
||||
) -> anyhow::Result<(Tendril, bool)> {
|
||||
) -> anyhow::Result<Tendril> {
|
||||
use std::process::Stdio;
|
||||
use tokio::process::Command;
|
||||
ensure!(!shell.is_empty(), "No shell set");
|
||||
@ -5535,7 +5528,7 @@ async fn shell_impl_async(
|
||||
let str = std::str::from_utf8(&output.stdout)
|
||||
.map_err(|_| anyhow!("Process did not output valid UTF-8"))?;
|
||||
let tendril = Tendril::from(str);
|
||||
Ok((tendril, output.status.success()))
|
||||
Ok(tendril)
|
||||
}
|
||||
|
||||
fn shell(cx: &mut compositor::Context, cmd: &str, behavior: &ShellBehavior) {
|
||||
@ -5556,14 +5549,14 @@ fn shell(cx: &mut compositor::Context, cmd: &str, behavior: &ShellBehavior) {
|
||||
let mut shell_output: Option<Tendril> = None;
|
||||
let mut offset = 0isize;
|
||||
for range in selection.ranges() {
|
||||
let (output, success) = if let Some(output) = shell_output.as_ref() {
|
||||
(output.clone(), true)
|
||||
let output = if let Some(output) = shell_output.as_ref() {
|
||||
output.clone()
|
||||
} else {
|
||||
let fragment = range.slice(text);
|
||||
match shell_impl(shell, cmd, pipe.then(|| fragment.into())) {
|
||||
Ok(result) => {
|
||||
if !pipe {
|
||||
shell_output = Some(result.0.clone());
|
||||
shell_output = Some(result.clone());
|
||||
}
|
||||
result
|
||||
}
|
||||
@ -5574,11 +5567,6 @@ fn shell(cx: &mut compositor::Context, cmd: &str, behavior: &ShellBehavior) {
|
||||
}
|
||||
};
|
||||
|
||||
if !success {
|
||||
cx.editor.set_error("Command failed");
|
||||
return;
|
||||
}
|
||||
|
||||
let output_len = output.chars().count();
|
||||
|
||||
let (from, to, deleted_len) = match behavior {
|
||||
|
@ -2261,7 +2261,7 @@ fn run_shell_command(
|
||||
let args = args.join(" ");
|
||||
|
||||
let callback = async move {
|
||||
let (output, success) = shell_impl_async(&shell, &args, None).await?;
|
||||
let output = shell_impl_async(&shell, &args, None).await?;
|
||||
let call: job::Callback = Callback::EditorCompositor(Box::new(
|
||||
move |editor: &mut Editor, compositor: &mut Compositor| {
|
||||
if !output.is_empty() {
|
||||
@ -2274,11 +2274,7 @@ fn run_shell_command(
|
||||
));
|
||||
compositor.replace_or_push("shell", popup);
|
||||
}
|
||||
if success {
|
||||
editor.set_status("Command succeeded");
|
||||
} else {
|
||||
editor.set_error("Command failed");
|
||||
}
|
||||
editor.set_status("Command succeeded");
|
||||
},
|
||||
));
|
||||
Ok(call)
|
||||
|
Loading…
Reference in New Issue
Block a user