Files
arthur-os/bin/omarchy-theme-set
T

163 lines
5.6 KiB
Bash
Executable File

#!/bin/bash
# omarchy:summary=Apply an Omarchy theme
# omarchy:args=<theme-name>
# omarchy:examples=omarchy theme list | omarchy theme set "Tokyo Night"
if [[ -z $1 ]]; then
echo "Usage: omarchy-theme-set <theme-name>"
exit 1
fi
CURRENT_THEME_PATH="$HOME/.config/omarchy/current/theme"
NEXT_THEME_PATH="$HOME/.config/omarchy/current/next-theme"
CURRENT_BACKGROUND_LINK="$HOME/.config/omarchy/current/background"
BACKGROUND_TRANSITION_CACHE="$HOME/.cache/omarchy/background-transitions"
USER_THEMES_PATH="$HOME/.config/omarchy/themes"
OMARCHY_THEMES_PATH="$OMARCHY_PATH/themes"
run_parallel() {
local pid
local pids=()
for command in "$@"; do
bash -lc "$command" &
pids+=("$!")
done
for pid in "${pids[@]}"; do
wait "$pid"
done
}
snapshot_current_background() {
local current_background snapshot extension
current_background=$(readlink -f "$CURRENT_BACKGROUND_LINK" 2>/dev/null || true)
[[ -f $current_background ]] || return
mkdir -p "$BACKGROUND_TRANSITION_CACHE"
extension=${current_background##*.}
snapshot="$BACKGROUND_TRANSITION_CACHE/previous-$$.$extension"
ln "$current_background" "$snapshot" 2>/dev/null || cp "$current_background" "$snapshot"
echo "$snapshot"
}
set_theme_background() {
local backgrounds=()
local current_background index new_background next_index
mapfile -d '' -t backgrounds < <(
find -L "$HOME/.config/omarchy/backgrounds/$THEME_NAME/" "$CURRENT_THEME_PATH/backgrounds/" -maxdepth 1 -type f \
\( -iname '*.jpg' -o -iname '*.jpeg' -o -iname '*.png' -o -iname '*.gif' -o -iname '*.bmp' -o -iname '*.webp' \) \
-print0 2>/dev/null | sort -z
)
if (( ${#backgrounds[@]} == 0 )); then
omarchy-notification-send "No background was found for theme" -t 2000
omarchy-shell-ipc-fast shell applyTheme "$colors_payload" "$shell_payload" >/dev/null 2>&1 || true
return
fi
current_background=$(readlink "$CURRENT_BACKGROUND_LINK" 2>/dev/null || true)
index=-1
for i in "${!backgrounds[@]}"; do
if [[ ${backgrounds[$i]} == $current_background ]]; then
index=$i
break
fi
done
if (( index == -1 )); then
new_background="${backgrounds[0]}"
else
next_index=$(((index + 1) % ${#backgrounds[@]}))
new_background="${backgrounds[$next_index]}"
fi
ln -nsf "$new_background" "$CURRENT_BACKGROUND_LINK"
if [[ -f $OLD_BACKGROUND_SNAPSHOT ]]; then
omarchy-shell-ipc-fast background themeTransition "$OLD_BACKGROUND_SNAPSHOT" "$new_background" "$colors_payload" "$shell_payload" >/dev/null 2>&1 || \
omarchy-shell-ipc-fast shell applyTheme "$colors_payload" "$shell_payload" >/dev/null 2>&1 || true
(sleep 3; rm -f "$OLD_BACKGROUND_SNAPSHOT") &
else
omarchy-shell-ipc-fast background themeTransition "" "$new_background" "$colors_payload" "$shell_payload" >/dev/null 2>&1 || \
omarchy-shell-ipc-fast shell applyTheme "$colors_payload" "$shell_payload" >/dev/null 2>&1 || true
fi
}
THEME_NAME=$(echo "$1" | sed -E 's/<[^>]+>//g' | tr '[:upper:]' '[:lower:]' | tr ' ' '-')
if [[ ! -d $OMARCHY_THEMES_PATH/$THEME_NAME ]] && [[ ! -d $USER_THEMES_PATH/$THEME_NAME ]]; then
echo "Theme '$THEME_NAME' does not exist"
exit 1
fi
# Prevent file-watch reloads from changing shell colors before the background
# reveal is ready. The theme IPC below resumes reloads as it applies colors.
omarchy-shell-ipc --if-running shell suspendThemeReloads >/dev/null 2>&1 || true
# Setup clean next theme directory (for atomic theme config swapping)
rm -rf "$NEXT_THEME_PATH"
mkdir -p "$NEXT_THEME_PATH"
# Copy official theme first, then overlay user customizations on top
cp -r "$OMARCHY_THEMES_PATH/$THEME_NAME/"* "$NEXT_THEME_PATH/" 2>/dev/null
cp -r "$USER_THEMES_PATH/$THEME_NAME/"* "$NEXT_THEME_PATH/" 2>/dev/null
# Generate colors.toml from alacritty.toml if theme is missing colors.toml
if [[ ! -f $NEXT_THEME_PATH/colors.toml && -f $NEXT_THEME_PATH/alacritty.toml ]]; then
omarchy-theme-colors-from-alacritty "$NEXT_THEME_PATH"
fi
# Generate dynamic configs
omarchy-theme-set-templates
OLD_BACKGROUND_SNAPSHOT=""
if [[ $OMARCHY_THEME_SKIP_BACKGROUND != "1" ]]; then
OLD_BACKGROUND_SNAPSHOT=$(snapshot_current_background)
fi
# Swap next theme in as current
rm -rf "$CURRENT_THEME_PATH"
mv "$NEXT_THEME_PATH" "$CURRENT_THEME_PATH"
# Store theme name for reference
echo "$THEME_NAME" >"$HOME/.config/omarchy/current/theme.name"
# Make the running shell pick up the new palette immediately instead of waiting
# for file-watch debounce while the rest of the theme hooks run.
colors_payload=$([[ -f $CURRENT_THEME_PATH/colors.toml ]] && base64 -w 0 "$CURRENT_THEME_PATH/colors.toml")
shell_payload=$([[ -f $CURRENT_THEME_PATH/shell.toml ]] && base64 -w 0 "$CURRENT_THEME_PATH/shell.toml")
if [[ $OMARCHY_THEME_SKIP_BACKGROUND == "1" ]]; then
omarchy-shell-ipc-fast shell applyTheme "$colors_payload" "$shell_payload" >/dev/null 2>&1 || true
else
set_theme_background
fi
post_theme_commands=(
omarchy-restart-terminal
omarchy-restart-hyprctl
omarchy-restart-btop
omarchy-restart-opencode
omarchy-restart-helix
omarchy-theme-set-foot
omarchy-theme-set-gnome
omarchy-theme-set-browser
omarchy-theme-set-vscode
omarchy-theme-set-obsidian
omarchy-theme-set-keyboard
)
run_parallel "${post_theme_commands[@]}"
# Call hook on theme set
omarchy-hook theme-set "$THEME_NAME" >/dev/null
# Warm selector caches after the theme is applied. The shell hot-reloads theme
# colors/backgrounds, so keep the running instance alive and preload the picker
# rows/selection to avoid first-open carousel settling after a theme change.
omarchy-theme-switcher --preload >/dev/null 2>&1
omarchy-theme-bg-cache >/dev/null 2>&1 &