Files
keycodex/pywal/chadwal.py
T

121 lines
4.0 KiB
Python

#!/usr/bin/env python3
import os
import shutil
import sys
import time
import subprocess
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler
# Constants
SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
HOME_DIR = os.path.expanduser("~")
TEMPLATE_SRC = {
"dark": os.path.join(SCRIPT_DIR, "dark.lua"),
"light": os.path.join(SCRIPT_DIR, "light.lua")
}
TEMPLATE_DST = {
"dark": f"{HOME_DIR}/.config/wal/templates/base46-dark.lua",
"light": f"{HOME_DIR}/.config/wal/templates/base46-light.lua"
}
CACHE_SRC = {
"dark": f"{HOME_DIR}/.cache/wal/base46-dark.lua",
"light": f"{HOME_DIR}/.cache/wal/base46-light.lua"
}
CACHE_DST = f"{HOME_DIR}/.local/share/nvim/lazy/base46/lua/base46/themes/chadwal.lua"
FALLBACK_THEME = f"{HOME_DIR}/.local/share/nvim/lazy/base46/lua/base46/themes/gruvchad.lua"
LOCK_FILE = "/tmp/wal_nvim_lock"
COLORS_FILE = f"{HOME_DIR}/.cache/wal/colors"
# Utility functions
def is_dark(hex_color):
"""Determine if the color is dark based on luminance."""
hex_color = hex_color.lstrip('#')
r, g, b = (int(hex_color[i:i+2], 16) for i in (0, 2, 4))
brightness = (r * 299 + g * 587 + b * 114) / 1000
return brightness < 128
def get_hex_from_colors_file():
"""Read the first color from the colors file."""
try:
with open(COLORS_FILE, 'r') as file:
return file.readline().strip()
except FileNotFoundError:
sys.exit(f"Error: Colors file not found: {COLORS_FILE}")
def acquire_lock():
"""Create a lock file to prevent multiple instances."""
if os.path.exists(LOCK_FILE):
sys.exit("Another instance is already running. Exiting...")
open(LOCK_FILE, 'w').close()
def release_lock():
"""Remove the lock file."""
if os.path.exists(LOCK_FILE):
os.remove(LOCK_FILE)
def copy_file(src, dst, skip_if_exists=False):
"""Copy a file from src to dst, optionally skipping if dst exists."""
if skip_if_exists and os.path.exists(dst):
print(f"File already exists at {dst}, skipping copy.")
return
try:
os.makedirs(os.path.dirname(dst), exist_ok=True)
shutil.copy(src, dst)
print(f"File copied from {src} to {dst}.")
except Exception as e:
sys.exit(f"Error copying file from {src} to {dst}: {e}")
def on_file_modified():
"""Handle file modifications based on current color scheme."""
is_dark_theme = is_dark(get_hex_from_colors_file())
mode = "dark" if is_dark_theme else "light"
copy_file(FALLBACK_THEME, CACHE_SRC[mode], skip_if_exists=True)
copy_file(TEMPLATE_SRC[mode], TEMPLATE_DST[mode])
copy_file(CACHE_SRC[mode], CACHE_DST)
# Signal running nvim instances, don't exit based on the result here.
subprocess.run(['killall', '-SIGUSR1', 'nvim'])
# Watchdog event handler
class MyHandler(FileSystemEventHandler):
def on_modified(self, event):
if event.src_path == CACHE_SRC["dark"]:
on_file_modified()
def monitor_file(file_path):
"""Monitor the specified file for changes."""
event_handler = MyHandler()
observer = Observer()
observer.schedule(event_handler, os.path.dirname(file_path), recursive=False)
observer.start()
try:
while True:
# Check every 5 seconds if nvim is running
time.sleep(5)
# Use pgrep to check for exact process name 'nvim'
result = subprocess.run(['pgrep', '-x', 'nvim'], capture_output=True)
if result.returncode != 0:
print("No running nvim instances found. Exiting.")
observer.stop() # Stop the observer thread
break # Exit the loop
except KeyboardInterrupt:
print("\nKeyboard interrupt received. Exiting.")
observer.stop()
finally:
# Ensure the observer thread is joined before exiting
observer.join()
if __name__ == "__main__":
on_file_modified()
acquire_lock()
try:
on_file_modified()
monitor_file(CACHE_SRC["dark"])
finally:
release_lock()