From caeffdc27b7ffbfe4d9d6e8cc1ba0f6c8842256f Mon Sep 17 00:00:00 2001 From: Luke Walker Date: Tue, 4 Aug 2026 12:26:26 -0600 Subject: [PATCH] fix: add bg/fg aliases for theme color resolution (#6546) * fix: add bg/fg aliases for theme color resolution Themes define bg/fg but the template system expects background/foreground. The fallback chain only checked color0/color7, leaving background/foreground empty for themes using bg/fg naming. * Complete legacy theme palette compatibility --------- Co-authored-by: David Heinemeier Hansson --- bin/omarchy-theme-color | 28 +++++++++++- docs/theming.md | 15 +++++++ test/cli | 94 ++++++++++++++++++++++++++++++++++++++++- 3 files changed, 134 insertions(+), 3 deletions(-) diff --git a/bin/omarchy-theme-color b/bin/omarchy-theme-color index cbbab0e2..cdf2592d 100755 --- a/bin/omarchy-theme-color +++ b/bin/omarchy-theme-color @@ -161,8 +161,24 @@ parse_colors_file() { resolve_theme_colors() { local key - # Canonical palette keys are background/foreground. Themes generated before - # the semantic palette existed may only define the ANSI names. + # Accept the complete legacy short-name palette before applying ANSI + # fallbacks or deriving shades. Canonical names take precedence when a theme + # defines both forms. + declare -A legacy_palette_alias=( + [background]=bg + [dark_background]=dark_bg + [darker_background]=darker_bg + [lighter_background]=lighter_bg + [foreground]=fg + [dark_foreground]=dark_fg + [light_foreground]=light_fg + [bright_foreground]=bright_fg + ) + for key in "${!legacy_palette_alias[@]}"; do + alias_theme_color "$key" "${legacy_palette_alias[$key]}" + done + + # Themes generated before the semantic palette may only define ANSI names. [[ ${THEME_COLORS[background]} ]] || THEME_COLORS[background]="${THEME_COLORS[color0]}" [[ ${THEME_COLORS[foreground]} ]] || THEME_COLORS[foreground]="${THEME_COLORS[color7]}" [[ ${THEME_COLORS[background]} ]] && THEME_COLORS[color0]="${THEME_COLORS[background]}" @@ -237,6 +253,14 @@ resolve_theme_colors() { alias_theme_color "$key" "${ansi_alias[$key]}" done + # Keep canonical themes compatible with old user templates and consumers + # that still query the short palette names directly. + for key in "${!legacy_palette_alias[@]}"; do + if [[ ${THEME_COLORS[$key]} ]]; then + THEME_COLORS["${legacy_palette_alias[$key]}"]="${THEME_COLORS[$key]}" + fi + done + resolve_theme_mode THEME_COLORS[theme_type]="${THEME_COLORS[mode]}" } diff --git a/docs/theming.md b/docs/theming.md index 9a6f3a1a..f21db05f 100644 --- a/docs/theming.md +++ b/docs/theming.md @@ -66,6 +66,21 @@ shell palette is loaded from: serves as ANSI `color8` - `urgent` / `red` / `color1` +Themes and user templates using the legacy short names remain supported. +Canonical names take precedence when both forms are defined, and resolved +canonical values are also exposed through their legacy names: + +| Canonical | Legacy | +|-----------|--------| +| `background` | `bg` | +| `dark_background` | `dark_bg` | +| `darker_background` | `darker_bg` | +| `lighter_background` | `lighter_bg` | +| `foreground` | `fg` | +| `dark_foreground` | `dark_fg` | +| `light_foreground` | `light_fg` | +| `bright_foreground` | `bright_fg` | + The neutral ramp is centered on `background -> bright_foreground`. Dark themes should read from darkest to lightest; light themes should read from lightest to darkest. Terminal and editor cursors use `bright_foreground`; there is no diff --git a/test/cli b/test/cli index e8e5363c..dfd819c0 100755 --- a/test/cli +++ b/test/cli @@ -221,7 +221,12 @@ mode = "light" accent = "#336699" hyprland_active_border = "rgba(010203ee) rgba(040506ee) 45deg" background = "#000000" +dark_background = "#010101" +darker_background = "#020202" +lighter_background = "#030303" foreground = "#ffffff" +dark_foreground = "#cccccc" +light_foreground = "#dddddd" selection = "#808080" red = "#ff0000" green = "#00ff00" @@ -237,6 +242,16 @@ bright_blue = "#1111ff" bright_magenta = "#ff11ff" bright_cyan = "#11ffff" bright_foreground = "#eeeeee" + +# Canonical values must win when a transitional theme defines both forms. +bg = "#abcdef" +dark_bg = "#abcdef" +darker_bg = "#abcdef" +lighter_bg = "#abcdef" +fg = "#abcdef" +dark_fg = "#abcdef" +light_fg = "#abcdef" +bright_fg = "#abcdef" EOF cat >"$USER_THEMED/mix-test.txt.tpl" <<'EOF' @@ -264,6 +279,15 @@ bright-magenta={{ bright_magenta }} legacy-bright-purple={{ bright_purple }} background={{ background }} foreground={{ foreground }} +legacy-background={{ bg }} +legacy-dark-background={{ dark_bg }} +legacy-darker-background={{ darker_bg }} +legacy-lighter-background={{ lighter_bg }} +legacy-foreground={{ fg }} +legacy-dark-foreground={{ dark_fg }} +legacy-light-foreground={{ light_fg }} +legacy-bright-foreground={{ bright_fg }} +legacy-mix={{ mix bg fg 50% }} selection-background={{ selection_background }} selection-foreground={{ selection_foreground }} cursor-alias={{ cursor }} @@ -290,10 +314,78 @@ grep -qx 'bright-magenta=#ff11ff' "$NEXT_THEME/alias-test.txt" || fail "theme te grep -qx 'legacy-bright-purple=#ff11ff' "$NEXT_THEME/alias-test.txt" || fail "theme template bright purple alias works" grep -qx 'background=#000000' "$NEXT_THEME/alias-test.txt" || fail "theme template resolves background" grep -qx 'foreground=#ffffff' "$NEXT_THEME/alias-test.txt" || fail "theme template resolves foreground" +grep -qx 'legacy-background=#000000' "$NEXT_THEME/alias-test.txt" || fail "theme template exposes legacy bg alias" +grep -qx 'legacy-dark-background=#010101' "$NEXT_THEME/alias-test.txt" || fail "theme template exposes legacy dark_bg alias" +grep -qx 'legacy-darker-background=#020202' "$NEXT_THEME/alias-test.txt" || fail "theme template exposes legacy darker_bg alias" +grep -qx 'legacy-lighter-background=#030303' "$NEXT_THEME/alias-test.txt" || fail "theme template exposes legacy lighter_bg alias" +grep -qx 'legacy-foreground=#ffffff' "$NEXT_THEME/alias-test.txt" || fail "theme template exposes legacy fg alias" +grep -qx 'legacy-dark-foreground=#cccccc' "$NEXT_THEME/alias-test.txt" || fail "theme template exposes legacy dark_fg alias" +grep -qx 'legacy-light-foreground=#dddddd' "$NEXT_THEME/alias-test.txt" || fail "theme template exposes legacy light_fg alias" +grep -qx 'legacy-bright-foreground=#eeeeee' "$NEXT_THEME/alias-test.txt" || fail "theme template exposes legacy bright_fg alias" +grep -qx 'legacy-mix=#808080' "$NEXT_THEME/alias-test.txt" || fail "theme template mix helper accepts legacy palette aliases" grep -qx 'selection-background=#808080' "$NEXT_THEME/alias-test.txt" || fail "theme template derives selection background from selection" grep -qx 'selection-foreground=#eeeeee' "$NEXT_THEME/alias-test.txt" || fail "theme template derives selection foreground from bright_foreground" grep -qx 'cursor-alias=#eeeeee' "$NEXT_THEME/alias-test.txt" || fail "theme template derives cursor alias from bright_foreground" -pass "theme template semantic aliases expose legacy colorN helpers" +pass "theme template semantic aliases expose legacy palette helpers" + +LEGACY_COLORS_FILE="$PI_TMPDIR/legacy-colors.toml" +cat >"$LEGACY_COLORS_FILE" <<'EOF' +mode = "dark" +accent = "#336699" +selection = "#292929" +muted = "#404040" +bg = "#101010" +dark_bg = "#111111" +darker_bg = "#121212" +lighter_bg = "#131313" +fg = "#f0f0f0" +dark_fg = "#d0d0d0" +light_fg = "#e0e0e0" +bright_fg = "#ffffff" +red = "#ff0000" +green = "#00ff00" +yellow = "#ffff00" +blue = "#0000ff" +magenta = "#ff00ff" +cyan = "#00ffff" +bright_red = "#ff1111" +bright_green = "#11ff11" +bright_yellow = "#ffff11" +bright_blue = "#1111ff" +bright_magenta = "#ff11ff" +bright_cyan = "#11ffff" +EOF + +while read -r canonical expected; do + actual=$("$ROOT/bin/omarchy-theme-color" --file "$LEGACY_COLORS_FILE" "$canonical") + [[ $actual == "$expected" ]] || fail "legacy palette resolves $canonical" +done <<'EOF' +background #101010 +dark_background #111111 +darker_background #121212 +lighter_background #131313 +foreground #f0f0f0 +dark_foreground #d0d0d0 +light_foreground #e0e0e0 +bright_foreground #ffffff +EOF +pass "legacy short palette resolves every canonical neutral color" + +LEGACY_THEME_HOME="$PI_TMPDIR/legacy-theme-home" +LEGACY_NEXT_THEME="$LEGACY_THEME_HOME/.local/state/omarchy/current/next-theme" +mkdir -p "$LEGACY_NEXT_THEME" +cp "$LEGACY_COLORS_FILE" "$LEGACY_NEXT_THEME/colors.toml" +OMARCHY_PATH="$ROOT" HOME="$LEGACY_THEME_HOME" "$ROOT/bin/omarchy-theme-set-templates" +grep -qx 'background = #101010' "$LEGACY_NEXT_THEME/ghostty.conf" || fail "legacy theme generates terminal background" +grep -qx 'foreground = #f0f0f0' "$LEGACY_NEXT_THEME/ghostty.conf" || fail "legacy theme generates terminal foreground" +grep -Fq 'dark_bg = "#111111"' "$LEGACY_NEXT_THEME/neovim.lua" || fail "legacy theme preserves dark_bg in generated editor theme" +grep -Fq 'lighter_bg = "#131313"' "$LEGACY_NEXT_THEME/neovim.lua" || fail "legacy theme preserves lighter_bg in generated editor theme" +grep -Fq 'dark_fg = "#d0d0d0"' "$LEGACY_NEXT_THEME/neovim.lua" || fail "legacy theme preserves dark_fg in generated editor theme" +grep -Fq 'bright_fg = "#ffffff"' "$LEGACY_NEXT_THEME/neovim.lua" || fail "legacy theme preserves bright_fg in generated editor theme" +if rg -q '\{\{[^}]+\}\}' "$LEGACY_NEXT_THEME"; then + fail "legacy theme renders every template placeholder" +fi +pass "legacy short palette renders the complete generated theme" osc_summary=$("$ROOT/bin/omarchy-theme-osc" "$NEXT_THEME/colors.toml" | python -c 'import sys; data = sys.stdin.buffer.read(); print(data.count(b"]4;"), b"]4;1;#ff0000" in data, b"]4;7;#ffffff" in data, b"]4;15;#eeeeee" in data, b"]12;#eeeeee" in data, b"]17;#808080" in data, b"]19;#eeeeee" in data)') [[ $osc_summary == "16 True True True True True True" ]] || fail "theme OSC aliases semantic colors to ANSI palette"