onagre_launcher_toolkit/lib.rs
1// Copyright 2021 System76 <info@system76.com>
2// SPDX-License-Identifier: MPL-2.0
3
4//! # onagre-launcher-toolkit
5//!
6//! A toolkit to write pop-launcher client and plugin.
7//!
8//! ## Crates
9//! - **[`launcher`]:** re-export the pop-launcher crate, containing all the IPC message struct and
10//! some utility functions to locate plugins.
11//! - **[`service`]:** re-export the pop-launcher-service crate, containing deserializable plugin config struct.
12//! This is useful if your client needs to read user defined plugins configs.
13//! - **[`plugins`]:** re-export pop-launcher-plugins which defines all the default pop-launcher plugins.
14//! Useful if your client needs to read default plugin configs
15//!
16//! ## Writing a plugin
17//!
18//! Add the following to your Cargo.toml :
19//!
20//! ```toml
21//! [dependencies]
22//! tokio = { version = "1.18.2", features = ["rt"] }
23//! onagre-launcher-toolkit = { git = "https://github.com/pop-os/launcher" }
24//! ```
25//!
26//! And implement the [`PluginExt`] trait:
27//!
28//! [`PluginExt`]: plugin_trait::PluginExt
29//!
30//! ```rust
31//! use pop_launcher_toolkit::launcher::{Indice, PluginResponse, PluginSearchResult};
32//! use pop_launcher_toolkit::plugin_trait::{async_trait, PluginExt};
33//! use pop_launcher_toolkit::plugins;
34//!
35//! // The plugin struct, here it holds the search result
36//! pub struct MyPlugin {
37//! data: Vec<String>
38//! }
39//!
40//! #[async_trait]
41//! impl PluginExt for MyPlugin {
42//!
43//! // Define the name of you plugin, this will be used
44//! // to generate a logfile in $XDG_STATE_HOME at runtime.
45//! fn name(&self) -> &str {
46//! "my_awesome_plugin"
47//! }
48//!
49//! // Respond to `pop-launcher` 'search' query
50//! async fn search(&mut self, query: &str) {
51//! // `pop-launcher` dispatches request to plugins according to the regex defined in
52//! // the `plugin.ron` config file, here we get rid of the prefix
53//! // before processing the request.
54//! let query = query.strip_prefix("plug ").unwrap();
55//!
56//! // Iterate through our internal search results with their indices.
57//! let search_results = self.data.iter()
58//! .enumerate()
59//! .filter(|(idx, data)| data.contains(query));
60//!
61//! // Send our search results to `pop-launcher` using their indices as id.
62//! for (idx, search_result) in search_results {
63//! self.respond_with(PluginResponse::Append(PluginSearchResult {
64//! id: idx as u32,
65//! name: search_result.clone(),
66//! description: "".to_string(),
67//! keywords: None,
68//! icon: None,
69//! exec: None,
70//! window: None,
71//! })).await;
72//! }
73//!
74//! // tell `pop-launcher` we are done with this request
75//! self.respond_with(PluginResponse::Finished).await;
76//! }
77//!
78//! // Respond to `pop-launcher` 'activate' query
79//! async fn activate(&mut self, id: Indice) {
80//! // Get the selected entry
81//! let entry = self.data.get(id as usize).unwrap();
82//! // Here we use xdg_open to run the entry but this could be anything
83//! plugins::xdg_open(entry);
84//! // Tell pop launcher we are done
85//! self.respond_with(PluginResponse::Finished).await;
86//! }
87//!
88//! // Respond to `pop-launcher` 'close' request.
89//! async fn quit(&mut self, id: Indice) {
90//! self.respond_with(PluginResponse::Close).await;
91//! }
92//! }
93//!
94//! #[tokio::main(flavor = "current_thread")]
95//! pub async fn main() {
96//!
97//! // Here we declare our plugin with dummy values, and never mutate them.
98//! // In a real plugin we would probably use some kind of mutable shared reference to
99//! // update our search results.
100//! let mut plugin = MyPlugin {
101//! data: vec!["https://crates.io".to_string(), "https://en.wikipedia.org".to_string()],
102//! };
103//!
104//! /// If you need to debug your plugin or display error messages use `tcracing` macros.
105//! tracing::info!("Starting my_awsome_plugin");
106//!
107//! // Call the plugin entry point function to start
108//! // talking with pop_launcherc
109//! plugin.run().await;
110//! }
111//! ```
112
113pub use onagre_launcher as launcher;
114pub use onagre_launcher_plugins as plugins;
115pub use onagre_launcher_service::{
116 self as service, load::from_path as load_plugin_from_path,
117 load::from_paths as load_plugins_from_paths,
118};
119
120/// A helper trait to quickly create `pop-launcher` plugins
121pub mod plugin_trait;