Skip to content

Commit b1505a0

Browse files
bjarneoryanrhughes
authored andcommitted
Implement semantic theme color system
1 parent 98ba4a9 commit b1505a0

60 files changed

Lines changed: 2329 additions & 1894 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

AGENTS.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ Exceptions are allowed for bootstrap, preflight, migration, and package-helper s
9999

100100
- `config/` - default configs copied to `~/.config/`
101101
- `default/themed/*.tpl` - templates with `{{ variable }}` placeholders for theme colors
102-
- `themes/*/colors.toml` - theme color definitions (accent, background, foreground, color0-15)
102+
- `themes/*/colors.toml` - theme color definitions (accent, background, foreground, red/green/yellow/blue/purple/cyan and bright_* variants)
103103

104104
# Tests
105105

bin/omarchy-theme-colors-from-alacritty

Lines changed: 34 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,24 @@ selection_background=${selection_background:-$foreground}
182182
selection_foreground=${selection_foreground:-$background}
183183
accent=$color4
184184

185+
# Remap ANSI slots to semantic names for the output palette
186+
bg=$color0
187+
red=$color1
188+
green=$color2
189+
yellow=$color3
190+
blue=$color4
191+
purple=$color5
192+
cyan=$color6
193+
fg=$color7
194+
muted=$color8
195+
bright_red=$color9
196+
bright_green=$color10
197+
bright_yellow=$color11
198+
bright_blue=$color12
199+
bright_purple=$color13
200+
bright_cyan=$color14
201+
bright_fg=$color15
202+
185203
mkdir -p "$THEME_SOURCE"
186204

187205
cat > "$COLORS_OUTPUT" <<EOF
@@ -192,20 +210,20 @@ background = "$background"
192210
selection_foreground = "$selection_foreground"
193211
selection_background = "$selection_background"
194212
195-
color0 = "$color0"
196-
color1 = "$color1"
197-
color2 = "$color2"
198-
color3 = "$color3"
199-
color4 = "$color4"
200-
color5 = "$color5"
201-
color6 = "$color6"
202-
color7 = "$color7"
203-
color8 = "$color8"
204-
color9 = "$color9"
205-
color10 = "$color10"
206-
color11 = "$color11"
207-
color12 = "$color12"
208-
color13 = "$color13"
209-
color14 = "$color14"
210-
color15 = "$color15"
213+
color0 = "$bg"
214+
color1 = "$red"
215+
color2 = "$green"
216+
color3 = "$yellow"
217+
color4 = "$blue"
218+
color5 = "$purple"
219+
color6 = "$cyan"
220+
color7 = "$fg"
221+
color8 = "$muted"
222+
color9 = "$bright_red"
223+
color10 = "$bright_green"
224+
color11 = "$bright_yellow"
225+
color12 = "$bright_blue"
226+
color13 = "$bright_purple"
227+
color14 = "$bright_cyan"
228+
color15 = "$bright_fg"
211229
EOF

bin/omarchy-theme-set-gnome

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,20 @@
33
# omarchy:summary=Apply the current theme to GNOME color mode and icon settings
44
# omarchy:hidden=true
55

6-
if [[ -f ~/.config/omarchy/current/theme/light.mode ]]; then
6+
# Detect mode (light|dark) with this precedence:
7+
# 1. `mode` key in the active theme's colors.toml
8+
# 2. legacy `light.mode` file shipped beside the theme
9+
THEME_DIR=~/.config/omarchy/current/theme
10+
COLORS_FILE="$THEME_DIR/colors.toml"
11+
mode=""
12+
if [[ -f $COLORS_FILE ]] && command -v tomlq >/dev/null; then
13+
mode=$(tomlq -r '.mode // empty' "$COLORS_FILE" 2>/dev/null)
14+
fi
15+
if [[ -z $mode && -f $THEME_DIR/light.mode ]]; then
16+
mode="light"
17+
fi
18+
19+
if [[ $mode == "light" ]]; then
720
gsettings set org.gnome.desktop.interface color-scheme "prefer-light"
821
gsettings set org.gnome.desktop.interface gtk-theme "Adwaita"
922
else

bin/omarchy-theme-set-templates

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -304,9 +304,60 @@ if [[ -f $COLORS_FILE ]]; then
304304
value="${value%%[\"\']*}" # extract value between quotes (ignores inline comments)
305305

306306
THEME_COLORS[$key]="$value"
307-
add_template_value "$key" "$value"
308307
done <"$COLORS_FILE"
309308

