diff --git a/MANIFEST.in b/MANIFEST.in index b0bc7ae..7014f98 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,6 +1,7 @@ include pywal/templates/* include pywal/backends/* include pywal/scripts/* +include pywal/colorschemes/* include tests/* include tests/test_files/* include .pylintrc diff --git a/pywal/__init__.py b/pywal/__init__.py index 98d9a08..8a00b5a 100644 --- a/pywal/__init__.py +++ b/pywal/__init__.py @@ -15,6 +15,7 @@ from . import export from . import image from . import reload from . import sequences +from . import theme from . import wallpaper __all__ = [ @@ -25,5 +26,6 @@ __all__ = [ "image", "reload", "sequences", + "theme", "wallpaper", ] diff --git a/pywal/__main__.py b/pywal/__main__.py index 05eea99..09d0769 100644 --- a/pywal/__main__.py +++ b/pywal/__main__.py @@ -20,6 +20,7 @@ from . import export from . import image from . import reload from . import sequences +from . import theme from . import util from . import wallpaper @@ -40,15 +41,17 @@ def get_args(args): help="Which color backend to use.", const="list_backends", type=str, nargs="?", default="wal") + arg.add_argument("--theme", metavar="/path/to/file or theme_name", + help="Which colorscheme file to use. \ + Use 'wal -f' to list available builtin themes.", + const="list_themes", nargs="?") + arg.add_argument("-c", action="store_true", help="Delete all cached colorschemes.") arg.add_argument("-i", metavar="\"/path/to/img.jpg\"", help="Which image or directory to use.") - arg.add_argument("-f", metavar="\"/path/to/colorscheme/file\"", - help="Which colorscheme file to use.") - arg.add_argument("-g", action="store_true", help="Generate an oomox theme.") @@ -93,7 +96,7 @@ def process_args(args): " Refer to \"wal -h\" for more info.") sys.exit(1) - if args.i and args.f: + if args.i and args.theme: print("error: Conflicting arguments -i and -f.\n" " Refer to \"wal -h\" for more info.") sys.exit(1) @@ -106,8 +109,15 @@ def process_args(args): reload.colors() sys.exit(0) + if args.theme == "list_themes": + themes = [theme.name.replace(".json", "") + for theme in theme.list_themes()] + print("Themes:", themes) + print("Extra: 'random' (select a random theme)") + sys.exit(0) + if args.backend == "list_backends": - print("Available backends:", colors.list_backends()) + print("Backends:", colors.list_backends()) sys.exit(0) if args.q: @@ -130,8 +140,8 @@ def process_args(args): image_file = image.get(args.i) colors_plain = colors.get(image_file, args.l, args.backend) - if args.f: - colors_plain = colors.file(args.f) + if args.theme: + colors_plain = theme.file(args.theme) if args.a: util.Color.alpha_num = args.a @@ -141,7 +151,7 @@ def process_args(args): colors_plain["special"]["background"] = args.b colors_plain["colors"]["color0"] = args.b - if args.i or args.f: + if args.i or args.theme: if not args.n: wallpaper.change(colors_plain["wallpaper"]) diff --git a/pywal/colors.py b/pywal/colors.py index 06863ac..33b68d5 100644 --- a/pywal/colors.py +++ b/pywal/colors.py @@ -5,6 +5,7 @@ import os import re import sys +from . import theme from . import util from .settings import CACHE_DIR, MODULE_DIR, __cache_version__ @@ -86,7 +87,7 @@ def get(img, light=False, backend="wal", cache_dir=CACHE_DIR): cache_file = os.path.join(*cache_name) if os.path.isfile(cache_file): - colors = file(cache_file) + colors = theme.file(cache_file) util.Color.alpha_num = colors["alpha"] print("colors: Found cached colorscheme.") @@ -110,13 +111,5 @@ def get(img, light=False, backend="wal", cache_dir=CACHE_DIR): def file(input_file): - """Import colorscheme from json file.""" - data = util.read_file_json(input_file) - - if "wallpaper" not in data: - data["wallpaper"] = "None" - - if "alpha" not in data: - data["alpha"] = "100" - - return data + """Deprecated: symbolic link to --> theme.file""" + return theme.file(input_file) diff --git a/pywal/colorschemes/3024-dark.json b/pywal/colorschemes/3024-dark.json new file mode 100644 index 0000000..498f96c --- /dev/null +++ b/pywal/colorschemes/3024-dark.json @@ -0,0 +1,25 @@ +{ + "special": { + "background": "#090300", + "foreground": "#a5a2a2", + "cursor": "#db2d20" + }, + "colors": { + "color0": "#090300", + "color1": "#db2d20", + "color2": "#01a252", + "color3": "#fded02", + "color4": "#01a0e4", + "color5": "#a16a94", + "color6": "#b5e4f4", + "color7": "#a5a2a2", + "color8": "#5c5855", + "color9": "#db2d20", + "color10": "#01a252", + "color11": "#fded02", + "color12": "#01a0e4", + "color13": "#a16a94", + "color14": "#b5e4f4", + "color15": "#f7f7f7" + } +} diff --git a/pywal/colorschemes/3024-light.json b/pywal/colorschemes/3024-light.json new file mode 100644 index 0000000..aedc835 --- /dev/null +++ b/pywal/colorschemes/3024-light.json @@ -0,0 +1,25 @@ +{ + "special": { + "background": "#f7f7f7", + "foreground": "#090300", + "cursor": "#db2d20" + }, + "colors": { + "color0": "#f7f7f7", + "color1": "#db2d20", + "color2": "#01a252", + "color3": "#fded02", + "color4": "#01a0e4", + "color5": "#a16a94", + "color6": "#b5e4f4", + "color7": "#090300", + "color8": "#5c5855", + "color9": "#db2d20", + "color10": "#01a252", + "color11": "#fded02", + "color12": "#01a0e4", + "color13": "#a16a94", + "color14": "#b5e4f4", + "color15": "#090300" + } +} diff --git a/pywal/colorschemes/ashes-dark.json b/pywal/colorschemes/ashes-dark.json new file mode 100644 index 0000000..86105d4 --- /dev/null +++ b/pywal/colorschemes/ashes-dark.json @@ -0,0 +1,25 @@ +{ + "special": { + "background": "#1c2023", + "foreground": "#c7ccd1", + "cursor": "#c7ae95" + }, + "colors": { + "color0": "#1c2023", + "color1": "#c7ae95", + "color2": "#95c7ae", + "color3": "#aec795", + "color4": "#ae95c7", + "color5": "#c795ae", + "color6": "#95aec7", + "color7": "#c7ccd1", + "color8": "#747c84", + "color9": "#c7ae95", + "color10": "#95c7ae", + "color11": "#aec795", + "color12": "#ae95c7", + "color13": "#c795ae", + "color14": "#95aec7", + "color15": "#f3f4f5" + } +} diff --git a/pywal/colorschemes/ashes-light.json b/pywal/colorschemes/ashes-light.json new file mode 100644 index 0000000..7af28e6 --- /dev/null +++ b/pywal/colorschemes/ashes-light.json @@ -0,0 +1,25 @@ +{ + "special": { + "background": "#f3f4f5", + "foreground": "#565e65", + "cursor": "#c7ae95" + }, + "colors": { + "color0": "#f3f4f5", + "color1": "#c7ae95", + "color2": "#95c7ae", + "color3": "#aec795", + "color4": "#ae95c7", + "color5": "#c795ae", + "color6": "#95aec7", + "color7": "#1c2023", + "color8": "#747c84", + "color9": "#c7ae95", + "color10": "#95c7ae", + "color11": "#aec795", + "color12": "#ae95c7", + "color13": "#c795ae", + "color14": "#95aec7", + "color15": "#1c2023" + } +} diff --git a/pywal/colorschemes/darktooth.json b/pywal/colorschemes/darktooth.json new file mode 100644 index 0000000..7ea165e --- /dev/null +++ b/pywal/colorschemes/darktooth.json @@ -0,0 +1,25 @@ +{ + "special": { + "background": "#1d2021", + "foreground": "#a89984", + "cursor": "#fb543f" + }, + "colors": { + "color0": "#1d2021", + "color1": "#fb543f", + "color2": "#95c085", + "color3": "#fac03b", + "color4": "#0d6678", + "color5": "#8f4673", + "color6": "#8ba59b", + "color7": "#a89984", + "color8": "#665c54", + "color9": "#fb543f", + "color10": "#95c085", + "color11": "#fac03b", + "color12": "#0d6678", + "color13": "#8f4673", + "color14": "#8ba59b", + "color15": "#fdf4c1" + } +} diff --git a/pywal/colorschemes/github.json b/pywal/colorschemes/github.json new file mode 100644 index 0000000..28f555f --- /dev/null +++ b/pywal/colorschemes/github.json @@ -0,0 +1,25 @@ +{ + "special": { + "background": "#f4f4f4", + "foreground": "#3e3e3e", + "cursor": "#970b16" + }, + "colors": { + "color0": "#ffffff", + "color1": "#970b16", + "color2": "#07962a", + "color3": "#f8eec7", + "color4": "#003e8a", + "color5": "#e94691", + "color6": "#89d1ec", + "color7": "#3e3e3e", + "color8": "#666666", + "color9": "#de0000", + "color10": "#87d5a2", + "color11": "#f1d007", + "color12": "#2e6cba", + "color13": "#ffa29f", + "color14": "#1cfafe", + "color15": "#3e3e3e" + } +} diff --git a/pywal/colorschemes/gruvbox.json b/pywal/colorschemes/gruvbox.json new file mode 100644 index 0000000..6f864d6 --- /dev/null +++ b/pywal/colorschemes/gruvbox.json @@ -0,0 +1,25 @@ +{ + "special": { + "background": "#282828", + "foreground": "#a89984", + "cursor": "#cc241d" + }, + "colors": { + "color0": "#282828", + "color1": "#cc241d", + "color2": "#d79921", + "color3": "#b58900", + "color4": "#458588", + "color5": "#b16286", + "color6": "#689d6a", + "color7": "#a89984", + "color8": "#928374", + "color9": "#cc241d", + "color10": "#d79921", + "color11": "#b58900", + "color12": "#458588", + "color13": "#b16286", + "color14": "#689d6a", + "color15": "#a89984" + } +} diff --git a/pywal/colorschemes/hybrid-material.json b/pywal/colorschemes/hybrid-material.json new file mode 100644 index 0000000..a5dd5a7 --- /dev/null +++ b/pywal/colorschemes/hybrid-material.json @@ -0,0 +1,25 @@ +{ + "special": { + "background": "#263238", + "foreground": "#ffffff", + "cursor": "#cc6666" + }, + "colors": { + "color0": "#263238", + "color1": "#cc6666", + "color2": "#f0c674", + "color3": "#b5bd68", + "color4": "#8abeb7", + "color5": "#81a2be", + "color6": "#b294bb", + "color7": "#ffffff", + "color8": "#707880", + "color9": "#cc6666", + "color10": "#f0c674", + "color11": "#b5bd68", + "color12": "#8abeb7", + "color13": "#81a2be", + "color14": "#b294bb", + "color15": "#ffffff" + } +} diff --git a/pywal/colorschemes/monokai-dark.json b/pywal/colorschemes/monokai-dark.json new file mode 100644 index 0000000..40ad451 --- /dev/null +++ b/pywal/colorschemes/monokai-dark.json @@ -0,0 +1,25 @@ +{ + "special": { + "background": "#272822", + "foreground": "#f8f8f2", + "cursor": "#f92672" + }, + "colors": { + "color0": "#272822", + "color1": "#f92672", + "color2": "#a6e22e", + "color3": "#f4bf75", + "color4": "#66d9ef", + "color5": "#ae81ff", + "color6": "#a1efe4", + "color7": "#f8f8f2", + "color8": "#75715e", + "color9": "#f92672", + "color10": "#a6e22e", + "color11": "#f4bf75", + "color12": "#66d9ef", + "color13": "#ae81ff", + "color14": "#a1efe4", + "color15": "#f9f8f5" + } +} diff --git a/pywal/colorschemes/solarized-dark.json b/pywal/colorschemes/solarized-dark.json new file mode 100644 index 0000000..a611e31 --- /dev/null +++ b/pywal/colorschemes/solarized-dark.json @@ -0,0 +1,25 @@ +{ + "special": { + "background": "#073642", + "foreground": "#fdf6e3", + "cursor": "#dc322f" + }, + "colors": { + "color0": "#073642", + "color1": "#dc322f", + "color2": "#859900", + "color3": "#b58900", + "color4": "#268bd2", + "color5": "#d33682", + "color6": "#2aa198", + "color7": "#eee8d5", + "color8": "#6c7c80", + "color9": "#dc322f", + "color10": "#859900", + "color11": "#b58900", + "color12": "#268bd2", + "color13": "#d33682", + "color14": "#2aa198", + "color15": "#eee8d5" + } +} diff --git a/pywal/colorschemes/vscode-dark.json b/pywal/colorschemes/vscode-dark.json new file mode 100644 index 0000000..a70b684 --- /dev/null +++ b/pywal/colorschemes/vscode-dark.json @@ -0,0 +1,25 @@ +{ + "special": { + "background": "#1e1e1e", + "foreground": "#d4d4d4", + "cursor": "#f44747" + }, + "colors": { + "color0": "#1e1e1e", + "color1": "#f44747", + "color2": "#d7ba7d", + "color3": "#608b4e", + "color4": "#569cd6", + "color5": "#4ec9b0", + "color6": "#c586c0", + "color7": "#d4d4d4", + "color8": "#808080", + "color9": "#f44747", + "color10": "#d7ba7d", + "color11": "#608b4e", + "color12": "#569cd6", + "color13": "#4ec9b0", + "color14": "#c586c0", + "color15": "#d4d4d4" + } +} diff --git a/pywal/colorschemes/zenburn.json b/pywal/colorschemes/zenburn.json new file mode 100644 index 0000000..b0b9c53 --- /dev/null +++ b/pywal/colorschemes/zenburn.json @@ -0,0 +1,25 @@ +{ + "special": { + "background": "#3f3f3f", + "foreground": "#dcdccc", + "cursor": "#cc9393" + }, + "colors": { + "color0": "#3f3f3f", + "color1": "#cc9393", + "color2": "#7f9f7f", + "color3": "#d0bf8f", + "color4": "#6ca0a3", + "color5": "#dc8cc3", + "color6": "#93e0e3", + "color7": "#dcdccc", + "color8": "#828282", + "color9": "#cc9393", + "color10": "#7f9f7f", + "color11": "#d0bf8f", + "color12": "#6ca0a3", + "color13": "#dc8cc3", + "color14": "#93e0e3", + "color15": "#dcdccc" + } +} diff --git a/pywal/sequences.py b/pywal/sequences.py index 3b32af5..0376342 100644 --- a/pywal/sequences.py +++ b/pywal/sequences.py @@ -50,7 +50,7 @@ def create_sequences(colors): # 13 = mouse foreground sequences.extend([set_special(10, colors["special"]["foreground"], "g"), set_special(11, colors["special"]["background"], "h"), - set_special(12, colors["colors"]["color1"], "l"), + set_special(12, colors["colors"]["color9"], "l"), set_special(13, colors["special"]["foreground"], "l"), set_special(17, colors["special"]["foreground"], "l"), set_special(19, colors["special"]["background"], "l")]) diff --git a/pywal/theme.py b/pywal/theme.py new file mode 100644 index 0000000..6439d40 --- /dev/null +++ b/pywal/theme.py @@ -0,0 +1,76 @@ +""" +Theme file handling. +""" +import os +import random +import sys + +from .settings import CONF_DIR, MODULE_DIR +from . import util + + +def list_themes(): + """List all installed theme files.""" + return [*os.scandir(os.path.join(CONF_DIR, "colorschemes")), + *os.scandir(os.path.join(MODULE_DIR, "colorschemes"))] + + +def terminal_sexy_to_wal(data): + """Convert terminal.sexy json schema to wal.""" + data["colors"] = {} + data["special"] = { + "foreground": data["foreground"], + "background": data["background"], + "cursor": data["color"][9] + } + + for i, color in enumerate(data["color"]): + data["colors"]["color%s" % i] = color + + return data + + +def parse_theme(theme_file): + """Parse the theme file.""" + data = util.read_file_json(theme_file) + + if "wallpaper" not in data: + data["wallpaper"] = "None" + + if "alpha" not in data: + data["alpha"] = "100" + + # Terminal.sexy format. + if "color" in data: + data = terminal_sexy_to_wal(data) + + return data + + +def file(input_file): + """Import colorscheme from json file.""" + theme_name = ".".join((input_file, "json")) + user_theme_file = os.path.join(CONF_DIR, "colorschemes", theme_name) + theme_file = os.path.join(MODULE_DIR, "colorschemes", theme_name) + + util.create_dir(os.path.dirname(user_theme_file)) + + # Find the theme file. + if os.path.isfile(input_file): + theme_file = input_file + + elif os.path.isfile(user_theme_file): + theme_file = user_theme_file + + elif input_file == "random": + themes = [theme.path for theme in list_themes()] + random.shuffle(themes) + theme_file = themes[0] + + # Parse the theme file. + if os.path.isfile(theme_file): + return parse_theme(theme_file) + + else: + print("No colorscheme file found, exiting...") + sys.exit(1)