Merge branch 'master' of github.com:dylanaraps/pywal

This commit is contained in:
Dylan Araps 2020-01-24 08:26:06 +02:00
commit 42ad8f014d
No known key found for this signature in database
GPG Key ID: 46D62DD9F1DE636E
6 changed files with 120 additions and 13 deletions

View File

@ -21,4 +21,4 @@ The goal of Pywal was to be as out of the way as possible. It doesn't modify any
Terminal emulators and TTYs have their color-schemes updated in real-time with no delay. With minimal configuration this functionality can be extended to almost anything running on your system. Terminal emulators and TTYs have their color-schemes updated in real-time with no delay. With minimal configuration this functionality can be extended to almost anything running on your system.
### More: \[[Installation](https://github.com/dylanaraps/pywal/wiki/Installation)\] \[[Getting Started](https://github.com/dylanaraps/pywal/wiki/Getting-Started)\] \[[Customization](https://github.com/dylanaraps/pywal/wiki/Customization)\] \[[Wiki](https://github.com/dylanaraps/pywal/wiki)\] \[[Screenshots](https://www.reddit.com/r/unixporn/search?q=wal&restrict_sr=on&sort=relevance&t=all)\] ### More: \[[Installation](https://github.com/dylanaraps/pywal/wiki/Installation)] \[[Getting Started](https://github.com/dylanaraps/pywal/wiki/Getting-Started)] \[[Customization](https://github.com/dylanaraps/pywal/wiki/Customization)] \[[Wiki](https://github.com/dylanaraps/pywal/wiki)] \[[Screenshots](https://www.reddit.com/r/unixporn/search?q=wal&restrict_sr=on&sort=relevance&t=all)]

View File

