mirror of
https://github.com/rust-lang/rustlings.git
synced 2026-05-15 17:58:44 +00:00
Add run_cmd
This commit is contained in:
parent
c9ccedcff6
commit
dace3e3953
@ -8,6 +8,25 @@ use anyhow::{Context, Result, bail};
|
|||||||
|
|
||||||
mod zellij;
|
mod zellij;
|
||||||
|
|
||||||
|
fn run_cmd(cmd: &mut Command) -> Result<Vec<u8>> {
|
||||||
|
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 {
|
pub enum Editor {
|
||||||
VSCode,
|
VSCode,
|
||||||
Cmd(String, Vec<String>),
|
Cmd(String, Vec<String>),
|
||||||
@ -39,32 +58,12 @@ impl Editor {
|
|||||||
let handle = thread::Builder::new()
|
let handle = thread::Builder::new()
|
||||||
.spawn(move || match self {
|
.spawn(move || match self {
|
||||||
Editor::VSCode => {
|
Editor::VSCode => {
|
||||||
if !Command::new("code")
|
run_cmd(Command::new("code").arg(exercise_path))?;
|
||||||
.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");
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(Self::VSCode)
|
Ok(Self::VSCode)
|
||||||
}
|
}
|
||||||
Editor::Cmd(program, args) => {
|
Editor::Cmd(program, args) => {
|
||||||
if !Command::new("code")
|
run_cmd(Command::new(&program).args(&args).arg(exercise_path))?;
|
||||||
.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`");
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(Self::Cmd(program, args))
|
Ok(Self::Cmd(program, args))
|
||||||
}
|
}
|
||||||
@ -83,20 +82,14 @@ impl Editor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let output = Command::new("zellij")
|
let stdout = run_cmd(
|
||||||
.arg("action")
|
Command::new("zellij")
|
||||||
.arg("edit")
|
.arg("action")
|
||||||
.arg(exercise_path)
|
.arg("edit")
|
||||||
.stdin(Stdio::null())
|
.arg(exercise_path),
|
||||||
.stderr(Stdio::null())
|
)?;
|
||||||
.output()
|
|
||||||
.context("Failed to run `zellij`")?;
|
|
||||||
|
|
||||||
if !output.status.success() {
|
let (pane_id_str, pane_id) = zellij::parse_pane_id(&stdout)
|
||||||
bail!("Failed to open a new Zellij editor pane");
|
|
||||||
}
|
|
||||||
|
|
||||||
let (pane_id_str, pane_id) = zellij::parse_pane_id(&output.stdout)
|
|
||||||
.context("Failed to parse the ID of the new Zellij pane")?;
|
.context("Failed to parse the ID of the new Zellij pane")?;
|
||||||
|
|
||||||
Ok(Self::Zellij(Some((pane_id_str, pane_id, exercise_ind))))
|
Ok(Self::Zellij(Some((pane_id_str, pane_id, exercise_ind))))
|
||||||
|
|||||||
@ -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 serde::Deserialize;
|
||||||
|
|
||||||
|
use crate::editor::run_cmd;
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
struct Pane {
|
struct Pane {
|
||||||
id: u32,
|
id: u32,
|
||||||
@ -24,39 +26,30 @@ pub fn parse_pane_id(b: &[u8]) -> Option<(String, u32)> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn pane_open(pane_id: u32) -> Result<bool> {
|
pub fn pane_open(pane_id: u32) -> Result<bool> {
|
||||||
let mut output = Command::new("zellij")
|
let mut stdout = run_cmd(
|
||||||
.arg("action")
|
Command::new("zellij")
|
||||||
.arg("list-panes")
|
.arg("action")
|
||||||
.arg("-j")
|
.arg("list-panes")
|
||||||
.stdin(Stdio::null())
|
.arg("-j"),
|
||||||
.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");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove newline
|
// Remove newline
|
||||||
output.stdout.pop();
|
stdout.pop();
|
||||||
|
|
||||||
let panes = serde_json::de::from_slice::<Vec<Pane>>(&output.stdout)
|
let panes = serde_json::de::from_slice::<Vec<Pane>>(&stdout)
|
||||||
.context("Failed to parse the output of `zellij action list-panes -j`")?;
|
.context("Failed to parse the output of `zellij action list-panes -j`")?;
|
||||||
|
|
||||||
Ok(panes.iter().any(|pane| pane.id == pane_id))
|
Ok(panes.iter().any(|pane| pane.id == pane_id))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn close_pane(pane_id: &str) -> Result<()> {
|
pub fn close_pane(pane_id: &str) -> Result<()> {
|
||||||
Command::new("zellij")
|
run_cmd(
|
||||||
.arg("action")
|
Command::new("zellij")
|
||||||
.arg("close-pane")
|
.arg("action")
|
||||||
.arg("-p")
|
.arg("close-pane")
|
||||||
.arg(pane_id)
|
.arg("-p")
|
||||||
.stdin(Stdio::null())
|
.arg(pane_id),
|
||||||
.stdout(Stdio::null())
|
)?;
|
||||||
.stderr(Stdio::null())
|
|
||||||
.status()
|
|
||||||
.context("Failed to run `zellij action close-pane -p ID`")?;
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user