diff --git a/Cargo.lock b/Cargo.lock index 286c929..9d9ae4d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -436,6 +436,7 @@ dependencies = [ "abi_stable", "anyrun-plugin", "reqwest", + "ron", "serde", ] @@ -1073,6 +1074,8 @@ dependencies = [ "fuzzy-matcher", "kidex-common", "open", + "ron", + "serde", ] [[package]] diff --git a/plugins/applications/src/lib.rs b/plugins/applications/src/lib.rs index 58b125e..804f9df 100644 --- a/plugins/applications/src/lib.rs +++ b/plugins/applications/src/lib.rs @@ -5,16 +5,32 @@ use scrubber::DesktopEntry; use serde::Deserialize; use std::{fs, process::Command}; -#[derive(Deserialize, Default)] +#[derive(Deserialize)] pub struct Config { desktop_actions: bool, + max_entries: usize, +} + +impl Default for Config { + fn default() -> Self { + Self { + desktop_actions: false, + max_entries: 5, + } + } +} + +pub struct State { + config: Config, + entries: Vec<(DesktopEntry, u64)>, } mod scrubber; #[handler] -pub fn handler(selection: Match, entries: &Vec<(DesktopEntry, u64)>) -> HandleResult { - let entry = entries +pub fn handler(selection: Match, state: &State) -> HandleResult { + let entry = state + .entries .iter() .find_map(|(entry, id)| { if *id == selection.id.unwrap() { @@ -33,7 +49,7 @@ pub fn handler(selection: Match, entries: &Vec<(DesktopEntry, u64)>) -> HandleRe } #[init] -pub fn init(config_dir: RString) -> Vec<(DesktopEntry, u64)> { +pub fn init(config_dir: RString) -> State { let config: Config = match fs::read_to_string(format!("{}/applications.ron", config_dir)) { Ok(content) => ron::from_str(&content).unwrap_or_else(|why| { eprintln!("Error parsing applications plugin config: {}", why); @@ -45,24 +61,26 @@ pub fn init(config_dir: RString) -> Vec<(DesktopEntry, u64)> { } }; - scrubber::scrubber(config).unwrap_or_else(|why| { + let entries = scrubber::scrubber(&config).unwrap_or_else(|why| { eprintln!("Failed to load desktop entries: {}", why); Vec::new() - }) + }); + + State { config, entries } } #[get_matches] -pub fn get_matches(input: RString, entries: &Vec<(DesktopEntry, u64)>) -> RVec { +pub fn get_matches(input: RString, state: &State) -> RVec { let matcher = fuzzy_matcher::skim::SkimMatcherV2::default().smart_case(); - let mut entries = entries - .clone() - .into_iter() + let mut entries = state + .entries + .iter() .filter_map(|(entry, id)| { let score = matcher.fuzzy_match(&entry.name, &input).unwrap_or(0) + matcher.fuzzy_match(&entry.exec, &input).unwrap_or(0); if score > 0 { - Some((entry, id, score)) + Some((entry, *id, score)) } else { None } @@ -71,14 +89,14 @@ pub fn get_matches(input: RString, entries: &Vec<(DesktopEntry, u64)>) -> RVec Result, Box> { +pub fn scrubber(config: &Config) -> Result, Box> { // Create iterator over all the files in the XDG_DATA_DIRS // XDG compliancy is cool let mut paths: Vec> = match env::var("XDG_DATA_DIRS") { @@ -186,7 +186,7 @@ pub fn scrubber(config: Config) -> Result, Box entry, Err(_why) => return None, }; - Some(DesktopEntry::from_dir_entry(entry, &config)) + Some(DesktopEntry::from_dir_entry(entry, config)) }) .flatten() .enumerate() diff --git a/plugins/dictionary/Cargo.toml b/plugins/dictionary/Cargo.toml index 45cb1b0..431ab47 100644 --- a/plugins/dictionary/Cargo.toml +++ b/plugins/dictionary/Cargo.toml @@ -13,3 +13,4 @@ anyrun-plugin = { path = "../../anyrun-plugin" } abi_stable = "0.11.1" reqwest = { version = "0.11.16", default-features = false, features = ["blocking", "json", "rustls-tls"] } serde = { version = "1.0.160", features = ["derive"] } +ron = "0.8.0" diff --git a/plugins/dictionary/src/lib.rs b/plugins/dictionary/src/lib.rs index 01e4cca..736c5e3 100644 --- a/plugins/dictionary/src/lib.rs +++ b/plugins/dictionary/src/lib.rs @@ -1,7 +1,24 @@ +use std::fs; + use abi_stable::std_types::{ROption, RString, RVec}; use anyrun_plugin::*; use serde::Deserialize; +#[derive(Deserialize)] +pub struct Config { + prefix: String, + max_entries: usize, +} + +impl Default for Config { + fn default() -> Self { + Self { + prefix: ":def".to_string(), + max_entries: 3, + } + } +} + #[allow(unused)] #[derive(Deserialize)] struct ApiResponse { @@ -36,7 +53,12 @@ struct Definition { } #[init] -pub fn init(_config_dir: RString) {} +pub fn init(config_dir: RString) -> Config { + match fs::read_to_string(format!("{}/dictionary.ron", config_dir)) { + Ok(content) => ron::from_str(&content).unwrap_or_default(), + Err(_) => Config::default(), + } +} #[handler] pub fn handler(_match: Match) -> HandleResult { @@ -44,12 +66,12 @@ pub fn handler(_match: Match) -> HandleResult { } #[get_matches] -pub fn get_matches(input: RString) -> RVec { - if !input.starts_with(":def") { +pub fn get_matches(input: RString, config: &Config) -> RVec { + let input = if let Some(input) = input.strip_prefix(&config.prefix) { + input.trim() + } else { return RVec::new(); - } - - let input = &input[4..].trim(); + }; let responses: Vec = match reqwest::blocking::get(format!( "https://api.dictionaryapi.dev/api/v2/entries/en/{}", @@ -89,7 +111,7 @@ pub fn get_matches(input: RString) -> RVec { }) .collect::>() }) - .take(3) + .take(config.max_entries) .collect() } diff --git a/plugins/kidex/Cargo.toml b/plugins/kidex/Cargo.toml index 66623f0..97fed44 100644 --- a/plugins/kidex/Cargo.toml +++ b/plugins/kidex/Cargo.toml @@ -14,3 +14,5 @@ kidex-common = { git = "https://github.com/Kirottu/kidex", features = ["util"] } abi_stable = "0.11.1" fuzzy-matcher = "0.3.7" open = "3.2.0" +serde = { version = "1.0.160", features = ["derive"] } +ron = "0.8.0" diff --git a/plugins/kidex/src/lib.rs b/plugins/kidex/src/lib.rs index 214aaaa..d7f3189 100644 --- a/plugins/kidex/src/lib.rs +++ b/plugins/kidex/src/lib.rs @@ -2,9 +2,22 @@ use abi_stable::std_types::{ROption, RString, RVec}; use anyrun_plugin::{anyrun_interface::HandleResult, *}; use fuzzy_matcher::FuzzyMatcher; use kidex_common::IndexEntry; -use std::{os::unix::prelude::OsStrExt, process::Command}; +use serde::Deserialize; +use std::{fs, os::unix::prelude::OsStrExt, process::Command}; + +#[derive(Deserialize)] +struct Config { + max_entries: usize, +} + +impl Default for Config { + fn default() -> Self { + Self { max_entries: 3 } + } +} pub struct State { + config: Config, index: Vec<(usize, IndexEntry)>, selection: Option, } @@ -58,15 +71,21 @@ pub fn handler(selection: Match, state: &mut State) -> HandleResult { } #[init] -pub fn init(_config_dir: RString) -> State { +pub fn init(config_dir: RString) -> State { + let config = match fs::read_to_string(format!("{}/kidex.ron", config_dir)) { + Ok(content) => ron::from_str(&content).unwrap_or_default(), + Err(_) => Config::default(), + }; + let index = match kidex_common::util::get_index(None) { + Ok(index) => index.into_iter().enumerate().collect(), + Err(why) => { + println!("Failed to get kidex index: {}", why); + Vec::new() + } + }; State { - index: match kidex_common::util::get_index(None) { - Ok(index) => index.into_iter().enumerate().collect(), - Err(why) => { - println!("Failed to get kidex index: {}", why); - Vec::new() - } - }, + config, + index, selection: None, } } @@ -116,7 +135,7 @@ pub fn get_matches(input: RString, state: &State) -> RVec { index.sort_by(|a, b| b.2.cmp(&a.2)); - index.truncate(3); + index.truncate(state.config.max_entries); index .into_iter() .map(|(entry_index, id, _)| Match { diff --git a/plugins/randr/src/lib.rs b/plugins/randr/src/lib.rs index b7431dc..73f330c 100644 --- a/plugins/randr/src/lib.rs +++ b/plugins/randr/src/lib.rs @@ -11,12 +11,14 @@ mod randr; #[derive(Deserialize)] struct Config { prefix: String, + max_entries: usize, } impl Default for Config { fn default() -> Self { Config { prefix: ":dp".to_string(), + max_entries: 5, } } } @@ -103,11 +105,11 @@ pub fn handler(_match: Match, state: &mut State) -> HandleResult { #[get_matches] pub fn get_matches(input: RString, state: &State) -> RVec { - if !input.starts_with(&state.config.prefix) { + let input = if let Some(input) = input.strip_prefix(&state.config.prefix) { + input.trim() + } else { return RVec::new(); - } - - let input = &input[state.config.prefix.len()..].trim(); + }; let matcher = fuzzy_matcher::skim::SkimMatcherV2::default().smart_case(); let mut vec = match &state.inner { @@ -187,7 +189,7 @@ pub fn get_matches(input: RString, state: &State) -> RVec { vec.sort_by(|a, b| b.1.cmp(&a.1)); - vec.truncate(5); + vec.truncate(state.config.max_entries); vec.into_iter().map(|(_match, _)| _match).collect() } diff --git a/plugins/symbols/src/lib.rs b/plugins/symbols/src/lib.rs index 70f1d01..78e0e32 100644 --- a/plugins/symbols/src/lib.rs +++ b/plugins/symbols/src/lib.rs @@ -16,35 +16,40 @@ struct Symbol { #[derive(Deserialize, Debug)] struct Config { symbols: HashMap, + max_entries: usize, +} + +impl Default for Config { + fn default() -> Self { + Self { + symbols: HashMap::new(), + max_entries: 3, + } + } +} + +struct State { + config: Config, + symbols: Vec, } #[init] -fn init(config_dir: RString) -> Vec { +fn init(config_dir: RString) -> State { // 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::(&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); - } - } - } + let config = if let Ok(content) = fs::read_to_string(format!("{}/symbols.ron", config_dir)) { + ron::from_str(&content).unwrap_or_default() + } else { + Config::default() + }; - UNICODE_CHARS + let symbols = UNICODE_CHARS .iter() - .map(|(name, chr)| Symbol { - chr: chr.to_string(), - name: name.to_string(), - }) - .collect() + .map(|(name, chr)| (name.to_string(), chr.to_string())) + .chain(config.symbols.clone().into_iter()) + .map(|(name, chr)| Symbol { chr, name }) + .collect(); + + State { config, symbols } } #[info] @@ -56,11 +61,11 @@ fn info() -> PluginInfo { } #[get_matches] -fn get_matches(input: RString, symbols: &Vec) -> RVec { +fn get_matches(input: RString, state: &State) -> RVec { let matcher = fuzzy_matcher::skim::SkimMatcherV2::default().ignore_case(); - let mut symbols = symbols - .clone() - .into_iter() + let mut symbols = state + .symbols + .iter() .filter_map(|symbol| { matcher .fuzzy_match(&symbol.name, &input) @@ -71,13 +76,13 @@ fn get_matches(input: RString, symbols: &Vec) -> RVec { // Sort the symbol list according to the score symbols.sort_by(|a, b| b.1.cmp(&a.1)); - symbols.truncate(3); + symbols.truncate(state.config.max_entries); symbols .into_iter() .map(|(symbol, _)| Match { - title: symbol.chr.into(), - description: ROption::RSome(symbol.name.into()), + title: symbol.chr.clone().into(), + description: ROption::RSome(symbol.name.clone().into()), use_pango: false, icon: ROption::RNone, id: ROption::RNone, diff --git a/plugins/translate/src/lib.rs b/plugins/translate/src/lib.rs index 9c36c25..b055cc6 100644 --- a/plugins/translate/src/lib.rs +++ b/plugins/translate/src/lib.rs @@ -8,12 +8,14 @@ use serde::Deserialize; #[derive(Deserialize)] struct Config { prefix: String, + max_entries: usize, } impl Default for Config { fn default() -> Self { Self { prefix: ":".to_string(), + max_entries: 3, } } } @@ -182,7 +184,7 @@ fn get_matches(input: RString, data: &State) -> RVec { matches.sort_by(|a, b| b.2.cmp(&a.2)); // We only want 3 matches - matches.truncate(3); + matches.truncate(data.config.max_entries); tokio::runtime::Runtime::new().expect("Failed to spawn tokio runtime!").block_on(async move { // Create the futures for fetching the translation results