improve config
This commit is contained in:
parent
8cc457dffc
commit
0ca65cae81
4 changed files with 314 additions and 480 deletions
|
@ -7,7 +7,6 @@ use clap::{Parser, ValueEnum};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use serde_json::Value;
|
use serde_json::Value;
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
use which::which;
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum ConfigurationError {
|
pub enum ConfigurationError {
|
||||||
|
@ -138,64 +137,61 @@ impl FromStr for WrapMode {
|
||||||
|
|
||||||
#[derive(Debug, Deserialize, Serialize, Clone, Parser)]
|
#[derive(Debug, Deserialize, Serialize, Clone, Parser)]
|
||||||
#[clap(about = "Worf is a wofi clone written in rust, it aims to be a drop-in replacement")]
|
#[clap(about = "Worf is a wofi clone written in rust, it aims to be a drop-in replacement")]
|
||||||
|
#[derive(Default)]
|
||||||
pub struct Config {
|
pub struct Config {
|
||||||
/// Forks the menu so you can close the terminal
|
/// Forks the menu so you can close the terminal
|
||||||
#[clap(short = 'f', long = "fork")]
|
#[clap(short = 'f', long = "fork")]
|
||||||
pub fork: Option<bool>,
|
fork: Option<bool>, // todo support fork
|
||||||
|
|
||||||
/// Selects a config file to use
|
/// Selects a config file to use
|
||||||
#[clap(short = 'c', long = "conf")]
|
#[clap(short = 'c', long = "conf")]
|
||||||
pub config: Option<String>,
|
config: Option<String>,
|
||||||
|
|
||||||
/// Prints the version and then exits
|
/// Prints the version and then exits
|
||||||
#[clap(short = 'v', long = "version")]
|
#[clap(short = 'v', long = "version")]
|
||||||
pub version: Option<bool>,
|
version: Option<bool>, // todo support or drop
|
||||||
|
|
||||||
/// Defines the style sheet to be loaded.
|
/// Defines the style sheet to be loaded.
|
||||||
/// Defaults to `$XDG_CONF_DIR/worf/style.css`
|
/// Defaults to `$XDG_CONF_DIR/worf/style.css`
|
||||||
/// or `$HOME/.config/worf/style.css` if `$XDG_CONF_DIR` is not set.
|
/// or `$HOME/.config/worf/style.css` if `$XDG_CONF_DIR` is not set.
|
||||||
#[serde(default = "default_style")]
|
|
||||||
#[clap(long = "style")]
|
#[clap(long = "style")]
|
||||||
pub style: Option<String>,
|
style: Option<String>,
|
||||||
|
|
||||||
/// Defines the mode worf is running in
|
/// Defines the mode worf is running in
|
||||||
#[clap(long = "show")]
|
#[clap(long = "show")]
|
||||||
pub show: Option<Mode>,
|
show: Option<Mode>,
|
||||||
|
|
||||||
/// Default width of the window, defaults to 50% of the screen
|
/// Default width of the window, defaults to 50% of the screen
|
||||||
#[serde(default = "default_width")]
|
|
||||||
#[clap(long = "width")]
|
#[clap(long = "width")]
|
||||||
pub width: Option<String>,
|
width: Option<String>,
|
||||||
|
|
||||||
/// Default height of the window, defaults to 40% of the screen
|
/// Default height of the window, defaults to 40% of the screen
|
||||||
#[serde(default = "default_height")]
|
|
||||||
#[clap(long = "height")]
|
#[clap(long = "height")]
|
||||||
pub height: Option<String>,
|
height: Option<String>,
|
||||||
|
|
||||||
/// Defines which prompt is used. Default is selected 'show'
|
/// Defines which prompt is used. Default is selected 'show'
|
||||||
#[clap(short = 'p', long = "prompt")]
|
#[clap(short = 'p', long = "prompt")]
|
||||||
pub prompt: Option<String>,
|
prompt: Option<String>,
|
||||||
|
|
||||||
#[clap(short = 'x', long = "xoffset")]
|
#[clap(short = 'x', long = "xoffset")]
|
||||||
pub xoffset: Option<i32>,
|
xoffset: Option<i32>,
|
||||||
|
|
||||||
#[clap(short = 'y', long = "yoffset")]
|
#[clap(short = 'y', long = "yoffset")]
|
||||||
pub yoffset: Option<i32>,
|
yoffset: Option<i32>,
|
||||||
|
|
||||||
/// If true a normal window instead of a layer shell will be used
|
/// If true a normal window instead of a layer shell will be used
|
||||||
#[serde(default = "default_normal_window")]
|
|
||||||
#[clap(short = 'n', long = "normal-window")]
|
#[clap(short = 'n', long = "normal-window")]
|
||||||
pub normal_window: bool,
|
normal_window: bool,
|
||||||
|
|
||||||
/// Set to 'false' to disable images, defaults to true
|
/// Set to 'false' to disable images, defaults to true
|
||||||
#[clap(short = 'I', long = "allow-images")]
|
#[clap(short = 'I', long = "allow-images")]
|
||||||
pub allow_images: Option<bool>,
|
allow_images: Option<bool>,
|
||||||
|
|
||||||
#[clap(short = 'm', long = "allow-markup")]
|
#[clap(short = 'm', long = "allow-markup")]
|
||||||
pub allow_markup: Option<bool>,
|
allow_markup: Option<bool>,
|
||||||
|
|
||||||
#[clap(short = 'k', long = "cache-file")]
|
#[clap(short = 'k', long = "cache-file")]
|
||||||
pub cache_file: Option<String>,
|
cache_file: Option<String>,
|
||||||
|
|
||||||
/// Defines which terminal to use. defaults to the first one found:
|
/// Defines which terminal to use. defaults to the first one found:
|
||||||
/// * kitty
|
/// * kitty
|
||||||
|
@ -209,362 +205,146 @@ pub struct Config {
|
||||||
///
|
///
|
||||||
/// Must be configured including the needed arguments to launch something
|
/// Must be configured including the needed arguments to launch something
|
||||||
/// i.e. 'kitty -c'
|
/// i.e. 'kitty -c'
|
||||||
#[serde(default = "default_terminal")]
|
|
||||||
#[clap(short = 't', long = "term")]
|
#[clap(short = 't', long = "term")]
|
||||||
pub term: Option<String>,
|
term: Option<String>,
|
||||||
|
|
||||||
#[serde(default = "default_password_char")]
|
|
||||||
#[clap(short = 'P', long = "password")]
|
#[clap(short = 'P', long = "password")]
|
||||||
pub password: Option<String>,
|
password: Option<String>,
|
||||||
|
|
||||||
#[clap(short = 'e', long = "exec-search")]
|
#[clap(short = 'e', long = "exec-search")]
|
||||||
pub exec_search: Option<bool>,
|
exec_search: Option<bool>,
|
||||||
|
|
||||||
/// Defines whether the scrollbar is visible
|
/// Defines whether the scrollbar is visible
|
||||||
#[clap(short = 'b', long = "hide-scroll")]
|
#[clap(short = 'b', long = "hide-scroll")]
|
||||||
pub hide_scroll: Option<bool>,
|
hide_scroll: Option<bool>,
|
||||||
|
|
||||||
/// Defines the matching method, defaults to contains
|
/// Defines the matching method, defaults to contains
|
||||||
#[serde(default = "default_match_method")]
|
|
||||||
#[clap(short = 'M', long = "matching")]
|
#[clap(short = 'M', long = "matching")]
|
||||||
pub matching: Option<MatchMethod>,
|
matching: Option<MatchMethod>,
|
||||||
|
|
||||||
#[clap(short = 'i', long = "insensitive")]
|
#[clap(short = 'i', long = "insensitive")]
|
||||||
pub insensitive: Option<bool>,
|
insensitive: Option<bool>,
|
||||||
|
|
||||||
#[clap(short = 'q', long = "parse-search")]
|
#[clap(short = 'q', long = "parse-search")]
|
||||||
pub parse_search: Option<bool>,
|
parse_search: Option<bool>,
|
||||||
|
|
||||||
/// set where the window is displayed.
|
/// set where the window is displayed.
|
||||||
/// can be used to anchor a window to an edge by
|
/// can be used to anchor a window to an edge by
|
||||||
/// setting top,left for example
|
/// setting top,left for example
|
||||||
#[clap(short = 'l', long = "location", value_delimiter = ',', value_parser = clap::builder::ValueParser::new(Anchor::from_str))]
|
#[clap(short = 'l', long = "location", value_delimiter = ',', value_parser = clap::builder::ValueParser::new(Anchor::from_str)
|
||||||
pub location: Option<Vec<Anchor>>,
|
)]
|
||||||
|
location: Option<Vec<Anchor>>,
|
||||||
|
|
||||||
#[clap(short = 'a', long = "no-actions")]
|
#[clap(short = 'a', long = "no-actions")]
|
||||||
pub no_actions: Option<bool>,
|
no_actions: Option<bool>,
|
||||||
|
|
||||||
#[clap(short = 'L', long = "lines")]
|
#[clap(short = 'L', long = "lines")]
|
||||||
pub lines: Option<u32>,
|
lines: Option<u32>,
|
||||||
|
|
||||||
#[serde(default = "default_columns")]
|
|
||||||
#[clap(short = 'w', long = "columns")]
|
#[clap(short = 'w', long = "columns")]
|
||||||
pub columns: Option<u32>,
|
columns: Option<u32>,
|
||||||
|
|
||||||
#[clap(short = 'O', long = "sort-order")]
|
#[clap(short = 'O', long = "sort-order")]
|
||||||
pub sort_order: Option<String>,
|
sort_order: Option<String>,
|
||||||
|
|
||||||
#[clap(short = 'G', long = "gtk-dark")]
|
#[clap(short = 'G', long = "gtk-dark")]
|
||||||
pub gtk_dark: Option<bool>,
|
gtk_dark: Option<bool>,
|
||||||
|
|
||||||
#[clap(short = 'Q', long = "search")]
|
#[clap(short = 'Q', long = "search")]
|
||||||
pub search: Option<String>,
|
search: Option<String>,
|
||||||
|
|
||||||
#[clap(short = 'o', long = "monitor")]
|
#[clap(short = 'o', long = "monitor")]
|
||||||
pub monitor: Option<String>,
|
monitor: Option<String>,
|
||||||
|
|
||||||
#[clap(short = 'r', long = "pre-display-cmd")]
|
#[clap(short = 'r', long = "pre-display-cmd")]
|
||||||
pub pre_display_cmd: Option<String>,
|
pre_display_cmd: Option<String>,
|
||||||
|
|
||||||
#[serde(default = "default_orientation")]
|
|
||||||
#[clap(long = "orientation")]
|
#[clap(long = "orientation")]
|
||||||
pub orientation: Option<Orientation>,
|
orientation: Option<Orientation>,
|
||||||
|
|
||||||
/// Horizontal alignment
|
/// Horizontal alignment
|
||||||
#[serde(default = "default_halign")]
|
|
||||||
#[clap(long = "halign")]
|
#[clap(long = "halign")]
|
||||||
pub halign: Option<Align>,
|
halign: Option<Align>,
|
||||||
|
|
||||||
/// Alignment of content
|
/// Alignment of content
|
||||||
#[serde(default = "default_content_halign")]
|
|
||||||
#[clap(long = "content-halign")]
|
#[clap(long = "content-halign")]
|
||||||
pub content_halign: Option<Align>,
|
content_halign: Option<Align>,
|
||||||
|
|
||||||
/// Vertical alignment
|
/// Vertical alignment
|
||||||
#[clap(long = "valign")]
|
#[clap(long = "valign")]
|
||||||
pub valign: Option<Align>,
|
valign: Option<Align>,
|
||||||
|
|
||||||
pub filter_rate: Option<u32>,
|
filter_rate: Option<u32>,
|
||||||
|
|
||||||
/// Defines the image size in pixels
|
/// Defines the image size in pixels
|
||||||
#[serde(default = "default_image_size")]
|
|
||||||
#[clap(long = "image-size")]
|
#[clap(long = "image-size")]
|
||||||
pub image_size: Option<i32>,
|
image_size: Option<i32>,
|
||||||
|
|
||||||
pub key_up: Option<String>,
|
key_up: Option<String>,
|
||||||
pub key_down: Option<String>,
|
key_down: Option<String>,
|
||||||
pub key_left: Option<String>,
|
key_left: Option<String>,
|
||||||
pub key_right: Option<String>,
|
key_right: Option<String>,
|
||||||
pub key_forward: Option<String>,
|
key_forward: Option<String>,
|
||||||
pub key_backward: Option<String>,
|
key_backward: Option<String>,
|
||||||
pub key_submit: Option<String>,
|
key_submit: Option<String>,
|
||||||
pub key_exit: Option<String>,
|
key_exit: Option<String>,
|
||||||
pub key_pgup: Option<String>,
|
key_pgup: Option<String>,
|
||||||
pub key_pgdn: Option<String>,
|
key_pgdn: Option<String>,
|
||||||
pub key_expand: Option<String>,
|
key_expand: Option<String>,
|
||||||
pub key_hide_search: Option<String>,
|
key_hide_search: Option<String>,
|
||||||
pub key_copy: Option<String>,
|
key_copy: Option<String>,
|
||||||
|
|
||||||
// todo re-add this
|
// todo re-add this
|
||||||
// #[serde(flatten)]
|
// #[serde(flatten)]
|
||||||
// pub key_custom: Option<HashMap<String, String>>,
|
// key_custom: Option<HashMap<String, String>>,
|
||||||
pub global_coords: Option<bool>,
|
global_coords: Option<bool>,
|
||||||
pub hide_search: Option<bool>,
|
hide_search: Option<bool>,
|
||||||
pub dynamic_lines: Option<bool>,
|
dynamic_lines: Option<bool>,
|
||||||
pub layer: Option<String>,
|
layer: Option<String>,
|
||||||
pub copy_exec: Option<String>,
|
copy_exec: Option<String>,
|
||||||
pub single_click: Option<bool>,
|
single_click: Option<bool>,
|
||||||
pub pre_display_exec: Option<bool>,
|
pre_display_exec: Option<bool>,
|
||||||
|
|
||||||
/// Minimum score for a fuzzy search to be shown
|
/// Minimum score for a fuzzy search to be shown
|
||||||
#[serde(default = "default_fuzzy_min_score")]
|
|
||||||
#[clap(long = "fuzzy-min-score")]
|
#[clap(long = "fuzzy-min-score")]
|
||||||
pub fuzzy_min_score: Option<f64>,
|
fuzzy_min_score: Option<f64>,
|
||||||
|
|
||||||
/// Orientation of items in the row box where items are displayed
|
/// Orientation of items in the row box where items are displayed
|
||||||
#[serde(default = "default_row_box_orientation")]
|
|
||||||
#[clap(long = "row-box-orientation")]
|
#[clap(long = "row-box-orientation")]
|
||||||
pub row_bow_orientation: Option<Orientation>,
|
row_bow_orientation: Option<Orientation>,
|
||||||
|
|
||||||
// /// Set to to true to wrap text after a given amount of chars
|
|
||||||
// #[serde(default = "default_text_wrap")]
|
|
||||||
// #[clap(long = "text-wrap")]
|
|
||||||
// pub text_wrap: Option<bool>,
|
|
||||||
//
|
|
||||||
// /// Defines after how many chars a line is broken over.
|
|
||||||
// /// Only cuts at spaces.
|
|
||||||
// #[serde(default = "default_text_wrap_length")]
|
|
||||||
// #[clap(long = "text-wrap-length")]
|
|
||||||
// pub text_wrap_length: Option<usize>,
|
|
||||||
/// Defines how long it takes for the show animation to finish
|
/// Defines how long it takes for the show animation to finish
|
||||||
/// Defaults to 70ms
|
/// Defaults to 70ms
|
||||||
#[serde(default = "default_show_animation_time")]
|
|
||||||
#[clap(long = "show-animation-time")]
|
#[clap(long = "show-animation-time")]
|
||||||
pub show_animation_time: Option<u64>,
|
show_animation_time: Option<u64>,
|
||||||
|
|
||||||
/// Defines how long it takes for the hide animation to finish
|
/// Defines how long it takes for the hide animation to finish
|
||||||
/// Defaults to 100ms
|
/// Defaults to 100ms
|
||||||
#[serde(default = "default_hide_animation_time")]
|
|
||||||
#[clap(long = "hide-animation-time")]
|
#[clap(long = "hide-animation-time")]
|
||||||
pub hide_animation_time: Option<u64>,
|
hide_animation_time: Option<u64>,
|
||||||
|
|
||||||
#[serde(default = "default_line_wrap")]
|
|
||||||
#[clap(long = "line-wrap")]
|
#[clap(long = "line-wrap")]
|
||||||
pub line_wrap: Option<WrapMode>,
|
line_wrap: Option<WrapMode>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Config {
|
impl Config {
|
||||||
fn default() -> Self {
|
#[must_use]
|
||||||
Config {
|
pub fn image_size(&self) -> i32 {
|
||||||
fork: None,
|
self.image_size.unwrap_or(32)
|
||||||
config: None,
|
|
||||||
version: None,
|
|
||||||
style: default_style(),
|
|
||||||
show: None,
|
|
||||||
width: default_width(),
|
|
||||||
height: default_height(),
|
|
||||||
prompt: None,
|
|
||||||
xoffset: None,
|
|
||||||
yoffset: None,
|
|
||||||
normal_window: default_normal_window(),
|
|
||||||
allow_images: None,
|
|
||||||
allow_markup: None,
|
|
||||||
cache_file: None,
|
|
||||||
term: None,
|
|
||||||
password: None,
|
|
||||||
exec_search: None,
|
|
||||||
hide_scroll: None,
|
|
||||||
matching: None,
|
|
||||||
insensitive: None,
|
|
||||||
parse_search: None,
|
|
||||||
location: None,
|
|
||||||
no_actions: None,
|
|
||||||
lines: None,
|
|
||||||
columns: default_columns(),
|
|
||||||
sort_order: None,
|
|
||||||
gtk_dark: None,
|
|
||||||
search: None,
|
|
||||||
monitor: None,
|
|
||||||
pre_display_cmd: None,
|
|
||||||
orientation: default_row_box_orientation(),
|
|
||||||
halign: default_halign(),
|
|
||||||
content_halign: default_content_halign(),
|
|
||||||
valign: None,
|
|
||||||
filter_rate: None,
|
|
||||||
image_size: default_image_size(),
|
|
||||||
key_up: None,
|
|
||||||
key_down: None,
|
|
||||||
key_left: None,
|
|
||||||
key_right: None,
|
|
||||||
key_forward: None,
|
|
||||||
key_backward: None,
|
|
||||||
key_submit: None,
|
|
||||||
key_exit: None,
|
|
||||||
key_pgup: None,
|
|
||||||
key_pgdn: None,
|
|
||||||
key_expand: None,
|
|
||||||
key_hide_search: None,
|
|
||||||
key_copy: None,
|
|
||||||
//key_custom: None,
|
|
||||||
line_wrap: default_line_wrap(),
|
|
||||||
global_coords: None,
|
|
||||||
hide_search: None,
|
|
||||||
dynamic_lines: None,
|
|
||||||
layer: None,
|
|
||||||
copy_exec: None,
|
|
||||||
single_click: None,
|
|
||||||
pre_display_exec: None,
|
|
||||||
fuzzy_min_score: default_fuzzy_min_score(),
|
|
||||||
row_bow_orientation: default_row_box_orientation(),
|
|
||||||
show_animation_time: default_show_animation_time(),
|
|
||||||
hide_animation_time: default_hide_animation_time(),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[must_use]
|
||||||
|
pub fn match_method(&self) -> MatchMethod {
|
||||||
|
self.matching.unwrap_or(MatchMethod::Contains)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// allowed because option is needed for serde macro
|
#[must_use]
|
||||||
#[allow(clippy::unnecessary_wraps)]
|
pub fn fuzzy_min_score(&self) -> f64 {
|
||||||
#[must_use]
|
self.fuzzy_min_score.unwrap_or(0.0)
|
||||||
pub fn default_show_animation_time() -> Option<u64> {
|
}
|
||||||
Some(10)
|
|
||||||
}
|
|
||||||
|
|
||||||
// allowed because option is needed for serde macro
|
#[must_use]
|
||||||
#[allow(clippy::unnecessary_wraps)]
|
pub fn style(&self) -> Option<String> {
|
||||||
#[must_use]
|
|
||||||
pub fn default_hide_animation_time() -> Option<u64> {
|
|
||||||
Some(0)
|
|
||||||
}
|
|
||||||
|
|
||||||
// allowed because option is needed for serde macro
|
|
||||||
#[allow(clippy::unnecessary_wraps)]
|
|
||||||
#[must_use]
|
|
||||||
pub fn default_row_box_orientation() -> Option<Orientation> {
|
|
||||||
Some(Orientation::Horizontal)
|
|
||||||
}
|
|
||||||
|
|
||||||
// allowed because option is needed for serde macro
|
|
||||||
#[allow(clippy::unnecessary_wraps)]
|
|
||||||
#[must_use]
|
|
||||||
pub fn default_orientation() -> Option<Orientation> {
|
|
||||||
Some(Orientation::Vertical)
|
|
||||||
}
|
|
||||||
|
|
||||||
// allowed because option is needed for serde macro
|
|
||||||
#[allow(clippy::unnecessary_wraps)]
|
|
||||||
#[must_use]
|
|
||||||
pub fn default_halign() -> Option<Align> {
|
|
||||||
Some(Align::Fill)
|
|
||||||
}
|
|
||||||
|
|
||||||
// allowed because option is needed for serde macro
|
|
||||||
#[allow(clippy::unnecessary_wraps)]
|
|
||||||
#[must_use]
|
|
||||||
pub fn default_content_halign() -> Option<Align> {
|
|
||||||
Some(Align::Fill)
|
|
||||||
}
|
|
||||||
|
|
||||||
// allowed because option is needed for serde macro
|
|
||||||
#[allow(clippy::unnecessary_wraps)]
|
|
||||||
#[must_use]
|
|
||||||
pub fn default_columns() -> Option<u32> {
|
|
||||||
Some(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
// allowed because option is needed for serde macro
|
|
||||||
#[allow(clippy::unnecessary_wraps)]
|
|
||||||
#[must_use]
|
|
||||||
pub fn default_normal_window() -> bool {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
|
|
||||||
// allowed because option is needed for serde macro
|
|
||||||
#[allow(clippy::unnecessary_wraps)]
|
|
||||||
#[must_use]
|
|
||||||
pub fn default_line_wrap() -> Option<WrapMode> {
|
|
||||||
Some(WrapMode::Word)
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO
|
|
||||||
// GtkOrientation orientation = config_get_mnemonic(config, "orientation", "vertical", 2, "vertical", "horizontal");
|
|
||||||
// outer_orientation = config_get_mnemonic(cstoonfig, "orientation", "vertical", 2, "horizontal", "vertical");
|
|
||||||
// GtkAlign halign = config_get_mnemonic(config, "halign", "fill", 4, "fill", "start", "end", "center");
|
|
||||||
// content_halign = config_get_mnemonic(config, "content_halign", "fill", 4, "fill", "start", "end", "center");
|
|
||||||
// char* default_valign = "start";
|
|
||||||
// if(outer_orientation == GTK_ORIENTATION_HORIZONTAL) {
|
|
||||||
// default_valign = "center";
|
|
||||||
// }
|
|
||||||
// GtkAlign valign = config_get_mnemonic(config, "valign", default_valign, 4, "fill", "start", "end", "center");
|
|
||||||
// char* prompt = config_get(config, "prompt", mode);
|
|
||||||
// uint64_t filter_rate = strtol(config_get(config, "filter_rate", "100"), NULL, 10);
|
|
||||||
// allow_images = strcmp(config_get(config, "allow_images", "false"), "true") == 0;
|
|
||||||
// allow_markup = strcmp(config_get(config, "allow_markup", "false"), "true") == 0;
|
|
||||||
// image_size = strtol(config_get(config, "image_size", "32"), NULL, 10);
|
|
||||||
// cache_file = map_get(config, "cache_file");
|
|
||||||
// config_dir = map_get(config, "config_dir");
|
|
||||||
// terminal = map_get(config, "term");
|
|
||||||
// exec_search = strcmp(config_get(config, "exec_search", "false"), "true") == 0;
|
|
||||||
// bool hide_scroll = strcmp(config_get(config, "hide_scroll", "false"), "true") == 0;
|
|
||||||
// matching = config_get_mnemonic(config, "matching", "contains", 3, "contains", "multi-contains", "fuzzy");
|
|
||||||
// insensitive = strcmp(config_get(config, "insensitive", "false"), "true") == 0;
|
|
||||||
// parse_search = strcmp(config_get(config, "parse_search", "false"), "true") == 0;
|
|
||||||
// location = config_get_mnemonic(config, "location", "center", 18,
|
|
||||||
// "center", "top_left", "top", "top_right", "right", "bottom_right", "bottom", "bottom_left", "left",
|
|
||||||
// "0", "1", "2", "3", "4", "5", "6", "7", "8");
|
|
||||||
// no_actions = strcmp(config_get(config, "no_actions", "false"), "true") == 0;
|
|
||||||
// lines = strtol(config_get(config, "lines", "0"), NULL, 10);
|
|
||||||
// max_lines = lines;
|
|
||||||
// columns = strtol(config_get(config, "columns", "1"), NULL, 10);
|
|
||||||
// sort_order = config_get_mnemonic(config, "sort_order", "default", 2, "default", "alphabetical");
|
|
||||||
// bool global_coords = strcmp(config_get(config, "global_coords", "false"), "true") == 0;
|
|
||||||
// hide_search = strcmp(config_get(config, "hide_search", "false"), "true") == 0;
|
|
||||||
// char* search = map_get(config, "search");
|
|
||||||
// dynamic_lines = strcmp(config_get(config, "dynamic_lines", "false"), "true") == 0;
|
|
||||||
// char* monitor = map_get(config, "monitor");
|
|
||||||
// char* layer = config_get(config, "layer", "top");
|
|
||||||
// copy_exec = config_get(config, "copy_exec", "wl-copy");
|
|
||||||
// pre_display_cmd = map_get(config, "pre_display_cmd");
|
|
||||||
// pre_display_exec = strcmp(config_get(config, "pre_display_exec", "false"), "true") == 0;
|
|
||||||
// single_click = strcmp(config_get(config, "single_click", "false"), "true") == 0;
|
|
||||||
//
|
|
||||||
// keys = map_init_void();
|
|
||||||
// mods = map_init_void();
|
|
||||||
//
|
|
||||||
// map_put_void(mods, "Shift", &shift_mask);
|
|
||||||
// map_put_void(mods, "Ctrl", &ctrl_mask);
|
|
||||||
// map_put_void(mods, "Alt", &alt_mask);
|
|
||||||
//
|
|
||||||
// key_default = "Up";
|
|
||||||
// char* key_up = (i == 0) ? "Up" : config_get(config, "key_up", key_default);
|
|
||||||
// key_default = "Down";
|
|
||||||
// char* key_down = (i == 0) ? key_default : config_get(config, "key_down", key_default);
|
|
||||||
// key_default = "Left";
|
|
||||||
// char* key_left = (i == 0) ? key_default : config_get(config, "key_left", key_default);
|
|
||||||
// key_default = "Right";
|
|
||||||
// char* key_right = (i == 0) ? key_default : config_get(config, "key_right", key_default);
|
|
||||||
// key_default = "Tab";
|
|
||||||
// char* key_forward = (i == 0) ? key_default : config_get(config, "key_forward", key_default);
|
|
||||||
// key_default = "Shift-ISO_Left_Tab";
|
|
||||||
// char* key_backward = (i == 0) ? key_default : config_get(config, "key_backward", key_default);
|
|
||||||
// key_default = "Return";
|
|
||||||
// char* key_submit = (i == 0) ? key_default : config_get(config, "key_submit", key_default);
|
|
||||||
// key_default = "Escape";
|
|
||||||
// char* key_exit = (i == 0) ? key_default : config_get(config, "key_exit", key_default);
|
|
||||||
// key_default = "Page_Up";
|
|
||||||
// char* key_pgup = (i == 0) ? key_default : config_get(config, "key_pgup", key_default);
|
|
||||||
// key_default = "Page_Down";
|
|
||||||
// char* key_pgdn = (i == 0) ? key_default : config_get(config, "key_pgdn", key_default);
|
|
||||||
// key_default = "";
|
|
||||||
// char* key_expand = (i == 0) ? key_default: config_get(config, "key_expand", key_default);
|
|
||||||
// key_default = "";
|
|
||||||
// char* key_hide_search = (i == 0) ? key_default: config_get(config, "key_hide_search", key_default);
|
|
||||||
// key_default = "Ctrl-c";
|
|
||||||
// char* key_copy = (i == 0) ? key_default : config_get(config, "key_copy", key_default);
|
|
||||||
|
|
||||||
// allowed because option is needed for serde macro
|
|
||||||
#[allow(clippy::unnecessary_wraps)]
|
|
||||||
#[must_use]
|
|
||||||
pub fn default_style() -> Option<String> {
|
|
||||||
style_path(None)
|
style_path(None)
|
||||||
.ok()
|
.ok()
|
||||||
.map(|pb| pb.display().to_string())
|
.map(|pb| pb.display().to_string())
|
||||||
|
@ -572,26 +352,104 @@ pub fn default_style() -> Option<String> {
|
||||||
log::error!("no stylesheet found, using system styles");
|
log::error!("no stylesheet found, using system styles");
|
||||||
None
|
None
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// allowed because option is needed for serde macro
|
#[must_use]
|
||||||
#[allow(clippy::unnecessary_wraps)]
|
pub fn normal_window(&self) -> bool {
|
||||||
#[must_use]
|
self.normal_window
|
||||||
pub fn default_height() -> Option<String> {
|
}
|
||||||
Some("40%".to_owned())
|
|
||||||
}
|
|
||||||
|
|
||||||
// allowed because option is needed for serde macro
|
#[must_use]
|
||||||
#[allow(clippy::unnecessary_wraps)]
|
pub fn location(&self) -> Option<&Vec<Anchor>> {
|
||||||
#[must_use]
|
self.location.as_ref()
|
||||||
pub fn default_width() -> Option<String> {
|
}
|
||||||
Some("50%".to_owned())
|
|
||||||
}
|
|
||||||
|
|
||||||
// allowed because option is needed for serde macro
|
#[must_use]
|
||||||
#[allow(clippy::unnecessary_wraps)]
|
pub fn hide_scroll(&self) -> bool {
|
||||||
#[must_use]
|
self.hide_scroll.unwrap_or(false)
|
||||||
pub fn default_terminal() -> Option<String> {
|
}
|
||||||
|
|
||||||
|
#[must_use]
|
||||||
|
pub fn columns(&self) -> u32 {
|
||||||
|
self.columns.unwrap_or(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[must_use]
|
||||||
|
pub fn halign(&self) -> Align {
|
||||||
|
self.halign.unwrap_or(Align::Fill)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[must_use]
|
||||||
|
pub fn content_halign(&self) -> Align {
|
||||||
|
self.content_halign.unwrap_or(Align::Fill)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[must_use]
|
||||||
|
pub fn valign(&self) -> Align {
|
||||||
|
self.valign.unwrap_or(Align::Center)
|
||||||
|
}
|
||||||
|
#[must_use]
|
||||||
|
pub fn orientation(&self) -> Orientation {
|
||||||
|
self.orientation.unwrap_or(Orientation::Vertical)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[must_use]
|
||||||
|
pub fn prompt(&self) -> String {
|
||||||
|
match &self.prompt {
|
||||||
|
None => match &self.show {
|
||||||
|
None => String::new(),
|
||||||
|
Some(mode) => match mode {
|
||||||
|
Mode::Run => "run".to_owned(),
|
||||||
|
Mode::Drun => "drun".to_owned(),
|
||||||
|
Mode::Dmenu => "dmenu".to_owned(),
|
||||||
|
Mode::Math => "math".to_owned(),
|
||||||
|
Mode::File => "file".to_owned(),
|
||||||
|
Mode::Auto => "auto".to_owned(),
|
||||||
|
Mode::Ssh => "ssh".to_owned(),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
Some(prompt) => prompt.clone(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[must_use]
|
||||||
|
pub fn height(&self) -> String {
|
||||||
|
self.height.clone().unwrap_or("40%".to_owned())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[must_use]
|
||||||
|
pub fn width(&self) -> String {
|
||||||
|
self.width.clone().unwrap_or("50%".to_owned())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[must_use]
|
||||||
|
pub fn show_animation_time(&self) -> u64 {
|
||||||
|
self.show_animation_time.unwrap_or(10)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[must_use]
|
||||||
|
pub fn hide_animation_time(&self) -> u64 {
|
||||||
|
self.hide_animation_time.unwrap_or(10)
|
||||||
|
}
|
||||||
|
#[must_use]
|
||||||
|
pub fn row_bow_orientation(&self) -> Orientation {
|
||||||
|
self.row_bow_orientation.unwrap_or(Orientation::Horizontal)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[must_use]
|
||||||
|
pub fn allow_images(&self) -> bool {
|
||||||
|
self.allow_images.unwrap_or(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[must_use]
|
||||||
|
pub fn line_wrap(&self) -> WrapMode {
|
||||||
|
self.line_wrap.clone().unwrap_or(WrapMode::None)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[must_use]
|
||||||
|
pub fn term(&self) -> Option<String> {
|
||||||
|
self.term.clone().or_else(|| {
|
||||||
let terminals = [
|
let terminals = [
|
||||||
("gnome-terminal", vec!["--"]),
|
("gnome-terminal", vec!["--"]),
|
||||||
("konsole", vec!["-e"]),
|
("konsole", vec!["-e"]),
|
||||||
|
@ -604,47 +462,98 @@ pub fn default_terminal() -> Option<String> {
|
||||||
];
|
];
|
||||||
|
|
||||||
for (term, launch) in &terminals {
|
for (term, launch) in &terminals {
|
||||||
if which(term).is_ok() {
|
if which::which(term).is_ok() {
|
||||||
return Some(format!("{term} {}", launch.join(" ")));
|
return Some(format!("{} {}", term, launch.join(" ")));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
None
|
None
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
#[must_use]
|
||||||
|
pub fn show(&self) -> Option<Mode> {
|
||||||
|
self.show.clone()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// allowed because option is needed for serde macro
|
//
|
||||||
#[allow(clippy::unnecessary_wraps)]
|
// // TODO
|
||||||
#[must_use]
|
// // GtkOrientation orientation = config_get_mnemonic(config, "orientation", "vertical", 2, "vertical", "horizontal");
|
||||||
pub fn default_password_char() -> Option<String> {
|
// // outer_orientation = config_get_mnemonic(cstoonfig, "orientation", "vertical", 2, "horizontal", "vertical");
|
||||||
Some("*".to_owned())
|
// // GtkAlign halign = config_get_mnemonic(config, "halign", "fill", 4, "fill", "start", "end", "center");
|
||||||
}
|
// // content_halign = config_get_mnemonic(config, "content_halign", "fill", 4, "fill", "start", "end", "center");
|
||||||
|
// // char* default_valign = "start";
|
||||||
// allowed because option is needed for serde macro
|
// // if(outer_orientation == GTK_ORIENTATION_HORIZONTAL) {
|
||||||
#[allow(clippy::unnecessary_wraps)]
|
// // default_valign = "center";
|
||||||
#[must_use]
|
// // }
|
||||||
pub fn default_fuzzy_min_length() -> Option<i32> {
|
// // GtkAlign valign = config_get_mnemonic(config, "valign", default_valign, 4, "fill", "start", "end", "center");
|
||||||
Some(10)
|
// // char* prompt = config_get(config, "prompt", mode);
|
||||||
}
|
// // uint64_t filter_rate = strtol(config_get(config, "filter_rate", "100"), NULL, 10);
|
||||||
|
// // allow_images = strcmp(config_get(config, "allow_images", "false"), "true") == 0;
|
||||||
// allowed because option is needed for serde macro
|
// // allow_markup = strcmp(config_get(config, "allow_markup", "false"), "true") == 0;
|
||||||
#[allow(clippy::unnecessary_wraps)]
|
// // image_size = strtol(config_get(config, "image_size", "32"), NULL, 10);
|
||||||
#[must_use]
|
// // cache_file = map_get(config, "cache_file");
|
||||||
pub fn default_fuzzy_min_score() -> Option<f64> {
|
// // config_dir = map_get(config, "config_dir");
|
||||||
Some(0.0)
|
// // terminal = map_get(config, "term");
|
||||||
}
|
// // exec_search = strcmp(config_get(config, "exec_search", "false"), "true") == 0;
|
||||||
|
// // bool hide_scroll = strcmp(config_get(config, "hide_scroll", "false"), "true") == 0;
|
||||||
// allowed because option is needed for serde macro
|
// // matching = config_get_mnemonic(config, "matching", "contains", 3, "contains", "multi-contains", "fuzzy");
|
||||||
#[allow(clippy::unnecessary_wraps)]
|
// // insensitive = strcmp(config_get(config, "insensitive", "false"), "true") == 0;
|
||||||
#[must_use]
|
// // parse_search = strcmp(config_get(config, "parse_search", "false"), "true") == 0;
|
||||||
pub fn default_match_method() -> Option<MatchMethod> {
|
// // location = config_get_mnemonic(config, "location", "center", 18,
|
||||||
Some(MatchMethod::Contains)
|
// // "center", "top_left", "top", "top_right", "right", "bottom_right", "bottom", "bottom_left", "left",
|
||||||
}
|
// // "0", "1", "2", "3", "4", "5", "6", "7", "8");
|
||||||
|
// // no_actions = strcmp(config_get(config, "no_actions", "false"), "true") == 0;
|
||||||
// allowed because option is needed for serde macro
|
// // lines = strtol(config_get(config, "lines", "0"), NULL, 10);
|
||||||
#[allow(clippy::unnecessary_wraps)]
|
// // max_lines = lines;
|
||||||
#[must_use]
|
// // columns = strtol(config_get(config, "columns", "1"), NULL, 10);
|
||||||
pub fn default_image_size() -> Option<i32> {
|
// // sort_order = config_get_mnemonic(config, "sort_order", "default", 2, "default", "alphabetical");
|
||||||
Some(32)
|
// // bool global_coords = strcmp(config_get(config, "global_coords", "false"), "true") == 0;
|
||||||
}
|
// // hide_search = strcmp(config_get(config, "hide_search", "false"), "true") == 0;
|
||||||
|
// // char* search = map_get(config, "search");
|
||||||
|
// // dynamic_lines = strcmp(config_get(config, "dynamic_lines", "false"), "true") == 0;
|
||||||
|
// // char* monitor = map_get(config, "monitor");
|
||||||
|
// // char* layer = config_get(config, "layer", "top");
|
||||||
|
// // copy_exec = config_get(config, "copy_exec", "wl-copy");
|
||||||
|
// // pre_display_cmd = map_get(config, "pre_display_cmd");
|
||||||
|
// // pre_display_exec = strcmp(config_get(config, "pre_display_exec", "false"), "true") == 0;
|
||||||
|
// // single_click = strcmp(config_get(config, "single_click", "false"), "true") == 0;
|
||||||
|
// //
|
||||||
|
// // keys = map_init_void();
|
||||||
|
// // mods = map_init_void();
|
||||||
|
// //
|
||||||
|
// // map_put_void(mods, "Shift", &shift_mask);
|
||||||
|
// // map_put_void(mods, "Ctrl", &ctrl_mask);
|
||||||
|
// // map_put_void(mods, "Alt", &alt_mask);
|
||||||
|
// //
|
||||||
|
// // key_default = "Up";
|
||||||
|
// // char* key_up = (i == 0) ? "Up" : config_get(config, "key_up", key_default);
|
||||||
|
// // key_default = "Down";
|
||||||
|
// // char* key_down = (i == 0) ? key_default : config_get(config, "key_down", key_default);
|
||||||
|
// // key_default = "Left";
|
||||||
|
// // char* key_left = (i == 0) ? key_default : config_get(config, "key_left", key_default);
|
||||||
|
// // key_default = "Right";
|
||||||
|
// // char* key_right = (i == 0) ? key_default : config_get(config, "key_right", key_default);
|
||||||
|
// // key_default = "Tab";
|
||||||
|
// // char* key_forward = (i == 0) ? key_default : config_get(config, "key_forward", key_default);
|
||||||
|
// // key_default = "Shift-ISO_Left_Tab";
|
||||||
|
// // char* key_backward = (i == 0) ? key_default : config_get(config, "key_backward", key_default);
|
||||||
|
// // key_default = "Return";
|
||||||
|
// // char* key_submit = (i == 0) ? key_default : config_get(config, "key_submit", key_default);
|
||||||
|
// // key_default = "Escape";
|
||||||
|
// // char* key_exit = (i == 0) ? key_default : config_get(config, "key_exit", key_default);
|
||||||
|
// // key_default = "Page_Up";
|
||||||
|
// // char* key_pgup = (i == 0) ? key_default : config_get(config, "key_pgup", key_default);
|
||||||
|
// // key_default = "Page_Down";
|
||||||
|
// // char* key_pgdn = (i == 0) ? key_default : config_get(config, "key_pgdn", key_default);
|
||||||
|
// // key_default = "";
|
||||||
|
// // char* key_expand = (i == 0) ? key_default: config_get(config, "key_expand", key_default);
|
||||||
|
// // key_default = "";
|
||||||
|
// // char* key_hide_search = (i == 0) ? key_default: config_get(config, "key_hide_search", key_default);
|
||||||
|
// // key_default = "Ctrl-c";
|
||||||
|
// // char* key_copy = (i == 0) ? key_default : config_get(config, "key_copy", key_default);
|
||||||
|
// }
|
||||||
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn parse_args() -> Config {
|
pub fn parse_args() -> Config {
|
||||||
|
@ -654,7 +563,7 @@ pub fn parse_args() -> Config {
|
||||||
/// # Errors
|
/// # Errors
|
||||||
///
|
///
|
||||||
/// Will return Err when it cannot resolve any path or no style is found
|
/// Will return Err when it cannot resolve any path or no style is found
|
||||||
pub fn style_path(full_path: Option<String>) -> Result<PathBuf, anyhow::Error> {
|
fn style_path(full_path: Option<String>) -> Result<PathBuf, anyhow::Error> {
|
||||||
let alternative_paths = path_alternatives(
|
let alternative_paths = path_alternatives(
|
||||||
vec![dirs::config_dir()],
|
vec![dirs::config_dir()],
|
||||||
&PathBuf::from("worf").join("style.css"),
|
&PathBuf::from("worf").join("style.css"),
|
||||||
|
@ -720,24 +629,8 @@ pub fn load_config(args_opt: Option<Config>) -> Result<Config, ConfigurationErro
|
||||||
.map_err(|e| ConfigurationError::Parse(format!("{e}")))?;
|
.map_err(|e| ConfigurationError::Parse(format!("{e}")))?;
|
||||||
|
|
||||||
if let Some(args) = args_opt {
|
if let Some(args) = args_opt {
|
||||||
let mut merge_result = merge_config_with_args(&mut config, &args)
|
let merge_result = merge_config_with_args(&mut config, &args)
|
||||||
.map_err(|e| ConfigurationError::Parse(format!("{e}")))?;
|
.map_err(|e| ConfigurationError::Parse(format!("{e}")))?;
|
||||||
|
|
||||||
if merge_result.prompt.is_none() {
|
|
||||||
match &merge_result.show {
|
|
||||||
None => {}
|
|
||||||
Some(mode) => match mode {
|
|
||||||
Mode::Run => merge_result.prompt = Some("run".to_owned()),
|
|
||||||
Mode::Drun => merge_result.prompt = Some("drun".to_owned()),
|
|
||||||
Mode::Dmenu => merge_result.prompt = Some("dmenu".to_owned()),
|
|
||||||
Mode::Math => merge_result.prompt = Some("math".to_owned()),
|
|
||||||
Mode::File => merge_result.prompt = Some("file".to_owned()),
|
|
||||||
Mode::Auto => merge_result.prompt = Some("auto".to_owned()),
|
|
||||||
Mode::Ssh => merge_result.prompt = Some("ssh".to_owned()),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(merge_result)
|
Ok(merge_result)
|
||||||
} else {
|
} else {
|
||||||
Ok(config)
|
Ok(config)
|
||||||
|
|
104
src/lib/gui.rs
104
src/lib/gui.rs
|
@ -58,8 +58,8 @@ impl From<config::Orientation> for Orientation {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<&WrapMode> for NaturalWrapMode {
|
impl From<WrapMode> for NaturalWrapMode {
|
||||||
fn from(value: &WrapMode) -> Self {
|
fn from(value: WrapMode) -> Self {
|
||||||
match value {
|
match value {
|
||||||
WrapMode::None => NaturalWrapMode::None,
|
WrapMode::None => NaturalWrapMode::None,
|
||||||
WrapMode::Word => NaturalWrapMode::Word,
|
WrapMode::Word => NaturalWrapMode::Word,
|
||||||
|
@ -164,7 +164,7 @@ where
|
||||||
P: ItemProvider<T> + 'static + Clone + Send,
|
P: ItemProvider<T> + 'static + Clone + Send,
|
||||||
{
|
{
|
||||||
log::debug!("Starting GUI");
|
log::debug!("Starting GUI");
|
||||||
if let Some(ref css) = config.style {
|
if let Some(ref css) = config.style() {
|
||||||
let provider = CssProvider::new();
|
let provider = CssProvider::new();
|
||||||
let css_file_path = File::for_path(css);
|
let css_file_path = File::for_path(css);
|
||||||
provider.load_from_file(&css_file_path);
|
provider.load_from_file(&css_file_path);
|
||||||
|
@ -246,7 +246,7 @@ fn build_ui<T, P>(
|
||||||
|
|
||||||
ui_elements.window.set_widget_name("window");
|
ui_elements.window.set_widget_name("window");
|
||||||
|
|
||||||
if !config.normal_window {
|
if !config.normal_window() {
|
||||||
// Initialize the window as a layer
|
// Initialize the window as a layer
|
||||||
ui_elements.window.init_layer_shell();
|
ui_elements.window.init_layer_shell();
|
||||||
ui_elements
|
ui_elements
|
||||||
|
@ -260,13 +260,13 @@ fn build_ui<T, P>(
|
||||||
|
|
||||||
let window_done = Instant::now();
|
let window_done = Instant::now();
|
||||||
|
|
||||||
if let Some(location) = config.location.as_ref() {
|
if let Some(location) = config.location() {
|
||||||
for anchor in location {
|
for anchor in location {
|
||||||
ui_elements.window.set_anchor(anchor.into(), true);
|
ui_elements.window.set_anchor(anchor.into(), true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let outer_box = gtk4::Box::new(config.orientation.unwrap().into(), 0);
|
let outer_box = gtk4::Box::new(config.orientation().into(), 0);
|
||||||
outer_box.set_widget_name("outer-box");
|
outer_box.set_widget_name("outer-box");
|
||||||
outer_box.append(&ui_elements.search);
|
outer_box.append(&ui_elements.search);
|
||||||
ui_elements.window.set_child(Some(&outer_box));
|
ui_elements.window.set_child(Some(&outer_box));
|
||||||
|
@ -276,7 +276,7 @@ fn build_ui<T, P>(
|
||||||
scroll.set_hexpand(true);
|
scroll.set_hexpand(true);
|
||||||
scroll.set_vexpand(true);
|
scroll.set_vexpand(true);
|
||||||
|
|
||||||
if config.hide_scroll.is_some_and(|hs| hs) {
|
if config.hide_scroll() {
|
||||||
scroll.set_policy(PolicyType::External, PolicyType::External);
|
scroll.set_policy(PolicyType::External, PolicyType::External);
|
||||||
}
|
}
|
||||||
outer_box.append(&scroll);
|
outer_box.append(&scroll);
|
||||||
|
@ -321,16 +321,12 @@ fn build_main_box<T: Clone + 'static>(config: &Config, ui_elements: &Rc<UiElemen
|
||||||
.set_selection_mode(gtk4::SelectionMode::Browse);
|
.set_selection_mode(gtk4::SelectionMode::Browse);
|
||||||
ui_elements
|
ui_elements
|
||||||
.main_box
|
.main_box
|
||||||
.set_max_children_per_line(config.columns.unwrap());
|
.set_max_children_per_line(config.columns());
|
||||||
ui_elements.main_box.set_activate_on_single_click(true);
|
ui_elements.main_box.set_activate_on_single_click(true);
|
||||||
|
|
||||||
if let Some(halign) = config.halign {
|
ui_elements.main_box.set_halign(config.halign().into());
|
||||||
ui_elements.main_box.set_halign(halign.into());
|
ui_elements.main_box.set_valign(config.valign().into());
|
||||||
}
|
if config.orientation() == config::Orientation::Horizontal {
|
||||||
if let Some(valign) = config.valign {
|
|
||||||
ui_elements.main_box.set_valign(valign.into());
|
|
||||||
}
|
|
||||||
if config.orientation.unwrap() == config::Orientation::Horizontal {
|
|
||||||
ui_elements.main_box.set_valign(Align::Center);
|
ui_elements.main_box.set_valign(Align::Center);
|
||||||
ui_elements.main_box.set_orientation(Orientation::Vertical);
|
ui_elements.main_box.set_orientation(Orientation::Vertical);
|
||||||
} else {
|
} else {
|
||||||
|
@ -350,7 +346,7 @@ fn build_search_entry<T: Clone>(config: &Config, ui_elements: &UiElements<T>) {
|
||||||
ui_elements.search.set_css_classes(&["input"]);
|
ui_elements.search.set_css_classes(&["input"]);
|
||||||
ui_elements
|
ui_elements
|
||||||
.search
|
.search
|
||||||
.set_placeholder_text(config.prompt.as_deref());
|
.set_placeholder_text(Some(config.prompt().as_ref()));
|
||||||
ui_elements.search.set_can_focus(false);
|
ui_elements.search.set_can_focus(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -533,13 +529,11 @@ fn animate_window_show(config: &Config, window: ApplicationWindow) {
|
||||||
let monitor = display.monitor_at_surface(&surface);
|
let monitor = display.monitor_at_surface(&surface);
|
||||||
if let Some(monitor) = monitor {
|
if let Some(monitor) = monitor {
|
||||||
let geometry = monitor.geometry();
|
let geometry = monitor.geometry();
|
||||||
let Some(target_width) = percent_or_absolute(config.width.as_ref(), geometry.width())
|
let Some(target_width) = percent_or_absolute(&config.width(), geometry.width()) else {
|
||||||
else {
|
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
let Some(target_height) =
|
let Some(target_height) = percent_or_absolute(&config.height(), geometry.height())
|
||||||
percent_or_absolute(config.height.as_ref(), geometry.height())
|
|
||||||
else {
|
else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
@ -551,7 +545,7 @@ fn animate_window_show(config: &Config, window: ApplicationWindow) {
|
||||||
let animation_start = Instant::now();
|
let animation_start = Instant::now();
|
||||||
animate_window(
|
animate_window(
|
||||||
window,
|
window,
|
||||||
config.show_animation_time.unwrap_or(0),
|
config.show_animation_time(),
|
||||||
target_height,
|
target_height,
|
||||||
target_width,
|
target_width,
|
||||||
move || {
|
move || {
|
||||||
|
@ -568,13 +562,7 @@ where
|
||||||
// todo the target size might not work for higher dpi displays or bigger resolutions
|
// todo the target size might not work for higher dpi displays or bigger resolutions
|
||||||
window.set_child(Widget::NONE);
|
window.set_child(Widget::NONE);
|
||||||
|
|
||||||
animate_window(
|
animate_window(window, config.hide_animation_time(), 10, 10, on_done_func);
|
||||||
window,
|
|
||||||
config.hide_animation_time.unwrap_or(0),
|
|
||||||
10,
|
|
||||||
10,
|
|
||||||
on_done_func,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ease_in_out_cubic(t: f32) -> f32 {
|
fn ease_in_out_cubic(t: f32) -> f32 {
|
||||||
|
@ -782,23 +770,13 @@ fn create_menu_row<T: Clone + 'static>(
|
||||||
});
|
});
|
||||||
row.add_controller(click);
|
row.add_controller(click);
|
||||||
|
|
||||||
let row_box = gtk4::Box::new(
|
let row_box = gtk4::Box::new(meta.config.row_bow_orientation().into(), 0);
|
||||||
meta.config
|
|
||||||
.row_bow_orientation
|
|
||||||
.unwrap_or(config::Orientation::Horizontal)
|
|
||||||
.into(),
|
|
||||||
0,
|
|
||||||
);
|
|
||||||
row_box.set_hexpand(true);
|
row_box.set_hexpand(true);
|
||||||
row_box.set_vexpand(false);
|
row_box.set_vexpand(false);
|
||||||
row_box.set_halign(Align::Fill);
|
row_box.set_halign(Align::Fill);
|
||||||
|
|
||||||
row.set_child(Some(&row_box));
|
row.set_child(Some(&row_box));
|
||||||
if meta
|
if meta.config.allow_images() {
|
||||||
.config
|
|
||||||
.allow_images
|
|
||||||
.is_some_and(|allow_images| allow_images)
|
|
||||||
{
|
|
||||||
if let Some(image) = lookup_icon(element_to_add, &meta.config) {
|
if let Some(image) = lookup_icon(element_to_add, &meta.config) {
|
||||||
image.set_widget_name("img");
|
image.set_widget_name("img");
|
||||||
row_box.append(&image);
|
row_box.append(&image);
|
||||||
|
@ -806,26 +784,15 @@ fn create_menu_row<T: Clone + 'static>(
|
||||||
}
|
}
|
||||||
|
|
||||||
let label = Label::new(Some(element_to_add.label.as_str()));
|
let label = Label::new(Some(element_to_add.label.as_str()));
|
||||||
let wrap_mode: NaturalWrapMode = if let Some(config_wrap) = &meta.config.line_wrap {
|
|
||||||
config_wrap.into()
|
|
||||||
} else {
|
|
||||||
NaturalWrapMode::Word
|
|
||||||
};
|
|
||||||
|
|
||||||
label.set_natural_wrap_mode(wrap_mode);
|
label.set_natural_wrap_mode(meta.config.line_wrap().into());
|
||||||
label.set_hexpand(true);
|
label.set_hexpand(true);
|
||||||
label.set_widget_name("label");
|
label.set_widget_name("label");
|
||||||
label.set_wrap(true);
|
label.set_wrap(true);
|
||||||
row_box.append(&label);
|
row_box.append(&label);
|
||||||
|
|
||||||
if meta
|
if meta.config.content_halign().eq(&config::Align::Start)
|
||||||
.config
|
|| meta.config.content_halign().eq(&config::Align::Fill)
|
||||||
.content_halign
|
|
||||||
.is_some_and(|c| c == config::Align::Start)
|
|
||||||
|| meta
|
|
||||||
.config
|
|
||||||
.content_halign
|
|
||||||
.is_some_and(|c| c == config::Align::Fill)
|
|
||||||
{
|
{
|
||||||
label.set_xalign(0.0);
|
label.set_xalign(0.0);
|
||||||
}
|
}
|
||||||
|
@ -851,11 +818,7 @@ fn lookup_icon<T: Clone>(menu_item: &MenuItem<T>, config: &Config) -> Option<Ima
|
||||||
Image::from_icon_name(image_path)
|
Image::from_icon_name(image_path)
|
||||||
};
|
};
|
||||||
|
|
||||||
image.set_pixel_size(
|
image.set_pixel_size(config.image_size());
|
||||||
config
|
|
||||||
.image_size
|
|
||||||
.unwrap_or(config::default_image_size().unwrap()),
|
|
||||||
);
|
|
||||||
Some(image)
|
Some(image)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
@ -886,27 +849,14 @@ fn set_menu_visibility_for_search<T: Clone>(
|
||||||
&menu_item.label.to_lowercase()
|
&menu_item.label.to_lowercase()
|
||||||
);
|
);
|
||||||
|
|
||||||
let matching = if let Some(matching) = &config.matching {
|
let (search_sort_score, visible) = match config.match_method() {
|
||||||
matching
|
|
||||||
} else {
|
|
||||||
&config::default_match_method().unwrap()
|
|
||||||
};
|
|
||||||
|
|
||||||
let (search_sort_score, visible) = match matching {
|
|
||||||
MatchMethod::Fuzzy => {
|
MatchMethod::Fuzzy => {
|
||||||
let mut score = strsim::jaro_winkler(&query, &menu_item_search);
|
let mut score = strsim::jaro_winkler(&query, &menu_item_search);
|
||||||
if score == 0.0 {
|
if score == 0.0 {
|
||||||
score = -1.0;
|
score = -1.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
(
|
(score, score > config.fuzzy_min_score() && score > 0.0)
|
||||||
score,
|
|
||||||
score
|
|
||||||
> config
|
|
||||||
.fuzzy_min_score
|
|
||||||
.unwrap_or(config::default_fuzzy_min_score().unwrap_or(0.0))
|
|
||||||
&& score > 0.0,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
MatchMethod::Contains => {
|
MatchMethod::Contains => {
|
||||||
if menu_item_search.contains(&query) {
|
if menu_item_search.contains(&query) {
|
||||||
|
@ -948,8 +898,7 @@ fn select_first_visible_child<T: Clone>(ui: &UiElements<T>) {
|
||||||
// allowed because truncating is fine, we do no need the precision
|
// allowed because truncating is fine, we do no need the precision
|
||||||
#[allow(clippy::cast_possible_truncation)]
|
#[allow(clippy::cast_possible_truncation)]
|
||||||
#[allow(clippy::cast_precision_loss)]
|
#[allow(clippy::cast_precision_loss)]
|
||||||
fn percent_or_absolute(value: Option<&String>, base_value: i32) -> Option<i32> {
|
fn percent_or_absolute(value: &str, base_value: i32) -> Option<i32> {
|
||||||
if let Some(value) = value {
|
|
||||||
if value.contains('%') {
|
if value.contains('%') {
|
||||||
let value = value.replace('%', "").trim().to_string();
|
let value = value.replace('%', "").trim().to_string();
|
||||||
match value.parse::<i32>() {
|
match value.parse::<i32>() {
|
||||||
|
@ -959,9 +908,6 @@ fn percent_or_absolute(value: Option<&String>, base_value: i32) -> Option<i32> {
|
||||||
} else {
|
} else {
|
||||||
value.parse::<i32>().ok()
|
value.parse::<i32>().ok()
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sorts menu items in alphabetical order, while maintaining the initial score
|
/// Sorts menu items in alphabetical order, while maintaining the initial score
|
||||||
|
|
|
@ -533,17 +533,15 @@ pub fn auto(config: &Config) -> Result<(), Error> {
|
||||||
let mut provider = AutoItemProvider::new();
|
let mut provider = AutoItemProvider::new();
|
||||||
let cache_path = provider.drun.cache_path.clone();
|
let cache_path = provider.drun.cache_path.clone();
|
||||||
let mut cache = provider.drun.cache.clone();
|
let mut cache = provider.drun.cache.clone();
|
||||||
let mut cfg_clone = config.clone();
|
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
// todo ues a arc instead of cloning the config
|
// todo ues a arc instead of cloning the config
|
||||||
let selection_result = gui::show(cfg_clone.clone(), provider.clone(), true);
|
let selection_result = gui::show(config.clone(), provider.clone(), true);
|
||||||
|
|
||||||
if let Ok(mut selection_result) = selection_result {
|
if let Ok(mut selection_result) = selection_result {
|
||||||
if let Some(data) = &selection_result.data {
|
if let Some(data) = &selection_result.data {
|
||||||
match data {
|
match data {
|
||||||
AutoRunType::Math => {
|
AutoRunType::Math => {
|
||||||
cfg_clone.prompt = Some(selection_result.label.clone());
|
|
||||||
provider.math.elements.push(selection_result);
|
provider.math.elements.push(selection_result);
|
||||||
}
|
}
|
||||||
AutoRunType::DRun => {
|
AutoRunType::DRun => {
|
||||||
|
@ -603,8 +601,7 @@ fn ssh_launch<T: Clone>(menu_item: &MenuItem<T>, config: &Config) -> Result<(),
|
||||||
action.clone()
|
action.clone()
|
||||||
} else {
|
} else {
|
||||||
let cmd = config
|
let cmd = config
|
||||||
.term
|
.term()
|
||||||
.clone()
|
|
||||||
.map(|s| format!("{s} ssh {}", menu_item.label));
|
.map(|s| format!("{s} ssh {}", menu_item.label));
|
||||||
if let Some(cmd) = cmd {
|
if let Some(cmd) = cmd {
|
||||||
cmd
|
cmd
|
||||||
|
@ -615,7 +612,7 @@ fn ssh_launch<T: Clone>(menu_item: &MenuItem<T>, config: &Config) -> Result<(),
|
||||||
|
|
||||||
let cmd = format!(
|
let cmd = format!(
|
||||||
"{} bash -c \"source ~/.bashrc; {ssh_cmd}\"",
|
"{} bash -c \"source ~/.bashrc; {ssh_cmd}\"",
|
||||||
config.term.clone().unwrap_or_default()
|
config.term().unwrap_or_default()
|
||||||
);
|
);
|
||||||
spawn_fork(&cmd, menu_item.working_dir.as_ref())
|
spawn_fork(&cmd, menu_item.working_dir.as_ref())
|
||||||
}
|
}
|
||||||
|
@ -639,14 +636,12 @@ pub fn ssh(config: &Config) -> Result<(), Error> {
|
||||||
|
|
||||||
/// Shows the math mode
|
/// Shows the math mode
|
||||||
pub fn math(config: &Config) {
|
pub fn math(config: &Config) {
|
||||||
let mut cfg_clone = config.clone();
|
|
||||||
let mut calc: Vec<MenuItem<String>> = vec![];
|
let mut calc: Vec<MenuItem<String>> = vec![];
|
||||||
loop {
|
loop {
|
||||||
let mut provider = MathProvider::new(String::new());
|
let mut provider = MathProvider::new(String::new());
|
||||||
provider.add_elements(&mut calc.clone());
|
provider.add_elements(&mut calc.clone());
|
||||||
let selection_result = gui::show(cfg_clone.clone(), provider, true);
|
let selection_result = gui::show(config.clone(), provider, true);
|
||||||
if let Ok(mi) = selection_result {
|
if let Ok(mi) = selection_result {
|
||||||
cfg_clone.prompt = Some(mi.label.clone());
|
|
||||||
calc.push(mi);
|
calc.push(mi);
|
||||||
} else {
|
} else {
|
||||||
log::error!("No item selected");
|
log::error!("No item selected");
|
||||||
|
|
|
@ -14,7 +14,7 @@ fn main() -> anyhow::Result<()> {
|
||||||
let args = config::parse_args();
|
let args = config::parse_args();
|
||||||
let config = config::load_config(Some(args)).map_err(|e| anyhow!(e))?;
|
let config = config::load_config(Some(args)).map_err(|e| anyhow!(e))?;
|
||||||
|
|
||||||
if let Some(show) = &config.show {
|
if let Some(show) = &config.show() {
|
||||||
match show {
|
match show {
|
||||||
Mode::Run => {
|
Mode::Run => {
|
||||||
todo!("run not implemented")
|
todo!("run not implemented")
|
||||||
|
|
Loading…
Add table
Reference in a new issue