From 44b7f8ffd0b76324f8aa8445309713ddd13bb022 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Helleu?= Date: Wed, 27 May 2026 13:57:55 +0200 Subject: [PATCH] core: register built-in "light" theme Add a small core-theme-builtin.c module containing the core contribution to the "light" theme: 33 overrides for "weechat.bar.{status,title}.color_*" and "weechat.color.*" tuned for light-background terminals. theme_builtin_init() builds a hashtable from the static entry table and calls theme_register("light", overrides), then frees the temporary hashtable. It is called once from weechat_init right after theme_init. Calling it twice is a no-op (the registry merges identical keys). Default option values are NOT changed. Existing configs render exactly as before; users opt in with "/theme apply light". Add TEST(CoreTheme, BuiltinInit) covering: - the "light" theme is absent before theme_builtin_init(); - it is present after, with >= 30 overrides; - three spot-checked values match the source table; - calling theme_builtin_init() a second time does not change the override count. Plugins contribute their own "light" overrides via weechat_theme_register in subsequent commits. --- src/core/CMakeLists.txt | 1 + src/core/core-theme-builtin.c | 129 ++++++++++++++++++++++++++++ src/core/core-theme.h | 3 + src/core/weechat.c | 1 + tests/unit/core/test-core-theme.cpp | 42 +++++++++ 5 files changed, 176 insertions(+) create mode 100644 src/core/core-theme-builtin.c diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index eca6ebe0e..20e7fdbfb 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -52,6 +52,7 @@ set(LIB_CORE_SRC core-string.c core-string.h core-sys.c core-sys.h core-theme.c core-theme.h + core-theme-builtin.c core-upgrade.c core-upgrade.h core-upgrade-file.c core-upgrade-file.h core-url.c core-url.h diff --git a/src/core/core-theme-builtin.c b/src/core/core-theme-builtin.c new file mode 100644 index 000000000..5293c996f --- /dev/null +++ b/src/core/core-theme-builtin.c @@ -0,0 +1,129 @@ +/* + * SPDX-FileCopyrightText: 2026 Sébastien Helleu + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + * This file is part of WeeChat, the extensible chat client. + * + * WeeChat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * WeeChat is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with WeeChat. If not, see . + */ + +/* Built-in theme registrations (core contribution only). */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include "weechat.h" +#include "core-hashtable.h" +#include "core-theme.h" +#include "../plugins/weechat-plugin.h" + + +/* + * Core overrides for the "light" theme: option values tuned for a + * light-background terminal. Order is by full option name to keep diffs + * stable; the list ends with a NULL sentinel. + */ + +struct t_theme_builtin_entry +{ + const char *option; + const char *value; +}; + +struct t_theme_builtin_entry theme_builtin_light_core[] = +{ + { "weechat.bar.status.color_bg", "254" }, + { "weechat.bar.status.color_bg_inactive", "default" }, + { "weechat.bar.title.color_bg", "254" }, + { "weechat.bar.title.color_bg_inactive", "default" }, + { "weechat.color.bar_more", "magenta" }, + { "weechat.color.chat_buffer", "default" }, + { "weechat.color.chat_channel", "default" }, + { "weechat.color.chat_nick", "cyan" }, + { "weechat.color.chat_nick_colors", + "red,green,brown,blue,magenta,cyan,lightred,lightblue,lightmagenta," + "20,28,52,57,58,61,63,88,94,128,166,202" }, + { "weechat.color.chat_nick_self", "default" }, + { "weechat.color.chat_prefix_action", "default" }, + { "weechat.color.chat_prefix_error", "94" }, + { "weechat.color.chat_prefix_join", "green" }, + { "weechat.color.chat_prefix_more", "magenta" }, + { "weechat.color.chat_prefix_quit", "red" }, + { "weechat.color.chat_prefix_suffix", "251" }, + { "weechat.color.chat_server", "94" }, + { "weechat.color.chat_text_found_bg", "magenta" }, + { "weechat.color.chat_time_delimiters", "94" }, + { "weechat.color.eval_syntax_colors", + "green,red,blue,magenta,94,cyan" }, + { "weechat.color.input_actions", "28" }, + { "weechat.color.item_away", "brown" }, + { "weechat.color.separator", "251" }, + { "weechat.color.status_count_msg", "94" }, + { "weechat.color.status_data_highlight", "93" }, + { "weechat.color.status_data_msg", "94" }, + { "weechat.color.status_data_private", "green" }, + { "weechat.color.status_more", "94" }, + { "weechat.color.status_mouse", "green" }, + { "weechat.color.status_name", "default" }, + { "weechat.color.status_name_insecure", "202" }, + { "weechat.color.status_name_tls", "default" }, + { "weechat.color.status_number", "28" }, + { NULL, NULL }, +}; + +/* + * Builds a hashtable of overrides from a NULL-terminated table and + * registers it under the given theme name. + */ + +void +theme_builtin_register_entries (const char *name, + const struct t_theme_builtin_entry *entries) +{ + struct t_hashtable *overrides; + int i; + + if (!name || !entries) + return; + + overrides = hashtable_new (32, + WEECHAT_HASHTABLE_STRING, + WEECHAT_HASHTABLE_STRING, + NULL, NULL); + if (!overrides) + return; + + for (i = 0; entries[i].option; i++) + hashtable_set (overrides, entries[i].option, entries[i].value); + + theme_register (name, overrides); + + hashtable_free (overrides); +} + +/* + * Registers all built-in themes contributed by core. Called once from + * theme_init; plugins/scripts add their own contributions later via + * weechat_theme_register. + */ + +void +theme_builtin_init (void) +{ + theme_builtin_register_entries ("light", theme_builtin_light_core); +} diff --git a/src/core/core-theme.h b/src/core/core-theme.h index b666062f2..05e0e7e01 100644 --- a/src/core/core-theme.h +++ b/src/core/core-theme.h @@ -55,4 +55,7 @@ extern void theme_free (struct t_theme *theme); extern void theme_init (void); extern void theme_end (void); +/* implemented in core-theme-builtin.c */ +extern void theme_builtin_init (void); + #endif /* WEECHAT_THEME_H */ diff --git a/src/core/weechat.c b/src/core/weechat.c index 5422b9278..2ade07fa5 100644 --- a/src/core/weechat.c +++ b/src/core/weechat.c @@ -386,6 +386,7 @@ weechat_init (int argc, char *argv[], void (*gui_init_cb)(void)) if (!secure_config_init ()) /* init secured data options (sec.*)*/ weechat_shutdown (EXIT_FAILURE, 0); theme_init (); /* initialize theme registry */ + theme_builtin_init (); /* register built-in themes */ if (!config_weechat_init ()) /* init WeeChat options (weechat.*) */ weechat_shutdown (EXIT_FAILURE, 0); args_parse (argc, argv); /* parse command line args */ diff --git a/tests/unit/core/test-core-theme.cpp b/tests/unit/core/test-core-theme.cpp index c7ca5c696..7d453d80f 100644 --- a/tests/unit/core/test-core-theme.cpp +++ b/tests/unit/core/test-core-theme.cpp @@ -749,3 +749,45 @@ TEST(CoreTheme, End) POINTERS_EQUAL(NULL, themes); POINTERS_EQUAL(NULL, last_theme); } + +/* + * Test functions: + * theme_builtin_init + * theme_builtin_register_entries + */ + +TEST(CoreTheme, BuiltinInit) +{ + struct t_theme *theme; + + /* registry is empty after setup() */ + POINTERS_EQUAL(NULL, theme_search ("light")); + + theme_builtin_init (); + + /* the "light" theme is registered */ + theme = theme_search ("light"); + CHECK(theme != NULL); + + /* sanity check: many core color overrides (>= 30) */ + CHECK(theme->overrides->items_count >= 30); + + /* spot-check a few known entries from the core light table */ + STRCMP_EQUAL("cyan", + (const char *)hashtable_get (theme->overrides, + "weechat.color.chat_nick")); + STRCMP_EQUAL("251", + (const char *)hashtable_get (theme->overrides, + "weechat.color.separator")); + STRCMP_EQUAL("254", + (const char *)hashtable_get (theme->overrides, + "weechat.bar.status.color_bg")); + + /* idempotency: a second call merges (no duplicate themes, count + stays the same because the same keys are re-inserted) */ + int count_before = theme->overrides->items_count; + theme_builtin_init (); + theme = theme_search ("light"); + CHECK(theme != NULL); + LONGS_EQUAL(count_before, theme->overrides->items_count); +}