aboutsummaryrefslogtreecommitdiff
path: root/iTerm/wal-iterm.py
diff options
context:
space:
mode:
Diffstat (limited to 'iTerm/wal-iterm.py')
-rw-r--r--iTerm/wal-iterm.py191
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()
+