309+
# Legacy compatibility: map ANSI color0..color15 and raw bg/fg to semantic names
310+
declare -A legacy_alias=(
311+
[bg]=background [fg]=foreground
312+
[red]=color1 [green]=color2 [yellow]=color3
313+
[blue]=color4 [purple]=color5 [cyan]=color6
314+
[bright_red]=color9 [bright_green]=color10 [bright_yellow]=color11
315+
[bright_blue]=color12 [bright_purple]=color13 [bright_cyan]=color14
316+
)
317+
for key in "${!legacy_alias[@]}"; do
318+
[[ ${THEME_COLORS[$key]} ]] || THEME_COLORS[$key]="${THEME_COLORS[${legacy_alias[$key]}]}"
319+
done
320+
321+
[[ ${THEME_COLORS[light_fg]} ]] || THEME_COLORS[light_fg]="${THEME_COLORS[color7]:-${THEME_COLORS[foreground]}}"
322+
[[ ${THEME_COLORS[bright_fg]} ]] || THEME_COLORS[bright_fg]="${THEME_COLORS[color15]:-${THEME_COLORS[foreground]}}"
323+
[[ ${THEME_COLORS[lighter_bg]} ]] || THEME_COLORS[lighter_bg]="${THEME_COLORS[color0]:-${THEME_COLORS[background]}}"
324+
[[ ${THEME_COLORS[dark_fg]} ]] || THEME_COLORS[dark_fg]="${THEME_COLORS[color8]:-${THEME_COLORS[foreground]}}"
325+
[[ ${THEME_COLORS[muted]} ]] || THEME_COLORS[muted]="${THEME_COLORS[color8]:-${THEME_COLORS[dark_fg]}}"
326+
[[ ${THEME_COLORS[selection]} ]] || THEME_COLORS[selection]="${THEME_COLORS[selection_background]:-${THEME_COLORS[color8]:-${THEME_COLORS[color0]}}}"
327+
[[ ${THEME_COLORS[orange]} ]] || THEME_COLORS[orange]="${THEME_COLORS[yellow]}"
328+
[[ ${THEME_COLORS[brown]} ]] || THEME_COLORS[brown]=$(mix_color "${THEME_COLORS[orange]}" "#000000" 50%)
329+
330+
# Auto-derive shades from base accents when not defined and not aliased from colorN
331+
[[ ${THEME_COLORS[dark_bg]} ]] || THEME_COLORS[dark_bg]=$(mix_color "${THEME_COLORS[background]}" "#000000" 25%)
332+
[[ ${THEME_COLORS[darker_bg]} ]] || THEME_COLORS[darker_bg]=$(mix_color "${THEME_COLORS[background]}" "#000000" 50%)
333+
[[ ${THEME_COLORS[bright_red]} ]] || THEME_COLORS[bright_red]=$(mix_color "${THEME_COLORS[red]}" "#ffffff" 20%)
334+
[[ ${THEME_COLORS[bright_yellow]} ]] || THEME_COLORS[bright_yellow]=$(mix_color "${THEME_COLORS[yellow]}" "#ffffff" 20%)
335+
[[ ${THEME_COLORS[bright_green]} ]] || THEME_COLORS[bright_green]=$(mix_color "${THEME_COLORS[green]}" "#ffffff" 20%)
336+
[[ ${THEME_COLORS[bright_cyan]} ]] || THEME_COLORS[bright_cyan]=$(mix_color "${THEME_COLORS[cyan]}" "#ffffff" 20%)
337+
[[ ${THEME_COLORS[bright_blue]} ]] || THEME_COLORS[bright_blue]=$(mix_color "${THEME_COLORS[blue]}" "#ffffff" 20%)
338+
[[ ${THEME_COLORS[bright_purple]} ]] || THEME_COLORS[bright_purple]=$(mix_color "${THEME_COLORS[purple]}" "#ffffff" 20%)
339+
340+
# Resolve theme mode (dark|light) with this precedence:
341+
# 1. `mode` key in colors.toml
342+
# 2. legacy `light.mode` file shipped beside the theme
343+
# 3. background luminance auto-detect
344+
# `theme_type` is kept as an alias so existing templates ({{ theme_type }}) keep working.
345+
[[ ${THEME_COLORS[mode]} ]] || THEME_COLORS[mode]="${THEME_COLORS[theme_type]}"
346+
if [[ ! ${THEME_COLORS[mode]} ]]; then
347+
if [[ -f $NEXT_THEME_DIR/light.mode ]]; then
348+
THEME_COLORS[mode]="light"
349+
else
350+
bg_hex="${THEME_COLORS[background]#\#}"
351+
lum=$(( $(printf "%d" "0x${bg_hex:0:2}") + $(printf "%d" "0x${bg_hex:2:2}") + $(printf "%d" "0x${bg_hex:4:2}") ))
352+
[[ $lum -gt 382 ]] && THEME_COLORS[mode]="light" || THEME_COLORS[mode]="dark"
353+
fi
354+
fi
355+
THEME_COLORS[theme_type]="${THEME_COLORS[mode]}"
356+
357+
for key in "${!THEME_COLORS[@]}"; do
358+
add_template_value "$key" "${THEME_COLORS[$key]}"
359+
done
360+
310361
add_mix_values
311362
add_gradient_function_values
312363

