From 5d1d994dce118e33e17ae1d9e801059927ccc458 Mon Sep 17 00:00:00 2001 From: Tobias Witek Date: Sun, 8 Oct 2017 08:13:10 +0200 Subject: [PATCH] [core] Add support for custom colorsets (e.g. pywal) In a theme file, it is now possible to provide an array of "color definitions", which allow you to use names instead of colors throughout the theme file. Currently, only the colorset "wal" is supported, which reads all colors from the wal JSON file (~/.cache/wal/colors.json) and makes them usable in the theme (as "foreground", "background", "cursor", "color12", etc.). An example of this can be found in the theme wal-powerline. see #185 --- bumblebee/theme.py | 26 +++++++++++++++++++++--- themes/wal-powerline.json | 42 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 65 insertions(+), 3 deletions(-) create mode 100644 themes/wal-powerline.json diff --git a/bumblebee/theme.py b/bumblebee/theme.py index 647a823..ee6f330 100644 --- a/bumblebee/theme.py +++ b/bumblebee/theme.py @@ -25,17 +25,20 @@ def themes(): class Theme(object): """Represents a collection of icons and colors""" def __init__(self, name): - self._init(self.load(name)) self._widget = None self._cycle_idx = 0 self._cycle = {} self._prevbg = None + self._colorset = {} + self._init(self.load(name)) def _init(self, data): """Initialize theme from data structure""" self._theme = data for iconset in data.get("icons", []): self._merge(data, self._load_icons(iconset)) + for colorset in data.get("colors", []): + self._merge(self._colorset, self._load_colors(colorset)) self._defaults = data.get("defaults", {}) self._cycles = self._theme.get("cycle", []) self.reset() @@ -99,6 +102,21 @@ class Theme(object): """Return the SBW""" return self._get(widget, "separator-block-width", None) + def _load_wal_colors(self): + walfile = os.path.expanduser("~/.cache/wal/colors.json") + result = {} + with io.open(walfile) as data: + colors = json.load(data) + for field in ["special", "colors"]: + for key in colors[field]: + result[key] = colors[field][key] + return result + + def _load_colors(self, name): + """Load colors for a theme""" + if name == "wal": + return self._load_wal_colors() + def _load_icons(self, name): """Load icons for a theme""" path = "{}/icons/".format(theme_path()) @@ -110,7 +128,7 @@ class Theme(object): if os.path.isfile(themefile): try: - with io.open(themefile,encoding="utf-8") as data: + with io.open(themefile, encoding="utf-8") as data: return json.load(data) except ValueError as exception: raise bumblebee.error.ThemeLoadError("JSON error: {}".format(exception)) @@ -155,7 +173,9 @@ class Theme(object): widget.set(key, (idx + 1) % len(value)) value = value[idx] - return value + if isinstance(value, list) or isinstance(value, dict): + return value + return self._colorset.get(value, value) # algorithm copied from # http://blog.impressiver.com/post/31434674390/deep-merge-multiple-python-dicts diff --git a/themes/wal-powerline.json b/themes/wal-powerline.json new file mode 100644 index 0000000..049ecf8 --- /dev/null +++ b/themes/wal-powerline.json @@ -0,0 +1,42 @@ +{ + "icons": [ "awesome-fonts" ], + "colors": [ "wal" ], + "defaults": { + "separator-block-width": 0, + "critical": { + "fg": "cursor", + "bg": "color5" + }, + "warning": { + "fg": "cursor", + "bg": "color6" + }, + "default_separators": false + }, + "cycle": [ + { + "fg": "foreground", + "bg": "background" + }, + { + "fg": "background", + "bg": "foreground" + } + ], + "dnf": { + "good": { + "fg": "background", + "bg": "color3" + } + }, + "battery": { + "charged": { + "fg": "background", + "bg": "color3" + }, + "AC": { + "fg": "background", + "bg": "color3" + } + } +}