From c57713ca9a4a4f6b112161ca9914915a006684d8 Mon Sep 17 00:00:00 2001
From: Safin Singh <42120904+safinsingh@users.noreply.github.com>
Date: Tue, 13 Oct 2020 09:57:50 -0700
Subject: [PATCH] CI/CD & Formatting (#6)
* Improve autoformatting guides, add editorconfig and add CI/CD
---
.editorconfig | 8 +++++
.github/workflows/build.yml | 26 +++++++++++++++
.github/workflows/fmt.yml | 26 +++++++++++++++
.github/workflows/test.yml | 26 +++++++++++++++
Cargo.toml | 6 ----
README.md | 27 ++++++----------
rustfmt.toml | 17 +++++++---
src/config/element.rs | 7 ++--
src/config/mod.rs | 14 +++++---
src/config/xml_ext.rs | 2 ++
src/eww_state.rs | 36 +++++++++++----------
src/main.rs | 14 ++++----
src/script_var_handler.rs | 3 +-
src/util.rs | 7 ++--
src/value.rs | 17 +++++++---
src/widgets/mod.rs | 53 +++++++++++++++++--------------
src/widgets/widget_definitions.rs | 18 +++++------
17 files changed, 209 insertions(+), 98 deletions(-)
create mode 100644 .editorconfig
create mode 100644 .github/workflows/build.yml
create mode 100644 .github/workflows/fmt.yml
create mode 100644 .github/workflows/test.yml
diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 0000000..e753483
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,8 @@
+root = true
+
+[*]
+indent_style = space
+indent_size = 4
+end_of_line = lf
+insert_final_newline = true
+trim_trailing_whitespace = true
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
new file mode 100644
index 0000000..f1b7556
--- /dev/null
+++ b/.github/workflows/build.yml
@@ -0,0 +1,26 @@
+name: build
+
+on:
+ push:
+ branches: [main]
+ pull_request:
+ branches: [main]
+
+env:
+ CARGO_TERM_COLOR: always
+
+jobs:
+ build:
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Set up
+ uses: actions-rs/toolchain@v1
+ with:
+ toolchain: nightly
+ override: true
+ components: rustfmt
+
+ - uses: actions/checkout@v2
+ - name: Format
+ run: cargo build
diff --git a/.github/workflows/fmt.yml b/.github/workflows/fmt.yml
new file mode 100644
index 0000000..ead5199
--- /dev/null
+++ b/.github/workflows/fmt.yml
@@ -0,0 +1,26 @@
+name: format
+
+on:
+ push:
+ branches: [main]
+ pull_request:
+ branches: [main]
+
+env:
+ CARGO_TERM_COLOR: always
+
+jobs:
+ fmt:
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Set up
+ uses: actions-rs/toolchain@v1
+ with:
+ toolchain: nightly
+ override: true
+ components: rustfmt
+
+ - uses: actions/checkout@v2
+ - name: Format
+ run: cargo fmt -- --check
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
new file mode 100644
index 0000000..e657d52
--- /dev/null
+++ b/.github/workflows/test.yml
@@ -0,0 +1,26 @@
+name: test
+
+on:
+ push:
+ branches: [main]
+ pull_request:
+ branches: [main]
+
+env:
+ CARGO_TERM_COLOR: always
+
+jobs:
+ test:
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Set up
+ uses: actions-rs/toolchain@v1
+ with:
+ toolchain: nightly
+ override: true
+ components: rustfmt
+
+ - uses: actions/checkout@v2
+ - name: Test
+ run: cargo test --verbose
diff --git a/Cargo.toml b/Cargo.toml
index 4a25298..6d8b156 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -4,8 +4,6 @@ version = "0.1.0"
authors = ["elkowar <5300871+elkowar@users.noreply.github.com>"]
edition = "2018"
-# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
-
[dependencies]
gtk = { version = "0.9", features = [ "v3_16" ] }
gdk = { version = "", features = ["v3_16"] }
@@ -13,7 +11,6 @@ gio = { version = "", features = ["v2_44"] }
glib = { version = "", features = ["v2_44"] }
gdk-pixbuf = "0.9"
-
regex = "1"
try_match = "0.2.2"
anyhow = "1.0"
@@ -39,8 +36,5 @@ lazy_static = "1.4.0"
libc = "0.2"
ref-cast = "1.0"
-#thiserror = "1.0"
-
[dev-dependencies]
pretty_assertions = "0.6.1"
-
diff --git a/README.md b/README.md
index 33f4305..ae842d4 100644
--- a/README.md
+++ b/README.md
@@ -1,15 +1,12 @@
-
# Table of Contents
-* [About](#org4ab08b6)
-* [Configuration](#org581ca61)
- * [Example Config](#orgb769597)
-* [Building](#orgbf66ce2)
- * [Prerequisites](#org727b3da)
- * [Installation](#orgdd31739)
-* [Usage](#org4a9b3c6)
-
-
+- [About](#org4ab08b6)
+- [Configuration](#org581ca61)
+ - [Example Config](#orgb769597)
+- [Building](#orgbf66ce2)
+ - [Prerequisites](#org727b3da)
+ - [Installation](#orgdd31739)
+- [Usage](#org4a9b3c6)
@@ -17,17 +14,16 @@
Elkowar’s Wacky Widgets is a standalone Widget System made in rust to add AwesomeWM like widgets to any WM
-
# Configuration
Eww’s configuration should be placed in `~/.config/eww/eww.xml` and any `scss` styles you want to add should be put into `~/.config/eww/eww.scss`.
-
## Example Config
+
```xml
@@ -66,17 +62,16 @@ Eww’s configuration should be placed in `~/.config/eww/eww.xml` and any `s
# Building
-
## Prerequisites
-- cargo with nightly toolchain
+- rustc
+- cargo (nightly toolchain)
Rather than with your system package manager, I recommend installing it using [rustup](https://rustup.rs/),
as this makes it easy to use the nightly toolchain, which is necessary to build eww.
-
## Installation
@@ -89,10 +84,8 @@ Build the Binary using -:
then copy the built binary from `./target/release` to anywhere in `$PATH` (example - `~/.local/bin`)
-
# Usage
Create a Config and then just do `eww`!
-
diff --git a/rustfmt.toml b/rustfmt.toml
index 7e7e554..a989f2b 100644
--- a/rustfmt.toml
+++ b/rustfmt.toml
@@ -1,4 +1,13 @@
-unstable_features=true
-fn_single_line=false
-max_width=130
-
+unstable_features = true
+fn_single_line = false
+max_width = 130
+reorder_impl_items = true
+merge_imports = true
+normalize_comments = true
+use_field_init_shorthand = true
+wrap_comments = true
+combine_control_expr = false
+condense_wildcard_suffixes = true
+format_code_in_doc_comments = true
+format_macro_matchers = true
+format_strings = true
diff --git a/src/config/element.rs b/src/config/element.rs
index fe49dcd..07f5b62 100644
--- a/src/config/element.rs
+++ b/src/config/element.rs
@@ -3,9 +3,10 @@ use lazy_static::lazy_static;
use regex::Regex;
use std::ops::Range;
-use crate::value::AttrValue;
-use crate::value::VarName;
-use crate::with_text_pos_context;
+use crate::{
+ value::{AttrValue, VarName},
+ with_text_pos_context,
+};
use maplit::hashmap;
use std::collections::HashMap;
diff --git a/src/config/mod.rs b/src/config/mod.rs
index 4a2555f..314b0a8 100644
--- a/src/config/mod.rs
+++ b/src/config/mod.rs
@@ -1,12 +1,12 @@
-use crate::util;
-use crate::value::PrimitiveValue;
-use crate::value::VarName;
+use crate::{
+ util,
+ value::{PrimitiveValue, VarName},
+};
use anyhow::*;
use derive_more;
use element::*;
use serde::{Deserialize, Serialize};
-use std::collections::HashMap;
-use std::fmt;
+use std::{collections::HashMap, fmt};
use util::Coords;
use xml_ext::*;
@@ -134,12 +134,15 @@ impl EwwConfig {
pub fn get_widgets(&self) -> &HashMap {
&self.widgets
}
+
pub fn get_windows(&self) -> &HashMap {
&self.windows
}
+
pub fn get_default_vars(&self) -> &HashMap {
&self.initial_variables
}
+
pub fn get_script_vars(&self) -> &Vec {
&self.script_vars
}
@@ -211,6 +214,7 @@ impl Default for WindowStacking {
impl std::str::FromStr for WindowStacking {
type Err = anyhow::Error;
+
fn from_str(s: &str) -> Result {
let s = s.to_lowercase();
match s.as_str() {
diff --git a/src/config/xml_ext.rs b/src/config/xml_ext.rs
index fc715a4..4908520 100644
--- a/src/config/xml_ext.rs
+++ b/src/config/xml_ext.rs
@@ -141,6 +141,7 @@ impl<'a, 'b> XmlElement<'a, 'b> {
format!("<{} {}>", self.tag_name(), attrs)
}
+
pub fn tag_name(&self) -> &str {
self.0.tag_name().name()
}
@@ -159,6 +160,7 @@ impl<'a, 'b> XmlElement<'a, 'b> {
.filter(|child| child.is_element() || (child.is_text() && !child.text().unwrap_or_default().is_blank()))
.map(XmlNode::from)
}
+
pub fn child_elements(&self) -> impl Iterator- {
self.0.children().filter(|child| child.is_element()).map(XmlElement)
}
diff --git a/src/eww_state.rs b/src/eww_state.rs
index 1263746..f91fa20 100644
--- a/src/eww_state.rs
+++ b/src/eww_state.rs
@@ -1,14 +1,11 @@
-use crate::config::WindowName;
-use crate::value::VarName;
+use crate::{config::WindowName, value::VarName};
use anyhow::*;
-use std::collections::HashMap;
-use std::process::Command;
-use std::sync::Arc;
+use std::{collections::HashMap, process::Command, sync::Arc};
use crate::value::{AttrValue, PrimitiveValue};
-/// Handler that get's executed to apply the necessary parts of the eww state to a gtk widget.
-/// These are created and initialized in EwwState::resolve.
+/// Handler that get's executed to apply the necessary parts of the eww state to
+/// a gtk widget. These are created and initialized in EwwState::resolve.
pub struct StateChangeHandler {
func: Box) -> Result<()> + 'static>,
constant_values: HashMap,
@@ -57,7 +54,8 @@ impl EwwWindowState {
}
}
-/// Stores the actual state of eww, including the variable state and the window-specific state-change handlers.
+/// Stores the actual state of eww, including the variable state and the
+/// window-specific state-change handlers.
#[derive(Default)]
pub struct EwwState {
windows: HashMap,
@@ -88,7 +86,8 @@ impl EwwState {
self.windows.clear();
}
- /// Update the value of a variable, running all registered [StateChangeHandler]s.
+ /// Update the value of a variable, running all registered
+ /// [StateChangeHandler]s.
pub fn update_variable(&mut self, key: VarName, value: PrimitiveValue) -> Result<()> {
if !self.variables_state.contains_key(&key) {
bail!("Tried to set unknown variable '{}'", key);
@@ -111,7 +110,8 @@ impl EwwState {
/// resolves a value if possible, using the current eww_state
/// Expects there to be at max one level of nesting var_refs from local-env.
- /// This means that no elements in the local_env may be var-refs into the local_env again, but only into the global state.
+ /// This means that no elements in the local_env may be var-refs into the
+ /// local_env again, but only into the global state.
pub fn resolve_once<'a>(
&'a self,
local_env: &'a HashMap,
@@ -134,9 +134,11 @@ impl EwwState {
}
}
- /// Resolve takes a function that applies a set of fully resolved attribute values to it's gtk widget.
- /// Expects there to be at max one level of nesting var_refs from local-env.
- /// This means that no elements in the local_env may be var-refs into the local_env again, but only into the global state.
+ /// Resolve takes a function that applies a set of fully resolved attribute
+ /// values to it's gtk widget. Expects there to be at max one level of
+ /// nesting var_refs from local-env. This means that no elements in the
+ /// local_env may be var-refs into the local_env again, but only into the
+ /// global state.
pub fn resolve) -> Result<()> + 'static + Clone>(
&mut self,
window_name: &WindowName,
@@ -144,9 +146,11 @@ impl EwwState {
mut needed_attributes: HashMap,
set_value: F,
) {
- // Resolve first collects all variable references and creates a set of unresolved attribute -> VarName pairs.
- // additionally, all constant values are looked up and collected, including the values from the local environment
- // These are then used to generate a StateChangeHandler, which is then executed and registered in the windows state.
+ // Resolve first collects all variable references and creates a set of
+ // unresolved attribute -> VarName pairs. additionally, all constant values are
+ // looked up and collected, including the values from the local environment
+ // These are then used to generate a StateChangeHandler, which is then executed
+ // and registered in the windows state.
let result: Result<_> = try {
let window_state = self
diff --git a/src/main.rs b/src/main.rs
index 55732da..bb7178d 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -16,11 +16,12 @@ use ipc_channel::ipc;
use log;
use pretty_env_logger;
use serde::{Deserialize, Serialize};
-use std::collections::HashMap;
-use std::path::{Path, PathBuf};
+use std::{
+ collections::HashMap,
+ path::{Path, PathBuf},
+};
use structopt::StructOpt;
-use value::PrimitiveValue;
-use value::VarName;
+use value::{PrimitiveValue, VarName};
pub mod app;
pub mod config;
@@ -221,7 +222,8 @@ fn run_filewatch_thread>(
Ok(hotwatch)
}
-/// detach the process from the terminal, also closing stdout and redirecting stderr into /dev/null
+/// detach the process from the terminal, also closing stdout and redirecting
+/// stderr into /dev/null
fn do_detach() {
// detach from terminal
let pid = unsafe { libc::fork() };
@@ -238,7 +240,7 @@ fn do_detach() {
libc::close(1);
}
}
- //close stderr to not spam output
+ // close stderr to not spam output
if unsafe { libc::isatty(2) } != 0 {
unsafe {
let fd = libc::open(std::ffi::CString::new("/dev/null").unwrap().as_ptr(), libc::O_RDWR);
diff --git a/src/script_var_handler.rs b/src/script_var_handler.rs
index 2569f1b..35bac1c 100644
--- a/src/script_var_handler.rs
+++ b/src/script_var_handler.rs
@@ -19,7 +19,8 @@ impl ScriptVarHandler {
})
}
- /// clears and stops the currently running poll handles, then opens the new ones as configured
+ /// clears and stops the currently running poll handles, then opens the new
+ /// ones as configured
pub fn setup_command_poll_tasks(&mut self, config: &config::EwwConfig) -> Result<()> {
log::info!("reloading handler for poll script vars");
self.poll_handles.iter().for_each(|handle| handle.stop());
diff --git a/src/util.rs b/src/util.rs
index c0081c4..f2c4142 100644
--- a/src/util.rs
+++ b/src/util.rs
@@ -3,8 +3,7 @@ use extend::ext;
use grass;
use itertools::Itertools;
use serde::{Deserialize, Serialize};
-use std::fmt;
-use std::path::Path;
+use std::{fmt, path::Path};
pub fn parse_scss_from_file>(path: P) -> Result {
let scss_content = std::fs::read_to_string(path)?;
@@ -14,7 +13,8 @@ pub fn parse_scss_from_file>(path: P) -> Result {
#[ext(pub, name = StringExt)]
impl> T {
- /// check if the string is empty after removing all linebreaks and trimming whitespace
+ /// check if the string is empty after removing all linebreaks and trimming
+ /// whitespace
fn is_blank(self) -> bool {
self.as_ref().replace('\n', "").trim().is_empty()
}
@@ -51,6 +51,7 @@ impl fmt::Display for Coords {
impl std::str::FromStr for Coords {
type Err = anyhow::Error;
+
fn from_str(s: &str) -> Result {
let (x, y) = s.split_once('x').ok_or_else(|| anyhow!("must be formatted like 200x500"))?;
Ok(Coords(x.parse()?, y.parse()?))
diff --git a/src/value.rs b/src/value.rs
index 15ea06d..6fddff7 100644
--- a/src/value.rs
+++ b/src/value.rs
@@ -4,8 +4,7 @@ use lazy_static::lazy_static;
use ref_cast::RefCast;
use regex::Regex;
use serde::{Deserialize, Serialize};
-use std::convert::TryFrom;
-use std::fmt;
+use std::{convert::TryFrom, fmt};
#[derive(Clone, PartialEq, Deserialize, Serialize, derive_more::From)]
pub enum PrimitiveValue {
@@ -32,7 +31,8 @@ impl fmt::Debug for PrimitiveValue {
impl std::str::FromStr for PrimitiveValue {
type Err = anyhow::Error;
- /// parses the value, trying to turn it into a number and a boolean first, before deciding that it is a string.
+ /// parses the value, trying to turn it into a number and a boolean first,
+ /// before deciding that it is a string.
fn from_str(s: &str) -> Result {
Ok(PrimitiveValue::parse_string(s))
}
@@ -44,6 +44,7 @@ fn remove_surrounding(s: &str, surround: char) -> &str {
impl TryFrom for String {
type Error = anyhow::Error;
+
fn try_from(x: PrimitiveValue) -> Result {
x.as_string()
}
@@ -51,6 +52,7 @@ impl TryFrom for String {
impl TryFrom for f64 {
type Error = anyhow::Error;
+
fn try_from(x: PrimitiveValue) -> Result {
x.as_f64()
}
@@ -58,6 +60,7 @@ impl TryFrom for f64 {
impl TryFrom for bool {
type Error = anyhow::Error;
+
fn try_from(x: PrimitiveValue) -> Result {
x.as_bool()
}
@@ -70,13 +73,15 @@ impl From<&str> for PrimitiveValue {
}
impl PrimitiveValue {
- /// parses the value, trying to turn it into a number and a boolean first, before deciding that it is a string.
+ /// parses the value, trying to turn it into a number and a boolean first,
+ /// before deciding that it is a string.
pub fn parse_string(s: &str) -> Self {
s.parse()
.map(PrimitiveValue::Number)
.or_else(|_| s.parse().map(PrimitiveValue::Boolean))
.unwrap_or_else(|_| PrimitiveValue::String(remove_surrounding(s, '\'').to_string()))
}
+
pub fn as_string(&self) -> Result {
match self {
PrimitiveValue::String(x) => Ok(x.clone()),
@@ -84,6 +89,7 @@ impl PrimitiveValue {
PrimitiveValue::Boolean(x) => Ok(format!("{}", x)),
}
}
+
pub fn as_f64(&self) -> Result {
match self {
PrimitiveValue::Number(x) => Ok(*x),
@@ -93,6 +99,7 @@ impl PrimitiveValue {
_ => Err(anyhow!("{:?} is not an f64", &self)),
}
}
+
pub fn as_bool(&self) -> Result {
match self {
PrimitiveValue::Boolean(x) => Ok(*x),
@@ -145,12 +152,14 @@ impl AttrValue {
_ => Err(anyhow!("{:?} is not a string", self)),
}
}
+
pub fn as_f64(&self) -> Result {
match self {
AttrValue::Concrete(x) => Ok(x.as_f64()?),
_ => Err(anyhow!("{:?} is not an f64", self)),
}
}
+
pub fn as_bool(&self) -> Result {
match self {
AttrValue::Concrete(x) => Ok(x.as_bool()?),
diff --git a/src/widgets/mod.rs b/src/widgets/mod.rs
index acf54cb..569dddd 100644
--- a/src/widgets/mod.rs
+++ b/src/widgets/mod.rs
@@ -1,6 +1,8 @@
-use crate::config::{element, WindowName};
-use crate::eww_state::*;
-use crate::value::{AttrValue, VarName};
+use crate::{
+ config::{element, WindowName},
+ eww_state::*,
+ value::{AttrValue, VarName},
+};
use anyhow::*;
use gtk::prelude::*;
@@ -11,8 +13,8 @@ pub mod widget_definitions;
const CMD_STRING_PLACEHODLER: &str = "{}";
-/// Run a command that was provided as an attribute. This command may use a placeholder ('{}')
-/// which will be replaced by the value provided as [arg]
+/// Run a command that was provided as an attribute. This command may use a
+/// placeholder ('{}') which will be replaced by the value provided as [arg]
pub fn run_command(cmd: &str, arg: T) {
let cmd = cmd.replace(CMD_STRING_PLACEHODLER, &format!("{}", arg));
if let Err(e) = Command::new("bash").arg("-c").arg(cmd).output() {
@@ -30,12 +32,14 @@ struct BuilderArgs<'a, 'b, 'c, 'd, 'e> {
}
/// Generate a [gtk::Widget] from a [element::WidgetUse].
-/// The widget_use may be using a builtin widget, or a custom [element::WidgetDefinition].
+/// The widget_use may be using a builtin widget, or a custom
+/// [element::WidgetDefinition].
///
/// Also registers all the necessary state-change handlers in the eww_state.
///
-/// This may return `Err` in case there was an actual error while parsing or resolving the widget,
-/// Or `Ok(None)` if the widget_use just didn't match any widget name.
+/// This may return `Err` in case there was an actual error while parsing or
+/// resolving the widget, Or `Ok(None)` if the widget_use just didn't match any
+/// widget name.
pub fn widget_use_to_gtk_widget(
widget_definitions: &HashMap,
eww_state: &mut EwwState,
@@ -48,18 +52,20 @@ pub fn widget_use_to_gtk_widget(
let gtk_widget = if let Some(builtin_gtk_widget) = builtin_gtk_widget {
builtin_gtk_widget
} else if let Some(def) = widget_definitions.get(widget.name.as_str()) {
- //let mut local_env = local_env.clone();
+ // let mut local_env = local_env.clone();
- // the attributes that are set on the widget need to be resolved as far as possible.
- // If an attribute is a variable reference, it must either reference a variable in the current local_env, or in the global state.
- // As we are building widgets from the outer most to the most nested, we can resolve attributes at every step.
- // This way, any definition that is affected by changes in the eww_state will be directly linked to the eww_state's value.
- // Example:
- // foo="{{in_eww_state}}" => attr_in_child="{{foo}}" => attr_in_nested_child="{{attr_in_child}}"
- // will be resolved step by step. This code will first resolve attr_in_child to directly be attr_in_child={{in_eww_state}}.
- // then, in the widget_use_to_gtk_widget call of that child element,
- // attr_in_nested_child will again be resolved to point to the value of attr_in_child,
- // and thus: attr_in_nested_child="{{in_eww_state}}"
+ // the attributes that are set on the widget need to be resolved as far as
+ // possible. If an attribute is a variable reference, it must either reference a
+ // variable in the current local_env, or in the global state. As we are building
+ // widgets from the outer most to the most nested, we can resolve attributes at
+ // every step. This way, any definition that is affected by changes in the
+ // eww_state will be directly linked to the eww_state's value. Example:
+ // foo="{{in_eww_state}}" => attr_in_child="{{foo}}" =>
+ // attr_in_nested_child="{{attr_in_child}}" will be resolved step by step. This
+ // code will first resolve attr_in_child to directly be
+ // attr_in_child={{in_eww_state}}. then, in the widget_use_to_gtk_widget call of
+ // that child element, attr_in_nested_child will again be resolved to point to
+ // the value of attr_in_child, and thus: attr_in_nested_child="{{in_eww_state}}"
let resolved_widget_attr_env = widget
.attrs
.clone()
@@ -93,13 +99,14 @@ pub fn widget_use_to_gtk_widget(
Ok(gtk_widget)
}
-/// build a [gtk::Widget] out of a [element::WidgetUse] that uses a **builtin widget**.
-/// User defined widgets are handled by [widget_use_to_gtk_widget].
+/// build a [gtk::Widget] out of a [element::WidgetUse] that uses a **builtin
+/// widget**. User defined widgets are handled by [widget_use_to_gtk_widget].
///
/// Also registers all the necessary handlers in the `eww_state`.
///
-/// This may return `Err` in case there was an actual error while parsing or resolving the widget,
-/// Or `Ok(None)` if the widget_use just didn't match any widget name.
+/// This may return `Err` in case there was an actual error while parsing or
+/// resolving the widget, Or `Ok(None)` if the widget_use just didn't match any
+/// widget name.
fn build_builtin_gtk_widget(
widget_definitions: &HashMap,
eww_state: &mut EwwState,
diff --git a/src/widgets/widget_definitions.rs b/src/widgets/widget_definitions.rs
index b9eacb8..1cf98b7 100644
--- a/src/widgets/widget_definitions.rs
+++ b/src/widgets/widget_definitions.rs
@@ -1,15 +1,12 @@
use super::{run_command, BuilderArgs};
-use crate::config;
-use crate::eww_state;
-use crate::resolve_block;
-use crate::value::{AttrValue, PrimitiveValue};
+use crate::{
+ config, eww_state, resolve_block,
+ value::{AttrValue, PrimitiveValue},
+};
use anyhow::*;
-use gtk::prelude::*;
-use gtk::ImageExt;
+use gtk::{prelude::*, ImageExt};
use maplit::hashmap;
-use std::cell::RefCell;
-use std::path::Path;
-use std::rc::Rc;
+use std::{cell::RefCell, path::Path, rc::Rc};
use gdk_pixbuf;
@@ -259,7 +256,8 @@ fn parse_align(o: &str) -> Result {
}
fn connect_first_map, F: Fn(&W) + 'static>(widget: &W, func: F) {
- // TODO it would be better to actually remove the connect_map after first map, but that would be highly annoying to implement...
+ // TODO it would be better to actually remove the connect_map after first map,
+ // but that would be highly annoying to implement...
let is_first_map = std::rc::Rc::new(std::cell::RefCell::new(true));
widget.connect_map(move |w| {
if is_first_map.replace(false) {