Use theme config templates with singular color definition (#4053)

* Attempt to templaterize the theme specific files

* Cleanup

* Slim down

* Combine render into -set

* Pull out the dynamic template rendering again, but simpler

* Fix vars

* Variables are lowercase

* Better presentation

* Fix missing colors

* Provide stripped values too

* Fix colors for regular hex format

* Bring back explicit btop themes

They're too involved to derive from a basic color set

* Make an atomic swap of the theme directories

* No longer used by walker to cancel

* Explain why

* Remove redundant const

* Consistent const naming

* No longe have $THEMES_DIR

* Correct the blue

* Set opencode colors too

* Fix colors for readability

* Move the templates together with the others in default

* Split user themes and default themes

* Fix paths

* Look for both user themes and default themes

Plus speed things up

* Migrate to the new setup where default themes live inside omarchy

* Explicitly store the name of the current theme

* Cleanup

* No longer need omarchy-theme-next since themes are now fully rendered, not symlinks

* Get current theme name from the new theme.name file

* Look for user background images in dedicated directory

* Need yq for toml

* Need yq to parse colors.toml

* Look for backgrounds matching the new theme.name

We no longer have symlinks

* Migrate existing user backgrounds to the new proper location

* Install user backgrounds in the correct path

* Fix quoting

* Just rely on the system theme for opencode and get ready for USRSIG2 being available to live reload

* Fix template generation for rgb colors
This commit is contained in:
David Heinemeier Hansson
2026-01-03 18:22:14 -08:00
committed by GitHub
parent de2757466b
commit 4a07b94cb6
174 changed files with 809 additions and 3234 deletions

View File

@@ -303,7 +303,7 @@ show_install_gaming_menu() {
show_install_style_menu() {
case $(menu "Install" "󰸌 Theme\n Background\n Font") in
*Theme*) present_terminal omarchy-theme-install ;;
*Background*) nautilus ~/.config/omarchy/current/theme/backgrounds ;;
*Background*) omarchy-theme-bg-install ;;
*Font*) show_install_font_menu ;;
*) show_install_menu ;;
esac

7
bin/omarchy-theme-bg-install Executable file
View File

@@ -0,0 +1,7 @@
#!/bin/bash
CURRENT_THEME_NAME=$(cat "$HOME/.config/omarchy/current/theme.name")
THEME_USER_BACKGROUNDS="$HOME/.config/omarchy/backgrounds/$CURRENT_THEME_NAME"
mkdir -p "$THEME_USER_BACKGROUNDS"
nautilus "$THEME_USER_BACKGROUNDS"

View File

