diff --git a/plugins/applications/README.md b/plugins/applications/README.md index ab77fe4..2be3a1b 100644 --- a/plugins/applications/README.md +++ b/plugins/applications/README.md @@ -15,7 +15,13 @@ Simply search for the application you wish to launch. Config( // Also show the Desktop Actions defined in the desktop files, e.g. "New Window" from LibreWolf desktop_actions: true, - max_entries: 5, + + max_entries: 5, + + // A command to preprocess the command from the desktop file. The commands should take arguments in this order: + // command_name + preprocess_exec_script: Some("/home/user/.local/share/anyrun/preprocess_application_command.sh") + // The terminal used for running terminal based desktop entries, if left as `None` a static list of terminals is used // to determine what terminal to use. terminal: Some("alacritty"), diff --git a/plugins/applications/src/lib.rs b/plugins/applications/src/lib.rs index 3dca60f..0cc81d8 100644 --- a/plugins/applications/src/lib.rs +++ b/plugins/applications/src/lib.rs @@ -3,12 +3,13 @@ use anyrun_plugin::{anyrun_interface::HandleResult, *}; use fuzzy_matcher::FuzzyMatcher; use scrubber::DesktopEntry; use serde::Deserialize; -use std::{env, fs, process::Command}; +use std::{env, fs, path::PathBuf, process::Command}; #[derive(Deserialize)] pub struct Config { desktop_actions: bool, max_entries: usize, + preprocess_exec_script: Option, terminal: Option, } @@ -17,6 +18,7 @@ impl Default for Config { Self { desktop_actions: false, max_entries: 5, + preprocess_exec_script: None, terminal: None, } } @@ -45,21 +47,36 @@ pub fn handler(selection: Match, state: &State) -> HandleResult { }) .unwrap(); + let exec = if let Some(script) = &state.config.preprocess_exec_script { + let output = Command::new("sh") + .arg("-c") + .arg(format!( + "{} {} {}", + script.display(), + if entry.term { "term" } else { "no-term" }, + &entry.exec + )) + .output() + .unwrap_or_else(|why| { + eprintln!("Error running preprocess script: {}", why); + std::process::exit(1); + }); + + String::from_utf8_lossy(&output.stdout).trim().to_string() + } else { + entry.exec.clone() + }; + if entry.term { match &state.config.terminal { Some(term) => { - if let Err(why) = Command::new(term).arg("-e").arg(&entry.exec).spawn() { + if let Err(why) = Command::new(term).arg("-e").arg(&exec).spawn() { eprintln!("Error running desktop entry: {}", why); } } None => { for term in SENSIBLE_TERMINALS { - if Command::new(term) - .arg("-e") - .arg(&entry.exec) - .spawn() - .is_ok() - { + if Command::new(term).arg("-e").arg(&exec).spawn().is_ok() { break; } } @@ -70,7 +87,7 @@ pub fn handler(selection: Match, state: &State) -> HandleResult { Command::new("sh") .arg("-c") - .arg(&entry.exec) + .arg(&exec) .current_dir(if let Some(path) = &entry.path { if path.exists() { path } else { current_dir } } else {