bin/omarchy-theme-set-vscode

Lines changed: 51 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,21 +4,67 @@
44
# omarchy:hidden=true
55

66
VS_CODE_THEME="$HOME/.config/omarchy/current/theme/vscode.json"
7+
GENERATED_THEME="$HOME/.config/omarchy/current/theme/vscode-theme.json"
8+
9+
# Install generated theme as a local extension for a given editor
10+
install_generated_extension() {
11+
local ext_dir="$1"
12+
local theme_type
13+
14+
theme_type=$(jq -r '.type // "dark"' "$GENERATED_THEME")
15+
16+
mkdir -p "$ext_dir/themes"
17+
cp "$GENERATED_THEME" "$ext_dir/themes/omarchy-color-theme.json"
18+
19+
cat > "$ext_dir/package.json" <<EOF
20+
{
21+
"name": "omarchy-theme",
22+
"displayName": "Omarchy",
23+
"description": "Omarchy color theme",
24+
"publisher": "local",
25+
"version": "1.0.0",
26+
"engines": { "vscode": "^1.70.0" },
27+
"categories": ["Themes"],
28+
"contributes": {
29+
"themes": [{
30+
"label": "Omarchy",
31+
"uiTheme": "vs-${theme_type}",
32+
"path": "./themes/omarchy-color-theme.json"
33+
}]
34+
}
35+
}
36+
EOF
37+
}
738

