feat: Support context options

This commit is contained in:
Michael Aaron Murphy 2021-08-17 15:15:23 +02:00
parent a852584a0d
commit dae8108cb1
8 changed files with 220 additions and 37 deletions

View file

@ -8,7 +8,7 @@ use postage::prelude::*;
use regex::Regex;
use slab::Slab;
use std::{
collections::HashSet,
collections::{HashMap, HashSet},
io::{self, Write},
};
@ -34,6 +34,7 @@ pub async fn main() {
pub struct Service<O> {
active_search: Vec<(PluginKey, PluginSearchResult)>,
associated_list: HashMap<Indice, Indice>,
awaiting_results: HashSet<PluginKey>,
last_query: String,
output: O,
@ -46,6 +47,7 @@ impl<O: Write> Service<O> {
pub fn new(output: O) -> Self {
Self {
active_search: Vec::new(),
associated_list: HashMap::new(),
awaiting_results: HashSet::new(),
last_query: String::new(),
output,
@ -105,7 +107,11 @@ impl<O: Write> Service<O> {
Request::Search(query) => self.search(query).await,
Request::Interrupt => self.interrupt().await,
Request::Activate(id) => self.activate(id).await,
Request::ActivateContext { id, context } => {
self.activate_context(id, context).await
}
Request::Complete(id) => self.complete(id).await,
Request::Context(id) => self.context(id).await,
Request::Quit(id) => self.quit(id).await,
// When requested to exit, the service will forward that
@ -125,10 +131,17 @@ impl<O: Write> Service<O> {
PluginResponse::Append(item) => self.append(plugin, item),
PluginResponse::Clear => self.clear(),
PluginResponse::Close => self.close(),
PluginResponse::Context { id, options } => self.context_response(id, options),
PluginResponse::Fill(text) => self.fill(text),
PluginResponse::Finished => self.finished(plugin).await,
PluginResponse::DesktopEntry(path) => {
self.respond(&Response::DesktopEntry(path));
PluginResponse::DesktopEntry {
path,
gpu_preference,
} => {
self.respond(&Response::DesktopEntry {
path,
gpu_preference,
});
}
},
@ -185,12 +198,24 @@ impl<O: Write> Service<O> {
));
}
async fn activate(&mut self, id: u32) {
async fn activate(&mut self, id: Indice) {
if let Some((plugin, meta)) = self.search_result(id as usize) {
let _ = plugin.sender_exec().send(Request::Activate(meta.id)).await;
}
}
async fn activate_context(&mut self, id: Indice, context: Indice) {
if let Some((plugin, meta)) = self.search_result(id as usize) {
let _ = plugin
.sender_exec()
.send(Request::ActivateContext {
id: meta.id,
context,
})
.await;
}
}
fn append(&mut self, plugin: PluginKey, append: PluginSearchResult) {
self.active_search.push((plugin, append));
}
@ -203,12 +228,25 @@ impl<O: Write> Service<O> {
self.respond(&Response::Close);
}
async fn complete(&mut self, id: u32) {
fn context_response(&mut self, id: Indice, options: Vec<ContextOption>) {
if let Some(id) = self.associated_list.get(&id) {
let id = *id;
self.respond(&Response::Context { id, options });
}
}
async fn complete(&mut self, id: Indice) {
if let Some((plugin, meta)) = self.search_result(id as usize) {
let _ = plugin.sender_exec().send(Request::Complete(meta.id)).await;
}
}
async fn context(&mut self, id: Indice) {
if let Some((plugin, meta)) = self.search_result(id as usize) {
let _ = plugin.sender_exec().send(Request::Context(meta.id)).await;
}
}
fn fill(&mut self, text: String) {
self.respond(&Response::Fill(text));
}
@ -222,7 +260,7 @@ impl<O: Write> Service<O> {
}
let search_list = self.sort();
self.respond(&Response::Update(search_list))
self.respond(&Response::Update(search_list));
}
}
@ -234,7 +272,7 @@ impl<O: Write> Service<O> {
}
}
async fn quit(&mut self, id: u32) {
async fn quit(&mut self, id: Indice) {
if let Some((plugin, meta)) = self.search_result(id as usize) {
let _ = plugin.sender_exec().send(Request::Quit(meta.id)).await;
}
@ -342,6 +380,7 @@ impl<O: Write> Service<O> {
fn sort(&mut self) -> Vec<SearchResult> {
let &mut Self {
ref mut active_search,
ref mut associated_list,
ref mut no_sort,
ref last_query,
ref plugins,
@ -423,21 +462,25 @@ impl<O: Write> Service<O> {
let mut windows = Vec::with_capacity(take);
let mut non_windows = Vec::with_capacity(take);
associated_list.clear();
let search_results =
active_search
.iter()
.take(take)
.enumerate()
.map(|(id, (plugin, meta))| SearchResult {
id: id as u32,
name: meta.name.clone(),
description: meta.description.clone(),
icon: meta.icon.clone(),
category_icon: plugins
.get(*plugin)
.and_then(|conn| conn.config.icon.clone()),
window: meta.window,
.map(|(id, (plugin, meta))| {
associated_list.insert(meta.id, id as u32);
SearchResult {
id: id as u32,
name: meta.name.clone(),
description: meta.description.clone(),
icon: meta.icon.clone(),
category_icon: plugins
.get(*plugin)
.and_then(|conn| conn.config.icon.clone()),
window: meta.window,
}
});
for result in search_results {

View file

@ -9,7 +9,7 @@ use std::{
},
};
use crate::{Event, Plugin, PluginResponse, Request};
use crate::{Event, Indice, Plugin, PluginResponse, Request};
use async_oneshot::oneshot;
use futures_lite::{AsyncWriteExt, FutureExt, StreamExt};
use postage::mpsc::Sender;
@ -168,14 +168,22 @@ impl ExternalPlugin {
#[async_trait::async_trait]
impl Plugin for ExternalPlugin {
async fn activate(&mut self, id: u32) {
async fn activate(&mut self, id: Indice) {
let _ = self.query(&Request::Activate(id)).await;
}
async fn complete(&mut self, id: u32) {
async fn activate_context(&mut self, id: Indice, context: Indice) {
let _ = self.query(&Request::ActivateContext { id, context }).await;
}
async fn complete(&mut self, id: Indice) {
let _ = self.query(&Request::Complete(id)).await;
}
async fn context(&mut self, id: Indice) {
let _ = self.query(&Request::Context(id)).await;
}
fn exit(&mut self) {
if let Some((_, _, mut trigger)) = self.process.take() {
let _ = trigger.send(());
@ -200,7 +208,7 @@ impl Plugin for ExternalPlugin {
.await;
}
}
async fn quit(&mut self, id: u32) {
async fn quit(&mut self, id: Indice) {
let _ = self.query(&Request::Quit(id)).await;
}
}

View file

@ -58,10 +58,14 @@ impl Plugin for HelpPlugin {
}
}
async fn activate_context(&mut self, _: u32, _: u32) {}
async fn complete(&mut self, id: u32) {
self.activate(id).await
}
async fn context(&mut self, _: u32) {}
fn exit(&mut self) {}
async fn interrupt(&mut self) {}

View file

@ -6,7 +6,7 @@ pub use self::config::{PluginBinary, PluginConfig, PluginQuery};
pub use self::external::ExternalPlugin;
pub use self::help::HelpPlugin;
use crate::{PluginHelp, Request};
use crate::{Indice, PluginHelp, Request};
use async_trait::async_trait;
use postage::mpsc::{Receiver, Sender};
use postage::prelude::*;
@ -18,9 +18,13 @@ where
Self: Sized + Send,
{
/// Activate the selected ID from this plugin
async fn activate(&mut self, id: u32);
async fn activate(&mut self, id: Indice);
async fn complete(&mut self, id: u32);
async fn activate_context(&mut self, id: Indice, context: Indice);
async fn complete(&mut self, id: Indice);
async fn context(&mut self, id: Indice);
fn exit(&mut self);
@ -30,7 +34,7 @@ where
async fn search(&mut self, query: &str);
async fn quit(&mut self, id: u32);
async fn quit(&mut self, id: Indice);
async fn run(&mut self, mut rx: Receiver<Request>) {
while let Some(request) = rx.recv().await {
@ -44,7 +48,11 @@ where
Request::Search(query) => self.search(&query).await,
Request::Interrupt => self.interrupt().await,
Request::Activate(id) => self.activate(id).await,
Request::ActivateContext { id, context } => {
self.activate_context(id, context).await
}
Request::Complete(id) => self.complete(id).await,
Request::Context(id) => self.context(id).await,
Request::Quit(id) => self.quit(id).await,
Request::Exit => {
self.exit();