From dace3e39534f31adc2ef95a036fc8aee1fbaf004 Mon Sep 17 00:00:00 2001 From: mo8it Date: Mon, 6 Apr 2026 16:12:49 +0200 Subject: [PATCH] Add run_cmd --- src/editor.rs | 63 ++++++++++++++++++++------------------------ src/editor/zellij.rs | 45 +++++++++++++------------------ 2 files changed, 47 insertions(+), 61 deletions(-) diff --git a/src/editor.rs b/src/editor.rs index be24e3ef..af5c2fbe 100644 --- a/src/editor.rs +++ b/src/editor.rs @@ -8,6 +8,25 @@ use anyhow::{Context, Result, bail}; mod zellij; +fn run_cmd(cmd: &mut Command) -> Result> { + let output = cmd + .stdin(Stdio::null()) + .output() + .with_context(|| format!("Failed to run the command {cmd:?}"))?; + + if !output.status.success() { + bail!( + "The command {cmd:?} didn't run successfully\n\n\ + stdout:\n{}\n\n\ + stderr:\n{}", + str::from_utf8(&output.stdout).unwrap_or_default(), + str::from_utf8(&output.stderr).unwrap_or_default(), + ); + } + + Ok(output.stdout) +} + pub enum Editor { VSCode, Cmd(String, Vec), @@ -39,32 +58,12 @@ impl Editor { let handle = thread::Builder::new() .spawn(move || match self { Editor::VSCode => { - if !Command::new("code") - .arg(exercise_path) - .stdin(Stdio::null()) - .stdout(Stdio::null()) - .stderr(Stdio::null()) - .status() - .context("Failed to run `code` to open the current exercise file")? - .success() - { - bail!("Failed to run `code PATH` to open the current exercise file"); - } + run_cmd(Command::new("code").arg(exercise_path))?; Ok(Self::VSCode) } Editor::Cmd(program, args) => { - if !Command::new("code") - .arg(exercise_path) - .stdin(Stdio::null()) - .stdout(Stdio::null()) - .stderr(Stdio::null()) - .status() - .context("Failed to run the command from `--edit-cmd`") - .is_ok_and(|status| status.success()) - { - bail!("Failed to run the command from `--edit-cmd`"); - } + run_cmd(Command::new(&program).args(&args).arg(exercise_path))?; Ok(Self::Cmd(program, args)) } @@ -83,20 +82,14 @@ impl Editor { } } - let output = Command::new("zellij") - .arg("action") - .arg("edit") - .arg(exercise_path) - .stdin(Stdio::null()) - .stderr(Stdio::null()) - .output() - .context("Failed to run `zellij`")?; + let stdout = run_cmd( + Command::new("zellij") + .arg("action") + .arg("edit") + .arg(exercise_path), + )?; - if !output.status.success() { - bail!("Failed to open a new Zellij editor pane"); - } - - let (pane_id_str, pane_id) = zellij::parse_pane_id(&output.stdout) + let (pane_id_str, pane_id) = zellij::parse_pane_id(&stdout) .context("Failed to parse the ID of the new Zellij pane")?; Ok(Self::Zellij(Some((pane_id_str, pane_id, exercise_ind)))) diff --git a/src/editor/zellij.rs b/src/editor/zellij.rs index ffa906dc..b628a682 100644 --- a/src/editor/zellij.rs +++ b/src/editor/zellij.rs @@ -1,8 +1,10 @@ -use std::process::{Command, Stdio}; +use std::process::Command; -use anyhow::{Context, Result, bail}; +use anyhow::{Context, Result}; use serde::Deserialize; +use crate::editor::run_cmd; + #[derive(Deserialize)] struct Pane { id: u32, @@ -24,39 +26,30 @@ pub fn parse_pane_id(b: &[u8]) -> Option<(String, u32)> { } pub fn pane_open(pane_id: u32) -> Result { - let mut output = Command::new("zellij") - .arg("action") - .arg("list-panes") - .arg("-j") - .stdin(Stdio::null()) - .stderr(Stdio::null()) - .output() - .context("Failed to run `zellij action list-panes -j`")?; - - if !output.status.success() { - bail!("`zellij action list-panes -j` didn't exit successfully"); - } + let mut stdout = run_cmd( + Command::new("zellij") + .arg("action") + .arg("list-panes") + .arg("-j"), + )?; // Remove newline - output.stdout.pop(); + stdout.pop(); - let panes = serde_json::de::from_slice::>(&output.stdout) + let panes = serde_json::de::from_slice::>(&stdout) .context("Failed to parse the output of `zellij action list-panes -j`")?; Ok(panes.iter().any(|pane| pane.id == pane_id)) } pub fn close_pane(pane_id: &str) -> Result<()> { - Command::new("zellij") - .arg("action") - .arg("close-pane") - .arg("-p") - .arg(pane_id) - .stdin(Stdio::null()) - .stdout(Stdio::null()) - .stderr(Stdio::null()) - .status() - .context("Failed to run `zellij action close-pane -p ID`")?; + run_cmd( + Command::new("zellij") + .arg("action") + .arg("close-pane") + .arg("-p") + .arg(pane_id), + )?; Ok(()) }