.dotfiles/wezterm/.config/wezterm/theme-switcher.lua

144 lines
3.9 KiB
Lua

local wezterm = require("wezterm")
local M = {}
-- Configuration
local cache_dir = os.getenv("XDG_CACHE_HOME") or (os.getenv("HOME") .. "/.cache")
local cache_file = cache_dir .. "/current_theme"
-- Color scheme definitions
local color_schemes = {
dark = {
name = "Monokai (dark) (terminal.sexy)",
palette = "monokai_pro",
},
light = {
name = "Solarized (light) (terminal.sexy)",
palette = "solarized_light",
},
}
-- Cache the last known mode to minimize file reads
local last_mode_cache = nil
local cache_timestamp = 0
-- Fast system appearance detection (cached)
local last_appearance = nil
local appearance_timestamp = 0
local function get_system_appearance()
local now = os.time()
-- Only check system appearance every 2 seconds to reduce GUI calls
if last_appearance and (now - appearance_timestamp) < 2 then
return last_appearance
end
local current_appearance = "dark" -- fallback
if wezterm.gui then
local appearance = wezterm.gui.get_appearance()
if appearance then
current_appearance = appearance:lower():find("dark") and "dark" or "light"
end
else
-- Fallback to environment variable (faster than GUI check)
local default_appearance = os.getenv("DEFAULT_APPEARANCE")
if default_appearance then
current_appearance = default_appearance:lower():find("dark") and "dark" or "light"
end
end
last_appearance = current_appearance
appearance_timestamp = now
return current_appearance
end
-- Ultra-fast cache read (non-blocking)
local function read_theme_cache_fast()
local now = os.time()
-- Only read file every 5 seconds to minimize I/O
if last_mode_cache and (now - cache_timestamp) < 5 then
return last_mode_cache
end
-- Non-blocking file read attempt
local file = io.open(cache_file, "r")
if file then
local content = file:read("*all") -- Read entire file
file:close()
if content then
-- Strip ALL whitespace characters
content = content:gsub("%s+", "")
if content == "dark" or content == "light" then -- Simple string comparison
last_mode_cache = content
cache_timestamp = now
return content
end
end
end
return nil
end
local function write_theme_cache_blocking(mode)
-- Ensure directory exists
os.execute(string.format('mkdir -p "%s" 2>/dev/null', cache_dir))
-- Write the cache file
local file = io.open(cache_file, "w")
if file then
file:write(mode)
file:close()
end
end
-- Ultra-fast async theme sync (fire-and-forget)
local function sync_theme_configs_async(mode)
local home_dir = os.getenv("HOME")
local script_path = home_dir .. "/.local/bin/scripts/update_app_theme.sh"
-- Fire-and-forget - don't even wait for command to start
local cmd = string.format('(TARGET_MODE="%s" "%s" >/dev/null 2>&1) &', mode, script_path)
print("Executing theme sync command:", cmd)
os.execute(cmd)
end
-- Apply theme configuration (with debug logging)
function M.apply_to_config(config)
local current_mode = get_system_appearance()
local cached_mode = read_theme_cache_fast()
-- Always sync if modes don't match - this ensures consistency
if current_mode ~= cached_mode then
-- Use direct file operations instead of shell commands
write_theme_cache_blocking(current_mode)
sync_theme_configs_async(current_mode)
end
-- Apply theme immediately (no I/O)
local theme = color_schemes[current_mode] or color_schemes.dark
config.color_scheme = theme.name
end
-- Fast manual mode setting
function M.set_mode(mode)
if color_schemes[mode] then
write_theme_cache_blocking(mode)
sync_theme_configs_async(mode)
return true
end
return false
end
-- Fast mode getter
function M.get_current_mode()
return get_system_appearance()
end
-- Refresh script path cache (useful if you move the script)
function M.refresh_script_path()
local script_path_cache = nil
return script_path_cache
end
return M