feat: better config defaults, added dmenu format, no-comments mode, placeholder opt

This commit is contained in:
imgurbot12 2023-08-11 16:24:30 -07:00
parent ad460bd8c2
commit 8bd0a91eb1
5 changed files with 80 additions and 17 deletions

View File

@ -5,6 +5,7 @@ use serde::{Deserialize, Serialize};
pub enum Method { pub enum Method {
Terminal(String), Terminal(String),
Run(String), Run(String),
Echo(String),
} }
impl Method { impl Method {
@ -31,6 +32,13 @@ impl Action {
comment: None, comment: None,
} }
} }
pub fn echo(echo: &str) -> Self {
Self {
name: "main".to_string(),
exec: Method::Echo(echo.to_string()),
comment: None,
}
}
} }
#[derive(Debug, PartialEq, Serialize, Deserialize)] #[derive(Debug, PartialEq, Serialize, Deserialize)]
@ -50,4 +58,13 @@ impl Entry {
icon: Default::default(), icon: Default::default(),
} }
} }
pub fn echo(echo: &str, comment: Option<&str>) -> Self {
Self {
name: echo.to_owned(),
actions: vec![Action::echo(echo)],
comment: comment.map(|c| c.to_owned()),
icon: Default::default(),
}
}
} }

View File

