diff --git a/src/apps/user.rs b/src/apps/user.rs index 8306a59..69241c5 100644 --- a/src/apps/user.rs +++ b/src/apps/user.rs @@ -73,7 +73,7 @@ impl MimeApps { (json::object! { handler: handler.to_string(), name: entry.name.as_str(), - cmd: entry.get_cmd(None)?.0 + cmd: entry.get_cmd(vec![])?.0 }) .to_string() } else { diff --git a/src/common/desktop_entry.rs b/src/common/desktop_entry.rs index cb99b80..40b7da1 100644 --- a/src/common/desktop_entry.rs +++ b/src/common/desktop_entry.rs @@ -19,24 +19,31 @@ pub struct DesktopEntry { pub(crate) mimes: Vec, } +#[derive(PartialEq, Eq)] +pub enum Mode { + Launch, + Open, +} + impl DesktopEntry { - pub fn exec(&self, arguments: Vec) -> Result<()> { + pub fn exec(&self, mode: Mode, arguments: Vec) -> Result<()> { let supports_multiple = self.exec.contains("%F") || self.exec.contains("%U"); if arguments.is_empty() { - self.exec_inner(None)? - } else if supports_multiple { - self.exec_inner(Some(arguments.join(" ")))?; + self.exec_inner(vec![])? + } else if supports_multiple || mode == Mode::Launch { + self.exec_inner(arguments)?; } else { for arg in arguments { - self.exec_inner(Some(arg))?; + self.exec_inner(vec![arg])?; } }; Ok(()) } - fn exec_inner(&self, arg: Option) -> Result<()> { + fn exec_inner(&self, arg: Vec) -> Result<()> { let (cmd, args) = self.get_cmd(arg)?; + dbg!(&cmd, &args); let mut cmd = Command::new(cmd); cmd.args(args); if self.term { @@ -46,23 +53,18 @@ impl DesktopEntry { }; Ok(()) } - pub fn get_cmd( - &self, - arg: Option, - ) -> Result<(String, Vec)> { + pub fn get_cmd(&self, arg: Vec) -> Result<(String, Vec)> { let special = regex::Regex::new("%(f|F|u|U)").unwrap(); let mut split = shlex::split(&self.exec) .unwrap() .into_iter() - .filter_map(|s| match s.as_str() { + .flat_map(|s| match s.as_str() { "%f" | "%F" | "%u" | "%U" => arg.clone(), - s if special.is_match(s) => Some( - special - .replace_all(s, arg.as_deref().unwrap_or_default()) - .into(), - ), - _ => Some(s), + s if special.is_match(s) => vec![special + .replace_all(s, arg.clone().join(" ").as_str()) + .into()], + _ => vec![s], }) .collect::>(); diff --git a/src/common/handler.rs b/src/common/handler.rs index e8d76f6..7ac1c80 100644 --- a/src/common/handler.rs +++ b/src/common/handler.rs @@ -1,4 +1,7 @@ -use crate::{common::DesktopEntry, Error, Result}; +use crate::{ + common::{DesktopEntry, ExecMode}, + Error, Result, +}; use std::{convert::TryFrom, ffi::OsString, path::PathBuf}; #[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] @@ -36,6 +39,9 @@ impl Handler { DesktopEntry::try_from(Self::get_path(&self.0).unwrap()) } pub fn launch(&self, args: Vec) -> Result<()> { - self.get_entry()?.exec(args) + self.get_entry()?.exec(ExecMode::Launch, args) + } + pub fn open(&self, args: Vec) -> Result<()> { + self.get_entry()?.exec(ExecMode::Open, args) } } diff --git a/src/common/mod.rs b/src/common/mod.rs index e1403f1..7964a76 100644 --- a/src/common/mod.rs +++ b/src/common/mod.rs @@ -4,6 +4,6 @@ mod handler; mod mime_types; pub use self::db::{autocomplete as db_autocomplete, SHARED_MIME_DB}; -pub use desktop_entry::{DesktopEntry, Rule as PestRule}; +pub use desktop_entry::{DesktopEntry, Mode as ExecMode, Rule as PestRule}; pub use handler::Handler; pub use mime_types::{MimeOrExtension, MimeType}; diff --git a/src/main.rs b/src/main.rs index a60c88c..89951b5 100644 --- a/src/main.rs +++ b/src/main.rs @@ -31,7 +31,7 @@ fn main() -> Result<()> { } Cmd::Open { paths } => { let mime = MimeType::try_from(paths[0].as_str())?.0; - apps.get_handler(&mime)?.launch(paths)?; + apps.get_handler(&mime)?.open(paths)?; } Cmd::List => { apps.print()?;