diff --git a/Cargo.lock b/Cargo.lock index 4c2d6d75..b8db4360 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -485,6 +485,7 @@ dependencies = [ "rustlings-macros", "serde", "serde_json", + "shlex", "tempfile", "toml", ] @@ -571,6 +572,12 @@ dependencies = [ "serde_core", ] +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + [[package]] name = "signal-hook" version = "0.3.18" diff --git a/Cargo.toml b/Cargo.toml index 068a3f49..192eeb61 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -52,6 +52,7 @@ notify = "8" rustlings-macros = { path = "rustlings-macros", version = "=6.5.0" } serde_json = "1" serde.workspace = true +shlex = "1" toml.workspace = true [target.'cfg(not(windows))'.dependencies] diff --git a/src/editor.rs b/src/editor.rs index af5c2fbe..6e712605 100644 --- a/src/editor.rs +++ b/src/editor.rs @@ -5,6 +5,7 @@ use std::{ }; use anyhow::{Context, Result, bail}; +use shlex::Shlex; mod zellij; @@ -34,20 +35,26 @@ pub enum Editor { } impl Editor { - pub fn new(cmd: Option) -> Option { + pub fn new(cmd: Option) -> Result> { if env::var_os("TERM_PROGRAM").is_some_and(|v| v == "vscode") { - return Some(Self::VSCode); + return Ok(Some(Self::VSCode)); } if let Some(cmd) = cmd { - todo!() + let shlex = &mut Shlex::new(&cmd); + let program = shlex.next().context("Program missing in `--edit-cmd`")?; + let args = shlex.collect(); + if shlex.had_error { + bail!("Failed to parse the command in `--edit-cmd`"); + } + return Ok(Some(Self::Cmd(program, args))); } if env::var_os("ZELLIJ").is_some() { - return Some(Self::Zellij(None)); + return Ok(Some(Self::Zellij(None))); } - None + Ok(None) } pub fn open( diff --git a/src/main.rs b/src/main.rs index 1d6c98b1..7cd5c80b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -60,10 +60,11 @@ fn main() -> Result { bail!(FORMAT_VERSION_HIGHER_ERR); } + let editor = Editor::new(args.edit_cmd)?; let (mut app_state, state_file_status) = AppState::new( info_file.exercises, info_file.final_message.unwrap_or_default(), - Editor::new(args.edit_cmd), + editor, )?; // Show the welcome message if the state file doesn't exist yet.