[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
This commit is contained in:
Tobias Witek 2017-10-08 08:13:10 +02:00
parent f3fe67e681
commit 5d1d994dce
2 changed files with 65 additions and 3 deletions

View file

@ -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]
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

42
themes/wal-powerline.json Normal file
View file

@ -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"
}
}
}