Refinement, plugins, etc.
This commit is contained in:
@@ -12,3 +12,4 @@ crate-type = ["cdylib"]
|
||||
anyrun-plugin = { path = "../../anyrun-plugin" }
|
||||
abi_stable = "0.11.1"
|
||||
sublime_fuzzy = "0.7.0"
|
||||
fuzzy-matcher = "0.3.7"
|
||||
|
@@ -1,18 +1,16 @@
|
||||
use abi_stable::std_types::{ROption, RString, RVec};
|
||||
use scrubber::DesktopEntry;
|
||||
use std::{process::Command, sync::RwLock, thread};
|
||||
use anyrun_plugin::{anyrun_interface::HandleResult, *};
|
||||
use fuzzy_matcher::FuzzyMatcher;
|
||||
use scrubber::DesktopEntry;
|
||||
use std::process::Command;
|
||||
|
||||
mod scrubber;
|
||||
|
||||
static ENTRIES: RwLock<Vec<(DesktopEntry, u64)>> = RwLock::new(Vec::new());
|
||||
|
||||
pub fn handler(selection: Match) -> HandleResult {
|
||||
let entries = ENTRIES.read().unwrap();
|
||||
pub fn handler(selection: Match, entries: &mut Vec<(DesktopEntry, u64)>) -> HandleResult {
|
||||
let entry = entries
|
||||
.iter()
|
||||
.find_map(|(entry, id)| {
|
||||
if *id == selection.id {
|
||||
if *id == selection.id.unwrap() {
|
||||
Some(entry)
|
||||
} else {
|
||||
None
|
||||
@@ -27,46 +25,32 @@ pub fn handler(selection: Match) -> HandleResult {
|
||||
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 init(_config_dir: RString) -> Vec<(DesktopEntry, u64)> {
|
||||
scrubber::scrubber().expect("Failed to load desktop entries!")
|
||||
}
|
||||
|
||||
pub fn get_matches(input: RString) -> RVec<Match> {
|
||||
if input.len() == 0 {
|
||||
return RVec::new();
|
||||
}
|
||||
|
||||
let mut entries = ENTRIES
|
||||
.read()
|
||||
.unwrap()
|
||||
pub fn get_matches(input: RString, entries: &mut Vec<(DesktopEntry, u64)>) -> RVec<Match> {
|
||||
let matcher = fuzzy_matcher::skim::SkimMatcherV2::default().smart_case();
|
||||
let mut entries = entries
|
||||
.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,
|
||||
}
|
||||
matcher
|
||||
.fuzzy_match(&entry.name, &input)
|
||||
.map(|val| (entry, id, val))
|
||||
})
|
||||
.collect::<Vec<(DesktopEntry, u64, isize)>>();
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
entries.sort_by(|a, b| b.1.cmp(&a.1));
|
||||
entries.sort_by(|a, b| b.2.cmp(&a.2));
|
||||
|
||||
entries.truncate(5);
|
||||
entries
|
||||
.into_iter()
|
||||
.map(|(entry, id, _)| Match {
|
||||
title: entry.name.into(),
|
||||
icon: entry.icon.into(),
|
||||
icon: ROption::RSome(entry.icon.into()),
|
||||
description: ROption::RNone,
|
||||
id,
|
||||
id: ROption::RSome(id),
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
@@ -78,4 +62,4 @@ pub fn info() -> PluginInfo {
|
||||
}
|
||||
}
|
||||
|
||||
plugin!(init, info, get_matches, handler);
|
||||
plugin!(init, info, get_matches, handler, Vec<(DesktopEntry, u64)>);
|
||||
|
@@ -115,7 +115,7 @@ pub fn scrubber() -> Result<Vec<(DesktopEntry, u64)>, Box<dyn std::error::Error>
|
||||
Ok(entry) => entry,
|
||||
Err(_why) => return None,
|
||||
};
|
||||
DesktopEntry::from_dir_entry(&entry).map(|val| (val, id))
|
||||
DesktopEntry::from_dir_entry(entry).map(|val| (val, id))
|
||||
})
|
||||
.collect())
|
||||
}
|
||||
|
@@ -1,5 +1,5 @@
|
||||
[package]
|
||||
name = "web-search"
|
||||
name = "rink"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
@@ -11,3 +11,4 @@ crate-type = ["cdylib"]
|
||||
[dependencies]
|
||||
anyrun-plugin = { path = "../../anyrun-plugin" }
|
||||
abi_stable = "0.11.1"
|
||||
rink-core = "0.6"
|
31
plugins/rink/src/lib.rs
Normal file
31
plugins/rink/src/lib.rs
Normal file
@@ -0,0 +1,31 @@
|
||||
use abi_stable::std_types::{ROption, RString, RVec};
|
||||
use anyrun_plugin::{anyrun_interface::HandleResult, plugin, Match, PluginInfo};
|
||||
|
||||
fn init(_config_dir: RString) {}
|
||||
|
||||
fn info() -> PluginInfo {
|
||||
PluginInfo {
|
||||
name: "Rink".into(),
|
||||
icon: "accessories-calculator".into(),
|
||||
}
|
||||
}
|
||||
|
||||
fn get_matches(input: RString, _: &mut ()) -> RVec<Match> {
|
||||
let mut ctx = rink_core::simple_context().unwrap();
|
||||
match rink_core::one_line(&mut ctx, &input) {
|
||||
Ok(result) => vec![Match {
|
||||
title: result.into(),
|
||||
icon: ROption::RNone,
|
||||
description: ROption::RNone,
|
||||
id: ROption::RNone,
|
||||
}]
|
||||
.into(),
|
||||
Err(_) => RVec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
fn handler(selection: Match, _: &mut ()) -> HandleResult {
|
||||
HandleResult::Copy(selection.title.into_bytes())
|
||||
}
|
||||
|
||||
plugin!(init, info, get_matches, handler, ());
|
@@ -11,3 +11,6 @@ crate-type = ["cdylib"]
|
||||
[dependencies]
|
||||
anyrun-plugin = { path = "../../anyrun-plugin" }
|
||||
abi_stable = "0.11.1"
|
||||
ron = "0.8.0"
|
||||
serde = { version = "1.0.152", features = ["derive"] }
|
||||
fuzzy-matcher = "0.3.7"
|
||||
|
28
plugins/symbols/build.rs
Normal file
28
plugins/symbols/build.rs
Normal file
@@ -0,0 +1,28 @@
|
||||
use std::{
|
||||
env,
|
||||
fs::{self, File},
|
||||
io::Write,
|
||||
};
|
||||
|
||||
fn main() {
|
||||
let string = fs::read_to_string("res/UnicodeData.txt").expect("Failed to load unicode data!");
|
||||
let mut file = File::create(format!("{}/unicode.rs", env::var("OUT_DIR").unwrap()))
|
||||
.expect("Unable to create unicode output file!");
|
||||
|
||||
file.write_all(b"#[allow(text_direction_codepoint_in_literal)]\nconst UNICODE_CHARS: &[(&str, &str)] = &[\n")
|
||||
.unwrap();
|
||||
string.lines().for_each(|line| {
|
||||
let fields = line.split(';').collect::<Vec<_>>();
|
||||
let chr = match char::from_u32(u32::from_str_radix(fields[0], 16).unwrap()) {
|
||||
Some(char) => char,
|
||||
None => return,
|
||||
};
|
||||
|
||||
if fields[1] != "<control>" {
|
||||
file.write_all(format!("(r#\"{}\"#, r#\"{}\"#),\n", fields[1], chr).as_bytes())
|
||||
.unwrap();
|
||||
}
|
||||
});
|
||||
|
||||
file.write_all(b"];\n").unwrap();
|
||||
}
|
34924
plugins/symbols/res/UnicodeData.txt
Normal file
34924
plugins/symbols/res/UnicodeData.txt
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,27 +1,88 @@
|
||||
use std::{collections::HashMap, fs};
|
||||
|
||||
use abi_stable::std_types::{ROption, RString, RVec};
|
||||
use anyrun_plugin::{plugin, anyrun_interface::HandleResult, Match, PluginInfo};
|
||||
use anyrun_plugin::{anyrun_interface::HandleResult, plugin, Match, PluginInfo};
|
||||
use fuzzy_matcher::FuzzyMatcher;
|
||||
use serde::Deserialize;
|
||||
|
||||
pub fn init(_config_dir: RString) {}
|
||||
include!(concat!(env!("OUT_DIR"), "/unicode.rs"));
|
||||
|
||||
pub fn info() -> PluginInfo {
|
||||
#[derive(Clone, Debug)]
|
||||
struct Symbol {
|
||||
chr: String,
|
||||
name: String,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Debug)]
|
||||
struct Config {
|
||||
symbols: HashMap<String, String>,
|
||||
}
|
||||
|
||||
fn init(config_dir: RString) -> Vec<Symbol> {
|
||||
// Try to load the config file, if it does not exist only use the static unicode characters
|
||||
if let Ok(content) = fs::read_to_string(format!("{}/symbols.ron", config_dir)) {
|
||||
match ron::from_str::<Config>(&content) {
|
||||
Ok(config) => {
|
||||
let symbols = UNICODE_CHARS
|
||||
.iter()
|
||||
.map(|(name, chr)| (name.to_string(), chr.to_string()))
|
||||
.chain(config.symbols.into_iter())
|
||||
.map(|(name, chr)| Symbol { chr, name })
|
||||
.collect();
|
||||
return symbols;
|
||||
}
|
||||
Err(why) => {
|
||||
println!("Error parsing symbols config file: {}", why);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
UNICODE_CHARS
|
||||
.iter()
|
||||
.map(|(name, chr)| Symbol {
|
||||
chr: chr.to_string(),
|
||||
name: name.to_string(),
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn info() -> PluginInfo {
|
||||
PluginInfo {
|
||||
name: "Symbols".into(),
|
||||
icon: "emblem-mail".into(),
|
||||
icon: "accessories-character-map".into(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_matches(input: RString) -> RVec<Match> {
|
||||
vec![Match {
|
||||
title: "Test".into(),
|
||||
description: ROption::RNone,
|
||||
icon: "dialog-warning".into(),
|
||||
id: 0,
|
||||
}]
|
||||
.into()
|
||||
fn get_matches(input: RString, symbols: &mut Vec<Symbol>) -> RVec<Match> {
|
||||
let matcher = fuzzy_matcher::skim::SkimMatcherV2::default().ignore_case();
|
||||
let mut symbols = symbols
|
||||
.clone()
|
||||
.into_iter()
|
||||
.filter_map(|symbol| {
|
||||
matcher
|
||||
.fuzzy_match(&symbol.name, &input)
|
||||
.map(|score| (symbol, score))
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
// Sort the symbol list according to the score
|
||||
symbols.sort_by(|a, b| b.1.cmp(&a.1));
|
||||
|
||||
symbols.truncate(3);
|
||||
|
||||
symbols
|
||||
.into_iter()
|
||||
.map(|(symbol, _)| Match {
|
||||
title: symbol.chr.into(),
|
||||
description: ROption::RSome(symbol.name.into()),
|
||||
icon: ROption::RNone,
|
||||
id: ROption::RNone,
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
pub fn handler(selection: Match) -> HandleResult {
|
||||
HandleResult::Close
|
||||
fn handler(selection: Match, _symbols: &mut Vec<Symbol>) -> HandleResult {
|
||||
HandleResult::Copy(selection.title.into_bytes())
|
||||
}
|
||||
|
||||
plugin!(init, info, get_matches, handler);
|
||||
plugin!(init, info, get_matches, handler, Vec<Symbol>);
|
||||
|
@@ -1,35 +0,0 @@
|
||||
use abi_stable::std_types::{ROption, RString, RVec};
|
||||
use anyrun_plugin::{plugin, anyrun_interface::HandleResult, Match, PluginInfo};
|
||||
|
||||
pub fn init(_config_dir: RString) {}
|
||||
|
||||
pub fn info() -> PluginInfo {
|
||||
PluginInfo {
|
||||
name: "Web search".into(),
|
||||
icon: "system-search".into(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_matches(input: RString) -> RVec<Match> {
|
||||
vec![
|
||||
Match {
|
||||
title: "DDG it!".into(),
|
||||
description: ROption::RSome(format!(r#"Look up "{}" with DuckDuckGo"#, input).into()),
|
||||
icon: "emblem-web".into(),
|
||||
id: 0,
|
||||
},
|
||||
Match {
|
||||
title: "Startpage it!".into(),
|
||||
description: ROption::RSome(format!(r#"Look up "{}" with Startpage"#, input).into()),
|
||||
icon: "emblem-web".into(),
|
||||
id: 0,
|
||||
},
|
||||
]
|
||||
.into()
|
||||
}
|
||||
|
||||
pub fn handler(selection: Match) -> HandleResult {
|
||||
HandleResult::Close
|
||||
}
|
||||
|
||||
plugin!(init, info, get_matches, handler);
|
Reference in New Issue
Block a user