Fix launch with multiple args

This commit is contained in:
Gregory 2020-06-07 14:48:12 -04:00
parent 92b815a38a
commit 31bc3e3370
No known key found for this signature in database
GPG key ID: 2E44FAEEDC94B1E2
5 changed files with 30 additions and 22 deletions

View file

@ -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 {

View file

@ -19,24 +19,31 @@ pub struct DesktopEntry {
pub(crate) mimes: Vec<Mime>,
}
#[derive(PartialEq, Eq)]
pub enum Mode {
Launch,
Open,
}
impl DesktopEntry {
pub fn exec(&self, arguments: Vec<String>) -> Result<()> {
pub fn exec(&self, mode: Mode, arguments: Vec<String>) -> 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<String>) -> Result<()> {
fn exec_inner(&self, arg: Vec<String>) -> 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<String>,
) -> Result<(String, Vec<String>)> {
pub fn get_cmd(&self, arg: Vec<String>) -> Result<(String, Vec<String>)> {
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::<Vec<_>>();

View file

@ -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<String>) -> Result<()> {
self.get_entry()?.exec(args)
self.get_entry()?.exec(ExecMode::Launch, args)
}
pub fn open(&self, args: Vec<String>) -> Result<()> {
self.get_entry()?.exec(ExecMode::Open, args)
}
}

View file

@ -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};

View file

@ -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()?;