@ -45,7 +45,7 @@ def get_args():
arg.add_argument("--theme", "-f", metavar="/path/to/file or theme_name", arg.add_argument("--theme", "-f", metavar="/path/to/file or theme_name",
help="Which colorscheme file to use. \ help="Which colorscheme file to use. \
Use 'wal --theme' to list builtin themes.", Use 'wal --theme' to list builtin and user themes.",
const="list_themes", nargs="?") const="list_themes", nargs="?")
arg.add_argument("--iterative", action="store_true", arg.add_argument("--iterative", action="store_true",
@ -82,6 +82,11 @@ def get_args():
arg.add_argument("-o", metavar="\"script_name\"", action="append", arg.add_argument("-o", metavar="\"script_name\"", action="append",
help="External script to run after \"wal\".") help="External script to run after \"wal\".")
arg.add_argument("-p", metavar="\"theme_name\"",
help="permanently save theme to "
"$XDG_CONFIG_HOME/wal/colorschemes with "
"the specified name")
arg.add_argument("-q", action="store_true", arg.add_argument("-q", action="store_true",
help="Quiet mode, don\'t print anything.") help="Quiet mode, don\'t print anything.")
@ -192,6 +197,9 @@ def parse_args(parser):
if not args.n: if not args.n:
wallpaper.change(colors_plain["wallpaper"]) wallpaper.change(colors_plain["wallpaper"])
if args.p:
theme.save(colors_plain, args.p, args.l)
sequences.send(colors_plain, to_send=not args.s, vte_fix=args.vte) sequences.send(colors_plain, to_send=not args.s, vte_fix=args.vte)
if sys.stdout.isatty(): if sys.stdout.isatty():

View File

@ -3,22 +3,60 @@ Export colors in various formats.
""" """
import logging import logging
import os import os
import re
from .settings import CACHE_DIR, MODULE_DIR, CONF_DIR
from . import util from . import util
from .settings import CACHE_DIR, CONF_DIR, MODULE_DIR
def template(colors, input_file, output_file=None): def template(colors, input_file, output_file=None):
"""Read template file, substitute markers and """Read template file, substitute markers and
save the file elsewhere.""" save the file elsewhere."""
template_data = util.read_file_raw(input_file) template_data = util.read_file_raw(input_file)
for i, l in enumerate(template_data):
for match in re.finditer(r"(?<=(?<!\{))(\{([^{}]+)\})(?=(?!\}))", l):
# Get the color, and the functions associated with it
cname, _, funcs = match.group(2).partition(".")
# Check that functions are needed for this color
if len(funcs) == 0:
continue
# Build up a string which will be replaced with the new color
replace_str = cname
# Color to be modified copied into new one
new_color = util.Color(colors[cname].hex_color)
# Execute each function to be done
for func in filter(None, funcs.split(")")):
# Get function name and arguments
func = func.split("(")
fname = func[0]
if fname[0] == '.':
fname = fname[1:]
if not hasattr(new_color, fname):
logging.error(
"Syntax error in template file '%s' on line '%s'",
input_file, i)
function = getattr(new_color, fname)
# If the function is callable, call it
if callable(function):
if len(func) > 1:
new_color = function(*func[1].split(","))
else:
new_color = function()
# string to replace generated colors
if func[0] != '.':
replace_str += "."
replace_str += "(".join(func) + ")"
# If the color was changed, replace with a unique identifier.
if new_color is not colors[cname]:
template_data[i] = l.replace(
replace_str, "color" + new_color.strip)
colors["color" + new_color.strip] = new_color
try: try:
template_data = "".join(template_data).format(**colors) template_data = "".join(template_data).format(**colors)
except ValueError: except ValueError:
logging.error("Syntax error in template file '%s'.", input_file) logging.error("Syntax error in template file '%s'.", input_file)
return return
util.save_file(template_data, output_file) util.save_file(template_data, output_file)
@ -52,6 +90,7 @@ def get_export_type(export_type):
"speedcrunch": "colors-speedcrunch.json", "speedcrunch": "colors-speedcrunch.json",
"sway": "colors-sway", "sway": "colors-sway",
"tty": "colors-tty.sh", "tty": "colors-tty.sh",
"vscode": "colors-vscode.json",
"waybar": "colors-waybar.css", "waybar": "colors-waybar.css",
"xresources": "colors.Xresources", "xresources": "colors.Xresources",
"xmonad": "colors.hs", "xmonad": "colors.hs",

View File

@ -0,0 +1,14 @@
{{
"editor.tokenColorCustomizations": {{
"functions": "{color1}",
"keywords": "{color2}",
"numbers": "{color3}",
"strings": "{color4}",
"types": "{color5}",
"variables": "{color6}",
"comments": "{color8}"
}},
"workbench.colorCustomizations": {{
"editor.background": "{background}"
}}
}}

View File

@ -6,7 +6,7 @@ import os
import random import random
import sys import sys
from .settings import CONF_DIR, MODULE_DIR from .settings import CACHE_DIR, CONF_DIR, MODULE_DIR
from . import util from . import util
@ -19,20 +19,30 @@ def list_out():
user_themes = [theme.name.replace(".json", "") user_themes = [theme.name.replace(".json", "")
for theme in list_themes_user()] for theme in list_themes_user()]
try:
last_used_theme = util.read_file(os.path.join(
CACHE_DIR, "last_used_theme"))[0].replace(".json", "")
except FileNotFoundError:
last_used_theme = ""
if user_themes: if user_themes:
print("\033[1;32mUser Themes\033[0m:") print("\033[1;32mUser Themes\033[0m:")
print(" -", "\n - ".join(sorted(user_themes))) print(" -", "\n - ".join(t + " (last used)" if t == last_used_theme
else t for t in sorted(user_themes)))
print("\033[1;32mDark Themes\033[0m:") print("\033[1;32mDark Themes\033[0m:")
print(" -", "\n - ".join(sorted(dark_themes))) print(" -", "\n - ".join(t + " (last used)" if t == last_used_theme else t
for t in sorted(dark_themes)))
print("\033[1;32mLight Themes\033[0m:") print("\033[1;32mLight Themes\033[0m:")
print(" -", "\n - ".join(sorted(ligh_themes))) print(" -", "\n - ".join(t + " (last used)" if t == last_used_theme else t
for t in sorted(ligh_themes)))
print("\033[1;32mExtra\033[0m:") print("\033[1;32mExtra\033[0m:")
print(" - random (select a random dark theme)") print(" - random (select a random dark theme)")
print(" - random_dark (select a random dark theme)") print(" - random_dark (select a random dark theme)")
print(" - random_light (select a random light theme)") print(" - random_light (select a random light theme)")
print(" - random_user (select a random user theme)")
def list_themes(dark=True): def list_themes(dark=True):
@ -88,6 +98,13 @@ def get_random_theme(dark=True):
return themes[0] return themes[0]
def get_random_theme_user():
"""Get a random theme file from user theme directories."""
themes = [theme.path for theme in list_themes_user()]
random.shuffle(themes)
return themes[0]
def file(input_file, light=False): def file(input_file, light=False):
"""Import colorscheme from json file.""" """Import colorscheme from json file."""
util.create_dir(os.path.join(CONF_DIR, "colorschemes/light/")) util.create_dir(os.path.join(CONF_DIR, "colorschemes/light/"))
@ -106,6 +123,9 @@ def file(input_file, light=False):
elif input_file == "random_light": elif input_file == "random_light":
theme_file = get_random_theme(light) theme_file = get_random_theme(light)
elif input_file == "random_user":
theme_file = get_random_theme_user()
elif os.path.isfile(user_theme_file): elif os.path.isfile(user_theme_file):
theme_file = user_theme_file theme_file = user_theme_file
@ -116,9 +136,19 @@ def file(input_file, light=False):
if os.path.isfile(theme_file): if os.path.isfile(theme_file):
logging.info("Set theme to \033[1;37m%s\033[0m.", logging.info("Set theme to \033[1;37m%s\033[0m.",
os.path.basename(theme_file)) os.path.basename(theme_file))
util.save_file(os.path.basename(theme_file),
os.path.join(CACHE_DIR, "last_used_theme"))
return parse(theme_file) return parse(theme_file)
logging.error("No %s colorscheme file found.", bri) logging.error("No %s colorscheme file found.", bri)
logging.error("Try adding '-l' to set light themes.") logging.error("Try adding '-l' to set light themes.")
logging.error("Try removing '-l' to set dark themes.") logging.error("Try removing '-l' to set dark themes.")
sys.exit(1) sys.exit(1)
def save(colors, theme_name, light=False):
"""Save colors to a theme file."""
theme_file = theme_name + ".json"
theme_path = os.path.join(CONF_DIR, "colorschemes",
"light" if light else "dark", theme_file)
util.save_file_json(colors, theme_path)

View File

@ -5,10 +5,11 @@ import colorsys
import json import json
import logging import logging
import os import os
import platform
import re
import shutil import shutil
import subprocess import subprocess
import sys import sys
import platform
class Color: class Color:
@ -35,7 +36,7 @@ class Color:
def rgba(self): def rgba(self):
"""Convert a hex color to rgba.""" """Convert a hex color to rgba."""
return "rgba(%s,%s,%s,%s)" % (*hex_to_rgb(self.hex_color), return "rgba(%s,%s,%s,%s)" % (*hex_to_rgb(self.hex_color),
int(self.alpha_num)/100) int(self.alpha_num) / 100)
@property @property
def alpha(self): def alpha(self):
@ -57,6 +58,21 @@ class Color:
"""Strip '#' from color.""" """Strip '#' from color."""
return self.hex_color[1:] return self.hex_color[1:]
def lighten(self, percent):
"""Lighten color by percent"""
percent = float(re.sub(r'[\D\.]', '', str(percent)))
return Color(lighten_color(self.hex_color, percent / 100))
def darken(self, percent):
"""Darken color by percent"""
percent = float(re.sub(r'[\D\.]', '', str(percent)))
return Color(darken_color(self.hex_color, percent / 100))
def saturate(self, percent):
"""Saturate a color"""
percent = float(re.sub(r'[\D\.]', '', str(percent)))
return Color(saturate_color(self.hex_color, percent / 100))
def read_file(input_file): def read_file(input_file):
"""Read data from a file and trim newlines.""" """Read data from a file and trim newlines."""
@ -156,11 +172,11 @@ def blend_color(color, color2):
def saturate_color(color, amount): def saturate_color(color, amount):
"""Saturate a hex color.""" """Saturate a hex color."""
r, g, b = hex_to_rgb(color) r, g, b = hex_to_rgb(color)
r, g, b = [x/255.0 for x in (r, g, b)] r, g, b = [x / 255.0 for x in (r, g, b)]
h, l, s = colorsys.rgb_to_hls(r, g, b) h, l, s = colorsys.rgb_to_hls(r, g, b)
s = amount s = amount
r, g, b = colorsys.hls_to_rgb(h, l, s) r, g, b = colorsys.hls_to_rgb(h, l, s)
r, g, b = [x*255.0 for x in (r, g, b)] r, g, b = [x * 255.0 for x in (r, g, b)]
return rgb_to_hex((int(r), int(g), int(b))) return rgb_to_hex((int(r), int(g), int(b)))