From 41c7c65528071891467532b23b2777413482e5d5 Mon Sep 17 00:00:00 2001 From: imgurbot12 Date: Mon, 24 Jul 2023 21:53:23 -0700 Subject: [PATCH] feat: impl simple run plugin --- Cargo.toml | 5 ++- plugin-desktop/Cargo.toml | 8 +++++ plugin-desktop/src/main.rs | 3 ++ plugin-run/Cargo.toml | 11 +++++++ plugin-run/src/main.rs | 64 ++++++++++++++++++++++++++++++++++++++ rmenu-plugin/src/lib.rs | 16 ++++++++-- 6 files changed, 103 insertions(+), 4 deletions(-) create mode 100644 plugin-desktop/Cargo.toml create mode 100644 plugin-desktop/src/main.rs create mode 100644 plugin-run/Cargo.toml create mode 100644 plugin-run/src/main.rs diff --git a/Cargo.toml b/Cargo.toml index 6b863fa..9b94371 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,5 +2,8 @@ resolver = "2" members = [ "rmenu", - "rmenu-plugin" + "rmenu-plugin", + "plugin-run", + "plugin-desktop", + "rtest", ] diff --git a/plugin-desktop/Cargo.toml b/plugin-desktop/Cargo.toml new file mode 100644 index 0000000..e2ddac0 --- /dev/null +++ b/plugin-desktop/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "desktop" +version = "0.0.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] \ No newline at end of file diff --git a/plugin-desktop/src/main.rs b/plugin-desktop/src/main.rs new file mode 100644 index 0000000..e7a11a9 --- /dev/null +++ b/plugin-desktop/src/main.rs @@ -0,0 +1,3 @@ +fn main() { + println!("Hello, world!"); +} diff --git a/plugin-run/Cargo.toml b/plugin-run/Cargo.toml new file mode 100644 index 0000000..59999c5 --- /dev/null +++ b/plugin-run/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "run" +version = "0.0.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +rmenu-plugin = { version = "0.0.0", path = "../rmenu-plugin" } +serde_json = "1.0.103" +walkdir = "2.3.3" diff --git a/plugin-run/src/main.rs b/plugin-run/src/main.rs new file mode 100644 index 0000000..def09ca --- /dev/null +++ b/plugin-run/src/main.rs @@ -0,0 +1,64 @@ +use std::env; +use std::os::unix::fs::PermissionsExt; + +use rmenu_plugin::Entry; +use walkdir::{DirEntry, WalkDir}; + +static PATH: &'static str = "PATH"; +static DEFAULT_PATH: &'static str = "/bin:/usr/bin:/usr/sbin"; +static EXEC_FLAG: u32 = 0o111; + +/// Retrieve Search Paths from OS-VAR or Default +fn bin_paths() -> Vec { + env::var(PATH) + .unwrap_or_else(|_| DEFAULT_PATH.to_string()) + .split(":") + .map(|s| s.to_string()) + .collect() +} + +/// Ignore Entry if Hidden or Filename contains a `.` +fn should_ignore(entry: &DirEntry) -> bool { + entry + .file_name() + .to_str() + .map(|s| s.contains(".")) + .unwrap_or(false) +} + +/// Retrieve Binaries for the Specified Paths +fn find_binaries(path: String) -> Vec { + WalkDir::new(path) + .follow_links(true) + .into_iter() + .filter_entry(|e| !should_ignore(e)) + .filter_map(|e| e.ok()) + .filter(|e| e.file_type().is_file()) + .filter(|e| { + e.metadata() + .map(|m| m.permissions().mode() & EXEC_FLAG != 0) + .unwrap_or(false) + }) + .map(|e| { + let path = e.path().to_string_lossy(); + Entry::new(&e.file_name().to_string_lossy(), &path, Some(&path)) + }) + .collect() +} + +fn main() { + // collect entries for sorting + let mut entries: Vec = bin_paths() + .into_iter() + .map(find_binaries) + .flatten() + .collect(); + // sort entries and render to json + entries.sort_by_cached_key(|e| e.name.clone()); + entries + .into_iter() + .map(|e| serde_json::to_string(&e)) + .filter_map(|r| r.ok()) + .map(|s| println!("{}", s)) + .last(); +} diff --git a/rmenu-plugin/src/lib.rs b/rmenu-plugin/src/lib.rs index 2a10945..47eab2f 100644 --- a/rmenu-plugin/src/lib.rs +++ b/rmenu-plugin/src/lib.rs @@ -13,6 +13,16 @@ pub struct Action { pub comment: Option, } +impl Action { + pub fn new(exec: &str) -> Self { + Self { + name: "main".to_string(), + exec: exec.to_string(), + comment: None, + } + } +} + #[derive(Debug, PartialEq, Serialize, Deserialize)] pub struct Entry { pub name: String, @@ -22,11 +32,11 @@ pub struct Entry { } impl Entry { - pub fn new(name: &str) -> Self { + pub fn new(name: &str, action: &str, comment: Option<&str>) -> Self { Self { name: name.to_owned(), - actions: Default::default(), - comment: Default::default(), + actions: vec![Action::new(action)], + comment: comment.map(|c| c.to_owned()), icon: Default::default(), } }