@ -116,12 +116,8 @@ impl Default for WindowConfig {
fn default() -> Self { fn default() -> Self {
Self { Self {
title: "RMenu - App Launcher".to_owned(), title: "RMenu - App Launcher".to_owned(),
// size: LogicalSize {
// width: 700.0,
// height: 400.0,
// },
size: LogicalSize { size: LogicalSize {
width: 1000.0, width: 700.0,
height: 400.0, height: 400.0,
}, },
position: LogicalPosition { x: 100.0, y: 100.0 }, position: LogicalPosition { x: 100.0, y: 100.0 },
@ -182,6 +178,13 @@ pub struct PluginConfig {
pub exec: Vec<String>, pub exec: Vec<String>,
#[serde(default)] #[serde(default)]
pub cache: CacheSetting, pub cache: CacheSetting,
#[serde(default)]
pub placeholder: Option<String>,
}
#[inline]
fn _true() -> bool {
true
} }
/// Global RMenu Complete Configuration /// Global RMenu Complete Configuration
@ -190,9 +193,15 @@ pub struct PluginConfig {
pub struct Config { pub struct Config {
pub page_size: usize, pub page_size: usize,
pub page_load: f64, pub page_load: f64,
#[serde(default = "_true")]
pub use_icons: bool, pub use_icons: bool,
#[serde(default = "_true")]
pub use_comments: bool,
#[serde(default = "_true")]
pub search_regex: bool, pub search_regex: bool,
#[serde(default = "_true")]
pub ignore_case: bool, pub ignore_case: bool,
pub placeholder: Option<String>,
pub plugins: BTreeMap<String, PluginConfig>, pub plugins: BTreeMap<String, PluginConfig>,
pub keybinds: KeyConfig, pub keybinds: KeyConfig,
pub window: WindowConfig, pub window: WindowConfig,
@ -205,8 +214,10 @@ impl Default for Config {
page_size: 50, page_size: 50,
page_load: 0.8, page_load: 0.8,
use_icons: true, use_icons: true,
use_comments: true,
search_regex: false, search_regex: false,
ignore_case: true, ignore_case: true,
placeholder: Default::default(),
plugins: Default::default(), plugins: Default::default(),
keybinds: Default::default(), keybinds: Default::default(),
window: Default::default(), window: Default::default(),

View File

@ -51,6 +51,10 @@ pub fn execute(action: &Action, term: Option<String>) {
let command = strfmt(&terminal, &args).expect("Failed String Format"); let command = strfmt(&terminal, &args).expect("Failed String Format");
parse_args(&command) parse_args(&command)
} }
Method::Echo(echo) => {
println!("{echo}");
std::process::exit(0);
}
}; };
let err = Command::new(&args[0]).args(&args[1..]).exec(); let err = Command::new(&args[0]).args(&args[1..]).exec();
panic!("Command Error: {err:?}"); panic!("Command Error: {err:?}");

View File

@ -121,6 +121,8 @@ fn TableEntry<'a>(cx: Scope<'a, GEntry<'a>>) -> Element<'a> {
} }
}) })
} }
match cx.props.state.config().use_comments {
true => cx.render(rsx! {
div { div {
class: "name", class: "name",
"{cx.props.entry.name}" "{cx.props.entry.name}"
@ -129,6 +131,14 @@ fn TableEntry<'a>(cx: Scope<'a, GEntry<'a>>) -> Element<'a> {
class: "comment", class: "comment",
render_comment(cx.props.entry.comment.as_ref()) render_comment(cx.props.entry.comment.as_ref())
} }
}),
false => cx.render(rsx! {
div {
class: "entry",
"{cx.props.entry.name}"
}
})
}
} }
div { div {
id: "result-{cx.props.index}-actions", id: "result-{cx.props.index}-actions",
@ -209,6 +219,16 @@ fn App<'a>(cx: Scope<App>) -> Element {
}) })
}); });
// retreive placeholder
let placeholder = cx
.props
.config
.placeholder
.as_ref()
.map(|s| s.to_string())
.unwrap_or_else(|| "".to_owned());
// complete final rendering
cx.render(rsx! { cx.render(rsx! {
style { DEFAULT_CSS_CONTENT } style { DEFAULT_CSS_CONTENT }
style { "{cx.props.css}" } style { "{cx.props.css}" }
@ -220,6 +240,7 @@ fn App<'a>(cx: Scope<App>) -> Element {
input { input {
id: "search", id: "search",
value: "{search}", value: "{search}",
placeholder: "{placeholder}",
oninput: move |evt| s_updater.set_search(cx, evt.value.clone()), oninput: move |evt| s_updater.set_search(cx, evt.value.clone()),
} }
} }

View File

@ -25,7 +25,7 @@ static DEFAULT_CSS_CONTENT: &'static str = include_str!("../public/default.css")
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub enum Format { pub enum Format {
Json, Json,
MsgPack, DMenu,
} }
impl Display for Format { impl Display for Format {
@ -40,7 +40,7 @@ impl FromStr for Format {
fn from_str(s: &str) -> Result<Self, Self::Err> { fn from_str(s: &str) -> Result<Self, Self::Err> {
match s.to_ascii_lowercase().as_str() { match s.to_ascii_lowercase().as_str() {
"json" => Ok(Format::Json), "json" => Ok(Format::Json),
"msgpack" => Ok(Format::MsgPack), "dmenu" => Ok(Format::DMenu),
_ => Err("No Such Format".to_owned()), _ => Err("No Such Format".to_owned()),
} }
} }
@ -90,6 +90,8 @@ pub struct Args {
config: Option<String>, config: Option<String>,
#[arg(long)] #[arg(long)]
css: Option<String>, css: Option<String>,
#[arg(short, long)]
placehold: Option<String>,
} }
impl Args { impl Args {
@ -114,7 +116,7 @@ impl Args {
fn readentry(&self, cfg: &config::Config, line: &str) -> Result<Entry, RMenuError> { fn readentry(&self, cfg: &config::Config, line: &str) -> Result<Entry, RMenuError> {
let mut entry = match self.format { let mut entry = match self.format {
Format::Json => serde_json::from_str::<Entry>(line)?, Format::Json => serde_json::from_str::<Entry>(line)?,
Format::MsgPack => todo!(), Format::DMenu => Entry::echo(line.trim(), None),
}; };
if !cfg.use_icons { if !cfg.use_icons {
entry.icon = None; entry.icon = None;
@ -140,7 +142,7 @@ impl Args {
} }
/// Load Entries From Specified Sources /// Load Entries From Specified Sources
fn load_sources(&self, cfg: &config::Config) -> Result<Vec<Entry>, RMenuError> { fn load_sources(&self, cfg: &mut config::Config) -> Result<Vec<Entry>, RMenuError> {
log::debug!("config: {cfg:?}"); log::debug!("config: {cfg:?}");
// execute commands to get a list of entries // execute commands to get a list of entries
let mut entries = vec![]; let mut entries = vec![];
@ -192,6 +194,10 @@ impl Args {
Some(status.clone()), Some(status.clone()),
)); ));
} }
// update placeholder if empty
if cfg.placeholder.is_none() {
cfg.placeholder = plugin.placeholder.clone();
}
// write cache for entries collected // write cache for entries collected
match cache::write_cache(name, plugin, &entries) { match cache::write_cache(name, plugin, &entries) {
Ok(_) => {} Ok(_) => {}
@ -217,12 +223,16 @@ impl Args {
}; };
// load entries from configured sources // load entries from configured sources
let entries = match args.run.len() > 0 { let entries = match args.run.len() > 0 {
true => args.load_sources(&config)?, true => args.load_sources(&mut config)?,
false => args.load_default(&config)?, false => args.load_default(&config)?,
}; };
// update configuration based on cli // update configuration based on cli
config.use_icons = config.use_icons && entries.iter().any(|e| e.icon.is_some()); config.use_icons = config.use_icons && entries.iter().any(|e| e.icon.is_some());
config.use_comments = config.use_icons && entries.iter().any(|e| e.comment.is_some());
config.search_regex = args.regex.unwrap_or(config.search_regex); config.search_regex = args.regex.unwrap_or(config.search_regex);
if args.placehold.is_some() {
config.placeholder = args.placehold.clone();
};
// generate app object // generate app object
return Ok(App { return Ok(App {
css, css,