Add EWW_CONFIG_DIR, EWW_CMD, EWW_EXECUTABLE variables
This commit is contained in:
parent
c0dcc43336
commit
6b5c35cbf9
5 changed files with 113 additions and 66 deletions
|
@ -32,6 +32,7 @@ All notable changes to eww will be listed here, starting at changes since versio
|
|||
- Add `matches` function
|
||||
- Add transform widget (By: druskus20)
|
||||
- Add `:onaccept` to input field, add `:onclick` to eventbox
|
||||
- Add `EWW_CMD`, `EWW_CONFIG_DIR`, `EWW_EXECUTABLE` magic variables
|
||||
|
||||
### Notable Internal changes
|
||||
- Rework state management completely, now making local state and dynamic widget hierarchy changes possible.
|
||||
|
|
|
@ -126,7 +126,7 @@ impl App {
|
|||
DaemonCommand::ReloadConfigAndCss(sender) => {
|
||||
let mut errors = Vec::new();
|
||||
|
||||
let config_result = config::read_from_file(&self.paths.get_yuck_path());
|
||||
let config_result = config::read_from_eww_paths(&self.paths);
|
||||
if let Err(e) = config_result.and_then(|new_config| self.load_config(new_config)) {
|
||||
errors.push(e)
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use anyhow::{bail, Context, Result};
|
||||
use eww_shared_util::VarName;
|
||||
use std::{collections::HashMap, path::Path};
|
||||
use std::collections::HashMap;
|
||||
use yuck::{
|
||||
config::{
|
||||
file_provider::YuckFiles, script_var_definition::ScriptVarDefinition, validate::ValidationError,
|
||||
|
@ -11,14 +11,15 @@ use yuck::{
|
|||
|
||||
use simplexpr::dynval::DynVal;
|
||||
|
||||
use crate::error_handling_ctx;
|
||||
use crate::{config::inbuilt, error_handling_ctx, widgets::widget_definitions, EwwPaths};
|
||||
|
||||
use super::script_var;
|
||||
|
||||
/// Load an [EwwConfig] from a given file, resetting and applying the global YuckFiles object in [`crate::error_handling_ctx`].
|
||||
pub fn read_from_file(path: impl AsRef<Path>) -> Result<EwwConfig> {
|
||||
/// Load an [`EwwConfig`] from the config dir of the given [`crate::EwwPaths`],
|
||||
/// resetting and applying the global YuckFiles object in [`crate::error_handling_ctx`].
|
||||
pub fn read_from_eww_paths(eww_paths: &EwwPaths) -> Result<EwwConfig> {
|
||||
error_handling_ctx::clear_files();
|
||||
EwwConfig::read_from_file(&mut error_handling_ctx::YUCK_FILES.write().unwrap(), path)
|
||||
EwwConfig::read_from_dir(&mut error_handling_ctx::YUCK_FILES.write().unwrap(), eww_paths)
|
||||
}
|
||||
|
||||
/// Eww configuration structure.
|
||||
|
@ -46,25 +47,34 @@ impl Default for EwwConfig {
|
|||
}
|
||||
|
||||
impl EwwConfig {
|
||||
pub fn read_from_file(files: &mut YuckFiles, path: impl AsRef<Path>) -> Result<Self> {
|
||||
if !path.as_ref().exists() {
|
||||
bail!("The configuration file `{}` does not exist", path.as_ref().display());
|
||||
/// Load an [`EwwConfig`] from the config dir of the given [`crate::EwwPaths`], reading the main config file.
|
||||
pub fn read_from_dir(files: &mut YuckFiles, eww_paths: &EwwPaths) -> Result<Self> {
|
||||
let yuck_path = eww_paths.get_yuck_path();
|
||||
if !yuck_path.exists() {
|
||||
bail!("The configuration file `{}` does not exist", yuck_path.display());
|
||||
}
|
||||
let config = Config::generate_from_main_file(files, path)?;
|
||||
let config = Config::generate_from_main_file(files, yuck_path)?;
|
||||
|
||||
// run some validations on the configuration
|
||||
yuck::config::validate::validate(&config, super::inbuilt::get_inbuilt_vars().keys().cloned().collect())?;
|
||||
let magic_globals: Vec<_> = inbuilt::MAGIC_CONSTANT_NAMES
|
||||
.into_iter()
|
||||
.chain(inbuilt::MAGIC_CONSTANT_NAMES)
|
||||
.into_iter()
|
||||
.map(|x| VarName::from(x.clone()))
|
||||
.collect();
|
||||
yuck::config::validate::validate(&config, magic_globals)?;
|
||||
|
||||
for (name, def) in &config.widget_definitions {
|
||||
if crate::widgets::widget_definitions::BUILTIN_WIDGET_NAMES.contains(&name.as_str()) {
|
||||
if widget_definitions::BUILTIN_WIDGET_NAMES.contains(&name.as_str()) {
|
||||
return Err(
|
||||
AstError::ValidationError(ValidationError::AccidentalBuiltinOverride(def.span, name.to_string())).into()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
let Config { widget_definitions, window_definitions, var_definitions, mut script_vars } = config;
|
||||
script_vars.extend(crate::config::inbuilt::get_inbuilt_vars());
|
||||
let Config { widget_definitions, window_definitions, mut var_definitions, mut script_vars } = config;
|
||||
script_vars.extend(inbuilt::get_inbuilt_vars());
|
||||
var_definitions.extend(inbuilt::get_magic_constants(eww_paths));
|
||||
|
||||
let mut poll_var_links = HashMap::<VarName, Vec<VarName>>::new();
|
||||
script_vars
|
||||
|
|
|
@ -1,60 +1,96 @@
|
|||
use std::{collections::HashMap, time::Duration};
|
||||
|
||||
use simplexpr::{dynval::DynVal, SimplExpr};
|
||||
use yuck::config::script_var_definition::{PollScriptVar, ScriptVarDefinition, VarSource};
|
||||
use yuck::config::{
|
||||
script_var_definition::{PollScriptVar, ScriptVarDefinition, VarSource},
|
||||
var_definition::VarDefinition,
|
||||
};
|
||||
|
||||
use crate::config::system_stats::*;
|
||||
use crate::{config::system_stats::*, EwwPaths};
|
||||
use eww_shared_util::VarName;
|
||||
|
||||
macro_rules! builtin_vars {
|
||||
($interval:expr, $($name:literal => $fun:expr),*$(,)?) => {{
|
||||
maplit::hashmap! {
|
||||
$(
|
||||
VarName::from($name) => ScriptVarDefinition::Poll(PollScriptVar {
|
||||
name: VarName::from($name),
|
||||
run_while_expr: SimplExpr::Literal(DynVal::from(true)),
|
||||
run_while_var_refs: Vec::new(),
|
||||
command: VarSource::Function($fun),
|
||||
initial_value: None,
|
||||
interval: $interval,
|
||||
name_span: eww_shared_util::span::Span::DUMMY,
|
||||
})
|
||||
),*
|
||||
}
|
||||
}}}
|
||||
|
||||
pub fn get_inbuilt_vars() -> HashMap<VarName, ScriptVarDefinition> {
|
||||
builtin_vars! {Duration::new(2, 0),
|
||||
// @desc EWW_TEMPS - Heat of the components in Celcius
|
||||
// @prop { <name>: temperature }
|
||||
"EWW_TEMPS" => || Ok(DynVal::from(get_temperatures())),
|
||||
|
||||
// @desc EWW_RAM - Information on ram and swap usage in kB.
|
||||
// @prop { total_mem, free_mem, total_swap, free_swap, available_mem, used_mem, used_mem_perc }
|
||||
"EWW_RAM" => || Ok(DynVal::from(get_ram())),
|
||||
|
||||
// @desc EWW_DISK - Information on on all mounted partitions (Might report inaccurately on some filesystems, like btrfs)\nExample: `{EWW_DISK["/"]}`
|
||||
// @prop { <mount_point>: { name, total, free, used, used_perc } }
|
||||
"EWW_DISK" => || Ok(DynVal::from(get_disks())),
|
||||
|
||||
// @desc EWW_BATTERY - Battery capacity in procent of the main battery
|
||||
// @prop { <name>: { capacity, status } }
|
||||
"EWW_BATTERY" => || Ok(DynVal::from(
|
||||
match get_battery_capacity() {
|
||||
Err(e) => {
|
||||
log::error!("Couldn't get the battery capacity: {:?}", e);
|
||||
"Error: Check `eww log` for more details".to_string()
|
||||
}
|
||||
Ok(o) => o,
|
||||
macro_rules! define_builtin_vars {
|
||||
($interval:expr, $($name:literal => $fun:expr),*$(,)?) => {
|
||||
pub static INBUILT_VAR_NAMES: &[&'static str] = &[$($name),*];
|
||||
pub fn get_inbuilt_vars() -> HashMap<VarName, ScriptVarDefinition> {
|
||||
maplit::hashmap! {
|
||||
$(
|
||||
VarName::from($name) => ScriptVarDefinition::Poll(PollScriptVar {
|
||||
name: VarName::from($name),
|
||||
run_while_expr: SimplExpr::Literal(DynVal::from(true)),
|
||||
run_while_var_refs: Vec::new(),
|
||||
command: VarSource::Function($fun),
|
||||
initial_value: None,
|
||||
interval: $interval,
|
||||
name_span: eww_shared_util::span::Span::DUMMY,
|
||||
})
|
||||
),*
|
||||
}
|
||||
)),
|
||||
|
||||
// @desc EWW_CPU - Information on the CPU cores: frequency and usage (No MacOS support)
|
||||
// @prop { cores: [{ core, freq, usage }], avg }
|
||||
"EWW_CPU" => || Ok(DynVal::from(get_cpus())),
|
||||
|
||||
// @desc EWW_NET - Bytes up/down on all interfaces
|
||||
// @prop { <name>: { up, down } }
|
||||
"EWW_NET" => || Ok(DynVal::from(net())),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
define_builtin_vars! { Duration::new(2, 0),
|
||||
// @desc EWW_TEMPS - Heat of the components in Celcius
|
||||
// @prop { <name>: temperature }
|
||||
"EWW_TEMPS" => || Ok(DynVal::from(get_temperatures())),
|
||||
|
||||
// @desc EWW_RAM - Information on ram and swap usage in kB.
|
||||
// @prop { total_mem, free_mem, total_swap, free_swap, available_mem, used_mem, used_mem_perc }
|
||||
"EWW_RAM" => || Ok(DynVal::from(get_ram())),
|
||||
|
||||
// @desc EWW_DISK - Information on on all mounted partitions (Might report inaccurately on some filesystems, like btrfs)\nExample: `{EWW_DISK["/"]}`
|
||||
// @prop { <mount_point>: { name, total, free, used, used_perc } }
|
||||
"EWW_DISK" => || Ok(DynVal::from(get_disks())),
|
||||
|
||||
// @desc EWW_BATTERY - Battery capacity in procent of the main battery
|
||||
// @prop { <name>: { capacity, status } }
|
||||
"EWW_BATTERY" => || Ok(DynVal::from(
|
||||
match get_battery_capacity() {
|
||||
Err(e) => {
|
||||
log::error!("Couldn't get the battery capacity: {:?}", e);
|
||||
"Error: Check `eww log` for more details".to_string()
|
||||
}
|
||||
Ok(o) => o,
|
||||
}
|
||||
)),
|
||||
|
||||
// @desc EWW_CPU - Information on the CPU cores: frequency and usage (No MacOS support)
|
||||
// @prop { cores: [{ core, freq, usage }], avg }
|
||||
"EWW_CPU" => || Ok(DynVal::from(get_cpus())),
|
||||
|
||||
// @desc EWW_NET - Bytes up/down on all interfaces
|
||||
// @prop { <name>: { up, down } }
|
||||
"EWW_NET" => || Ok(DynVal::from(net())),
|
||||
}
|
||||
|
||||
macro_rules! define_magic_constants {
|
||||
($eww_paths:ident, $($name:literal => $value:expr),*$(,)?) => {
|
||||
pub static MAGIC_CONSTANT_NAMES: &[&'static str] = &[$($name),*];
|
||||
pub fn get_magic_constants($eww_paths: &EwwPaths) -> HashMap<VarName, VarDefinition> {
|
||||
maplit::hashmap! {
|
||||
$(VarName::from($name) => VarDefinition {
|
||||
name: VarName::from($name),
|
||||
initial_value: $value,
|
||||
span: eww_shared_util::span::Span::DUMMY
|
||||
}),*
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
define_magic_constants! { eww_paths,
|
||||
// @desc EWW_CONFIG_DIR - Path to the eww configuration of the current process
|
||||
"EWW_CONFIG_DIR" => DynVal::from_string(eww_paths.get_config_dir().to_string_lossy().into_owned()),
|
||||
|
||||
// @desc EWW_CMD - eww command running in the current configuration, useful in event handlers. I.e.: `:onclick "${EWW_CMD} update foo=bar"`
|
||||
"EWW_CMD" => DynVal::from_string(
|
||||
format!("\"{}\" --config \"{}\"",
|
||||
std::env::current_exe().map(|x| x.to_string_lossy().into_owned()).unwrap_or_else(|_| "eww".to_string()),
|
||||
eww_paths.get_config_dir().to_string_lossy().into_owned()
|
||||
)
|
||||
),
|
||||
// @desc EWW_EXECUTABLE - Full path of the eww executable
|
||||
"EWW_EXECUTABLE" => DynVal::from_string(
|
||||
std::env::current_exe().map(|x| x.to_string_lossy().into_owned()).unwrap_or_else(|_| "eww".to_string()),
|
||||
),
|
||||
}
|
||||
|
|
|
@ -24,7 +24,7 @@ pub fn initialize_server(paths: EwwPaths, action: Option<DaemonCommand>, should_
|
|||
|
||||
log::info!("Loading paths: {}", &paths);
|
||||
|
||||
let read_config = config::read_from_file(&paths.get_yuck_path());
|
||||
let read_config = config::read_from_eww_paths(&paths);
|
||||
|
||||
let eww_config = match read_config {
|
||||
Ok(config) => config,
|
||||
|
|
Loading…
Add table
Reference in a new issue