Files
anyrun/plugins/applications/src/lib.rs
2022-12-29 23:56:32 +02:00

82 lines
2.0 KiB
Rust

use abi_stable::std_types::{ROption, RString, RVec};
use scrubber::DesktopEntry;
use std::{process::Command, sync::RwLock, thread};
use anyrun_plugin::{anyrun_interface::HandleResult, *};
mod scrubber;
static ENTRIES: RwLock<Vec<(DesktopEntry, u64)>> = RwLock::new(Vec::new());
pub fn handler(selection: Match) -> HandleResult {
let entries = ENTRIES.read().unwrap();
let entry = entries
.iter()
.find_map(|(entry, id)| {
if *id == selection.id {
Some(entry)
} else {
None
}
})
.unwrap();
if let Err(why) = Command::new("sh").arg("-c").arg(&entry.exec).spawn() {
println!("Error running desktop entry: {}", why);
}
HandleResult::Close
}
pub fn init(_config_dir: RString) {
thread::spawn(|| {
*ENTRIES.write().unwrap() = match scrubber::scrubber() {
Ok(results) => results,
Err(why) => {
println!("Error reading desktop entries: {}", why);
return;
}
};
});
}
pub fn get_matches(input: RString) -> RVec<Match> {
if input.len() == 0 {
return RVec::new();
}
let mut entries = ENTRIES
.read()
.unwrap()
.clone()
.into_iter()
.filter_map(|(entry, id)| {
match sublime_fuzzy::best_match(&input.to_lowercase(), &entry.name.to_lowercase()) {
Some(val) => Some((entry, id, val.score())),
None => None,
}
})
.collect::<Vec<(DesktopEntry, u64, isize)>>();
entries.sort_by(|a, b| b.1.cmp(&a.1));
entries.truncate(5);
entries
.into_iter()
.map(|(entry, id, _)| Match {
title: entry.name.into(),
icon: entry.icon.into(),
description: ROption::RNone,
id,
})
.collect()
}
pub fn info() -> PluginInfo {
PluginInfo {
name: "Applications".into(),
icon: "application-x-executable".into(),
}
}
plugin!(init, info, get_matches, handler);