@@ -2,10 +2,12 @@
# Cycles through the background images available
BACKGROUNDS_DIR="$HOME/.config/omarchy/current/theme/backgrounds/"
THEME_NAME=$(cat "$HOME/.config/omarchy/current/theme.name" 2>/dev/null)
THEME_BACKGROUNDS_PATH="$HOME/.config/omarchy/current/theme/backgrounds/"
USER_BACKGROUNDS_PATH="$HOME/.config/omarchy/backgrounds/$THEME_NAME/"
CURRENT_BACKGROUND_LINK="$HOME/.config/omarchy/current/background"
mapfile -d '' -t BACKGROUNDS < <(find -L "$BACKGROUNDS_DIR" -type f -print0 | sort -z)
mapfile -d '' -t BACKGROUNDS < <(find -L "$USER_BACKGROUNDS_PATH" "$THEME_BACKGROUNDS_PATH" -maxdepth 1 -type f -print0 2>/dev/null | sort -z)
TOTAL=${#BACKGROUNDS[@]}
if [[ $TOTAL -eq 0 ]]; then

View File

@@ -1,3 +1,9 @@
#!/bin/bash
basename "$(realpath "$HOME/.config/omarchy/current/theme")" | sed -E 's/(^|-)([a-z])/\1\u\2/g; s/-/ /g'
THEME_NAME_PATH="$HOME/.config/omarchy/current/theme.name"
if [[ -f $THEME_NAME_PATH ]]; then
cat $THEME_NAME_PATH | sed -E 's/(^|-)([a-z])/\1\u\2/g; s/-/ /g'
else
echo "Unknown"
fi

View File

@@ -1,5 +1,8 @@
#!/bin/bash
find ~/.config/omarchy/themes/ -mindepth 1 -maxdepth 1 \( -type d -o -type l \) | sort | while read -r path; do
echo "$(basename "$path" | sed -E 's/(^|-)([a-z])/\1\u\2/g; s/-/ /g')"
{
find ~/.config/omarchy/themes/ -mindepth 1 -maxdepth 1 \( -type d -o -type l \) -printf '%f\n'
find "$OMARCHY_PATH/themes/" -mindepth 1 -maxdepth 1 -type d -printf '%f\n'
} | sort -u | while read -r name; do
echo "$name" | sed -E 's/(^|-)([a-z])/\1\u\2/g; s/-/ /g'
done

View File

@@ -1,34 +0,0 @@
#!/bin/bash
THEMES_DIR="$HOME/.config/omarchy/themes/"
CURRENT_THEME_LINK="$HOME/.config/omarchy/current/theme"
THEMES=($(find "$THEMES_DIR" -mindepth 1 -maxdepth 1 | sort))
TOTAL=${#THEMES[@]}
# Get current theme from symlink
if [[ -L "$CURRENT_THEME_LINK" ]]; then
CURRENT_THEME=$(realpath "$CURRENT_THEME_LINK")
else
# Default to first theme if no symlink exists
CURRENT_THEME=$(realpath "${THEMES[0]}")
fi
# Find current theme index
INDEX=0
for i in "${!THEMES[@]}"; do
THEMES[$i]=$(realpath "${THEMES[$i]}")
if [[ "${THEMES[$i]}" == "$CURRENT_THEME" ]]; then
INDEX=$i
break
fi
done
# Get next theme (wrap around)
NEXT_INDEX=$(((INDEX + 1) % TOTAL))
NEW_THEME=${THEMES[$NEXT_INDEX]}
NEW_THEME_NAME=$(basename "$NEW_THEME")
omarchy-theme-set $NEW_THEME_NAME
notify-send "Theme changed to $NEW_THEME_NAME" -t 2000

View File

@@ -31,10 +31,5 @@ if [ ! -d "$THEME_PATH" ]; then
exit 1
fi
# Move to the next theme if the current theme is the one being removed
if [ "$(readlink -f "$CURRENT_DIR/theme")" = "$(readlink -f "$THEME_PATH")" ]; then
omarchy-theme-next
fi
# Now remove the theme directory for THEME_NAME
rm -rf "$THEME_PATH"

View File

@@ -1,24 +1,42 @@
#!/bin/bash
if [[ -z $1 && $1 != "CNCLD" ]]; then
if [[ -z $1 ]]; then
echo "Usage: omarchy-theme-set <theme-name>"
exit 1
fi
THEMES_DIR="$HOME/.config/omarchy/themes/"
CURRENT_THEME_DIR="$HOME/.config/omarchy/current/theme"
CURRENT_THEME_PATH="$HOME/.config/omarchy/current/theme"
NEXT_THEME_PATH="$HOME/.config/omarchy/current/next-theme"
USER_THEMES_PATH="$HOME/.config/omarchy/themes"
OMARCHY_THEMES_PATH="$OMARCHY_PATH/themes"
THEME_NAME=$(echo "$1" | sed -E 's/<[^>]+>//g' | tr '[:upper:]' '[:lower:]' | tr ' ' '-')
THEME_PATH="$THEMES_DIR/$THEME_NAME"
# Check if the theme entered exists
if [[ ! -d "$THEME_PATH" ]]; then
echo "Theme '$THEME_NAME' does not exist in $THEMES_DIR"
if [[ -d "$USER_THEMES_PATH/$THEME_NAME" ]]; then
THEME_PATH="$USER_THEMES_PATH/$THEME_NAME"
elif [[ -d "$OMARCHY_THEMES_PATH/$THEME_NAME" ]]; then
THEME_PATH="$OMARCHY_THEMES_PATH/$THEME_NAME"
else
echo "Theme '$THEME_NAME' does not exist"
exit 1
fi
# Update theme symlinks
ln -nsf "$THEME_PATH" "$CURRENT_THEME_DIR"
# Setup clean next theme directory (for atomic theme config swapping)
rm -rf "$NEXT_THEME_PATH"
mkdir -p "$NEXT_THEME_PATH"
# Copy static configs
cp -r "$THEME_PATH/"* "$NEXT_THEME_PATH/" 2>/dev/null
# Generate dynamic configs
omarchy-theme-set-templates
# 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"
# Change background with theme
omarchy-theme-bg-next
@@ -31,9 +49,10 @@ omarchy-restart-swayosd
omarchy-restart-terminal
hyprctl reload
pkill -SIGUSR2 btop
# pkill -SIGUSR2 opencode
makoctl reload
# Change gnome, browser, vscode, cursor themes
# Change app-specific themes
omarchy-theme-set-gnome
omarchy-theme-set-browser
omarchy-theme-set-vscode

44
bin/omarchy-theme-set-templates Executable file
View File

@@ -0,0 +1,44 @@
#!/bin/bash
TEMPLATES_DIR="$OMARCHY_PATH/default/themed"
NEXT_THEME_DIR="$HOME/.config/omarchy/current/next-theme"
COLORS_FILE="$NEXT_THEME_DIR/colors.toml"
# Convert hex color to decimal RGB (e.g., "#1e1e2e" -> "30,30,46")
hex_to_rgb() {
local hex="${1#\#}"
printf "%d,%d,%d" "0x${hex:0:2}" "0x${hex:2:2}" "0x${hex:4:2}"
}
# Only generate dynamic templates for themes with a colors.toml definition
if [[ -f $COLORS_FILE ]]; then
# Parse TOML using yq (treating it as YAML since the flat key=value structure is compatible)
# We convert 'key = value' to 'key: value' to make it valid YAML, then use yq/jq to generate the replacement commands.
sed_script=$(mktemp)
# Generate standard and _strip substitutions
sed 's/=/:/' "$COLORS_FILE" | yq -r 'to_entries[] | "s|{{ \(.key) }}|\(.value)|g", "s|{{ \(.key)_strip }}|\(.value | sub("^#";""))|g"' > "$sed_script"
# Generate _rgb substitutions for hex colors
while IFS='=' read -r key value; do
key=$(echo "$key" | xargs)
value=$(echo "$value" | xargs | tr -d '"')
if [[ $value =~ ^# ]]; then
rgb=$(hex_to_rgb "$value")
echo "s|{{ ${key}_rgb }}|${rgb}|g" >> "$sed_script"
fi
done < "$COLORS_FILE"
shopt -s nullglob
for tpl in "$TEMPLATES_DIR"/*.tpl; do
filename=$(basename "$tpl" .tpl)
output_path="$NEXT_THEME_DIR/$filename"
# Don't overwrite configs already exists in the output directory (copied from theme specific folder)
if [[ ! -f $output_path ]]; then
sed -f "$sed_script" "$tpl" > "$output_path"
fi
done
rm "$sed_script"
fi