839
set_theme() {
940
local editor_cmd="$1"
1041
local settings_path="$2"
42+
local ext_base="$3"
1143

1244
omarchy-cmd-present "$editor_cmd" || return 0
1345

14-
if [[ -f $VS_CODE_THEME ]]; then
46+
local theme_name=""
47+
48+
# Always deploy the generated theme so it's available in the theme picker
49+
if [[ -f "$GENERATED_THEME" ]]; then
50+
install_generated_extension "$ext_base/omarchy-theme"
51+
fi
52+
53+
if [[ -f "$VS_CODE_THEME" ]]; then
54+
# Theme specifies a preferred 3rd-party extension
1555
theme_name=$(jq -r '.name' "$VS_CODE_THEME")
56+
local extension
1657
extension=$(jq -r '.extension' "$VS_CODE_THEME")
1758

1859
if [[ -n $extension ]] && ! "$editor_cmd" --list-extensions 2>/dev/null | grep -Fxq "$extension"; then
1960
"$editor_cmd" --install-extension "$extension" >/dev/null 2>&1
2061
fi
62+
elif [[ -f "$GENERATED_THEME" ]]; then
63+
# No 3rd-party preference, activate the generated theme
64+
theme_name="Omarchy"
65+
fi
2166

67+
if [[ -n "$theme_name" ]]; then
2268
mkdir -p "$(dirname "$settings_path")"
2369
[[ -f $settings_path ]] || printf '{\n}\n' >"$settings_path"
2470

@@ -34,7 +80,7 @@ set_theme() {
3480
fi
3581
}
3682

37-
! omarchy-toggle-enabled skip-vscode-theme-changes && set_theme "code" "$HOME/.config/Code/User/settings.json"
38-
! omarchy-toggle-enabled skip-vscode-insiders-theme-changes && set_theme "code-insiders" "$HOME/.config/Code - Insiders/User/settings.json"
39-
! omarchy-toggle-enabled skip-codium-theme-changes && set_theme "codium" "$HOME/.config/VSCodium/User/settings.json"
40-
! omarchy-toggle-enabled skip-cursor-theme-changes && set_theme "cursor" "$HOME/.config/Cursor/User/settings.json"
83+
! omarchy-toggle-enabled skip-vscode-theme-changes && set_theme "code" "$HOME/.config/Code/User/settings.json" "$HOME/.vscode/extensions"
84+
! omarchy-toggle-enabled skip-vscode-insiders-theme-changes && set_theme "code-insiders" "$HOME/.config/Code - Insiders/User/settings.json" "$HOME/.vscode-insiders/extensions"
85+
! omarchy-toggle-enabled skip-codium-theme-changes && set_theme "codium" "$HOME/.config/VSCodium/User/settings.json" "$HOME/.vscode-oss/extensions"
86+
! omarchy-toggle-enabled skip-cursor-theme-changes && set_theme "cursor" "$HOME/.config/Cursor/User/settings.json" "$HOME/.cursor/extensions"

config/omarchy/themed/alacritty.toml.tpl.sample

Lines changed: 22 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,10 @@
2525
# {{ color0 }} through {{ color15 }} - Standard 16-color terminal palette
2626
# color0-7: Normal colors (black, red, green, yellow, blue, magenta, cyan, white)
2727
# color8-15: Bright variants
28+
# Semantic aliases are also available: {{ bg }}, {{ fg }}, {{ red }}, {{ green }},
29+
# {{ yellow }}, {{ blue }}, {{ purple }}, {{ cyan }}, {{ muted }} and the
30+
# {{ bright_* }} variants. The two forms are kept in sync by
31+
# bin/omarchy-theme-set-templates.
2832
#
2933
# VARIABLE MODIFIERS:
3034
# {{ variable_strip }} - Hex color without the # prefix (e.g., "1a1b26")
@@ -51,11 +55,11 @@ cursor = "{{ cursor }}"
5155

5256
[colors.search.matches]
5357
foreground = "{{ background }}"
54-
background = "{{ color3 }}"
58+
background = "{{ yellow }}"
5559

5660
[colors.search.focused_match]
5761
foreground = "{{ background }}"
58-
background = "{{ color1 }}"
62+
background = "{{ red }}"
5963

6064
[colors.footer_bar]
6165
foreground = "{{ background }}"
@@ -66,21 +70,21 @@ text = "{{ selection_foreground }}"
6670
background = "{{ selection_background }}"
6771

6872
[colors.normal]
69-
black = "{{ color0 }}"
70-
red = "{{ color1 }}"
71-
green = "{{ color2 }}"
72-
yellow = "{{ color3 }}"
73-
blue = "{{ color4 }}"
74-
magenta = "{{ color5 }}"
75-
cyan = "{{ color6 }}"
76-
white = "{{ color7 }}"
73+
black = "{{ bg }}"
74+
red = "{{ red }}"
75+
green = "{{ green }}"
76+
yellow = "{{ yellow }}"
77+
blue = "{{ blue }}"
78+
magenta = "{{ purple }}"
79+
cyan = "{{ cyan }}"
80+
white = "{{ fg }}"
7781

7882
[colors.bright]
79-
black = "{{ color8 }}"
80-
red = "{{ color9 }}"
81-
green = "{{ color10 }}"
82-
yellow = "{{ color11 }}"
83-
blue = "{{ color12 }}"
84-
magenta = "{{ color13 }}"
85-
cyan = "{{ color14 }}"
86-
white = "{{ color15 }}"
83+
black = "{{ muted }}"
84+
red = "{{ bright_red }}"
85+
green = "{{ bright_green }}"
86+
yellow = "{{ bright_yellow }}"
87+
blue = "{{ bright_blue }}"
88+
magenta = "{{ bright_purple }}"
89+
cyan = "{{ bright_cyan }}"
90+
white = "{{ bright_fg }}"

default/themed/alacritty.toml.tpl

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,11 @@ cursor = "{{ cursor }}"
1212

1313
[colors.search.matches]
1414
foreground = "{{ background }}"
15-
background = "{{ color3 }}"
15+
background = "{{ yellow }}"
1616

1717
[colors.search.focused_match]
1818
foreground = "{{ background }}"
19-
background = "{{ color1 }}"
19+
background = "{{ red }}"
2020

2121
[colors.footer_bar]
2222
foreground = "{{ background }}"
@@ -27,21 +27,21 @@ text = "{{ selection_foreground }}"
2727
background = "{{ selection_background }}"
2828

2929
[colors.normal]
30-
black = "{{ color0 }}"
31-
red = "{{ color1 }}"
32-
green = "{{ color2 }}"
33-
yellow = "{{ color3 }}"
34-
blue = "{{ color4 }}"
35-
magenta = "{{ color5 }}"
36-
cyan = "{{ color6 }}"
37-
white = "{{ color7 }}"
30+
black = "{{ bg }}"
31+
red = "{{ red }}"
32+
green = "{{ green }}"
33+
yellow = "{{ yellow }}"
34+
blue = "{{ blue }}"
35+
magenta = "{{ purple }}"
36+
cyan = "{{ cyan }}"
37+
white = "{{ fg }}"
3838

3939
[colors.bright]
40-
black = "{{ color8 }}"
41-
red = "{{ color9 }}"
42-
green = "{{ color10 }}"
43-
yellow = "{{ color11 }}"
44-
blue = "{{ color12 }}"
45-
magenta = "{{ color13 }}"
46-
cyan = "{{ color14 }}"
47-
white = "{{ color15 }}"
40+
black = "{{ muted }}"
41+
red = "{{ bright_red }}"
42+
green = "{{ bright_green }}"
43+
yellow = "{{ bright_yellow }}"
44+
blue = "{{ bright_blue }}"
45+
magenta = "{{ bright_purple }}"
46+
cyan = "{{ bright_cyan }}"
47+
white = "{{ bright_fg }}"

0 commit comments

Comments
 (0)