forked from mirrors/rmenu
feat: better config defaults, added dmenu format, no-comments mode, placeholder opt
This commit is contained in:
parent
ad460bd8c2
commit
8bd0a91eb1
@ -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(),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -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(),
|
||||||
|
@ -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:?}");
|
||||||
|
@ -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()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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,
|
||||||
|
Loading…
Reference in New Issue
Block a user