From df2e82a82db02c497bcc178bea1807ee0fea99b3 Mon Sep 17 00:00:00 2001 From: Ed_ Date: Thu, 4 Jun 2026 23:10:16 -0400 Subject: [PATCH] feat(themes): add Solarized Dark/Light, Gruvbox Dark, Moss TOML themes --- tests/test_theme.py | 29 ++++++++++++++++++++++++++++ themes/gruvbox_dark.toml | 38 +++++++++++++++++++++++++++++++++++++ themes/moss.toml | 38 +++++++++++++++++++++++++++++++++++++ themes/solarized_dark.toml | 38 +++++++++++++++++++++++++++++++++++++ themes/solarized_light.toml | 38 +++++++++++++++++++++++++++++++++++++ 5 files changed, 181 insertions(+) create mode 100644 themes/gruvbox_dark.toml create mode 100644 themes/moss.toml create mode 100644 themes/solarized_dark.toml create mode 100644 themes/solarized_light.toml diff --git a/tests/test_theme.py b/tests/test_theme.py index 52560a77..6c401d83 100644 --- a/tests/test_theme.py +++ b/tests/test_theme.py @@ -71,3 +71,32 @@ def test_get_syntax_palette_for_unknown_theme_returns_default(tmp_path, monkeypa monkeypatch.setattr(theme, "get_global_themes_path", lambda: themes_dir) theme.load_themes_from_disk() assert theme.get_syntax_palette_for_theme("NonExistent") == "dark" + + +def test_all_four_new_themes_registered(tmp_path, monkeypatch): + from src import paths as paths_mod + + themes_dir = tmp_path / "themes" + themes_dir.mkdir() + for name in ["solarized_dark", "solarized_light", "gruvbox_dark", "moss"]: + (themes_dir / f"{name}.toml").write_text( + 'syntax_palette = "dark"\n[colors]\nwindow_bg = [0, 0, 0]\n' + ) + monkeypatch.setattr(theme, "get_global_themes_path", lambda: themes_dir) + theme.load_themes_from_disk() + names = theme.get_palette_names() + for name in ["solarized_dark", "solarized_light", "gruvbox_dark", "moss"]: + assert name in names, f"missing theme: {name}" + + +def test_solarized_light_uses_light_syntax_palette(tmp_path, monkeypatch): + from src import paths as paths_mod + + themes_dir = tmp_path / "themes" + themes_dir.mkdir() + (themes_dir / "solarized_light.toml").write_text( + 'syntax_palette = "light"\n[colors]\nwindow_bg = [253, 246, 227]\n' + ) + monkeypatch.setattr(theme, "get_global_themes_path", lambda: themes_dir) + theme.load_themes_from_disk() + assert theme.get_syntax_palette_for_theme("solarized_light") == "light" diff --git a/themes/gruvbox_dark.toml b/themes/gruvbox_dark.toml new file mode 100644 index 00000000..e6a0e549 --- /dev/null +++ b/themes/gruvbox_dark.toml @@ -0,0 +1,38 @@ +# Gruvbox Dark — Pavel Pertsev's warm retro palette +syntax_palette = "retro_blue" +description = "Gruvbox Dark by Pavel Pertsev (github.com/morhetz/gruvbox)" + +[colors] +window_bg = [ 40, 40, 40] # bg +child_bg = [ 50, 48, 47] # bg1 +popup_bg = [ 50, 48, 47] +border = [ 60, 56, 54] +frame_bg = [ 50, 48, 47] +frame_bg_hovered = [ 80, 80, 80] +frame_bg_active = [ 90, 90, 90] +title_bg = [ 40, 40, 40] +title_bg_active = [ 80, 80, 80] +menu_bar_bg = [ 40, 40, 40] +scrollbar_bg = [ 40, 40, 40] +scrollbar_grab = [ 80, 80, 80] +scrollbar_grab_hovered = [251, 241, 199] +scrollbar_grab_active = [251, 241, 199] +button = [ 60, 56, 54] +button_hovered = [180, 120, 40] # orange +button_active = [200, 140, 0] # bright orange +header = [ 60, 56, 54] +header_hovered = [180, 120, 40] +header_active = [251, 73, 52] # red +separator = [ 80, 80, 80] +separator_hovered = [180, 120, 40] +separator_active = [251, 241, 199] +tab = [ 60, 56, 54] +tab_hovered = [180, 120, 40] +tab_selected = [ 80, 80, 80] +text = [251, 241, 199] # fg +text_disabled = [146, 131, 116] # comment +text_selected_bg = [180, 120, 40] +check_mark = [184, 187, 38] # green +slider_grab = [184, 187, 38] +slider_grab_active = [184, 187, 38] +table_header_bg = [ 60, 56, 54] \ No newline at end of file diff --git a/themes/moss.toml b/themes/moss.toml new file mode 100644 index 00000000..5d43840a --- /dev/null +++ b/themes/moss.toml @@ -0,0 +1,38 @@ +# Moss — green-tinted dark theme +syntax_palette = "mariana" +description = "Moss — green-tinted dark theme" + +[colors] +window_bg = [ 40, 47, 49] # green-gray +child_bg = [ 24, 32, 30] +popup_bg = [ 20, 35, 35] +border = [ 60, 80, 90] +frame_bg = [ 50, 70, 80] +frame_bg_hovered = [ 60, 90, 100] +frame_bg_active = [ 70, 100, 110] +title_bg = [ 40, 47, 49] +title_bg_active = [ 42, 77, 50] # mossy green +menu_bar_bg = [ 40, 47, 49] +scrollbar_bg = [ 40, 47, 49] +scrollbar_grab = [ 80, 80, 80] +scrollbar_grab_hovered = [100, 100, 100] +scrollbar_grab_active = [120, 120, 120] +button = [ 60, 80, 90] +button_hovered = [105, 101, 255] # blue accent +button_active = [120, 80, 200] +header = [ 60, 80, 90] +header_hovered = [120, 160, 130] # green +header_active = [ 42, 77, 50] # mossy green +separator = [ 60, 80, 90] +separator_hovered = [120, 160, 130] +separator_active = [105, 101, 255] +tab = [ 60, 80, 90] +tab_hovered = [ 80, 100, 110] +tab_selected = [ 42, 77, 50] # mossy green +text = [255, 255, 255] +text_disabled = [208, 208, 208] +text_selected_bg = [105, 101, 255] +check_mark = [120, 160, 130] # green +slider_grab = [120, 160, 130] +slider_grab_active = [120, 160, 130] +table_header_bg = [ 50, 70, 80] \ No newline at end of file diff --git a/themes/solarized_dark.toml b/themes/solarized_dark.toml new file mode 100644 index 00000000..dfc4dd14 --- /dev/null +++ b/themes/solarized_dark.toml @@ -0,0 +1,38 @@ +# Solarized Dark — Ethan Schoonover's canonical dark palette +syntax_palette = "dark" +description = "Solarized Dark by Ethan Schoonover" + +[colors] +window_bg = [ 0, 43, 54] # base03 +child_bg = [ 7, 54, 66] # base02 +popup_bg = [ 0, 43, 54] +border = [ 88, 110, 117] # base01 +frame_bg = [ 7, 54, 66] +frame_bg_hovered = [ 88, 110, 117] +frame_bg_active = [101, 123, 131] +title_bg = [ 7, 54, 66] +title_bg_active = [ 88, 110, 117] +menu_bar_bg = [ 0, 43, 54] +scrollbar_bg = [ 7, 54, 66] +scrollbar_grab = [ 88, 110, 117] +scrollbar_grab_hovered = [131, 148, 150] +scrollbar_grab_active = [253, 246, 227] +button = [ 7, 54, 66] +button_hovered = [ 38, 139, 210] # blue +button_active = [ 38, 139, 210] +header = [ 7, 54, 66] +header_hovered = [ 38, 139, 210] +header_active = [ 38, 139, 210] +separator = [ 88, 110, 117] +separator_hovered = [ 38, 139, 210] +separator_active = [203, 75, 22] # orange +tab = [ 7, 54, 66] +tab_hovered = [ 38, 139, 210] +tab_selected = [ 88, 110, 117] +text = [147, 161, 161] # base1 +text_disabled = [ 88, 110, 117] # base01 +text_selected_bg = [ 38, 139, 210] +check_mark = [ 38, 139, 210] +slider_grab = [ 38, 139, 210] +slider_grab_active = [ 38, 139, 210] +table_header_bg = [ 7, 54, 66] \ No newline at end of file diff --git a/themes/solarized_light.toml b/themes/solarized_light.toml new file mode 100644 index 00000000..3eb82133 --- /dev/null +++ b/themes/solarized_light.toml @@ -0,0 +1,38 @@ +# Solarized Light — Ethan Schoonover's canonical light palette +syntax_palette = "light" +description = "Solarized Light by Ethan Schoonover" + +[colors] +window_bg = [238, 232, 213] # base2 +child_bg = [253, 246, 227] # base3 +popup_bg = [253, 246, 227] +border = [147, 161, 161] # base1 +frame_bg = [253, 246, 227] +frame_bg_hovered = [238, 232, 213] +frame_bg_active = [238, 232, 213] +title_bg = [238, 232, 213] +title_bg_active = [147, 161, 161] +menu_bar_bg = [238, 232, 213] +scrollbar_bg = [238, 232, 213] +scrollbar_grab = [147, 161, 161] +scrollbar_grab_hovered = [131, 148, 150] +scrollbar_grab_active = [ 7, 54, 66] +button = [253, 246, 227] +button_hovered = [ 38, 139, 210] # blue +button_active = [ 38, 139, 210] +header = [253, 246, 227] +header_hovered = [ 38, 139, 210] +header_active = [ 38, 139, 210] +separator = [147, 161, 161] +separator_hovered = [181, 137, 0] # yellow +separator_active = [203, 75, 22] # orange +tab = [238, 232, 213] +tab_hovered = [ 38, 139, 210] +tab_selected = [147, 161, 161] +text = [ 7, 54, 66] # base02 +text_disabled = [147, 161, 161] # base1 +text_selected_bg = [ 38, 139, 210] +check_mark = [ 38, 139, 210] +slider_grab = [ 38, 139, 210] +slider_grab_active = [ 38, 139, 210] +table_header_bg = [238, 232, 213] \ No newline at end of file