From 7648a400c3b2d8e0a38c6c1a8543442be8e0ddcd Mon Sep 17 00:00:00 2001
From: legendofmiracles <30902201+legendofmiracles@users.noreply.github.com>
Date: Sun, 31 Jan 2021 15:11:52 +0000
Subject: [PATCH] Shows warnings when defining variables that are already
defined, and other general improvements (#105)
* refactored everything into a function, and checks the larger/smaller one
* general improvements
* Simplify code
Co-authored-by: elkowar <5300871+elkowar@users.noreply.github.com>
---
docs/content/main/configuration.md | 6 ++-
src/app.rs | 2 +-
src/config/eww_config.rs | 66 ++++++++++++++++++++++--------
src/main.rs | 2 +-
4 files changed, 54 insertions(+), 22 deletions(-)
diff --git a/docs/content/main/configuration.md b/docs/content/main/configuration.md
index a9ad2fe..aefced7 100644
--- a/docs/content/main/configuration.md
+++ b/docs/content/main/configuration.md
@@ -118,11 +118,13 @@ Here you can include other config files so that they are merged together at star
```xml
-
-
+
+
```
+If you define a variable/widget/window, in a config file, when it's defined somewhere else, you can see a warning in the eww logs (`eww logs`)
+
### The `` block
In here you whole widget will be made, and you can also create your own widgets. Check [Widget Documentation](@/main/widgets.md) for pre-defined widgets.
diff --git a/src/app.rs b/src/app.rs
index 4c930ba..7a0d8e5 100644
--- a/src/app.rs
+++ b/src/app.rs
@@ -265,7 +265,7 @@ impl App {
// TODO somehow make this less shit
for newly_used_var in self
.variables_only_used_in(&window_name)
- .filter_map(|var| self.eww_config.get_script_var(&var))
+ .filter_map(|var| self.eww_config.get_script_var(&var).ok())
{
self.script_var_handler.add(newly_used_var.clone());
}
diff --git a/src/config/eww_config.rs b/src/config/eww_config.rs
index f11008e..ff0f0c2 100644
--- a/src/config/eww_config.rs
+++ b/src/config/eww_config.rs
@@ -14,24 +14,41 @@ use super::{
use std::path::PathBuf;
#[derive(Debug, Clone)]
+/// Structure to hold the eww config
pub struct EwwConfig {
widgets: HashMap,
windows: HashMap,
initial_variables: HashMap,
-
- // TODO make this a hashmap
- script_vars: Vec,
+ script_vars: HashMap,
pub filepath: PathBuf,
}
impl EwwConfig {
pub fn merge_includes(mut eww_config: EwwConfig, includes: Vec) -> Result {
- // TODO issue warnings on conflict
- for config in includes {
- eww_config.widgets.extend(config.widgets);
- eww_config.windows.extend(config.windows);
- eww_config.script_vars.extend(config.script_vars);
- eww_config.initial_variables.extend(config.initial_variables);
+ let config_path = eww_config.filepath.clone();
+ let log_conflict = |what: &str, conflict: &str, included_path: &std::path::PathBuf| {
+ eprintln!(
+ "{} '{}' defined twice (defined in {} and in {})",
+ what,
+ conflict,
+ config_path.display(),
+ included_path.display()
+ );
+ };
+
+ for included_config in includes {
+ for conflict in extend_safe(&mut eww_config.widgets, included_config.widgets) {
+ log_conflict("widget", &conflict, &included_config.filepath)
+ }
+ for conflict in extend_safe(&mut eww_config.windows, included_config.windows) {
+ log_conflict("window", &conflict.to_string(), &included_config.filepath)
+ }
+ for conflict in extend_safe(&mut eww_config.script_vars, included_config.script_vars) {
+ log_conflict("script-var", &conflict.to_string(), &included_config.filepath)
+ }
+ for conflict in extend_safe(&mut eww_config.initial_variables, included_config.initial_variables) {
+ log_conflict("var", &conflict.to_string(), &included_config.filepath)
+ }
}
Ok(eww_config)
}
@@ -118,7 +135,7 @@ impl EwwConfig {
let mut vars = self
.script_vars
.iter()
- .map(|var| Ok((var.name().clone(), var.initial_value()?)))
+ .map(|var| Ok((var.0.clone(), var.1.initial_value()?)))
.collect::>>()?;
vars.extend(self.get_default_vars().clone());
Ok(vars)
@@ -142,18 +159,20 @@ impl EwwConfig {
&self.initial_variables
}
- pub fn get_script_vars(&self) -> &Vec {
- &self.script_vars
+ pub fn get_script_vars(&self) -> Vec {
+ self.script_vars.values().cloned().collect()
}
- pub fn get_script_var(&self, name: &VarName) -> Option<&ScriptVar> {
- self.script_vars.iter().find(|x| x.name() == name)
+ pub fn get_script_var(&self, name: &VarName) -> Result<&ScriptVar> {
+ self.script_vars
+ .get(name)
+ .with_context(|| format!("No script var named '{}' exists", name))
}
}
-fn parse_variables_block(xml: XmlElement) -> Result<(HashMap, Vec)> {
+fn parse_variables_block(xml: XmlElement) -> Result<(HashMap, HashMap)> {
let mut normal_vars = HashMap::new();
- let mut script_vars = Vec::new();
+ let mut script_vars = HashMap::new();
for node in xml.child_elements() {
match node.tag_name() {
"var" => {
@@ -165,7 +184,8 @@ fn parse_variables_block(xml: XmlElement) -> Result<(HashMap {
- script_vars.push(ScriptVar::from_xml_element(node)?);
+ let script_var = ScriptVar::from_xml_element(node)?;
+ script_vars.insert(script_var.name().clone(), script_var);
}
_ => bail!("Illegal element in variables block: {}", node.as_tag_string()),
}
@@ -187,6 +207,16 @@ fn join_path_pretty, P2: AsRef>(a: P,
}
}
+/// extends a hashmap, returning a list of keys that already where present in the hashmap.
+fn extend_safe>(
+ a: &mut HashMap,
+ b: T,
+) -> Vec {
+ b.into_iter()
+ .filter_map(|(k, v)| a.insert(k.clone(), v).map(|_| k.clone()))
+ .collect()
+}
+
#[cfg(test)]
mod test {
use crate::config::{EwwConfig, XmlNode};
@@ -254,7 +284,7 @@ mod test {
widgets: HashMap::new(),
windows: HashMap::new(),
initial_variables: HashMap::new(),
- script_vars: Vec::new(),
+ script_vars: HashMap::new(),
filepath: "test_path".into(),
};
diff --git a/src/main.rs b/src/main.rs
index 9d4fa46..51fbb95 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -90,7 +90,7 @@ fn main() {
} else {
log::info!("Initializing Eww server.");
let _ = std::fs::remove_file(&*crate::IPC_SOCKET_PATH);
- println!("Run `eww logs` to see any errors, warnings or informatiion while editing your configuration.");
+ println!("Run `eww logs` to see any errors, warnings or information while editing your configuration.");
server::initialize_server()?;
}
}