diff --git a/Cargo.lock b/Cargo.lock index 7bb05ef..4cca9ff 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1311,6 +1311,16 @@ dependencies = [ "serde", ] +[[package]] +name = "shell" +version = "0.1.0" +dependencies = [ + "abi_stable", + "anyrun-plugin", + "ron", + "serde", +] + [[package]] name = "slab" version = "0.4.7" diff --git a/Cargo.toml b/Cargo.toml index 6d7b2d6..a3934d3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,4 +6,5 @@ members = [ "plugins/applications", "plugins/symbols", "plugins/rink", + "plugins/shell", ] \ No newline at end of file diff --git a/plugins/shell/Cargo.toml b/plugins/shell/Cargo.toml new file mode 100644 index 0000000..b9b1d2f --- /dev/null +++ b/plugins/shell/Cargo.toml @@ -0,0 +1,15 @@ +[package] +name = "shell" +version = "0.1.0" +edition = "2021" + +[lib] +crate-type = ["cdylib"] + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +anyrun-plugin = { path = "../../anyrun-plugin" } +abi_stable = "0.11.1" +ron = "0.8.0" +serde = { version = "1.0.152", features = ["derive"] } diff --git a/plugins/shell/src/lib.rs b/plugins/shell/src/lib.rs new file mode 100644 index 0000000..2d0392a --- /dev/null +++ b/plugins/shell/src/lib.rs @@ -0,0 +1,70 @@ +use std::{env, fs, process::Command}; + +use abi_stable::std_types::{ROption, RString, RVec}; +use anyrun_plugin::{anyrun_interface::HandleResult, plugin, Match, PluginInfo}; +use serde::Deserialize; + +#[derive(Deserialize)] +struct Config { + prefix: String, +} + +impl Default for Config { + fn default() -> Self { + Config { + prefix: ":sh".to_string(), + } + } +} + +fn init(config_dir: RString) -> Config { + match fs::read_to_string(format!("{}/shell.ron", config_dir)) { + Ok(content) => ron::from_str(&content).unwrap_or_default(), + Err(_) => Config::default(), + } +} + +fn info() -> PluginInfo { + PluginInfo { + name: "Shell".into(), + icon: "utilities-terminal".into(), + } +} + +fn get_matches(input: RString, config: &mut Config) -> RVec { + let prefix_with_delim = format!("{} ", config.prefix); + if input.starts_with(&prefix_with_delim) { + let (_, command) = input.split_once(&prefix_with_delim).unwrap(); + if !command.is_empty() { + vec![Match { + title: command.into(), + description: ROption::RSome( + env::var("SHELL") + .unwrap_or_else(|_| "No shell!".to_string()) + .into(), + ), + icon: ROption::RNone, + id: ROption::RNone, + }] + .into() + } else { + RVec::new() + } + } else { + RVec::new() + } +} + +fn handler(selection: Match, _config: &mut Config) -> HandleResult { + if let Err(why) = Command::new(selection.description.unwrap().as_str()) + .arg("-c") + .arg(selection.title.as_str()) + .spawn() + { + println!("Failed to run command: {}", why); + } + + HandleResult::Close +} + +plugin!(init, info, get_matches, handler, Config);