diff options
Diffstat (limited to 'iTerm/wal-iterm.py')
| -rw-r--r-- | iTerm/wal-iterm.py | 191 |
1 files changed, 191 insertions, 0 deletions
diff --git a/iTerm/wal-iterm.py b/iTerm/wal-iterm.py new file mode 100644 index 0000000..6e9b443 --- /dev/null +++ b/iTerm/wal-iterm.py @@ -0,0 +1,191 @@ +#!/usr/bin/env python3 +""" +Script to run pywal and apply colors to iTerm2 automatically. +Usage: python3 wal-iterm.py [path_to_image] +""" + +import subprocess +import sys +import os +import json +import tempfile +from pathlib import Path +import plistlib + +HOME = Path.home() +WAL_CACHE = HOME / ".cache" / "wal" +ITERM_COLORS_DIR = WAL_CACHE / "itermcolors" +COLORS_JSON = WAL_CACHE / "colors.json" + + +def run_command(cmd, check=True): + """Run a shell command and return the result.""" + try: + result = subprocess.run( + cmd, shell=True, capture_output=True, text=True, check=check + ) + return result.stdout.strip(), result.stderr.strip(), result.returncode + except subprocess.CalledProcessError as e: + print(f"Error running command: {cmd}") + print(f"Error: {e.stderr}") + sys.exit(1) + + +def hex_to_rgb(hex_color): + """Convert hex color to RGB values (0-1 range).""" + hex_color = hex_color.lstrip('#') + r = int(hex_color[0:2], 16) / 255.0 + g = int(hex_color[2:4], 16) / 255.0 + b = int(hex_color[4:6], 16) / 255.0 + return r, g, b + + +def run_wal(image_path=None, backend="haishoku"): + """Run pywal to generate colors.""" + if image_path: + if not os.path.exists(image_path): + print(f"Error: Image file not found: {image_path}") + sys.exit(1) + print(f"Running wal on image: {image_path} (backend: {backend})") + cmd = f'wal -i "{image_path}" --backend {backend}' + else: + print("Running wal to regenerate colors from last image...") + cmd = "wal -n" + + stdout, stderr, returncode = run_command(cmd, check=False) + + if returncode != 0: + print(f"\nError: wal failed to process the image.") + if stderr: + print(f"Details: {stderr}") + + if not image_path: + print("Cannot retry without image path. Please specify an image.") + sys.exit(1) + + # Try alternative backends as fallback + fallback_backends = ["colorthief", "colorz", "wal"] + + for fallback_backend in fallback_backends: + if fallback_backend == backend: + continue + print(f"\nTrying with {fallback_backend} backend...") + cmd_fallback = f'wal -i "{image_path}" --backend {fallback_backend}' + stdout, stderr, returncode = run_command(cmd_fallback, check=False) + + if returncode == 0: + print(f"✓ Successfully generated colors using {fallback_backend} backend") + break + else: + print(f" {fallback_backend} backend also failed") + else: + print(f"\nError: wal failed with all attempted backends.") + print("This may be a pywal bug with this specific image.") + print("Suggestions:") + print(" - Try a different image") + print(" - Update pywal: pip install --upgrade pywal") + print(" - Try manually: wal -i <image> --backend <backend>") + sys.exit(1) + + if stderr and "error" not in stderr.lower(): + print(stderr) + + print("✓ Colors generated by wal") + + + + + +def create_dynamic_profile(): + """Create/update a dynamic profile with pywal colors.""" + print("Creating/updating dynamic profile...") + + if not COLORS_JSON.exists(): + print(f"Error: colors.json not found at {COLORS_JSON}") + sys.exit(1) + + # Read pywal colors + with open(COLORS_JSON) as f: + colors = json.load(f) + + colors_dict = colors.get("colors", {}) + special = colors.get("special", {}) + + # Create dynamic profile structure + dynamic_profile = { + "Profiles": [ + { + "Name": "wal", + "Guid": "wal-dynamic-profile-uuid", + "Rewritable": True, + } + ] + } + + profile = dynamic_profile["Profiles"][0] + + # Add ANSI colors (0-15) + for i in range(16): + color_key = f"color{i}" + hex_color = colors_dict.get(color_key, "#000000") + r, g, b = hex_to_rgb(hex_color) + profile[f"Ansi {i} Color"] = { + "Color Space": "sRGB", + "Red Component": r, + "Green Component": g, + "Blue Component": b, + "Alpha Component": 1.0, + } + + # Add special colors + profile["Background Color"] = { + "Color Space": "sRGB", + "Red Component": hex_to_rgb(special.get("background", "#000000"))[0], + "Green Component": hex_to_rgb(special.get("background", "#000000"))[1], + "Blue Component": hex_to_rgb(special.get("background", "#000000"))[2], + "Alpha Component": 1.0, + } + + profile["Foreground Color"] = { + "Color Space": "sRGB", + "Red Component": hex_to_rgb(special.get("foreground", "#ffffff"))[0], + "Green Component": hex_to_rgb(special.get("foreground", "#ffffff"))[1], + "Blue Component": hex_to_rgb(special.get("foreground", "#ffffff"))[2], + "Alpha Component": 1.0, + } + + profile["Cursor Color"] = { + "Color Space": "sRGB", + "Red Component": hex_to_rgb(special.get("cursor", "#ffffff"))[0], + "Green Component": hex_to_rgb(special.get("cursor", "#ffffff"))[1], + "Blue Component": hex_to_rgb(special.get("cursor", "#ffffff"))[2], + "Alpha Component": 1.0, + } + + # Write the dynamic profile + dynamic_profiles_dir = Path.home() / "Library/Application Support/iTerm2/DynamicProfiles" + dynamic_profiles_dir.mkdir(parents=True, exist_ok=True) + profile_file = dynamic_profiles_dir / "wal-profile.json" + + with open(profile_file, 'w') as f: + json.dump(dynamic_profile, f, indent=2) + + print(f"✓ Dynamic profile created/updated: {profile_file}") + print("✓ iTerm2 will automatically detect the changes") + print("\nTo use: Switch to the 'wal' profile in iTerm2") + print("Future runs will update the 'wal' profile automatically") + + +def main(): + """Main function.""" + image_path = sys.argv[1] if len(sys.argv) > 1 else None + + run_wal(image_path, backend="haishoku") + create_dynamic_profile() + + print("\n✓ Done! Dynamic profile 'wal' updated with new colors.") + + +if __name__ == "__main__": + main() + |
