1
0
mirror of https://github.com/weechat/weechat.git synced 2026-06-17 16:44:47 +02:00

Compare commits

..

35 Commits

Author SHA1 Message Date
Sébastien Helleu d4ed290a37 core: always write all options in theme files
Theme files saved with /theme save and automatic backups now always
contain every themable option (full snapshot), so a theme file is
self-contained and round-trips exactly regardless of the current
configuration. The diff-only mode and the "-full" argument of
/theme save are removed.
2026-06-08 09:39:22 +02:00
Sébastien Helleu a98568788b core: fix description of automatic theme backup 2026-06-08 09:39:22 +02:00
Sébastien Helleu 215fdfc0a7 core: add /theme rename to rename a user theme file 2026-06-08 09:39:22 +02:00
Sébastien Helleu deedaed1f9 core: auto-detect terminal background and apply light theme on first start
Detect the terminal background (via COLORFGBG or an OSC 11 query) before
GUI init and, on the first start, automatically apply the built-in
"light" theme when a light terminal is detected.

The function gui_term_theme_is_light returns an int (1 if light, 0 otherwise,
0 being the safe value when detection is unsure).
2026-06-08 09:39:22 +02:00
Sébastien Helleu fb220e1afd core: fix style in comments 2026-06-08 09:39:22 +02:00
Sébastien Helleu afd7e08691 core: display path to theme written with /theme save <name> 2026-06-08 09:39:22 +02:00
Sébastien Helleu 0fb0b3bb07 core: add /theme reset to restore original themable defaults 2026-06-08 09:39:22 +02:00
Sébastien Helleu ecec47c633 tests: cover apply edge cases for /theme command 2026-06-08 09:39:22 +02:00
Sébastien Helleu 3f64975a72 doc: add ChangeLog entry for /theme command and built-in light theme
Add six entries to the "Added" section of Version 4.10.0 in
CHANGELOG.md:

- the /theme command with its subcommands (list/apply/save/delete/
  info) and the automatic backup mechanism, plus the shipped
  "light" built-in theme;
- the themable flag on configuration options;
- the weechat.look.theme and weechat.look.theme_backup options;
- the theme_register plugin/script API function;
- the t:themable filter in fset.

No UPGRADING.md entry: the change is purely additive — default option
values are unchanged, so existing users see no visible difference
until they explicitly /theme apply light. weechat.look.theme is a new
option (empty by default at first launch) and weechat.look.theme_backup
defaults to "on".
2026-06-08 09:39:22 +02:00
Sébastien Helleu b970962bdb doc: document /theme command and theme file format
Add the "Themes" section to user guides and plugin API references in
every language where the corresponding adoc exists.

User guide (10 files): English (the new prose) and French (a full
translation, with section title "Thèmes"). For the other languages —
German, Italian, Japanese, Polish, Serbian — the body is the English
text with only the section title localized where the existing Colors
section is localized (Themen / Motywy / Теме); Italian and Japanese
keep the English "Themes" title to match their existing English-only
section titles. Coverage by file:

  - doc/en/weechat_user.en.adoc       (new English section)
  - doc/fr/weechat_user.fr.adoc       (full French translation)
  - doc/de/weechat_user.de.adoc       (English body, "Themen" title)
  - doc/it/weechat_user.it.adoc       (English body and title)
  - doc/ja/weechat_user.ja.adoc       (English body and title)
  - doc/pl/weechat_user.pl.adoc       (English body, "Motywy" title)
  - doc/sr/weechat_user.sr.adoc       (English body, "Теме" title)

Plugin API reference (5 files): same approach — English plus full
French translation; Italian, Japanese and Serbian keep the English
body with their conventional section title:

  - doc/en/weechat_plugin_api.en.adoc (new English section)
  - doc/fr/weechat_plugin_api.fr.adoc (full French translation)
  - doc/it/weechat_plugin_api.it.adoc (English body and title)
  - doc/ja/weechat_plugin_api.ja.adoc (English body and title)
  - doc/sr/weechat_plugin_api.sr.adoc (English body, "Теме" title)

User-guide content covers themable options, /theme apply with the
automatic backup mechanism, /theme save and /theme delete with the
reserved-name rules, the .theme file format with a sample, and the
user-file-shadows-built-in resolution order. The API-reference content
documents weechat_theme_register (prototype, arguments, return value,
C example, Python example) with notes on the themable flag and
per-script auto-cleanup on script unload.

The /theme command's CMD_ARGS_DESC help text and the cmdline option
descriptions are picked up automatically by the doc generator
(doc-autogen), so no manual entries are needed there.
2026-06-08 09:39:22 +02:00
Sébastien Helleu d56e46908f script: track per-script theme contributions and purge on script unload
Make individual scripts the unit of ownership for theme contributions
so that loading a script that calls weechat.theme_register(...) and
later unloading it correctly removes the script's overrides.

Plugin API addition (weechat-plugin.h):

  - new function pointer t_weechat_plugin.theme_unregister_script
    delegates to core's theme_unregister_script.
  - new convenience macro weechat_theme_unregister_script(script).
  - WEECHAT_PLUGIN_API_VERSION bumped to 20260527-02.

Script API additions (plugin-script-api.{c,h}):

  - new plugin_script_api_theme_register (plugin, script, name,
    overrides) forwards to the plugin API with the script pointer
    as the contribution owner, so contributions are tracked
    per-script (not per script-language plugin).

Lifecycle wiring (plugin-script.c):

  - new file-local plugin_script_remove_themes (plugin, script)
    calls weechat_theme_unregister_script.
  - plugin_script_remove now calls it alongside the other
    plugin_script_remove_* helpers, so script-unload tears down
    everything (configs, bar items, themes, hooks).

Eight language bindings updated to call
plugin_script_api_theme_register instead of weechat_theme_register
directly, so they pass the script pointer as owner:

  - python, perl, ruby, lua, tcl, javascript, php, guile.

The behavior change is end-to-end visible only at script unload:
before, an unloaded script's theme overrides lingered in the
registry forever and would be re-applied on the next /theme apply;
after, they vanish when the script unloads. /plugin unload of an
entire script-language plugin already worked via commit 24's hook
in plugin_remove (which drops both plugin-only contributions and
their script-owned children when the language plugin itself goes
away, because the contribution's plugin pointer matches).

No new unit tests in this commit: the underlying theme_unregister_script
function is covered by TEST(CoreTheme, UnregisterByOwner), and the
remaining changes are plumbing.
2026-06-08 09:39:22 +02:00
Sébastien Helleu 8b19d3b0a4 core: auto-purge plugin contributions on plugin unload
Call theme_unregister_plugin (plugin) from plugin_remove, right after
config_file_free_all_plugin and before unhook_all_plugin. This drops
every theme contribution whose plugin pointer matches the plugin being
unloaded, so subsequent /theme apply runs no longer try to set
options for an unloaded plugin and per-plugin contributions don't
outlive the plugin.

Script-owned contributions (plugin != NULL && script != NULL) are
left intact - they are cleaned up per-script in the next commit.

This commit is wiring only: the underlying theme_unregister_plugin
function and its semantics are already covered by
TEST(CoreTheme, UnregisterByOwner) in the previous commit.
2026-06-08 09:39:22 +02:00
Sébastien Helleu fcf439dfa0 core: track per-contributor overrides in theme registry
Refactor the theme registry to store one sub-table per contributor
instead of a single merged hashtable. Each registered theme now holds
a linked list of t_theme_contribution entries:

  struct t_theme_contribution {
      struct t_weechat_plugin *plugin;  /* NULL = core */
      const void *script;               /* NULL for non-script */
      struct t_hashtable *overrides;
      ...
  };

Identity of a contributor is the (plugin, script) pair:

  - (NULL, NULL)     -> core (theme_builtin_init)
  - (plugin, NULL)   -> plugin-level contribution
  - (plugin, script) -> individual script (filled in by next commit)

theme_register is now (plugin, script, name, overrides). It searches
the existing contributions for a matching (plugin, script) and merges
the new overrides into it; otherwise it appends a fresh contribution.
The public macro weechat_theme_register(name, overrides) still takes
two args - it now expands to pass weechat_plugin and NULL for script.

theme_apply iterates contributions in list order, calling
config_file_option_set for each entry; later contributions naturally
win for duplicate keys.

Two new internal helpers prepare for the lifecycle work in the next
two commits:

  - theme_unregister_plugin (plugin): drops every contribution owned
    by that plugin (with script == NULL).
  - theme_unregister_script (plugin, script): drops every contribution
    owned by that script.

Neither is called yet; the auto-purge wiring lands in commits 24
(plugin_unloaded signal) and 25 (script API + script-unload hook).

Other touched code:

  - core-theme-builtin.c switches to theme_register (NULL, NULL, ...).
  - core-command.c /theme info uses theme_overrides_count helper
    instead of reaching into theme->overrides (which no longer
    exists).
  - WEECHAT_PLUGIN_API_VERSION bumped to 20260527-01 (function-pointer
    signature change).

Two new tests cover the new semantics:

  - UnregisterByOwner: registers four contributions from distinct
    (plugin, script) pairs, then prunes by plugin and by script,
    asserting per-contribution removal.
  - RegisterMergesPerContributor: two successive register calls from
    the same (plugin, script) merge into a single contribution with
    later keys overriding earlier ones.

Existing tests are updated to use the new theme_register signature,
theme_overrides_count, and theme_get_override (replacing direct
access to theme->overrides->items_count and hashtable_get on
theme->overrides). No plugin or script call sites change - the
public weechat_theme_register macro keeps the same shape.
2026-06-08 09:39:22 +02:00
Sébastien Helleu e4a2a6d3f2 trigger: contribute "light" theme overrides
Add trigger-theme.{c,h} with the trigger plugin contribution to the
built-in "light" theme: 6 entries (flag_command, flag_conditions,
flag_post_action, flag_regex, flag_return_code, regex) tuned for a
light-background terminal.

Same 2D-array pattern as the other plugin contributions.

Default option values are NOT changed.
2026-06-08 09:39:22 +02:00
Sébastien Helleu 7051d7e08b spell: contribute "light" theme overrides
Add spell-theme.{c,h} with the spell plugin contribution to the
built-in "light" theme: 1 entry (spell.color.misspelled=red) tuned for
a light-background terminal.

Same 2D-array pattern as the other plugin contributions.

Default option values are NOT changed.
2026-06-08 09:39:22 +02:00
Sébastien Helleu 36d09a2ba6 script: contribute "light" theme overrides
Add script-theme.{c,h} with the script plugin contribution to the
built-in "light" theme: 24 entries on script.color.* (status_* and
text_*) tuned for a light-background terminal.

Same 2D-array pattern as the other plugin contributions.

Default option values are NOT changed.
2026-06-08 09:39:22 +02:00
Sébastien Helleu ee799c9032 relay: contribute "light" theme overrides
Add relay-theme.{c,h} with the relay plugin contribution to the
built-in "light" theme: 5 entries (status_auth_failed, status_authenticating,
status_connecting, status_disconnected, text_selected) tuned for a
light-background terminal.

Same 2D-array pattern as the other plugin contributions.

Default option values are NOT changed.
2026-06-08 09:39:22 +02:00
Sébastien Helleu 797d3c0db2 logger: contribute "light" theme overrides
Add logger-theme.{c,h} with the logger plugin contribution to the
built-in "light" theme: 2 entries (logger.color.backlog_end=darkgray,
logger.color.backlog_line=darkgray) tuned for a light-background
terminal.

Same 2D-array pattern as the other plugin contributions.

Default option values are NOT changed.
2026-06-08 09:39:22 +02:00
Sébastien Helleu 91223591e9 exec: contribute "light" theme overrides
Add exec-theme.{c,h} with the exec plugin contribution to the built-in
"light" theme: 2 entries (exec.color.flag_finished=red,
exec.color.flag_running=green) tuned for a light-background terminal.

Same 2D-array pattern as the other plugin contributions.

Default option values are NOT changed.
2026-06-08 09:39:22 +02:00
Sébastien Helleu f50b91a6d9 xfer: contribute "light" theme overrides
Add xfer-theme.{c,h} with the xfer plugin contribution to the built-in
"light" theme: 7 overrides on xfer.color.* (status_aborted,
status_active, status_connecting, status_done, status_failed,
status_waiting, text_selected) tuned for a light-background terminal.

Same NULL-terminated 2D-array pattern as the irc, fset and buflist
contributions; xfer_theme_init() is called once from
weechat_plugin_init after xfer_config_init / xfer_config_read.

Default option values are NOT changed.
2026-06-08 09:39:22 +02:00
Sébastien Helleu d2d490146c buflist: contribute "light" theme overrides
Add buflist-theme.{c,h} with the buflist plugin contribution to the
built-in "light" theme: 5 overrides on buflist.format.* options
(buffer_current, hotlist_low, hotlist_message, lag, number) tuned for
a light-background terminal. Each target is a "string|themable" option
holding an evaluated format expression with embedded ${color:...}
references.

Follows the same pattern as the irc and fset contributions: a
NULL-terminated 2D string table consumed by a tiny local register
helper that builds a hashtable and calls weechat_theme_register;
buflist_theme_init() is called once from weechat_plugin_init after
buflist_config_init / buflist_config_read.

Default option values are NOT changed.
2026-06-08 09:39:22 +02:00
Sébastien Helleu f587a9dcaf fset: contribute "light" theme overrides
Add fset-theme.{c,h} with the fset plugin contribution to the built-in
"light" theme: 47 overrides on fset.color.* options (line backgrounds,
selected-row tuning, title and value colors) tuned for a
light-background terminal.

The table is a NULL-terminated 2-column array of strings (no struct
wrapper, matching the pattern adopted for the irc contribution).
fset_theme_register builds a hashtable from the table and calls
weechat_theme_register; fset_theme_init() is called once from
weechat_plugin_init after fset_config_init / fset_config_read.

Default option values are NOT changed.
2026-06-08 09:39:22 +02:00
Sébastien Helleu 54b0753aab irc: contribute "light" theme overrides
Add irc-theme.{c,h} with the IRC plugin contribution to the built-in
"light" theme: 9 overrides on irc.color.* options tuned for a
light-background terminal (input_nick, item_lag_finished,
item_tls_version_deprecated, list_buffer_line_selected,
message_chghost, message_setname, nick_prefixes, topic_new, topic_old).

The registration is a small wrapper around weechat_theme_register that
builds a hashtable from a static (option, value) table and frees it
after the call. irc_theme_init() is called from weechat_plugin_init
after irc_config_init/read so the option names are already created
when the theme registry references them.

Default option values are NOT changed.
2026-06-08 09:39:22 +02:00
Sébastien Helleu d189ca7f19 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.
2026-06-08 09:39:22 +02:00
Sébastien Helleu 86d8bec433 script: expose theme_register to python, perl, ruby, lua, tcl, javascript, php, guile
Add weechat.theme_register (name, overrides) to all eight script
languages. Each binding is a mechanical translation of the same
signature:

  - name:      string
  - overrides: language-native dict / hash / associative array of
               full_option_name -> value strings
  - returns:   pointer-as-string of the registered t_theme (empty
               string on failure)

Each binding converts the dict to a struct t_hashtable using the
existing per-language helper (weechat_python_dict_to_hashtable,
weechat_perl_hash_to_hashtable, weechat_ruby_hash_to_hashtable,
weechat_lua_tohashtable, weechat_tcl_dict_to_hashtable,
weechat_js_object_to_hashtable, weechat_php_array_to_hashtable,
weechat_guile_alist_to_hashtable), calls weechat_theme_register,
frees the temporary hashtable, and returns the result. The new
function is registered right after the config_* functions so the API
listing stays grouped by topic.

PHP also receives a new arginfo entry (string, array -> string) in
both weechat-php_arginfo.h and weechat-php_legacy_arginfo.h.

This is plumbing only - the underlying theme_register function is
already covered by tests/unit/core/test-core-theme.cpp
(TEST(CoreTheme, Register)). No script-side tests are added here.
2026-06-08 09:39:22 +02:00
Sébastien Helleu 53db79aa5f api: expose theme_register to plugins
Add a single new entry point to the plugin API:

  struct t_theme *weechat_theme_register (const char *name,
                                          struct t_hashtable *overrides);

Plugins call this at init time to contribute their per-theme color (or
other themable) overrides for a built-in theme like "dark". The
overrides hashtable maps full option names ("irc.color.input_nick") to
their string values; the caller retains ownership and may free it
right after the call. Repeated calls with the same theme name merge
into the existing registry entry, so each plugin can declare its own
contributions independently of core and of other plugins.

Wiring:

- struct t_theme forward-declared in weechat-plugin.h alongside the
  other opaque types.
- theme_register function pointer added to t_weechat_plugin.
- weechat_theme_register convenience macro added.
- plugin.c initializes the pointer to core's theme_register.
- WEECHAT_PLUGIN_API_VERSION bumped to 20260526-01.

This commit is plumbing only: the underlying theme_register function
already has unit-test coverage in tests/unit/core/test-core-theme.cpp
(TEST(CoreTheme, Register)), so no new tests are added here.
2026-06-08 09:39:22 +02:00
Sébastien Helleu b994a645e3 core: add theme name completion
Add two completion items hooked alongside "layouts_names":

- "theme_themes_all": all theme names (built-ins from the registry
  plus every *.theme file in <weechat_config_dir>/themes/, including
  backup-*.theme). Used by tab-complete on /theme apply and
  /theme info.
- "theme_themes_user": user theme files only (excludes built-ins
  and backup-*.theme). Used by tab-complete on /theme save and
  /theme delete, so users cannot accidentally try to overwrite a
  built-in name or save a name colliding with the reserved backup
  prefix.

Both callbacks share a small dir_exec_on_files-based helper to filter
the themes directory. The /theme command's completion template in
core-command.c is updated to reference these new items.
2026-06-08 09:39:22 +02:00
Sébastien Helleu 64f17761f1 core: implement /theme save and /theme delete
Add two complementary subcommands:

  /theme save <name> [-full]: writes a user theme file at
    ${weechat_config_dir}/themes/<name>.theme containing the current
    themable options. By default only options whose value differs from
    their default (config_file_option_has_changed) are written, which
    keeps the file small and focused. Pass "-full" to write every
    themable option (matches the format used by automatic backups).

    Name validation: refuses any name matching a built-in theme (those
    are reserved for in-memory registrations) and any name starting
    with "backup-" (reserved for /theme apply backups). Both checks
    print an error and abort without writing.

  /theme delete <name>: removes ${weechat_config_dir}/themes/<name>.theme
    via unlink. Refuses to delete a name registered as a built-in
    theme (a built-in has no file on disk to delete, even if the user
    has a shadowing file of the same name they cannot remove it this
    way; they can rename or delete it manually).

The full-snapshot writer used by /theme apply backups is refactored
into theme_write_file (name, description, diff_only). It is reused
by theme_make_backup (diff_only=0) and theme_save (diff_only inverted
from the user's -full flag).

Bug fix while at it: the writer was previously calling
config_file_option_value_to_string (ptr_option, 0, 1, 0); the third
and fourth arguments are "use_colors" and "use_delimiters", so the
call inserted GUI color escape codes into the file output and skipped
quoting strings. Corrected to (ptr_option, 0, 0, 1) so plain text
with proper string quoting is written; the change also fixes the
content of files produced by theme_make_backup in the previous commit.
2026-06-08 09:39:22 +02:00
Sébastien Helleu 3bdb31bbf6 core: implement theme file parsing and transient file reads in /theme apply
Add a small INI-style parser for *.theme files and wire it into the
/theme command so user themes living in directory "themes" inside the
WeeChat configuration directory can be applied (and inspected) without
ever being cached.

Parser (theme_file_parse in core-theme.c) accepts two sections:

  [info]
  name = "..."          \ shown by /theme info; ignored for apply
  description = "..."   |
  date = "..."          |
  weechat = "..."       /
  (unknown keys are ignored with a warning)

  [options]
  full.option.name = "value"

Surrounding single or double quotes around a value are stripped (same
rule used by the regular config file reader). The parsed result is a
heap-allocated t_theme; the caller frees with theme_free.

Resolution rule in theme_apply: if the path
"${weechat_config_dir}/themes/<name>.theme" is readable it is parsed
and used (file shadows any built-in of the same name); otherwise the
built-in registry is consulted. The transient t_theme is freed before
the final refresh, so user themes have no steady-state memory
footprint regardless of how many .theme files have accumulated.

/theme list now also scans the themes directory and appends user
files to the listing (each marked "(file)"). backup-*.theme are
hidden by default; pass "-backups" to include them.

/theme info <name> works for both sources: file path is shown when the
information comes from disk; "built-in (in-memory)" otherwise.
2026-06-08 09:39:22 +02:00
Sébastien Helleu 7f1f9462f4 core: implement /theme apply with themable enforcement and auto-backup
Implement /theme apply <name> for themes currently in the in-memory
registry. The file-shadowing branch (read a .theme file from
${weechat_config_dir}/themes/ when no built-in matches) is added in
the next commit together with the parser.

Apply algorithm (theme_apply in core-theme.c):

- Look up the theme in the registry; abort with an error if unknown.
- If weechat.look.theme_backup is on and the target name does not
  begin with "backup-", write a full snapshot of every themable
  option to ${weechat_config_dir}/themes/backup-<timestamp>.theme
  via theme_make_backup; abort the apply if the backup cannot be
  written, so the user can always undo.
- Iterate the theme's overrides with theme_applying=1 so the
  per-option config_change_color skips its gui refresh; for each
  entry look up the option, refuse it if missing or non-themable
  (warning to core buffer), otherwise call config_file_option_set.
- Perform a single gui_color_init_weechat + gui_window_ask_refresh
  at the end.
- Persist the active label in weechat.look.theme and send signal
  "theme_applied" with the name as data.

Add the new option weechat.look.theme_backup (boolean, default on)
which controls the backup-or-abort behaviour described above.

Wire the new /theme apply subcommand into core-command.c with the
existing /theme registration; update help text accordingly.
2026-06-08 09:39:22 +02:00
Sébastien Helleu 9fbc81dc54 core: add /theme command with list and info subcommands
Add the /theme command with two read-only subcommands for now:

- /theme  (or  /theme list): list registered themes; the active theme
  (matching weechat.look.theme) is marked with "->".
- /theme info <name>: show name, description, creation date, WeeChat
  version and override count of a theme.

Both subcommands only consider themes present in the in-memory
registry (registered via core/plugins/scripts). User theme files on
disk are not yet handled: the file parser and transient file reads
land in a later commit together with /theme apply.
2026-06-08 09:39:22 +02:00
Sébastien Helleu 4550c3e33a core: add weechat.look.theme option and theme_applying guard
Add a new string option "weechat.look.theme" holding the name of the
last theme applied via the upcoming /theme command. It is set
automatically by /theme apply and persisted on disk for /theme info to
display after restart; it is NOT re-applied at startup (the user's
saved color values win to avoid clobbering manual post-apply tweaks).

Amend config_change_color so it skips the gui_color_init_weechat ()
and gui_window_ask_refresh (1) calls when theme_applying is set.
/theme apply will set this flag while iterating overrides so the N
individual option changes do not trigger N redundant screen refreshes;
the apply path then performs a single refresh at the end.
2026-06-08 09:39:22 +02:00
Sébastien Helleu 7e2b9ffa9a core: add core-theme skeleton and theme registry
Introduce a new module (core-theme.{c,h}) holding the in-memory registry
of built-in themes used by the upcoming /theme command:

- struct t_theme stores name, description, date and weechat version
  captured at registration time, plus a hashtable of overrides keyed by
  full option name (file.section.option) -> value string.
- theme_register (name, overrides) creates a new theme or merges the
  given overrides into an existing one (later calls override duplicate
  keys); this is the API plugins and scripts will use to contribute
  per-theme color values.
- theme_search and theme_list provide lookup and ordered enumeration.
- theme_init / theme_end are called from weechat_init / weechat_end.

The theme_applying flag is declared here but not yet consumed (it will
gate config_change_color in the next commit to avoid N redundant
window refreshes during /theme apply).

User theme files are not handled by this module: they are read
transiently inside /theme apply (a later commit) and never cached.
2026-06-08 09:39:22 +02:00
Sébastien Helleu 04f817814f fset: add "t:themable" filter
Extend the "t:" filter so the special value "themable" matches every
option whose new themable flag is set, regardless of type (color,
string, integer, boolean, enum). This makes the flag interactively
discoverable in the fset buffer and is the natural way to inspect the
surface area that an upcoming /theme command will be allowed to touch.

The themable flag of an option is now mirrored on struct t_fset_option,
exposed via hdata ("themable", integer) and infolist ("themable",
integer), and printed in the log.
2026-06-08 09:39:22 +02:00
Sébastien Helleu 0315c53a9e core: add themable flag to configuration options
Add an "int themable" field on struct t_config_option. The flag is set
automatically for every CONFIG_OPTION_TYPE_COLOR option, and may be set
explicitly on any other type by suffixing the type argument with
"|themable" in the call to config_file_new_option (e.g. "string|themable"
for a string option whose value contains "${color:...}" references).

Opt in the relevant string options in core (buffer_time_format,
day_change_message_*, item_time_format, nick_color_force, prefix_*,
chat_nick_colors, eval_syntax_colors, color palette aliases) and in the
buflist, fset, irc, relay plugins.

The flag is exposed via hdata, infolist, and print_log so scripts and
/debug can read it. This is the foundation for an upcoming /theme
command that will only be allowed to modify themable options.
2026-06-08 09:39:22 +02:00
163 changed files with 6954 additions and 1009 deletions
+11 -10
View File
@@ -118,7 +118,7 @@ jobs:
strategy:
matrix:
os:
- ubuntu-26.04
- ubuntu-24.04
runs-on: ${{ matrix.os }}
@@ -153,7 +153,7 @@ jobs:
strategy:
matrix:
os:
- ubuntu-26.04
- ubuntu-24.04
config:
- name: "gcc"
cc: "gcc"
@@ -194,8 +194,6 @@ jobs:
name: "install (${{ matrix.os }}, ${{ matrix.config.name }})"
runs-on: ${{ matrix.os }}
env:
PHP_INI_SCAN_DIR: /tmp/php-noscan # embed PHP loads no add-on extensions (see #2009)
steps:
@@ -205,7 +203,8 @@ jobs:
run: |
sudo apt-get update -qq
sudo apt-get --yes --no-install-recommends install ${{ env.WEECHAT_DEPS_UBUNTU }}
mkdir -p /tmp/php-noscan
# uninstall php imagick as is causes a crash when loading php plugin (see #2009)
sudo apt-get --yes purge php8.3-imagick
pipx install schemathesis
- name: Build and run tests
@@ -259,7 +258,7 @@ jobs:
strategy:
matrix:
os:
- ubuntu-26.04
- ubuntu-24.04
config:
- name: "gcc"
cc: "gcc"
@@ -305,7 +304,7 @@ jobs:
strategy:
matrix:
os:
- ubuntu-26.04
- ubuntu-24.04
config:
- name: "gcc"
cc: "gcc"
@@ -356,7 +355,7 @@ jobs:
strategy:
matrix:
os:
- ubuntu-26.04
- ubuntu-24.04
config:
# - name: "gcc"
# cc: "gcc"
@@ -451,7 +450,7 @@ jobs:
strategy:
matrix:
os:
- ubuntu-26.04
- ubuntu-24.04
runs-on: ${{ matrix.os }}
@@ -488,7 +487,7 @@ jobs:
strategy:
matrix:
os:
- ubuntu-26.04
- ubuntu-24.04
runs-on: ${{ matrix.os }}
@@ -506,6 +505,8 @@ jobs:
run: |
sudo apt-get update -qq
sudo apt-get --yes --no-install-recommends install ${{ env.WEECHAT_DEPS_UBUNTU }}
# uninstall php imagick as is causes a crash when loading php plugin (see #2009)
sudo apt-get --yes purge php8.3-imagick
- name: Initialize CodeQL
uses: github/codeql-action/init@v3
+13 -10
View File
@@ -12,30 +12,33 @@ SPDX-License-Identifier: GPL-3.0-or-later
- core: add condition on connected relay api clients in default value of option weechat.look.hotlist_add_conditions
- core: add `/mute` in default command for key `Alt`+`=` (toggle filters)
- api: change type of parameter "pos_option_name" to "const char **" in function config_search_with_string
- relay/api: add field "last_read_line_id" in GET /api/buffers
### Added
- relay/api: add resource `GET /api/scripts`
- core: add `/theme` command with subcommands `list`, `apply`, `reset`, `save`, `rename`, `delete`, `info`, automatic backup of current themable options before apply, and built-in "light" theme
- core: detect terminal background on first start and automatically apply the built-in "light" theme when a light terminal is detected
- core: add `themable` flag on configuration options (auto-set for color options; explicit opt-in for string options containing `${color:...}` references via the `type|themable` syntax)
- core: add option weechat.look.theme (informational, set by `/theme apply`)
- core: add option weechat.look.theme_backup (boolean, default `on`)
- api: add function `theme_register` (available to plugins and to all script languages)
- fset: add filter `t:themable` (matches every themable option regardless of type)
- relay: add option relay.network.unix_socket_permissions ([#2317](https://github.com/weechat/weechat/issues/2317))
- script: add info "script_languages"
### Fixed
- core: fix option weechat.look.color_real_white not applied when color is "white" on 16+ colors terminals ([#1742](https://github.com/weechat/weechat/issues/1742))
- core: fix buffer overflow in connection to SOCKS5 proxy ([#2325](https://github.com/weechat/weechat/issues/2325))
- api: fix infinite loop in function string_replace when the search string is empty
- irc: fix tag in message with list of names when joining a channel
- fset: remove error displayed in core buffer when clicking with the mouse below the last option displayed
- irc: limit size of data received from the server to prevent memory exhaustion
- irc: fix out-of-bounds read on incoming DCC command with a quoted filename ending the message ([#2322](https://github.com/weechat/weechat/issues/2322))
- relay: limit size of decompressed websocket frame with permessage-deflate to prevent memory exhaustion ([GHSA-v2v4-45wm-5cr3](https://github.com/weechat/weechat/security/advisories/GHSA-v2v4-45wm-5cr3), [CVE-2026-53524](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2026-53524))
- relay: limit size of decompressed websocket frame with permessage-deflate to prevent memory exhaustion ([GHSA-v2v4-45wm-5cr3](https://github.com/weechat/weechat/security/advisories/GHSA-v2v4-45wm-5cr3))
- relay: limit size of received websocket frame and HTTP body to prevent memory exhaustion
- relay: limit size of partial message received while reading an HTTP request to prevent memory exhaustion
- relay: fix timing attack on password authentication ([GHSA-vhv8-g2r9-cwcc](https://github.com/weechat/weechat/security/advisories/GHSA-vhv8-g2r9-cwcc), [CVE-2026-53525](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2026-53525))
- relay: fix timing attack on password authentication ([GHSA-vhv8-g2r9-cwcc](https://github.com/weechat/weechat/security/advisories/GHSA-vhv8-g2r9-cwcc))
- relay: fix out-of-bounds read in dump of data ([#2324](https://github.com/weechat/weechat/issues/2324))
- api, relay: fix timing attack on TOTP validation ([GHSA-vhv8-g2r9-cwcc](https://github.com/weechat/weechat/security/advisories/GHSA-vhv8-g2r9-cwcc), [CVE-2026-53525](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2026-53525))
- api, relay: fix timing attack on TOTP validation ([GHSA-vhv8-g2r9-cwcc](https://github.com/weechat/weechat/security/advisories/GHSA-vhv8-g2r9-cwcc))
- xfer: replace directory separator in remote nick by underscore in download filename to prevent writing the file outside the download directory ([#2321](https://github.com/weechat/weechat/issues/2321))
- xfer: fix out-of-bounds read when receiving empty line in DCC chat ([#2323](https://github.com/weechat/weechat/issues/2323))
@@ -58,9 +61,9 @@ SPDX-License-Identifier: GPL-3.0-or-later
- core: fix option weechat.look.color_real_white not applied when color is "white" on 16+ colors terminals ([#1742](https://github.com/weechat/weechat/issues/1742))
- irc: fix tag in message with list of names when joining a channel
- relay: limit size of decompressed websocket frame with permessage-deflate to prevent memory exhaustion ([GHSA-v2v4-45wm-5cr3](https://github.com/weechat/weechat/security/advisories/GHSA-v2v4-45wm-5cr3), [CVE-2026-53524](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2026-53524))
- relay: fix timing attack on password authentication ([GHSA-vhv8-g2r9-cwcc](https://github.com/weechat/weechat/security/advisories/GHSA-vhv8-g2r9-cwcc), [CVE-2026-53525](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2026-53525))
- api, relay: fix timing attack on TOTP validation ([GHSA-vhv8-g2r9-cwcc](https://github.com/weechat/weechat/security/advisories/GHSA-vhv8-g2r9-cwcc), [CVE-2026-53525](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2026-53525))
- relay: limit size of decompressed websocket frame with permessage-deflate to prevent memory exhaustion ([GHSA-v2v4-45wm-5cr3](https://github.com/weechat/weechat/security/advisories/GHSA-v2v4-45wm-5cr3))
- relay: fix timing attack on password authentication ([GHSA-vhv8-g2r9-cwcc](https://github.com/weechat/weechat/security/advisories/GHSA-vhv8-g2r9-cwcc))
- api, relay: fix timing attack on TOTP validation ([GHSA-vhv8-g2r9-cwcc](https://github.com/weechat/weechat/security/advisories/GHSA-vhv8-g2r9-cwcc))
## Version 4.9.0 (2026-03-29)
+146
View File
@@ -2197,6 +2197,152 @@ Um der Vordergrundfarbe des Terminals das Attribut "fett" zuzuordnen:
/set weechat.color.status_time *99999
----
// TRANSLATION MISSING
[[themes]]
=== Themen
A theme is a named bundle of option overrides that can be applied with
the <<command_weechat_theme,/theme>> command. WeeChat ships a built-in
`"light"` theme tuned for light-background terminals and supports
user-defined themes loaded transiently from files.
[[themes_themable_options]]
==== Themable options
Themes can only set options marked as _themable_. All `*.color.*`
options are themable by default; a few string options that hold format
expressions with `+${color:...}+` references (such as
`+weechat.color.chat_nick_colors+`, `+weechat.look.prefix_error+` or the
`+buflist.format.*+` formats) are explicitly opted in.
You can list the full themable surface area from the
<<command_fset_fset,/fset>> buffer with the `+t:themable+` filter.
[[themes_apply]]
==== Applying a theme
To switch to the built-in light-background theme:
----
/theme apply light
----
The current state of every themable option is saved beforehand to a
backup theme file named like `+backup-YYYYMMDD-HHMMSS-uuuuuu+` in
directory `+themes+` inside the WeeChat configuration directory, so the
previous look can be restored at any time with:
----
/theme apply backup-YYYYMMDD-HHMMSS-uuuuuu
----
Backup creation can be disabled (not recommended):
----
/set weechat.look.theme_backup off
----
If backup is enabled and the backup file cannot be written, the apply
is aborted before any option is changed.
The name of the last applied theme is stored in
`+weechat.look.theme+` (informational only; not re-applied at startup).
[[themes_reset]]
==== Resetting to defaults
To restore the look shipped with WeeChat, reset every themable option
to its default value:
----
/theme reset
----
A backup is written first (same gate as `+/theme apply+`); on backup
failure the reset is aborted before any option is changed.
`+weechat.look.theme+` is cleared too.
[[themes_save_delete]]
==== Saving and deleting user themes
Save the current themable options as a new user theme file:
----
/theme save mytheme
----
Every themable option is written, so the file is self-contained and
applies the exact same look on any WeeChat, regardless of its current
configuration.
Reserved names (built-in theme names like `+light+` and any name
starting with `+backup-+`) are refused. Files live at
`+${weechat_config_dir}/themes/<name>.theme+`.
Rename a user theme (typical use: keep a useful automatic backup
under a meaningful name):
----
/theme rename backup-20260525-094210-123456 mybackup
----
Built-in themes have no file and cannot be renamed; the target name
cannot match a built-in name or start with `+backup-+`, and the
target file must not already exist. The `+[info]+` `+name+` field
inside the file is rewritten so `/theme info` reports the new name
consistently.
Delete a user theme:
----
/theme delete mytheme
----
This removes the file on disk; built-in themes cannot be deleted.
[[themes_file_format]]
==== Theme file format
A theme file is INI-like with two sections:
----
[info]
name = "solarized_light"
description = "Light-background theme inspired by Solarized"
date = "2026-05-25 09:42:10"
weechat = "4.10.0-dev"
[options]
weechat.color.chat = "darkgray"
weechat.color.separator = "blue"
irc.color.input_nick = "magenta"
buflist.format.number = "${color:28}${number}${if:${number_displayed}?.: }"
----
`+[info]+` is informational metadata shown by `/theme info`. `+[options]+`
holds the actual overrides; keys are the full option names that would
appear in `/set`. String values can be enclosed in double or single
quotes; quotes are stripped at parse time. Non-themable options listed
in a theme file are refused at apply time and logged to the core
buffer (so a `.theme` file imported from an untrusted source cannot
overwrite passwords, autoload lists, or startup commands).
User theme files are never cached: on every `/theme apply <name>` the
file is parsed, applied, and freed.
[[themes_resolution]]
==== Resolution order
When `+/theme apply <name>+` is run:
* If `+${weechat_config_dir}/themes/<name>.theme+` exists, the file
is parsed and used (it shadows any built-in with the same name).
* Otherwise the built-in theme registry is consulted; built-ins are
registered programmatically by core, plugins and scripts (see the
plugin and scripting documentation for `+weechat_theme_register+`).
If neither source provides the name, the apply is refused.
[[charset]]
=== Charset
+88 -5
View File
@@ -4348,7 +4348,7 @@ Prototype:
[source,c]
----
int weechat_mkdir_home (const char *directory, int mode);
int weechat_mkdir_home (char *directory, int mode);
----
Arguments:
@@ -4395,7 +4395,7 @@ Prototype:
[source,c]
----
int weechat_mkdir (const char *directory, int mode);
int weechat_mkdir (char *directory, int mode);
----
Arguments:
@@ -4436,7 +4436,7 @@ Prototype:
[source,c]
----
int weechat_mkdir_parents (const char *directory, int mode);
int weechat_mkdir_parents (char *directory, int mode);
----
Arguments:
@@ -7709,7 +7709,7 @@ void weechat_config_search_with_string (const char *option_name,
struct t_config_file **config_file,
struct t_config_section **section,
struct t_config_option **option,
const char **pos_option_name);
char **pos_option_name);
----
Arguments:
@@ -7731,7 +7731,7 @@ C example:
struct t_config_file *ptr_config_file;
struct t_config_section *ptr_section;
struct t_config_option *ptr_option;
const char *option_name;
char *option_name;
weechat_config_search_with_string ("file.section.option",
&ptr_config_file,
@@ -9627,6 +9627,89 @@ elif rc == weechat.WEECHAT_CONFIG_OPTION_UNSET_ERROR:
# ...
----
[[themes]]
=== Themes
Functions to contribute color (and other themable option) overrides to
built-in themes. See the
link:weechat_user.en.html#themes[user's guide / Themes] section for the
end-user side and the `+/theme+` command.
==== theme_register
_WeeChat ≥ 4.10.0._
Register a contribution of option overrides under a named theme. The
caller's plugin is the owner of the contribution; subsequent calls
with the same theme name from the same plugin merge into the existing
contribution (later keys win for duplicates).
When the calling plugin is unloaded, all its contributions are
automatically dropped from every theme.
Prototype:
[source,c]
----
struct t_theme *weechat_theme_register (const char *name,
struct t_hashtable *overrides);
----
Arguments:
* _name_: theme name (for example `+light+` or a custom name)
* _overrides_: hashtable mapping full option names
(e.g. `+irc.color.input_nick+`) to their string values; the caller
retains ownership and may free the hashtable right after the call
Return value:
* pointer to the registered theme (existing or newly created), NULL on
error
C example:
[source,c]
----
struct t_hashtable *overrides = weechat_hashtable_new (
8,
WEECHAT_HASHTABLE_STRING,
WEECHAT_HASHTABLE_STRING,
NULL, NULL);
if (overrides)
{
weechat_hashtable_set (overrides, "irc.color.input_nick", "cyan");
weechat_hashtable_set (overrides, "irc.color.topic_old", "darkgray");
weechat_theme_register ("light", overrides);
weechat_hashtable_free (overrides);
}
----
Script (Python):
[source,python]
----
# prototype
def theme_register(name: str, overrides: Dict[str, str]) -> str: ...
# example
weechat.theme_register("light", {
"irc.color.input_nick": "cyan",
"irc.color.topic_old": "darkgray",
})
----
[NOTE]
Only options that have the _themable_ flag will be set by `/theme apply`.
All `*.color.*` options are themable by default; string options that
hold `+${color:...}+` references are explicitly opted in. Entries
targeting non-themable options are silently skipped at apply-time with
a warning logged to the _core_ buffer.
[NOTE]
When called from a script, the contribution is automatically dropped
when the script unloads (no manual cleanup is needed).
[[key_bindings]]
=== Key bindings
-46
View File
@@ -1179,51 +1179,6 @@ HTTP/1.1 200 OK
]
----
[[resource_scripts]]
=== Scripts
Return loaded scripts (all languages).
Endpoint:
----
GET /api/scripts
----
Request example:
[source,shell]
----
curl -L -u 'plain:secret_password' 'https://localhost:9000/api/scripts'
----
Response:
[source,http]
----
HTTP/1.1 200 OK
----
[source,json]
----
[
{
"name": "highmon.pl",
"version": "2.7",
"description": "Highlight Monitor",
"author": "KenjiE20",
"license": "GPL3"
},
{
"name": "go.py",
"version": "3.1.1",
"description": "Quick jump to buffers",
"author": "Sébastien Helleu <flashcode@flashtux.org>",
"license": "GPL3"
}
]
----
[[resource_input]]
=== Input
@@ -1555,7 +1510,6 @@ Body types that can be returned:
* `nick_group` (object)
* `nick` (object)
* `hotlist` (object)
* `scripts` (array)
* `ping` (object)
[TIP]
+145
View File
@@ -2185,6 +2185,151 @@ Example of bold with terminal foreground color:
/set weechat.color.status_time *99999
----
[[themes]]
=== Themes
A theme is a named bundle of option overrides that can be applied with
the <<command_weechat_theme,/theme>> command. WeeChat ships a built-in
`"light"` theme tuned for light-background terminals and supports
user-defined themes loaded transiently from files.
[[themes_themable_options]]
==== Themable options
Themes can only set options marked as _themable_. All `*.color.*`
options are themable by default; a few string options that hold format
expressions with `+${color:...}+` references (such as
`+weechat.color.chat_nick_colors+`, `+weechat.look.prefix_error+` or the
`+buflist.format.*+` formats) are explicitly opted in.
You can list the full themable surface area from the
<<command_fset_fset,/fset>> buffer with the `+t:themable+` filter.
[[themes_apply]]
==== Applying a theme
To switch to the built-in light-background theme:
----
/theme apply light
----
The current state of every themable option is saved beforehand to a
backup theme file named like `+backup-YYYYMMDD-HHMMSS-uuuuuu+` in
directory `+themes+` inside the WeeChat configuration directory, so the
previous look can be restored at any time with:
----
/theme apply backup-YYYYMMDD-HHMMSS-uuuuuu
----
Backup creation can be disabled (not recommended):
----
/set weechat.look.theme_backup off
----
If backup is enabled and the backup file cannot be written, the apply
is aborted before any option is changed.
The name of the last applied theme is stored in
`+weechat.look.theme+` (informational only; not re-applied at startup).
[[themes_reset]]
==== Resetting to defaults
To restore the look shipped with WeeChat, reset every themable option
to its default value:
----
/theme reset
----
A backup is written first (same gate as `+/theme apply+`); on backup
failure the reset is aborted before any option is changed.
`+weechat.look.theme+` is cleared too.
[[themes_save_delete]]
==== Saving and deleting user themes
Save the current themable options as a new user theme file:
----
/theme save mytheme
----
Every themable option is written, so the file is self-contained and
applies the exact same look on any WeeChat, regardless of its current
configuration.
Reserved names (built-in theme names like `+light+` and any name
starting with `+backup-+`) are refused. Files live at
`+${weechat_config_dir}/themes/<name>.theme+`.
Rename a user theme (typical use: keep a useful automatic backup
under a meaningful name):
----
/theme rename backup-20260525-094210-123456 mybackup
----
Built-in themes have no file and cannot be renamed; the target name
cannot match a built-in name or start with `+backup-+`, and the
target file must not already exist. The `+[info]+` `+name+` field
inside the file is rewritten so `/theme info` reports the new name
consistently.
Delete a user theme:
----
/theme delete mytheme
----
This removes the file on disk; built-in themes cannot be deleted.
[[themes_file_format]]
==== Theme file format
A theme file is INI-like with two sections:
----
[info]
name = "solarized_light"
description = "Light-background theme inspired by Solarized"
date = "2026-05-25 09:42:10"
weechat = "4.10.0-dev"
[options]
weechat.color.chat = "darkgray"
weechat.color.separator = "blue"
irc.color.input_nick = "magenta"
buflist.format.number = "${color:28}${number}${if:${number_displayed}?.: }"
----
`+[info]+` is informational metadata shown by `/theme info`. `+[options]+`
holds the actual overrides; keys are the full option names that would
appear in `/set`. String values can be enclosed in double or single
quotes; quotes are stripped at parse time. Non-themable options listed
in a theme file are refused at apply time and logged to the core
buffer (so a `.theme` file imported from an untrusted source cannot
overwrite passwords, autoload lists, or startup commands).
User theme files are never cached: on every `/theme apply <name>` the
file is parsed, applied, and freed.
[[themes_resolution]]
==== Resolution order
When `+/theme apply <name>+` is run:
* If `+${weechat_config_dir}/themes/<name>.theme+` exists, the file
is parsed and used (it shadows any built-in with the same name).
* Otherwise the built-in theme registry is consulted; built-ins are
registered programmatically by core, plugins and scripts (see the
plugin and scripting documentation for `+weechat_theme_register+`).
If neither source provides the name, the apply is refused.
[[charset]]
=== Charset
+94 -5
View File
@@ -4424,7 +4424,7 @@ Prototype :
[source,c]
----
int weechat_mkdir_home (const char *directory, int mode);
int weechat_mkdir_home (char *directory, int mode);
----
Paramètres :
@@ -4471,7 +4471,7 @@ Prototype :
[source,c]
----
int weechat_mkdir (const char *directory, int mode);
int weechat_mkdir (char *directory, int mode);
----
Paramètres :
@@ -4512,7 +4512,7 @@ Prototype :
[source,c]
----
int weechat_mkdir_parents (const char *directory, int mode);
int weechat_mkdir_parents (char *directory, int mode);
----
Paramètres :
@@ -7838,7 +7838,7 @@ void weechat_config_search_with_string (const char *option_name,
struct t_config_file **config_file,
struct t_config_section **section,
struct t_config_option **option,
const char **pos_option_name);
char **pos_option_name);
----
Paramètres :
@@ -7861,7 +7861,7 @@ Exemple en C :
struct t_config_file *ptr_config_file;
struct t_config_section *ptr_section;
struct t_config_option *ptr_option;
const char *option_name;
char *option_name;
weechat_config_search_with_string ("fichier.section.option",
&ptr_config_file,
@@ -9771,6 +9771,95 @@ elif rc == weechat.WEECHAT_CONFIG_OPTION_UNSET_ERROR:
# ...
----
[[themes]]
=== Thèmes
Fonctions permettant de contribuer des surcharges d'options de couleur
(et autres options modifiables par un thème) à des thèmes intégrés.
Voir la section
link:weechat_user.fr.html#themes[guide utilisateur / Thèmes] pour le
côté utilisateur final et la commande `+/theme+`.
==== theme_register
_WeeChat ≥ 4.10.0._
Enregistrer une contribution de surcharges d'options sous un thème
nommé. L'extension appelante est le propriétaire de la contribution ;
les appels suivants avec le même nom de thème depuis la même extension
sont fusionnés dans la contribution existante (en cas de doublons, les
dernières clés gagnent).
Lorsque l'extension appelante est déchargée, toutes ses contributions
sont automatiquement retirées de tous les thèmes.
Prototype :
[source,c]
----
struct t_theme *weechat_theme_register (const char *name,
struct t_hashtable *overrides);
----
Paramètres :
* _name_ : nom du thème (par exemple `+light+` ou un nom personnalisé)
* _overrides_ : table de hachage associant des noms d'options complets
(par exemple `+irc.color.input_nick+`) à leurs valeurs chaîne ;
l'appelant en conserve la propriété et peut la libérer juste après
l'appel
Valeur de retour :
* pointeur vers le thème enregistré (existant ou nouvellement créé),
NULL en cas d'erreur
Exemple en C :
[source,c]
----
struct t_hashtable *overrides = weechat_hashtable_new (
8,
WEECHAT_HASHTABLE_STRING,
WEECHAT_HASHTABLE_STRING,
NULL, NULL);
if (overrides)
{
weechat_hashtable_set (overrides, "irc.color.input_nick", "cyan");
weechat_hashtable_set (overrides, "irc.color.topic_old", "darkgray");
weechat_theme_register ("light", overrides);
weechat_hashtable_free (overrides);
}
----
Script (Python) :
[source,python]
----
# prototype
def theme_register(name: str, overrides: Dict[str, str]) -> str: ...
# exemple
weechat.theme_register("light", {
"irc.color.input_nick": "cyan",
"irc.color.topic_old": "darkgray",
})
----
[NOTE]
Seules les options possédant le flag _themable_ seront modifiées par
`/theme apply`. Toutes les options `*.color.*` sont modifiables par
défaut ; les options de type chaîne contenant des références
`+${color:...}+` sont explicitement déclarées comme modifiables. Les
entrées ciblant des options non modifiables sont silencieusement
ignorées au moment de l'application avec un avertissement écrit sur
le tampon _core_.
[NOTE]
Lorsqu'elle est appelée depuis un script, la contribution est
automatiquement retirée lorsque le script est déchargé (aucun nettoyage
manuel n'est nécessaire).
[[key_bindings]]
=== Associations de touches
-46
View File
@@ -1191,51 +1191,6 @@ HTTP/1.1 200 OK
]
----
[[resource_scripts]]
=== Scripts
Retourner la liste des scripts chargés (tous les langages).
Point de terminaison:
----
GET /api/scripts
----
Exemple de requête:
[source,shell]
----
curl -L -u 'plain:secret_password' 'https://localhost:9000/api/scripts'
----
Réponse:
[source,http]
----
HTTP/1.1 200 OK
----
[source,json]
----
[
{
"name": "highmon.pl",
"version": "2.7",
"description": "Highlight Monitor",
"author": "KenjiE20",
"license": "GPL3"
},
{
"name": "go.py",
"version": "3.1.1",
"description": "Quick jump to buffers",
"author": "Sébastien Helleu <flashcode@flashtux.org>",
"license": "GPL3"
}
]
----
[[resource_input]]
=== Entrée
@@ -1575,7 +1530,6 @@ Les types de corps qui peuvent être retournés :
* `nick_group` (objet)
* `nick` (objet)
* `hotlist` (objet)
* `scripts` (tableau)
* `ping` (objet)
[TIP]
+160
View File
@@ -2227,6 +2227,166 @@ Exemple de gras avec la couleur de texte du terminal :
/set weechat.color.status_time *99999
----
[[themes]]
=== Thèmes
Un thème est un ensemble nommé de surcharges d'options qui peut être
appliqué par la commande <<command_weechat_theme,/theme>>. WeeChat est
livré avec un thème intégré `"light"` adapté aux terminaux à fond clair
et permet de charger temporairement des thèmes utilisateur depuis des
fichiers.
[[themes_themable_options]]
==== Options modifiables par un thème
Les thèmes ne peuvent modifier que les options marquées comme
_themable_ (modifiables par un thème). Toutes les options `*.color.*`
le sont par défaut ; certaines options de type chaîne contenant des
références `+${color:...}+` (par exemple
`+weechat.color.chat_nick_colors+`, `+weechat.look.prefix_error+` ou les
formats `+buflist.format.*+`) sont explicitement déclarées comme
modifiables.
La liste complète des options modifiables peut être affichée depuis le
tampon <<command_fset_fset,/fset>> avec le filtre `+t:themable+`.
[[themes_apply]]
==== Appliquer un thème
Pour basculer vers le thème intégré pour fond clair :
----
/theme apply light
----
L'état actuel de toutes les options modifiables est sauvegardé au
préalable dans un fichier de sauvegarde nommé
`+backup-AAAAMMJJ-HHMMSS-uuuuuu+` dans le répertoire `+themes+` du
répertoire de configuration de WeeChat. L'apparence précédente peut
ainsi être restaurée à tout moment avec :
----
/theme apply backup-AAAAMMJJ-HHMMSS-uuuuuu
----
La création de la sauvegarde peut être désactivée (déconseillé) :
----
/set weechat.look.theme_backup off
----
Si la sauvegarde est activée et que le fichier ne peut pas être écrit,
l'application est annulée avant qu'aucune option ne soit modifiée.
Le nom du dernier thème appliqué est conservé dans
`+weechat.look.theme+` (à titre informatif uniquement ; il n'est pas
ré-appliqué au démarrage).
[[themes_reset]]
==== Réinitialiser aux valeurs par défaut
Pour rétablir l'apparence d'origine livrée avec WeeChat, réinitialiser
toutes les options modifiables à leur valeur par défaut :
----
/theme reset
----
Une sauvegarde est écrite au préalable (même garde-fou que
`+/theme apply+`) ; si la sauvegarde échoue, la réinitialisation est
annulée avant qu'aucune option ne soit modifiée. L'option
`+weechat.look.theme+` est également remise à vide.
[[themes_save_delete]]
==== Sauvegarder et supprimer des thèmes utilisateur
Sauvegarder l'état actuel des options modifiables en tant que nouveau
thème utilisateur :
----
/theme save monTheme
----
Toutes les options modifiables sont écrites, donc le fichier est
autonome et applique exactement le même aspect sur n'importe quel
WeeChat, quelle que soit sa configuration actuelle.
Les noms réservés (noms de thèmes intégrés comme `+light+` et tout nom
commençant par `+backup-+`) sont refusés. Les fichiers sont placés
dans `+${weechat_config_dir}/themes/<nom>.theme+`.
Renommer un thème utilisateur (usage typique : conserver une
sauvegarde automatique utile sous un nom plus parlant) :
----
/theme rename backup-20260525-094210-123456 maSauvegarde
----
Les thèmes intégrés n'ont pas de fichier et ne peuvent pas être
renommés ; le nom cible ne peut pas correspondre à un nom intégré ni
commencer par `+backup-+`, et le fichier cible ne doit pas déjà
exister. Le champ `+name+` de la section `+[info]+` à l'intérieur du
fichier est réécrit afin que `/theme info` affiche le nouveau nom de
manière cohérente.
Supprimer un thème utilisateur :
----
/theme delete monTheme
----
Cela supprime le fichier sur le disque ; les thèmes intégrés ne
peuvent pas être supprimés.
[[themes_file_format]]
==== Format du fichier de thème
Un fichier de thème est de type INI avec deux sections :
----
[info]
name = "solarized_light"
description = "Thème fond clair inspiré de Solarized"
date = "2026-05-25 09:42:10"
weechat = "4.10.0-dev"
[options]
weechat.color.chat = "darkgray"
weechat.color.separator = "blue"
irc.color.input_nick = "magenta"
buflist.format.number = "${color:28}${number}${if:${number_displayed}?.: }"
----
`+[info]+` est une section de métadonnées informatives affichées par
`/theme info`. `+[options]+` contient les surcharges réelles ; les clés
sont les noms complets d'options tels qu'affichés par `/set`. Les
valeurs de type chaîne peuvent être encadrées par des guillemets
simples ou doubles ; les guillemets sont retirés à l'analyse. Les
options non modifiables par un thème listées dans un fichier sont
refusées au moment de l'application et signalées sur le tampon _core_
(ainsi, un fichier `.theme` importé depuis une source non fiable ne
peut pas écraser des mots de passe, des listes d'auto-chargement ou
des commandes de démarrage).
Les fichiers de thème utilisateur ne sont jamais mis en cache : à
chaque `/theme apply <nom>`, le fichier est analysé, appliqué, puis
libéré.
[[themes_resolution]]
==== Ordre de résolution
Lors de l'exécution de `+/theme apply <nom>+` :
* Si `+${weechat_config_dir}/themes/<nom>.theme+` existe, le fichier
est analysé et utilisé (il masque tout thème intégré du même nom).
* Sinon, le registre des thèmes intégrés est consulté ; les thèmes
intégrés sont enregistrés par programmation par le cœur, les
extensions et les scripts (voir la documentation des extensions et
des scripts pour `+weechat_theme_register+`).
Si aucune des deux sources ne fournit le nom, l'application est
refusée.
[[charset]]
=== Charset
+89 -5
View File
@@ -4549,7 +4549,7 @@ Prototipo:
[source,c]
----
int weechat_mkdir_home (const char *directory, int mode);
int weechat_mkdir_home (char *directory, int mode);
----
Argomenti:
@@ -4597,7 +4597,7 @@ Prototipo:
[source,c]
----
int weechat_mkdir (const char *directory, int mode);
int weechat_mkdir (char *directory, int mode);
----
Argomenti:
@@ -4638,7 +4638,7 @@ Prototipo:
[source,c]
----
int weechat_mkdir_parents (const char *directory, int mode);
int weechat_mkdir_parents (char *directory, int mode);
----
Argomenti:
@@ -8011,7 +8011,7 @@ void weechat_config_search_with_string (const char *option_name,
struct t_config_file **config_file,
struct t_config_section **section,
struct t_config_option **option,
const char **pos_option_name);
char **pos_option_name);
----
Argomenti:
@@ -8034,7 +8034,7 @@ Esempio in C:
struct t_config_file *ptr_config_file;
struct t_config_section *ptr_section;
struct t_config_option *ptr_option;
const char *option_name;
char *option_name;
weechat_config_search_with_string ("file.section.option",
&ptr_config_file,
@@ -9967,6 +9967,90 @@ elif rc == weechat.WEECHAT_CONFIG_OPTION_UNSET_ERROR:
# ...
----
// TRANSLATION MISSING
[[themes]]
=== Themes
Functions to contribute color (and other themable option) overrides to
built-in themes. See the
link:weechat_user.it.html#themes[user's guide / Themes] section for the
end-user side and the `+/theme+` command.
==== theme_register
_WeeChat ≥ 4.10.0._
Register a contribution of option overrides under a named theme. The
caller's plugin is the owner of the contribution; subsequent calls
with the same theme name from the same plugin merge into the existing
contribution (later keys win for duplicates).
When the calling plugin is unloaded, all its contributions are
automatically dropped from every theme.
Prototype:
[source,c]
----
struct t_theme *weechat_theme_register (const char *name,
struct t_hashtable *overrides);
----
Arguments:
* _name_: theme name (for example `+light+` or a custom name)
* _overrides_: hashtable mapping full option names
(e.g. `+irc.color.input_nick+`) to their string values; the caller
retains ownership and may free the hashtable right after the call
Return value:
* pointer to the registered theme (existing or newly created), NULL on
error
C example:
[source,c]
----
struct t_hashtable *overrides = weechat_hashtable_new (
8,
WEECHAT_HASHTABLE_STRING,
WEECHAT_HASHTABLE_STRING,
NULL, NULL);
if (overrides)
{
weechat_hashtable_set (overrides, "irc.color.input_nick", "cyan");
weechat_hashtable_set (overrides, "irc.color.topic_old", "darkgray");
weechat_theme_register ("light", overrides);
weechat_hashtable_free (overrides);
}
----
Script (Python):
[source,python]
----
# prototype
def theme_register(name: str, overrides: Dict[str, str]) -> str: ...
# example
weechat.theme_register("light", {
"irc.color.input_nick": "cyan",
"irc.color.topic_old": "darkgray",
})
----
[NOTE]
Only options that have the _themable_ flag will be set by `/theme apply`.
All `*.color.*` options are themable by default; string options that
hold `+${color:...}+` references are explicitly opted in. Entries
targeting non-themable options are silently skipped at apply-time with
a warning logged to the _core_ buffer.
[NOTE]
When called from a script, the contribution is automatically dropped
when the script unloads (no manual cleanup is needed).
[[key_bindings]]
=== Combinazione tasti
+146
View File
@@ -2439,6 +2439,152 @@ Esempio di grassetto con il colore di primo piano del terminale:
/set weechat.color.status_time *99999
----
// TRANSLATION MISSING
[[themes]]
=== Themes
A theme is a named bundle of option overrides that can be applied with
the <<command_weechat_theme,/theme>> command. WeeChat ships a built-in
`"light"` theme tuned for light-background terminals and supports
user-defined themes loaded transiently from files.
[[themes_themable_options]]
==== Themable options
Themes can only set options marked as _themable_. All `*.color.*`
options are themable by default; a few string options that hold format
expressions with `+${color:...}+` references (such as
`+weechat.color.chat_nick_colors+`, `+weechat.look.prefix_error+` or the
`+buflist.format.*+` formats) are explicitly opted in.
You can list the full themable surface area from the
<<command_fset_fset,/fset>> buffer with the `+t:themable+` filter.
[[themes_apply]]
==== Applying a theme
To switch to the built-in light-background theme:
----
/theme apply light
----
The current state of every themable option is saved beforehand to a
backup theme file named like `+backup-YYYYMMDD-HHMMSS-uuuuuu+` in
directory `+themes+` inside the WeeChat configuration directory, so the
previous look can be restored at any time with:
----
/theme apply backup-YYYYMMDD-HHMMSS-uuuuuu
----
Backup creation can be disabled (not recommended):
----
/set weechat.look.theme_backup off
----
If backup is enabled and the backup file cannot be written, the apply
is aborted before any option is changed.
The name of the last applied theme is stored in
`+weechat.look.theme+` (informational only; not re-applied at startup).
[[themes_reset]]
==== Resetting to defaults
To restore the look shipped with WeeChat, reset every themable option
to its default value:
----
/theme reset
----
A backup is written first (same gate as `+/theme apply+`); on backup
failure the reset is aborted before any option is changed.
`+weechat.look.theme+` is cleared too.
[[themes_save_delete]]
==== Saving and deleting user themes
Save the current themable options as a new user theme file:
----
/theme save mytheme
----
Every themable option is written, so the file is self-contained and
applies the exact same look on any WeeChat, regardless of its current
configuration.
Reserved names (built-in theme names like `+light+` and any name
starting with `+backup-+`) are refused. Files live at
`+${weechat_config_dir}/themes/<name>.theme+`.
Rename a user theme (typical use: keep a useful automatic backup
under a meaningful name):
----
/theme rename backup-20260525-094210-123456 mybackup
----
Built-in themes have no file and cannot be renamed; the target name
cannot match a built-in name or start with `+backup-+`, and the
target file must not already exist. The `+[info]+` `+name+` field
inside the file is rewritten so `/theme info` reports the new name
consistently.
Delete a user theme:
----
/theme delete mytheme
----
This removes the file on disk; built-in themes cannot be deleted.
[[themes_file_format]]
==== Theme file format
A theme file is INI-like with two sections:
----
[info]
name = "solarized_light"
description = "Light-background theme inspired by Solarized"
date = "2026-05-25 09:42:10"
weechat = "4.10.0-dev"
[options]
weechat.color.chat = "darkgray"
weechat.color.separator = "blue"
irc.color.input_nick = "magenta"
buflist.format.number = "${color:28}${number}${if:${number_displayed}?.: }"
----
`+[info]+` is informational metadata shown by `/theme info`. `+[options]+`
holds the actual overrides; keys are the full option names that would
appear in `/set`. String values can be enclosed in double or single
quotes; quotes are stripped at parse time. Non-themable options listed
in a theme file are refused at apply time and logged to the core
buffer (so a `.theme` file imported from an untrusted source cannot
overwrite passwords, autoload lists, or startup commands).
User theme files are never cached: on every `/theme apply <name>` the
file is parsed, applied, and freed.
[[themes_resolution]]
==== Resolution order
When `+/theme apply <name>+` is run:
* If `+${weechat_config_dir}/themes/<name>.theme+` exists, the file
is parsed and used (it shadows any built-in with the same name).
* Otherwise the built-in theme registry is consulted; built-ins are
registered programmatically by core, plugins and scripts (see the
plugin and scripting documentation for `+weechat_theme_register+`).
If neither source provides the name, the apply is refused.
[[charset]]
=== Charset
+89 -5
View File
@@ -4477,7 +4477,7 @@ WeeChat ホームディレクトリの下にディレクトリを作成。
[source,c]
----
int weechat_mkdir_home (const char *directory, int mode);
int weechat_mkdir_home (char *directory, int mode);
----
引数:
@@ -4525,7 +4525,7 @@ weechat.mkdir_home("${weechat_cache_dir}/temp", 0755)
[source,c]
----
int weechat_mkdir (const char *directory, int mode);
int weechat_mkdir (char *directory, int mode);
----
引数:
@@ -4566,7 +4566,7 @@ weechat.mkdir("/tmp/mydir", 0755)
[source,c]
----
int weechat_mkdir_parents (const char *directory, int mode);
int weechat_mkdir_parents (char *directory, int mode);
----
引数:
@@ -7816,7 +7816,7 @@ void weechat_config_search_with_string (const char *option_name,
struct t_config_file **config_file,
struct t_config_section **section,
struct t_config_option **option,
const char **pos_option_name);
char **pos_option_name);
----
引数:
@@ -7838,7 +7838,7 @@ C 言語での使用例:
struct t_config_file *ptr_config_file;
struct t_config_section *ptr_section;
struct t_config_option *ptr_option;
const char *option_name;
char *option_name;
weechat_config_search_with_string ("file.section.option",
&ptr_config_file,
@@ -9746,6 +9746,90 @@ elif rc == weechat.WEECHAT_CONFIG_OPTION_UNSET_ERROR:
# ...
----
// TRANSLATION MISSING
[[themes]]
=== Themes
Functions to contribute color (and other themable option) overrides to
built-in themes. See the
link:weechat_user.ja.html#themes[user's guide / Themes] section for the
end-user side and the `+/theme+` command.
==== theme_register
_WeeChat ≥ 4.10.0._
Register a contribution of option overrides under a named theme. The
caller's plugin is the owner of the contribution; subsequent calls
with the same theme name from the same plugin merge into the existing
contribution (later keys win for duplicates).
When the calling plugin is unloaded, all its contributions are
automatically dropped from every theme.
Prototype:
[source,c]
----
struct t_theme *weechat_theme_register (const char *name,
struct t_hashtable *overrides);
----
Arguments:
* _name_: theme name (for example `+light+` or a custom name)
* _overrides_: hashtable mapping full option names
(e.g. `+irc.color.input_nick+`) to their string values; the caller
retains ownership and may free the hashtable right after the call
Return value:
* pointer to the registered theme (existing or newly created), NULL on
error
C example:
[source,c]
----
struct t_hashtable *overrides = weechat_hashtable_new (
8,
WEECHAT_HASHTABLE_STRING,
WEECHAT_HASHTABLE_STRING,
NULL, NULL);
if (overrides)
{
weechat_hashtable_set (overrides, "irc.color.input_nick", "cyan");
weechat_hashtable_set (overrides, "irc.color.topic_old", "darkgray");
weechat_theme_register ("light", overrides);
weechat_hashtable_free (overrides);
}
----
Script (Python):
[source,python]
----
# prototype
def theme_register(name: str, overrides: Dict[str, str]) -> str: ...
# example
weechat.theme_register("light", {
"irc.color.input_nick": "cyan",
"irc.color.topic_old": "darkgray",
})
----
[NOTE]
Only options that have the _themable_ flag will be set by `/theme apply`.
All `*.color.*` options are themable by default; string options that
hold `+${color:...}+` references are explicitly opted in. Entries
targeting non-themable options are silently skipped at apply-time with
a warning logged to the _core_ buffer.
[NOTE]
When called from a script, the contribution is automatically dropped
when the script unloads (no manual cleanup is needed).
[[key_bindings]]
=== キー割り当て
+146
View File
@@ -2375,6 +2375,152 @@ WeeChat は画面に色が表示された時点で色ペアを動的に割り当
/set weechat.color.status_time *99999
----
// TRANSLATION MISSING
[[themes]]
=== Themes
A theme is a named bundle of option overrides that can be applied with
the <<command_weechat_theme,/theme>> command. WeeChat ships a built-in
`"light"` theme tuned for light-background terminals and supports
user-defined themes loaded transiently from files.
[[themes_themable_options]]
==== Themable options
Themes can only set options marked as _themable_. All `*.color.*`
options are themable by default; a few string options that hold format
expressions with `+${color:...}+` references (such as
`+weechat.color.chat_nick_colors+`, `+weechat.look.prefix_error+` or the
`+buflist.format.*+` formats) are explicitly opted in.
You can list the full themable surface area from the
<<command_fset_fset,/fset>> buffer with the `+t:themable+` filter.
[[themes_apply]]
==== Applying a theme
To switch to the built-in light-background theme:
----
/theme apply light
----
The current state of every themable option is saved beforehand to a
backup theme file named like `+backup-YYYYMMDD-HHMMSS-uuuuuu+` in
directory `+themes+` inside the WeeChat configuration directory, so the
previous look can be restored at any time with:
----
/theme apply backup-YYYYMMDD-HHMMSS-uuuuuu
----
Backup creation can be disabled (not recommended):
----
/set weechat.look.theme_backup off
----
If backup is enabled and the backup file cannot be written, the apply
is aborted before any option is changed.
The name of the last applied theme is stored in
`+weechat.look.theme+` (informational only; not re-applied at startup).
[[themes_reset]]
==== Resetting to defaults
To restore the look shipped with WeeChat, reset every themable option
to its default value:
----
/theme reset
----
A backup is written first (same gate as `+/theme apply+`); on backup
failure the reset is aborted before any option is changed.
`+weechat.look.theme+` is cleared too.
[[themes_save_delete]]
==== Saving and deleting user themes
Save the current themable options as a new user theme file:
----
/theme save mytheme
----
Every themable option is written, so the file is self-contained and
applies the exact same look on any WeeChat, regardless of its current
configuration.
Reserved names (built-in theme names like `+light+` and any name
starting with `+backup-+`) are refused. Files live at
`+${weechat_config_dir}/themes/<name>.theme+`.
Rename a user theme (typical use: keep a useful automatic backup
under a meaningful name):
----
/theme rename backup-20260525-094210-123456 mybackup
----
Built-in themes have no file and cannot be renamed; the target name
cannot match a built-in name or start with `+backup-+`, and the
target file must not already exist. The `+[info]+` `+name+` field
inside the file is rewritten so `/theme info` reports the new name
consistently.
Delete a user theme:
----
/theme delete mytheme
----
This removes the file on disk; built-in themes cannot be deleted.
[[themes_file_format]]
==== Theme file format
A theme file is INI-like with two sections:
----
[info]
name = "solarized_light"
description = "Light-background theme inspired by Solarized"
date = "2026-05-25 09:42:10"
weechat = "4.10.0-dev"
[options]
weechat.color.chat = "darkgray"
weechat.color.separator = "blue"
irc.color.input_nick = "magenta"
buflist.format.number = "${color:28}${number}${if:${number_displayed}?.: }"
----
`+[info]+` is informational metadata shown by `/theme info`. `+[options]+`
holds the actual overrides; keys are the full option names that would
appear in `/set`. String values can be enclosed in double or single
quotes; quotes are stripped at parse time. Non-themable options listed
in a theme file are refused at apply time and logged to the core
buffer (so a `.theme` file imported from an untrusted source cannot
overwrite passwords, autoload lists, or startup commands).
User theme files are never cached: on every `/theme apply <name>` the
file is parsed, applied, and freed.
[[themes_resolution]]
==== Resolution order
When `+/theme apply <name>+` is run:
* If `+${weechat_config_dir}/themes/<name>.theme+` exists, the file
is parsed and used (it shadows any built-in with the same name).
* Otherwise the built-in theme registry is consulted; built-ins are
registered programmatically by core, plugins and scripts (see the
plugin and scripting documentation for `+weechat_theme_register+`).
If neither source provides the name, the apply is refused.
[[charset]]
=== Charset
+146
View File
@@ -2191,6 +2191,152 @@ Przykład pogrubienia z domyślnym kolorem terminala:
/set weechat.color.status_time *99999
----
// TRANSLATION MISSING
[[themes]]
=== Motywy
A theme is a named bundle of option overrides that can be applied with
the <<command_weechat_theme,/theme>> command. WeeChat ships a built-in
`"light"` theme tuned for light-background terminals and supports
user-defined themes loaded transiently from files.
[[themes_themable_options]]
==== Themable options
Themes can only set options marked as _themable_. All `*.color.*`
options are themable by default; a few string options that hold format
expressions with `+${color:...}+` references (such as
`+weechat.color.chat_nick_colors+`, `+weechat.look.prefix_error+` or the
`+buflist.format.*+` formats) are explicitly opted in.
You can list the full themable surface area from the
<<command_fset_fset,/fset>> buffer with the `+t:themable+` filter.
[[themes_apply]]
==== Applying a theme
To switch to the built-in light-background theme:
----
/theme apply light
----
The current state of every themable option is saved beforehand to a
backup theme file named like `+backup-YYYYMMDD-HHMMSS-uuuuuu+` in
directory `+themes+` inside the WeeChat configuration directory, so the
previous look can be restored at any time with:
----
/theme apply backup-YYYYMMDD-HHMMSS-uuuuuu
----
Backup creation can be disabled (not recommended):
----
/set weechat.look.theme_backup off
----
If backup is enabled and the backup file cannot be written, the apply
is aborted before any option is changed.
The name of the last applied theme is stored in
`+weechat.look.theme+` (informational only; not re-applied at startup).
[[themes_reset]]
==== Resetting to defaults
To restore the look shipped with WeeChat, reset every themable option
to its default value:
----
/theme reset
----
A backup is written first (same gate as `+/theme apply+`); on backup
failure the reset is aborted before any option is changed.
`+weechat.look.theme+` is cleared too.
[[themes_save_delete]]
==== Saving and deleting user themes
Save the current themable options as a new user theme file:
----
/theme save mytheme
----
Every themable option is written, so the file is self-contained and
applies the exact same look on any WeeChat, regardless of its current
configuration.
Reserved names (built-in theme names like `+light+` and any name
starting with `+backup-+`) are refused. Files live at
`+${weechat_config_dir}/themes/<name>.theme+`.
Rename a user theme (typical use: keep a useful automatic backup
under a meaningful name):
----
/theme rename backup-20260525-094210-123456 mybackup
----
Built-in themes have no file and cannot be renamed; the target name
cannot match a built-in name or start with `+backup-+`, and the
target file must not already exist. The `+[info]+` `+name+` field
inside the file is rewritten so `/theme info` reports the new name
consistently.
Delete a user theme:
----
/theme delete mytheme
----
This removes the file on disk; built-in themes cannot be deleted.
[[themes_file_format]]
==== Theme file format
A theme file is INI-like with two sections:
----
[info]
name = "solarized_light"
description = "Light-background theme inspired by Solarized"
date = "2026-05-25 09:42:10"
weechat = "4.10.0-dev"
[options]
weechat.color.chat = "darkgray"
weechat.color.separator = "blue"
irc.color.input_nick = "magenta"
buflist.format.number = "${color:28}${number}${if:${number_displayed}?.: }"
----
`+[info]+` is informational metadata shown by `/theme info`. `+[options]+`
holds the actual overrides; keys are the full option names that would
appear in `/set`. String values can be enclosed in double or single
quotes; quotes are stripped at parse time. Non-themable options listed
in a theme file are refused at apply time and logged to the core
buffer (so a `.theme` file imported from an untrusted source cannot
overwrite passwords, autoload lists, or startup commands).
User theme files are never cached: on every `/theme apply <name>` the
file is parsed, applied, and freed.
[[themes_resolution]]
==== Resolution order
When `+/theme apply <name>+` is run:
* If `+${weechat_config_dir}/themes/<name>.theme+` exists, the file
is parsed and used (it shadows any built-in with the same name).
* Otherwise the built-in theme registry is consulted; built-ins are
registered programmatically by core, plugins and scripts (see the
plugin and scripting documentation for `+weechat_theme_register+`).
If neither source provides the name, the apply is refused.
[[charset]]
=== Charset
+89 -5
View File
@@ -4209,7 +4209,7 @@ _Ажурирано у верзији 3.2._
[source,c]
----
int weechat_mkdir_home (const char *directory, int mode);
int weechat_mkdir_home (char *directory, int mode);
----
Аргументи:
@@ -4255,7 +4255,7 @@ weechat.mkdir_home("${weechat_cache_dir}/temp", 0755)
[source,c]
----
int weechat_mkdir (const char *directory, int mode);
int weechat_mkdir (char *directory, int mode);
----
Аргументи:
@@ -4296,7 +4296,7 @@ weechat.mkdir("/tmp/mydir", 0755)
[source,c]
----
int weechat_mkdir_parents (const char *directory, int mode);
int weechat_mkdir_parents (char *directory, int mode);
----
Аргументи:
@@ -7492,7 +7492,7 @@ void weechat_config_search_with_string (const char *option_name,
struct t_config_file **config_file,
struct t_config_section **section,
struct t_config_option **option,
const char **pos_option_name);
char **pos_option_name);
----
Аргументи:
@@ -7510,7 +7510,7 @@ C пример:
struct t_config_file *ptr_config_file;
struct t_config_section *ptr_section;
struct t_config_option *ptr_option;
const char *option_name;
char *option_name;
weechat_config_search_with_string ("file.section.option",
&ptr_config_file,
@@ -9436,6 +9436,90 @@ elif rc == weechat.WEECHAT_CONFIG_OPTION_UNSET_ERROR:
# ...
----
// TRANSLATION MISSING
[[themes]]
=== Теме
Functions to contribute color (and other themable option) overrides to
built-in themes. See the
link:weechat_user.sr.html#themes[user's guide / Themes] section for the
end-user side and the `+/theme+` command.
==== theme_register
_WeeChat ≥ 4.10.0._
Register a contribution of option overrides under a named theme. The
caller's plugin is the owner of the contribution; subsequent calls
with the same theme name from the same plugin merge into the existing
contribution (later keys win for duplicates).
When the calling plugin is unloaded, all its contributions are
automatically dropped from every theme.
Prototype:
[source,c]
----
struct t_theme *weechat_theme_register (const char *name,
struct t_hashtable *overrides);
----
Arguments:
* _name_: theme name (for example `+light+` or a custom name)
* _overrides_: hashtable mapping full option names
(e.g. `+irc.color.input_nick+`) to their string values; the caller
retains ownership and may free the hashtable right after the call
Return value:
* pointer to the registered theme (existing or newly created), NULL on
error
C example:
[source,c]
----
struct t_hashtable *overrides = weechat_hashtable_new (
8,
WEECHAT_HASHTABLE_STRING,
WEECHAT_HASHTABLE_STRING,
NULL, NULL);
if (overrides)
{
weechat_hashtable_set (overrides, "irc.color.input_nick", "cyan");
weechat_hashtable_set (overrides, "irc.color.topic_old", "darkgray");
weechat_theme_register ("light", overrides);
weechat_hashtable_free (overrides);
}
----
Script (Python):
[source,python]
----
# prototype
def theme_register(name: str, overrides: Dict[str, str]) -> str: ...
# example
weechat.theme_register("light", {
"irc.color.input_nick": "cyan",
"irc.color.topic_old": "darkgray",
})
----
[NOTE]
Only options that have the _themable_ flag will be set by `/theme apply`.
All `*.color.*` options are themable by default; string options that
hold `+${color:...}+` references are explicitly opted in. Entries
targeting non-themable options are silently skipped at apply-time with
a warning logged to the _core_ buffer.
[NOTE]
When called from a script, the contribution is automatically dropped
when the script unloads (no manual cleanup is needed).
[[key_bindings]]
=== Тастерске пречице
-48
View File
@@ -1181,53 +1181,6 @@ HTTP/1.1 200 OK
]
----
// TRANSLATION MISSING
[[resource_scripts]]
=== Scripts
// TRANSLATION MISSING
Return loaded scripts (all languages).
Крајња тачка:
----
GET /api/scripts
----
Пример захтева:
[source,shell]
----
curl -L -u 'plain:secret_password' 'https://localhost:9000/api/scripts'
----
Одговор:
[source,http]
----
HTTP/1.1 200 OK
----
[source,json]
----
[
{
"name": "highmon.pl",
"version": "2.7",
"description": "Highlight Monitor",
"author": "KenjiE20",
"license": "GPL3"
},
{
"name": "go.py",
"version": "3.1.1",
"description": "Quick jump to buffers",
"author": "Sébastien Helleu <flashcode@flashtux.org>",
"license": "GPL3"
}
]
----
[[resource_input]]
=== Input
@@ -1557,7 +1510,6 @@ GUID `258EAFA5-E914-47DA-95CA-C5AB0DC85B11` (SHA-1 се кодира у base64).
* `nick_group` (објекат)
* `nick` (објекат)
* `hotlist` (објекат)
* `scripts` (низ)
* `ping` (објекат)
[TIP]
+146
View File
@@ -2093,6 +2093,152 @@ include::{autogendir}/autogen_user_options.sr.adoc[tag=fset_options]
/set weechat.color.status_time *99999
----
// TRANSLATION MISSING
[[themes]]
=== Теме
A theme is a named bundle of option overrides that can be applied with
the <<command_weechat_theme,/theme>> command. WeeChat ships a built-in
`"light"` theme tuned for light-background terminals and supports
user-defined themes loaded transiently from files.
[[themes_themable_options]]
==== Themable options
Themes can only set options marked as _themable_. All `*.color.*`
options are themable by default; a few string options that hold format
expressions with `+${color:...}+` references (such as
`+weechat.color.chat_nick_colors+`, `+weechat.look.prefix_error+` or the
`+buflist.format.*+` formats) are explicitly opted in.
You can list the full themable surface area from the
<<command_fset_fset,/fset>> buffer with the `+t:themable+` filter.
[[themes_apply]]
==== Applying a theme
To switch to the built-in light-background theme:
----
/theme apply light
----
The current state of every themable option is saved beforehand to a
backup theme file named like `+backup-YYYYMMDD-HHMMSS-uuuuuu+` in
directory `+themes+` inside the WeeChat configuration directory, so the
previous look can be restored at any time with:
----
/theme apply backup-YYYYMMDD-HHMMSS-uuuuuu
----
Backup creation can be disabled (not recommended):
----
/set weechat.look.theme_backup off
----
If backup is enabled and the backup file cannot be written, the apply
is aborted before any option is changed.
The name of the last applied theme is stored in
`+weechat.look.theme+` (informational only; not re-applied at startup).
[[themes_reset]]
==== Resetting to defaults
To restore the look shipped with WeeChat, reset every themable option
to its default value:
----
/theme reset
----
A backup is written first (same gate as `+/theme apply+`); on backup
failure the reset is aborted before any option is changed.
`+weechat.look.theme+` is cleared too.
[[themes_save_delete]]
==== Saving and deleting user themes
Save the current themable options as a new user theme file:
----
/theme save mytheme
----
Every themable option is written, so the file is self-contained and
applies the exact same look on any WeeChat, regardless of its current
configuration.
Reserved names (built-in theme names like `+light+` and any name
starting with `+backup-+`) are refused. Files live at
`+${weechat_config_dir}/themes/<name>.theme+`.
Rename a user theme (typical use: keep a useful automatic backup
under a meaningful name):
----
/theme rename backup-20260525-094210-123456 mybackup
----
Built-in themes have no file and cannot be renamed; the target name
cannot match a built-in name or start with `+backup-+`, and the
target file must not already exist. The `+[info]+` `+name+` field
inside the file is rewritten so `/theme info` reports the new name
consistently.
Delete a user theme:
----
/theme delete mytheme
----
This removes the file on disk; built-in themes cannot be deleted.
[[themes_file_format]]
==== Theme file format
A theme file is INI-like with two sections:
----
[info]
name = "solarized_light"
description = "Light-background theme inspired by Solarized"
date = "2026-05-25 09:42:10"
weechat = "4.10.0-dev"
[options]
weechat.color.chat = "darkgray"
weechat.color.separator = "blue"
irc.color.input_nick = "magenta"
buflist.format.number = "${color:28}${number}${if:${number_displayed}?.: }"
----
`+[info]+` is informational metadata shown by `/theme info`. `+[options]+`
holds the actual overrides; keys are the full option names that would
appear in `/set`. String values can be enclosed in double or single
quotes; quotes are stripped at parse time. Non-themable options listed
in a theme file are refused at apply time and logged to the core
buffer (so a `.theme` file imported from an untrusted source cannot
overwrite passwords, autoload lists, or startup commands).
User theme files are never cached: on every `/theme apply <name>` the
file is parsed, applied, and freed.
[[themes_resolution]]
==== Resolution order
When `+/theme apply <name>+` is run:
* If `+${weechat_config_dir}/themes/<name>.theme+` exists, the file
is parsed and used (it shadows any built-in with the same name).
* Otherwise the built-in theme registry is consulted; built-ins are
registered programmatically by core, plugins and scripts (see the
plugin and scripting documentation for `+weechat_theme_register+`).
If neither source provides the name, the apply is refused.
[[charset]]
=== Charset
+1 -5
View File
@@ -23,7 +23,7 @@ msgid ""
msgstr ""
"Project-Id-Version: WeeChat\n"
"Report-Msgid-Bugs-To: flashcode@flashtux.org\n"
"POT-Creation-Date: 2026-06-08 22:23+0200\n"
"POT-Creation-Date: 2026-05-30 14:00+0200\n"
"PO-Revision-Date: 2026-05-30 14:01+0200\n"
"Last-Translator: Ondřej Súkup <mimi.vx@gmail.com>\n"
"Language-Team: Czech <weechat-dev@nongnu.org>\n"
@@ -16068,10 +16068,6 @@ msgstr "načteny %s skripty:"
msgid "script name with extension"
msgstr "seznam skriptů"
#, fuzzy
msgid "comma-separated list of plugin:extension with supported languages"
msgstr "čárkami oddělený seznam slovníků, které použít pro tento buffer"
#, fuzzy
msgid "script name with extension (wildcard \"*\" is allowed) (optional)"
msgstr "jméno serveru (zástupný znak \"*\" je povolen) (volitelné)"
+2 -7
View File
@@ -29,8 +29,8 @@ msgid ""
msgstr ""
"Project-Id-Version: WeeChat\n"
"Report-Msgid-Bugs-To: flashcode@flashtux.org\n"
"POT-Creation-Date: 2026-06-08 22:23+0200\n"
"PO-Revision-Date: 2026-06-09 10:41+0200\n"
"POT-Creation-Date: 2026-05-30 14:00+0200\n"
"PO-Revision-Date: 2026-05-30 14:01+0200\n"
"Last-Translator: Nils Görs <weechatter@arcor.de>\n"
"Language-Team: German - Germany <weechat-dev@nongnu.org>\n"
"Language: de\n"
@@ -17510,11 +17510,6 @@ msgstr "1 falls Skript geladen wurde"
msgid "script name with extension"
msgstr "Skriptname mit Erweiterung"
msgid "comma-separated list of plugin:extension with supported languages"
msgstr ""
"durch Kommata getrennte Liste von Erweiterungen: Endung mit unterstützen "
"Sprachen"
msgid "script name with extension (wildcard \"*\" is allowed) (optional)"
msgstr ""
"Name des Skriptes, mit Dateierweiterung (Platzhalter \"*\" kann verwendet "
+1 -6
View File
@@ -24,7 +24,7 @@ msgid ""
msgstr ""
"Project-Id-Version: WeeChat\n"
"Report-Msgid-Bugs-To: flashcode@flashtux.org\n"
"POT-Creation-Date: 2026-06-08 22:23+0200\n"
"POT-Creation-Date: 2026-05-30 14:00+0200\n"
"PO-Revision-Date: 2026-05-30 14:01+0200\n"
"Last-Translator: Santiago Forero <santiago@forero.xyz>\n"
"Language-Team: Spanish - Spain <weechat-dev@nongnu.org>\n"
@@ -16346,11 +16346,6 @@ msgstr "scripts en %s cargados:"
msgid "script name with extension"
msgstr "lista de scripts"
#, fuzzy
#| msgid "comma separated list of file name extensions for plugins"
msgid "comma-separated list of plugin:extension with supported languages"
msgstr "lista separada por comas de extensiones de archivo para plugins"
#, fuzzy
msgid "script name with extension (wildcard \"*\" is allowed) (optional)"
msgstr ""
+2 -5
View File
@@ -23,8 +23,8 @@ msgid ""
msgstr ""
"Project-Id-Version: WeeChat\n"
"Report-Msgid-Bugs-To: flashcode@flashtux.org\n"
"POT-Creation-Date: 2026-06-08 22:23+0200\n"
"PO-Revision-Date: 2026-06-08 23:14+0200\n"
"POT-Creation-Date: 2026-05-30 14:00+0200\n"
"PO-Revision-Date: 2026-05-30 14:01+0200\n"
"Last-Translator: Sébastien Helleu <flashcode@flashtux.org>\n"
"Language-Team: French - France <weechat-dev@nongnu.org>\n"
"Language: fr\n"
@@ -17182,9 +17182,6 @@ msgstr "1 si le script est chargé"
msgid "script name with extension"
msgstr "nom du script avec l'extension"
msgid "comma-separated list of plugin:extension with supported languages"
msgstr "liste de extension:extension_fichier avec les langages supportés"
msgid "script name with extension (wildcard \"*\" is allowed) (optional)"
msgstr ""
"nom du script avec extension (le caractère joker \"*\" est autorisé) "
+1 -4
View File
@@ -22,7 +22,7 @@ msgid ""
msgstr ""
"Project-Id-Version: WeeChat\n"
"Report-Msgid-Bugs-To: flashcode@flashtux.org\n"
"POT-Creation-Date: 2026-06-08 22:23+0200\n"
"POT-Creation-Date: 2026-05-30 14:00+0200\n"
"PO-Revision-Date: 2026-03-08 08:59+0100\n"
"Last-Translator: Andras Voroskoi <voroskoi@frugalware.org>\n"
"Language-Team: Hungarian <weechat-dev@nongnu.org>\n"
@@ -15314,9 +15314,6 @@ msgstr "FIFO cső bezárva\n"
msgid "script name with extension"
msgstr "Aliaszok listája:\n"
msgid "comma-separated list of plugin:extension with supported languages"
msgstr ""
msgid "script name with extension (wildcard \"*\" is allowed) (optional)"
msgstr ""
+1 -6
View File
@@ -22,7 +22,7 @@ msgid ""
msgstr ""
"Project-Id-Version: WeeChat\n"
"Report-Msgid-Bugs-To: flashcode@flashtux.org\n"
"POT-Creation-Date: 2026-06-08 22:23+0200\n"
"POT-Creation-Date: 2026-05-30 14:00+0200\n"
"PO-Revision-Date: 2026-05-30 14:02+0200\n"
"Last-Translator: Esteban I. Ruiz Moreno <exio4.com@gmail.com>\n"
"Language-Team: Italian <weechat-dev@nongnu.org>\n"
@@ -16432,11 +16432,6 @@ msgstr "script %s caricati:"
msgid "script name with extension"
msgstr "elenco degli script"
#, fuzzy
#| msgid "comma separated list of file name extensions for plugins"
msgid "comma-separated list of plugin:extension with supported languages"
msgstr "elenco separato da virgole di estensioni dei nomi file per i plugin"
#, fuzzy
msgid "script name with extension (wildcard \"*\" is allowed) (optional)"
msgstr ""
+1 -6
View File
@@ -22,7 +22,7 @@ msgid ""
msgstr ""
"Project-Id-Version: WeeChat\n"
"Report-Msgid-Bugs-To: flashcode@flashtux.org\n"
"POT-Creation-Date: 2026-06-08 22:23+0200\n"
"POT-Creation-Date: 2026-05-30 14:00+0200\n"
"PO-Revision-Date: 2026-05-30 14:02+0200\n"
"Last-Translator: AYANOKOUZI, Ryuunosuke <i38w7i3@yahoo.co.jp>\n"
"Language-Team: Japanese <weechat-dev@nongnu.org>\n"
@@ -16996,11 +16996,6 @@ msgstr "ロードされた %s スクリプト:"
msgid "script name with extension"
msgstr "スクリプトの拡張子のリスト"
#, fuzzy
#| msgid "comma separated list of file name extensions for plugins"
msgid "comma-separated list of plugin:extension with supported languages"
msgstr "プラグインのファイル拡張子のコンマ区切りリスト"
msgid "script name with extension (wildcard \"*\" is allowed) (optional)"
msgstr ""
"拡張子を含めたスクリプト名 (ワイルドカード \"*\" を使うことができます) (任意)"
+1 -6
View File
@@ -24,7 +24,7 @@ msgid ""
msgstr ""
"Project-Id-Version: WeeChat\n"
"Report-Msgid-Bugs-To: flashcode@flashtux.org\n"
"POT-Creation-Date: 2026-06-08 22:23+0200\n"
"POT-Creation-Date: 2026-05-30 14:00+0200\n"
"PO-Revision-Date: 2026-05-30 14:02+0200\n"
"Last-Translator: Krzysztof Korościk <soltys@soltys.info>\n"
"Language-Team: Polish <weechat-dev@nongnu.org>\n"
@@ -16747,11 +16747,6 @@ msgstr "1 jeśli skrypt jest załadowany"
msgid "script name with extension"
msgstr "nazwa skryptu z rozszerzeniem"
#, fuzzy
#| msgid "comma separated list of file name extensions for plugins"
msgid "comma-separated list of plugin:extension with supported languages"
msgstr "oddzielona przecinkami lista rozszerzeń nazw plików dla wtyczek"
msgid "script name with extension (wildcard \"*\" is allowed) (optional)"
msgstr ""
"nazwa skryptu z rozszerzeniem (wildcard \"*\" jest dozwolony) (opcjonalne)\""
+1 -6
View File
@@ -22,7 +22,7 @@ msgid ""
msgstr ""
"Project-Id-Version: WeeChat\n"
"Report-Msgid-Bugs-To: flashcode@flashtux.org\n"
"POT-Creation-Date: 2026-06-08 22:23+0200\n"
"POT-Creation-Date: 2026-05-30 14:00+0200\n"
"PO-Revision-Date: 2026-05-30 14:02+0200\n"
"Last-Translator: Vasco Almeida <vascomalmeida@sapo.pt>\n"
"Language-Team: Portuguese - Portugal <weechat-dev@nongnu.org>\n"
@@ -16869,11 +16869,6 @@ msgstr "scripts %s carregados:"
msgid "script name with extension"
msgstr "lista de extensões de script"
#, fuzzy
#| msgid "comma separated list of file name extensions for plugins"
msgid "comma-separated list of plugin:extension with supported languages"
msgstr "lista de extensões de ficheiros separadas por vírgula para os plugins"
msgid "script name with extension (wildcard \"*\" is allowed) (optional)"
msgstr ""
"nome do script com extensão (o caráter universal \"*\" é permitido) "
+1 -5
View File
@@ -46,7 +46,7 @@ msgid ""
msgstr ""
"Project-Id-Version: WeeChat\n"
"Report-Msgid-Bugs-To: flashcode@flashtux.org\n"
"POT-Creation-Date: 2026-06-08 22:23+0200\n"
"POT-Creation-Date: 2026-05-30 14:00+0200\n"
"PO-Revision-Date: 2026-05-30 14:02+0200\n"
"Last-Translator: Érico Nogueira <ericonr@disroot.org>\n"
"Language-Team: Portuguese - Brazil <weechat-dev@nongnu.org>\n"
@@ -15838,10 +15838,6 @@ msgstr "scripts %s carregados:"
msgid "script name with extension"
msgstr "list de scripts"
#, fuzzy
msgid "comma-separated list of plugin:extension with supported languages"
msgstr "lista de dicionários (separados por vírgula) para uso neste buffer"
#, fuzzy
msgid "script name with extension (wildcard \"*\" is allowed) (optional)"
msgstr ""
+1 -4
View File
@@ -23,7 +23,7 @@ msgid ""
msgstr ""
"Project-Id-Version: WeeChat\n"
"Report-Msgid-Bugs-To: flashcode@flashtux.org\n"
"POT-Creation-Date: 2026-06-08 22:23+0200\n"
"POT-Creation-Date: 2026-05-30 14:00+0200\n"
"PO-Revision-Date: 2026-03-08 08:59+0100\n"
"Last-Translator: Aleksey V Zapparov AKA ixti <ixti@member.fsf.org>\n"
"Language-Team: Russian <weechat-dev@nongnu.org>\n"
@@ -15367,9 +15367,6 @@ msgstr "FIFO pipe закрыт\n"
msgid "script name with extension"
msgstr "Список сокращений:\n"
msgid "comma-separated list of plugin:extension with supported languages"
msgstr ""
msgid "script name with extension (wildcard \"*\" is allowed) (optional)"
msgstr ""
+1 -6
View File
@@ -22,7 +22,7 @@ msgid ""
msgstr ""
"Project-Id-Version: WeeChat\n"
"Report-Msgid-Bugs-To: flashcode@flashtux.org\n"
"POT-Creation-Date: 2026-06-08 22:23+0200\n"
"POT-Creation-Date: 2026-05-30 14:00+0200\n"
"PO-Revision-Date: 2026-05-30 14:02+0200\n"
"Last-Translator: Ivan Pešić <ivan.pesic@gmail.com>\n"
"Language-Team: Serbian <weechat-dev@nongnu.org>\n"
@@ -16695,11 +16695,6 @@ msgstr "1 ако је скрипта учитана"
msgid "script name with extension"
msgstr "име скрипте са екстензијом"
#, fuzzy
#| msgid "comma separated list of file name extensions for plugins"
msgid "comma-separated list of plugin:extension with supported languages"
msgstr "листа екстензија имена фајлова за додатке раздвојених запетама"
msgid "script name with extension (wildcard \"*\" is allowed) (optional)"
msgstr "име скрипте са екстензијом (дозвољен је џокер „*”) (није обавезно)"
+1 -6
View File
@@ -23,7 +23,7 @@ msgid ""
msgstr ""
"Project-Id-Version: WeeChat\n"
"Report-Msgid-Bugs-To: flashcode@flashtux.org\n"
"POT-Creation-Date: 2026-06-08 22:23+0200\n"
"POT-Creation-Date: 2026-05-30 14:00+0200\n"
"PO-Revision-Date: 2026-05-30 14:02+0200\n"
"Last-Translator: Emir SARI <emir_sari@icloud.com>\n"
"Language-Team: Turkish <weechat-dev@nongnu.org>\n"
@@ -17120,11 +17120,6 @@ msgstr "Hiçbir betik yüklenmedi"
msgid "script name with extension"
msgstr "betik uzantılarının listesi"
#, fuzzy
#| msgid "comma separated list of file name extensions for plugins"
msgid "comma-separated list of plugin:extension with supported languages"
msgstr "eklentiler için dosya adı uzantılarının virgülle ayrılmış listesi"
msgid "script name with extension (wildcard \"*\" is allowed) (optional)"
msgstr "betik adı, uzantı ile (\"*\" jokerine izin verilir) (isteğe bağlı)"
+1 -4
View File
@@ -23,7 +23,7 @@ msgid ""
msgstr ""
"Project-Id-Version: WeeChat\n"
"Report-Msgid-Bugs-To: flashcode@flashtux.org\n"
"POT-Creation-Date: 2026-06-08 22:23+0200\n"
"POT-Creation-Date: 2026-05-30 14:00+0200\n"
"PO-Revision-Date: 2014-08-16 10:27+0200\n"
"Last-Translator: Sébastien Helleu <flashcode@flashtux.org>\n"
"Language-Team: weechat-dev <weechat-dev@nongnu.org>\n"
@@ -14018,9 +14018,6 @@ msgstr ""
msgid "script name with extension"
msgstr ""
msgid "comma-separated list of plugin:extension with supported languages"
msgstr ""
msgid "script name with extension (wildcard \"*\" is allowed) (optional)"
msgstr ""
+2
View File
@@ -51,6 +51,8 @@ set(LIB_CORE_SRC
core-signal.c core-signal.h
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
+304
View File
@@ -68,6 +68,7 @@
#include "core-signal.h"
#include "core-string.h"
#include "core-sys.h"
#include "core-theme.h"
#include "core-upgrade.h"
#include "core-url.h"
#include "core-utf8.h"
@@ -7180,6 +7181,250 @@ COMMAND_CALLBACK(sys)
COMMAND_ERROR;
}
/*
* Callback for "dir_exec_on_files": collects names of files matching
* "*.theme" into an arraylist passed as data; "backup-*.theme" is
* excluded when *(int *)data->show_backups is zero.
*
* The arraylist is iterated outside this callback so all dirent
* processing can happen in one place.
*/
struct t_command_theme_dir_collect
{
struct t_arraylist *names; /* arraylist of char * (owned) */
int show_backups; /* include backup-*.theme ? */
};
void
command_theme_collect_file_cb (void *data, const char *filename)
{
struct t_command_theme_dir_collect *ctx;
const char *base;
char *name;
size_t len;
ctx = (struct t_command_theme_dir_collect *)data;
base = strrchr (filename, '/');
base = (base) ? base + 1 : filename;
len = strlen (base);
if ((len < 7) || (strcmp (base + len - 6, ".theme") != 0))
return;
if (!ctx->show_backups && (strncmp (base, "backup-", 7) == 0))
return;
name = string_strndup (base, len - 6);
if (name)
arraylist_add (ctx->names, name);
}
int
command_theme_strcmp_cb (void *data, struct t_arraylist *arraylist,
void *pointer1, void *pointer2)
{
/* make C compiler happy */
(void) data;
(void) arraylist;
return strcmp ((const char *)pointer1, (const char *)pointer2);
}
/*
* Callback for command "/theme": list or display details on themes.
*/
COMMAND_CALLBACK(theme)
{
struct t_arraylist *list, *file_names;
struct t_command_theme_dir_collect collect;
struct t_theme *ptr_theme, *file_theme;
const char *ptr_active, *ptr_name;
char *path, *dir;
int i, size, show_backups;
/* make C compiler happy */
(void) pointer;
(void) data;
(void) buffer;
(void) argv_eol;
/* "/theme" or "/theme list [-backups]": list themes */
if ((argc == 1) || (string_strcmp (argv[1], "list") == 0))
{
show_backups = ((argc >= 3)
&& (string_strcmp (argv[2], "-backups") == 0));
ptr_active = CONFIG_STRING(config_look_theme);
list = theme_list ();
/* scan ${weechat_config_dir}/themes/ for *.theme files */
file_names = arraylist_new (8, 1, 0,
&command_theme_strcmp_cb, NULL,
NULL, NULL);
if (file_names)
{
dir = NULL;
string_asprintf (&dir, "%s/themes", weechat_config_dir);
if (dir)
{
collect.names = file_names;
collect.show_backups = show_backups;
dir_exec_on_files (dir, 0, 0,
&command_theme_collect_file_cb,
&collect);
free (dir);
}
}
if ((!list || (arraylist_size (list) == 0))
&& (!file_names || (arraylist_size (file_names) == 0)))
{
gui_chat_printf (NULL, _("No theme available"));
arraylist_free (list);
arraylist_free (file_names);
return WEECHAT_RC_OK;
}
gui_chat_printf (NULL, "");
gui_chat_printf (NULL, _("Themes:"));
size = (list) ? arraylist_size (list) : 0;
for (i = 0; i < size; i++)
{
ptr_theme = (struct t_theme *)arraylist_get (list, i);
gui_chat_printf (
NULL,
" %s %s%s%s%s%s",
(ptr_active && (strcmp (ptr_active, ptr_theme->name) == 0))
? "->" : " ",
GUI_COLOR(GUI_COLOR_CHAT_BUFFER),
ptr_theme->name,
GUI_COLOR(GUI_COLOR_CHAT_DELIMITERS),
(ptr_theme->description && ptr_theme->description[0])
? ": " : "",
(ptr_theme->description) ? ptr_theme->description : "");
}
size = (file_names) ? arraylist_size (file_names) : 0;
for (i = 0; i < size; i++)
{
ptr_name = (const char *)arraylist_get (file_names, i);
gui_chat_printf (
NULL,
" %s %s%s%s (file)",
(ptr_active && (strcmp (ptr_active, ptr_name) == 0))
? "->" : " ",
GUI_COLOR(GUI_COLOR_CHAT_BUFFER),
ptr_name,
GUI_COLOR(GUI_COLOR_CHAT));
}
if (file_names)
{
size = arraylist_size (file_names);
for (i = 0; i < size; i++)
free (arraylist_get (file_names, i));
arraylist_free (file_names);
}
arraylist_free (list);
return WEECHAT_RC_OK;
}
/* "/theme apply <name>": apply a theme */
if (string_strcmp (argv[1], "apply") == 0)
{
COMMAND_MIN_ARGS(3, "apply");
return theme_apply (argv[2]);
}
/* "/theme reset": reset every themable option to its default value */
if (string_strcmp (argv[1], "reset") == 0)
{
return theme_reset ();
}
/* "/theme save <name>": write a user theme file */
if (string_strcmp (argv[1], "save") == 0)
{
COMMAND_MIN_ARGS(3, "save");
return theme_save (argv[2]);
}
/* "/theme rename <old> <new>": rename a user theme file */
if (string_strcmp (argv[1], "rename") == 0)
{
COMMAND_MIN_ARGS(4, "rename");
return theme_rename (argv[2], argv[3]);
}
/* "/theme delete <name>": remove a user theme file */
if (string_strcmp (argv[1], "delete") == 0)
{
COMMAND_MIN_ARGS(3, "delete");
return theme_delete (argv[2]);
}
/* "/theme info <name>": show details about a theme */
if (string_strcmp (argv[1], "info") == 0)
{
COMMAND_MIN_ARGS(3, "info");
/* file shadows registry: try user file first */
path = theme_user_file_path (argv[2]);
file_theme = NULL;
if (path && (access (path, R_OK) == 0))
file_theme = theme_file_parse (path);
if (!file_theme)
{
free (path);
path = NULL;
ptr_theme = theme_search (argv[2]);
if (!ptr_theme)
{
gui_chat_printf (NULL,
_("%sTheme \"%s\" not found"),
gui_chat_prefix[GUI_CHAT_PREFIX_ERROR],
argv[2]);
return WEECHAT_RC_ERROR;
}
}
else
{
ptr_theme = file_theme;
}
gui_chat_printf (NULL, "");
gui_chat_printf (NULL,
_("Theme \"%s%s%s\":"),
GUI_COLOR(GUI_COLOR_CHAT_BUFFER),
(ptr_theme->name && ptr_theme->name[0])
? ptr_theme->name : argv[2],
GUI_COLOR(GUI_COLOR_CHAT));
if (path)
{
gui_chat_printf (NULL,
_(" source : %s"), path);
}
else
{
gui_chat_printf (NULL,
_(" source : built-in (in-memory)"));
}
gui_chat_printf (NULL,
_(" description : %s"),
(ptr_theme->description) ? ptr_theme->description : "");
gui_chat_printf (NULL,
_(" date : %s"),
(ptr_theme->date) ? ptr_theme->date : "");
gui_chat_printf (NULL,
_(" WeeChat version: %s"),
(ptr_theme->weechat_version)
? ptr_theme->weechat_version : "");
gui_chat_printf (NULL,
_(" overrides : %d"),
theme_overrides_count (ptr_theme));
free (path);
theme_free (file_theme);
return WEECHAT_RC_OK;
}
COMMAND_ERROR;
}
/*
* Callback for command "/toggle": toggle value of configuration option.
*/
@@ -9832,6 +10077,65 @@ command_init (void)
" || suspend"
" || waitpid 1|10|100|1000",
&command_sys, NULL, NULL);
hook_command (
NULL, "theme",
N_("manage color themes"),
/* TRANSLATORS: only text between angle brackets (eg: "<name>") may be translated */
N_("[list [-backups]]"
" || apply <name>"
" || reset"
" || save <name>"
" || rename <old> <new>"
" || delete <name>"
" || info <name>"),
CMD_ARGS_DESC(
N_("raw[list]: list registered themes and any *.theme files in "
"the WeeChat configuration directory; the active theme "
"(matching weechat.look.theme) is marked with \"->\". By "
"default backup-*.theme files are hidden; pass \"-backups\" "
"to include them"),
N_("raw[apply]: apply a theme (set every themable option to the "
"value from the theme); if a file named <name>.theme "
"exists in directory \"themes\" it shadows any built-in "
"theme of the same name"),
N_("raw[reset]: reset every themable option to its default "
"value (restores the original look shipped with WeeChat)"),
N_("raw[save]: save current themable options to a file "
"<name>.theme in directory \"themes\"; every themable "
"option is written, so the file is self-contained; the "
"name must not match a built-in theme or start with "
"\"backup-\""),
N_("raw[rename]: rename a user theme file (typically to "
"give an automatic backup a meaningful name); refuses to "
"rename built-in themes, refuses target names matching a "
"built-in or starting with \"backup-\", and refuses if "
"the target file already exists"),
N_("raw[delete]: delete a user theme file (refuses to delete "
"built-in themes, which have no file)"),
N_("raw[info]: display details on a theme (name, description, "
"creation date, WeeChat version, number of option overrides)"),
N_("name: name of a theme"),
"",
N_("Themes are named bundles of color (and other themable) "
"option overrides. Built-in themes are registered in memory "
"by core/plugins/scripts; user themes are read from files "
"in directory \"themes\" inside the WeeChat configuration "
"directory."),
"",
N_("By default, /theme apply creates a backup of current "
"themable values in directory \"themes\" before applying "
"(file name: \"backup-<timestamp>.theme\"); the previous "
"state can be restored with: /theme apply "
"backup-<timestamp>. This is controlled by the option "
"weechat.look.theme_backup.")),
"list -backups"
" || apply %(theme_themes_all)"
" || reset"
" || save %(theme_themes_user)"
" || rename %(theme_themes_files)"
" || delete %(theme_themes_user)"
" || info %(theme_themes_all)",
&command_theme, NULL, NULL);
hook_command (
NULL, "toggle",
N_("toggle value of a config option"),
+156
View File
@@ -46,6 +46,7 @@
#include "core-proxy.h"
#include "core-secure.h"
#include "core-string.h"
#include "core-theme.h"
#include "../gui/gui-completion.h"
#include "../gui/gui-bar.h"
#include "../gui/gui-bar-item.h"
@@ -1974,6 +1975,151 @@ completion_list_add_layouts_names_cb (const void *pointer, void *data,
return WEECHAT_RC_OK;
}
/*
* Add filename (without ".theme" suffix) to completion list if it ends
* with ".theme"; skips "backup-*.theme" entries unless data is non-NULL.
*
* Callback for dir_exec_on_files; "data" carries a pair of pointers:
* data[0] = struct t_gui_completion *completion (target)
* data[1] = int *show_backups
*/
struct t_completion_theme_dir
{
struct t_gui_completion *completion;
int show_backups;
};
void
completion_theme_add_file_cb (void *data, const char *filename)
{
struct t_completion_theme_dir *ctx;
const char *base;
char *name;
size_t len;
ctx = (struct t_completion_theme_dir *)data;
base = strrchr (filename, '/');
base = (base) ? base + 1 : filename;
len = strlen (base);
if ((len < 7) || (strcmp (base + len - 6, ".theme") != 0))
return;
if (!ctx->show_backups && (strncmp (base, "backup-", 7) == 0))
return;
name = string_strndup (base, len - 6);
if (!name)
return;
gui_completion_list_add (ctx->completion, name, 0, WEECHAT_LIST_POS_SORT);
free (name);
}
/*
* Add theme names to completion list: in-memory built-ins plus any
* "*.theme" files in <weechat_config_dir>/themes/ (including backups).
*/
int
completion_list_add_theme_themes_all_cb (const void *pointer, void *data,
const char *completion_item,
struct t_gui_buffer *buffer,
struct t_gui_completion *completion)
{
struct t_theme *ptr_theme;
struct t_completion_theme_dir ctx;
char *dir;
/* make C compiler happy */
(void) pointer;
(void) data;
(void) completion_item;
(void) buffer;
for (ptr_theme = themes; ptr_theme; ptr_theme = ptr_theme->next_theme)
{
gui_completion_list_add (completion, ptr_theme->name,
0, WEECHAT_LIST_POS_SORT);
}
dir = NULL;
string_asprintf (&dir, "%s/themes", weechat_config_dir);
if (dir)
{
ctx.completion = completion;
ctx.show_backups = 1;
dir_exec_on_files (dir, 0, 0, &completion_theme_add_file_cb, &ctx);
free (dir);
}
return WEECHAT_RC_OK;
}
/*
* Add user theme file names (excluding built-ins and backups) to the
* completion list; suitable for /theme save and /theme delete.
*/
int
completion_list_add_theme_themes_user_cb (const void *pointer, void *data,
const char *completion_item,
struct t_gui_buffer *buffer,
struct t_gui_completion *completion)
{
struct t_completion_theme_dir ctx;
char *dir;
/* make C compiler happy */
(void) pointer;
(void) data;
(void) completion_item;
(void) buffer;
dir = NULL;
string_asprintf (&dir, "%s/themes", weechat_config_dir);
if (dir)
{
ctx.completion = completion;
ctx.show_backups = 0;
dir_exec_on_files (dir, 0, 0, &completion_theme_add_file_cb, &ctx);
free (dir);
}
return WEECHAT_RC_OK;
}
/*
* Add every on-disk theme file (user files + backups, no built-ins)
* to the completion list; suitable for /theme rename which can take a
* backup as its source.
*/
int
completion_list_add_theme_themes_files_cb (const void *pointer, void *data,
const char *completion_item,
struct t_gui_buffer *buffer,
struct t_gui_completion *completion)
{
struct t_completion_theme_dir ctx;
char *dir;
/* make C compiler happy */
(void) pointer;
(void) data;
(void) completion_item;
(void) buffer;
dir = NULL;
string_asprintf (&dir, "%s/themes", weechat_config_dir);
if (dir)
{
ctx.completion = completion;
ctx.show_backups = 1;
dir_exec_on_files (dir, 0, 0, &completion_theme_add_file_cb, &ctx);
free (dir);
}
return WEECHAT_RC_OK;
}
/*
* Add a secured data to completion list.
*/
@@ -2365,6 +2511,16 @@ completion_init (void)
hook_completion (NULL, "layouts_names",
N_("names of layouts"),
&completion_list_add_layouts_names_cb, NULL, NULL);
hook_completion (NULL, "theme_themes_all",
N_("names of themes (built-ins + user files + backups)"),
&completion_list_add_theme_themes_all_cb, NULL, NULL);
hook_completion (NULL, "theme_themes_user",
N_("names of user theme files (excludes built-ins and backups)"),
&completion_list_add_theme_themes_user_cb, NULL, NULL);
hook_completion (NULL, "theme_themes_files",
N_("names of theme files on disk (user files + backups, "
"no built-ins)"),
&completion_list_add_theme_themes_files_cb, NULL, NULL);
hook_completion (NULL, "secured_data",
N_("names of secured data (file sec.conf, section data)"),
&completion_list_add_secured_data_cb, NULL, NULL);
+41 -9
View File
@@ -648,6 +648,7 @@ config_file_option_malloc (void)
new_option->name = NULL;
new_option->parent_name = NULL;
new_option->type = 0;
new_option->themable = 0;
new_option->description = NULL;
new_option->string_values = NULL;
new_option->min = 0;
@@ -704,17 +705,37 @@ config_file_new_option (struct t_config_file *config_file,
void *callback_delete_data)
{
struct t_config_option *new_option;
int var_type, int_value, argc, i, index_value, number;
const char *pos;
char *option_name, *parent_name;
int var_type, int_value, argc, i, index_value, number, themable;
char *pos, *option_name, *parent_name, *type_name;
const char *ptr_type;
new_option = NULL;
option_name = NULL;
parent_name = NULL;
type_name = NULL;
themable = 0;
if (!name || !type)
goto error;
/*
* extract optional "|themable" suffix from type
* (e.g.: "string|themable" for a string option that contains color names)
*/
pos = strchr (type, '|');
if (pos && (strcmp (pos, "|themable") == 0))
{
type_name = string_strndup (type, pos - type);
if (!type_name)
goto error;
ptr_type = type_name;
themable = 1;
}
else
{
ptr_type = type;
}
pos = strstr (name, " << ");
if (pos)
{
@@ -735,7 +756,7 @@ config_file_new_option (struct t_config_file *config_file,
var_type = -1;
for (i = 0; i < CONFIG_NUM_OPTION_TYPES; i++)
{
if (strcmp (type, config_option_type_string[i]) == 0)
if (strcmp (ptr_type, config_option_type_string[i]) == 0)
{
var_type = i;
break;
@@ -745,10 +766,14 @@ config_file_new_option (struct t_config_file *config_file,
{
gui_chat_printf (NULL, "%sUnknown option type \"%s\"",
gui_chat_prefix[GUI_CHAT_PREFIX_ERROR],
type);
ptr_type);
goto error;
}
/* color options are always themable */
if (var_type == CONFIG_OPTION_TYPE_COLOR)
themable = 1;
/*
* compatibility with versions < 4.1.0: force enum type for an integer
* with string values
@@ -785,6 +810,7 @@ config_file_new_option (struct t_config_file *config_file,
goto error;
new_option->parent_name = (parent_name) ? strdup (parent_name) : NULL;
new_option->type = var_type;
new_option->themable = themable;
if (description)
{
new_option->description = strdup (description);
@@ -970,6 +996,7 @@ error:
end:
free (option_name);
free (parent_name);
free (type_name);
return new_option;
}
@@ -1096,13 +1123,12 @@ config_file_search_with_string (const char *option_name,
struct t_config_file **config_file,
struct t_config_section **section,
struct t_config_option **option,
const char **pos_option_name)
char **pos_option_name)
{
struct t_config_file *ptr_config;
struct t_config_section *ptr_section;
struct t_config_option *ptr_option;
const char *pos_section, *pos_option;
char *file_name, *section_name;
char *file_name, *pos_section, *section_name, *pos_option;
if (config_file)
*config_file = NULL;
@@ -2440,6 +2466,8 @@ config_file_option_get_pointer (struct t_config_option *option,
return option->parent_name;
else if (strcmp (property, "type") == 0)
return &option->type;
else if (strcmp (property, "themable") == 0)
return &option->themable;
else if (strcmp (property, "description") == 0)
return option->description;
else if (strcmp (property, "string_values") == 0)
@@ -2555,7 +2583,7 @@ config_file_option_set_with_string (const char *option_name, const char *value)
struct t_config_file *ptr_config;
struct t_config_section *ptr_section;
struct t_config_option *ptr_option;
const char *pos_option;
char *pos_option;
rc = WEECHAT_CONFIG_OPTION_SET_OPTION_NOT_FOUND;
@@ -4249,6 +4277,7 @@ config_file_hdata_config_option_cb (const void *pointer, void *data,
HDATA_VAR(struct t_config_option, name, STRING, 0, NULL, NULL);
HDATA_VAR(struct t_config_option, parent_name, STRING, 0, NULL, NULL);
HDATA_VAR(struct t_config_option, type, INTEGER, 0, NULL, NULL);
HDATA_VAR(struct t_config_option, themable, INTEGER, 0, NULL, NULL);
HDATA_VAR(struct t_config_option, description, STRING, 0, NULL, NULL);
HDATA_VAR(struct t_config_option, string_values, STRING, 0, "*,*", NULL);
HDATA_VAR(struct t_config_option, min, INTEGER, 0, NULL, NULL);
@@ -4361,6 +4390,8 @@ config_file_add_option_to_infolist (struct t_infolist *infolist,
{
goto error;
}
if (!infolist_new_var_integer (ptr_item, "themable", option->themable))
goto error;
if (option->value)
{
value = config_file_option_value_to_string (option, 0, 0, 0);
@@ -4525,6 +4556,7 @@ config_file_print_log (void)
log_printf (" name . . . . . . . . . . . . : '%s'", ptr_option->name);
log_printf (" parent_name. . . . . . . . . : '%s'", ptr_option->parent_name);
log_printf (" type . . . . . . . . . . . . : %d", ptr_option->type);
log_printf (" themable . . . . . . . . . . : %d", ptr_option->themable);
log_printf (" description. . . . . . . . . : '%s'", ptr_option->description);
log_printf (" string_values. . . . . . . . : %p", ptr_option->string_values);
log_printf (" min. . . . . . . . . . . . . : %d", ptr_option->min);
+3 -1
View File
@@ -154,6 +154,8 @@ struct t_config_option
char *parent_name; /* parent name (to inherit the */
/* value from another option) */
enum t_config_option_type type; /* type */
int themable; /* 1 if option is themable */
/* (color, or string with color) */
char *description; /* description */
char **string_values; /* allowed string values */
int min, max; /* min and max for value */
@@ -286,7 +288,7 @@ extern void config_file_search_with_string (const char *option_name,
struct t_config_file **config_file,
struct t_config_section **section,
struct t_config_option **option,
const char **pos_option_name);
char **pos_option_name);
extern int config_file_string_to_boolean (const char *text);
extern int config_file_option_reset (struct t_config_option *option,
int run_callback);
+43 -24
View File
@@ -50,6 +50,7 @@
#include "core-proxy.h"
#include "core-string.h"
#include "core-sys.h"
#include "core-theme.h"
#include "core-util.h"
#include "core-version.h"
#include "../gui/gui-bar.h"
@@ -222,6 +223,8 @@ struct t_config_option *config_look_separator_horizontal = NULL;
struct t_config_option *config_look_separator_vertical = NULL;
struct t_config_option *config_look_tab_whitespace_char = NULL;
struct t_config_option *config_look_tab_width = NULL;
struct t_config_option *config_look_theme = NULL;
struct t_config_option *config_look_theme_backup = NULL;
struct t_config_option *config_look_time_format = NULL;
struct t_config_option *config_look_whitespace_char = NULL;
struct t_config_option *config_look_window_auto_zoom = NULL;
@@ -1381,7 +1384,7 @@ config_change_color (const void *pointer, void *data,
(void) data;
(void) option;
if (gui_init_ok)
if (gui_init_ok && !theme_applying)
{
gui_color_init_weechat ();
gui_window_ask_refresh (1);
@@ -1709,7 +1712,7 @@ config_weechat_update_cb (const void *pointer, void *data,
int version_read,
struct t_hashtable *data_read)
{
const char *ptr_config, *ptr_section, *ptr_option, *ptr_value, *pos_option;
const char *ptr_config, *ptr_section, *ptr_option, *ptr_value;
char *new_commands[][2] = {
/* old command, new command */
{ "/input jump_smart", "/buffer jump smart" },
@@ -1739,7 +1742,7 @@ config_weechat_update_cb (const void *pointer, void *data,
{ "number_desc" "-buffer.number" },
{ NULL, NULL },
};
char *new_option, *new_value;
char *new_option, *new_value, *pos_option;
int changes, i;
/* make C compiler happy */
@@ -2262,8 +2265,7 @@ config_weechat_proxy_read_cb (const void *pointer, void *data,
struct t_config_section *section,
const char *option_name, const char *value)
{
const char *pos_option;
char *proxy_name;
char *pos_option, *proxy_name;
struct t_proxy *ptr_temp_proxy;
int index_option;
@@ -2342,8 +2344,7 @@ config_weechat_bar_read_cb (const void *pointer, void *data,
struct t_config_section *section,
const char *option_name, const char *value)
{
const char *pos_option;
char *bar_name;
char *pos_option, *bar_name;
struct t_gui_bar *ptr_temp_bar;
int index_option;
@@ -2423,8 +2424,7 @@ config_weechat_custom_bar_item_read_cb (const void *pointer, void *data,
struct t_config_section *section,
const char *option_name, const char *value)
{
const char *pos_option;
char *item_name;
char *pos_option, *item_name;
struct t_gui_bar_item_custom *ptr_temp_item;
int index_option;
@@ -2515,8 +2515,7 @@ config_weechat_layout_read_cb (const void *pointer, void *data,
const char *option_name, const char *value)
{
int argc, force_current_layout, number1, number2, number3, number4;
const char *pos;
char **argv, *layout_name;
char **argv, *pos, *layout_name;
const char *ptr_option_name;
struct t_gui_layout *ptr_layout;
struct t_gui_layout_window *parent;
@@ -3450,7 +3449,7 @@ config_weechat_init_options (void)
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
config_look_buffer_time_format = config_file_new_option (
weechat_config_file, weechat_config_section_look,
"buffer_time_format", "string",
"buffer_time_format", "string|themable",
/* TRANSLATORS: string "${color:xxx}" must NOT be translated */
N_("time format for each line displayed in buffers (see man "
"strftime for date/time specifiers, extra specifiers are "
@@ -3474,7 +3473,7 @@ config_weechat_init_options (void)
NULL, NULL, NULL);
config_look_buffer_time_same = config_file_new_option (
weechat_config_file, weechat_config_section_look,
"buffer_time_same", "string",
"buffer_time_same", "string|themable",
/* TRANSLATORS: string "${color:xxx}" must NOT be translated */
N_("time displayed for a message with same time as previous message: "
"use a space \" \" to hide time, another string to display this "
@@ -3641,7 +3640,7 @@ config_weechat_init_options (void)
NULL, NULL, NULL);
config_look_day_change_message_1date = config_file_new_option (
weechat_config_file, weechat_config_section_look,
"day_change_message_1date", "string",
"day_change_message_1date", "string|themable",
/* TRANSLATORS: string "${color:xxx}" must NOT be translated */
N_("message displayed when the day has changed, with one date "
"displayed (for example at beginning of buffer) (see man "
@@ -3654,7 +3653,7 @@ config_weechat_init_options (void)
NULL, NULL, NULL);
config_look_day_change_message_2dates = config_file_new_option (
weechat_config_file, weechat_config_section_look,
"day_change_message_2dates", "string",
"day_change_message_2dates", "string|themable",
/* TRANSLATORS: string "${color:xxx}" must NOT be translated */
N_("message displayed when the day has changed, with two dates "
"displayed (between two messages); the second date specifiers "
@@ -3971,7 +3970,7 @@ config_weechat_init_options (void)
NULL, NULL, NULL);
config_look_item_time_format = config_file_new_option (
weechat_config_file, weechat_config_section_look,
"item_time_format", "string",
"item_time_format", "string|themable",
N_("time format for \"time\" bar item (see man strftime for "
"date/time specifiers) (note: content is evaluated, so you can "
"use colors with format \"${color:xxx}\", see /help eval)"),
@@ -4026,7 +4025,7 @@ config_weechat_init_options (void)
NULL, NULL, NULL);
config_look_nick_color_force = config_file_new_option (
weechat_config_file, weechat_config_section_look,
"nick_color_force", "string",
"nick_color_force", "string|themable",
N_("force color for some nicks: hash computed with nickname "
"to find color will not be used for these nicks (format is: "
"\"nick1:color1;nick2:color2\"); look up for nicks is with "
@@ -4118,7 +4117,7 @@ config_weechat_init_options (void)
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
config_look_prefix[GUI_CHAT_PREFIX_ERROR] = config_file_new_option (
weechat_config_file, weechat_config_section_look,
"prefix_error", "string",
"prefix_error", "string|themable",
/* TRANSLATORS: string "${color:xxx}" must NOT be translated */
N_("prefix for error messages (note: content is evaluated, so you "
"can use colors with format \"${color:xxx}\", see /help eval)"),
@@ -4128,7 +4127,7 @@ config_weechat_init_options (void)
NULL, NULL, NULL);
config_look_prefix[GUI_CHAT_PREFIX_NETWORK] = config_file_new_option (
weechat_config_file, weechat_config_section_look,
"prefix_network", "string",
"prefix_network", "string|themable",
/* TRANSLATORS: string "${color:xxx}" must NOT be translated */
N_("prefix for network messages (note: content is evaluated, so you "
"can use colors with format \"${color:xxx}\", see /help eval)"),
@@ -4138,7 +4137,7 @@ config_weechat_init_options (void)
NULL, NULL, NULL);
config_look_prefix[GUI_CHAT_PREFIX_ACTION] = config_file_new_option (
weechat_config_file, weechat_config_section_look,
"prefix_action", "string",
"prefix_action", "string|themable",
/* TRANSLATORS: string "${color:xxx}" must NOT be translated */
N_("prefix for action messages (note: content is evaluated, so you "
"can use colors with format \"${color:xxx}\", see /help eval)"),
@@ -4148,7 +4147,7 @@ config_weechat_init_options (void)
NULL, NULL, NULL);
config_look_prefix[GUI_CHAT_PREFIX_JOIN] = config_file_new_option (
weechat_config_file, weechat_config_section_look,
"prefix_join", "string",
"prefix_join", "string|themable",
/* TRANSLATORS: string "${color:xxx}" must NOT be translated */
N_("prefix for join messages (note: content is evaluated, so you "
"can use colors with format \"${color:xxx}\", see /help eval)"),
@@ -4158,7 +4157,7 @@ config_weechat_init_options (void)
NULL, NULL, NULL);
config_look_prefix[GUI_CHAT_PREFIX_QUIT] = config_file_new_option (
weechat_config_file, weechat_config_section_look,
"prefix_quit", "string",
"prefix_quit", "string|themable",
/* TRANSLATORS: string "${color:xxx}" must NOT be translated */
N_("prefix for quit messages (note: content is evaluated, so you "
"can use colors with format \"${color:xxx}\", see /help eval)"),
@@ -4427,6 +4426,26 @@ config_weechat_init_options (void)
NULL, NULL, NULL,
&config_change_tab, NULL, NULL,
NULL, NULL, NULL);
config_look_theme = config_file_new_option (
weechat_config_file, weechat_config_section_look,
"theme", "string",
N_("name of the last theme applied with command /theme "
"(set automatically, do not change manually); informational "
"only, the theme is not re-applied at startup"),
NULL, 0, 0, "", NULL, 0,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
config_look_theme_backup = config_file_new_option (
weechat_config_file, weechat_config_section_look,
"theme_backup", "boolean",
N_("create a backup theme file with the current themable "
"options before applying a theme with command /theme; if "
"the backup file cannot be written, the apply is aborted "
"(no option is changed); the backup file is written to "
"directory \"themes\" inside the WeeChat configuration "
"directory and can be restored with: /theme apply "
"backup-<timestamp>"),
NULL, 0, 0, "on", NULL, 0,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
config_look_time_format = config_file_new_option (
weechat_config_file, weechat_config_section_look,
"time_format", "string",
@@ -4647,7 +4666,7 @@ config_weechat_init_options (void)
NULL, NULL, NULL);
config_color_chat_nick_colors = config_file_new_option (
weechat_config_file, weechat_config_section_color,
"chat_nick_colors", "string",
"chat_nick_colors", "string|themable",
/* TRANSLATORS: please do not translate "lightred:blue" */
N_("text color for nicks (comma separated list of colors, "
"background is allowed with format: \"fg:bg\", for example: "
@@ -4918,7 +4937,7 @@ config_weechat_init_options (void)
/* eval syntax highlighting colors (for "${raw_hl:xxx}" and "${hl:xxx}") */
config_color_eval_syntax_colors = config_file_new_option (
weechat_config_file, weechat_config_section_color,
"eval_syntax_colors", "string",
"eval_syntax_colors", "string|themable",
/* TRANSLATORS: please do not translate "lightred:blue" */
N_("text color for syntax highlighting in evaluated strings, "
"with \"${raw_hl:...}\" and \"${hl:...}\" (comma separated "
+2
View File
@@ -277,6 +277,8 @@ extern struct t_config_option *config_look_separator_horizontal;
extern struct t_config_option *config_look_separator_vertical;
extern struct t_config_option *config_look_tab_whitespace_char;
extern struct t_config_option *config_look_tab_width;
extern struct t_config_option *config_look_theme;
extern struct t_config_option *config_look_theme_backup;
extern struct t_config_option *config_look_time_format;
extern struct t_config_option *config_look_whitespace_char;
extern struct t_config_option *config_look_window_auto_zoom;
+9 -14
View File
@@ -508,8 +508,7 @@ eval_string_repeat (const char *text)
char *
eval_string_split (const char *text)
{
const char *pos, *pos2, *pos3;
char *str_number, *separators, **items, *value;
char *pos, *pos2, *pos3, *str_number, *separators, **items, *value;
char str_value[32], *str_flags, **list_flags, *strip_items, **ptr_flag;
int num_items, count_items, random_item, flags, max_items;
long number;
@@ -656,8 +655,7 @@ end:
char *
eval_string_split_shell (const char *text)
{
const char *pos;
char *str_number, **items, *value, str_value[32];
char *pos, *str_number, **items, *value, str_value[32];
int num_items, count_items, random_item;
long number;
@@ -1048,8 +1046,7 @@ eval_string_if (const char *text, struct t_eval_context *eval_context)
char *
eval_string_random (const char *text)
{
const char *pos;
char *tmp, result[128];
char *pos, *tmp, result[128];
long long min_number, max_number;
if (!text || !text[0])
@@ -1115,8 +1112,7 @@ eval_string_translate (const char *text)
void
eval_string_define (const char *text, struct t_eval_context *eval_context)
{
const char *pos;
char *name;
char *pos, *name;
pos = strchr (text, ',');
if (!pos)
@@ -1143,8 +1139,7 @@ eval_hdata_count (const char *text, struct t_eval_context *eval_context)
struct t_hdata *hdata;
unsigned long ptr_value;
void *pointer;
const char *pos1, *pos2;
char *value, *hdata_name, *pointer_name, str_count[64];
char *pos1, *pos2, *value, *hdata_name, *pointer_name, str_count[64];
int rc, count;
value = NULL;
@@ -1216,8 +1211,8 @@ char *
eval_hdata_get_value (struct t_hdata *hdata, void *pointer, const char *path,
struct t_eval_context *eval_context)
{
char *value, *var_name, str_value[128], *property;
const char *ptr_value, *hdata_name, *ptr_var_name, *pos, *pos_open_paren;
char *value, *var_name, str_value[128], *pos, *property;
const char *ptr_value, *hdata_name, *ptr_var_name, *pos_open_paren;
int type, debug_id;
struct t_hashtable *hashtable;
@@ -1544,8 +1539,8 @@ eval_syntax_highlight_add_markers (const char *prefix, const char *text,
char *
eval_syntax_highlight_colorize (const char *value)
{
const char *ptr_value, *pos;
char **result;
const char *ptr_value;
char **result, *pos;
int color;
if (!value)
+1 -2
View File
@@ -688,8 +688,7 @@ hdata_count (struct t_hdata *hdata, void *pointer)
void
hdata_get_index_and_name (const char *name, int *index, const char **ptr_name)
{
const char *pos;
char *str_index;
char *pos, *str_index;
int number;
if (index)
+3 -8
View File
@@ -242,8 +242,8 @@ int
input_data (struct t_gui_buffer *buffer, const char *data,
const char *commands_allowed, int split_newline, int user_data)
{
const char *ptr_data_for_buffer;
char *pos, str_buffer[128], *new_data, *buffer_full_name, *ptr_data;
char *pos, str_buffer[128], *new_data, *buffer_full_name;
const char *ptr_data, *ptr_data_for_buffer;
int first_command, rc;
if (!buffer || !gui_buffer_valid (buffer) || !data)
@@ -272,13 +272,8 @@ input_data (struct t_gui_buffer *buffer, const char *data,
if (data[0] && new_data && !new_data[0])
goto end;
if (!new_data)
new_data = strdup (data);
if (!new_data)
goto end;
first_command = 1;
ptr_data = new_data;
ptr_data = (new_data) ? new_data : data;
while (ptr_data)
{
/*
+1 -19
View File
@@ -582,13 +582,7 @@ network_pass_socks5proxy (struct t_proxy *proxy, int sock, const char *address,
int port)
{
struct t_network_socks5 socks5;
/*
* buffer must be large enough for the username/password authentication
* request, which is the longest message sent/received here; according to
* RFC 1929 it is: version (1) + username length (1) + username (max 255)
* + password length (1) + password (max 255)
*/
unsigned char buffer[2 + 255 + 1 + 255];
unsigned char buffer[288];
int username_len, password_len, addr_len, addr_buffer_len;
unsigned char *addr_buffer;
char *username, *password;
@@ -637,18 +631,6 @@ network_pass_socks5proxy (struct t_proxy *proxy, int sock, const char *address,
username_len = strlen (username);
password_len = strlen (password);
/*
* username and password length are each stored on a single byte
* (RFC 1929), so they cannot exceed 255 bytes: reject longer values,
* otherwise the memcpy calls below would overflow the buffer
*/
if ((username_len > 255) || (password_len > 255))
{
free (username);
free (password);
return 0;
}
/* make username/password buffer */
buffer[0] = 1;
buffer[1] = (unsigned char) username_len;
+6 -6
View File
@@ -1686,8 +1686,9 @@ string_mask_to_regex (const char *mask)
const char *
string_regex_flags (const char *regex, int default_flags, int *flags)
{
const char *ptr_regex, *ptr_flags, *pos;
const char *ptr_regex, *ptr_flags;
int set_flag, flag;
char *pos;
if (flags)
*flags = default_flags;
@@ -2965,9 +2966,8 @@ char **
string_split_command (const char *command, char separator)
{
int nb_substr, arr_idx, str_idx, type;
const char *p;
char **array, **array2;
char *buffer;
char *buffer, *p;
const char *ptr;
if (!command || !command[0])
@@ -4138,7 +4138,8 @@ string_is_command_char (const char *string)
const char *
string_input_for_buffer (const char *string)
{
const char *pos_slash, *pos_space, *pos_newline, *next_char;
char *pos_slash, *pos_space, *pos_newline;
const char *next_char;
if (!string)
return NULL;
@@ -4475,8 +4476,7 @@ string_get_priority_and_name (const char *string,
int *priority, const char **name,
int default_priority)
{
const char *pos;
char *str_priority;
char *pos, *str_priority;
int number;
if (priority)
+129
View File
@@ -0,0 +1,129 @@
/*
* SPDX-FileCopyrightText: 2026 Sébastien Helleu <flashcode@flashtux.org>
*
* 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 <https://www.gnu.org/licenses/>.
*/
/* Built-in theme registrations (core contribution only). */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stddef.h>
#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 (NULL, NULL, 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);
}
File diff suppressed because it is too large Load Diff
+92
View File
@@ -0,0 +1,92 @@
/*
* SPDX-FileCopyrightText: 2026 Sébastien Helleu <flashcode@flashtux.org>
*
* 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 <https://www.gnu.org/licenses/>.
*/
#ifndef WEECHAT_THEME_H
#define WEECHAT_THEME_H
struct t_hashtable;
struct t_arraylist;
struct t_weechat_plugin;
/*
* A contribution is one (owner, overrides) pair attached to a theme.
* "owner" is identified by a (plugin, script) pair:
* - plugin == NULL && script == NULL => core
* - plugin != NULL && script == NULL => plugin (e.g. irc, fset)
* - plugin != NULL && script != NULL => individual script under that
* script-language plugin
*/
struct t_theme_contribution
{
struct t_weechat_plugin *plugin;
const void *script;
struct t_hashtable *overrides; /* full_option_name -> value */
struct t_theme_contribution *prev_contribution;
struct t_theme_contribution *next_contribution;
};
struct t_theme
{
char *name; /* "light", "solarized", ... */
char *description; /* free-form text */
char *date; /* "YYYY-MM-DD HH:MM:SS" */
char *weechat_version; /* version at registration time */
struct t_theme_contribution *contributions;
struct t_theme_contribution *last_contribution;
struct t_theme *prev_theme;
struct t_theme *next_theme;
};
extern struct t_theme *themes;
extern struct t_theme *last_theme;
extern int theme_applying; /* gate for config_change_color */
extern struct t_theme *theme_search (const char *name);
extern struct t_theme *theme_register (struct t_weechat_plugin *plugin,
const void *script,
const char *name,
struct t_hashtable *overrides);
extern int theme_overrides_count (struct t_theme *theme);
extern const char *theme_get_override (struct t_theme *theme,
const char *option_name);
extern struct t_arraylist *theme_list (void);
extern int theme_apply (const char *name);
extern int theme_reset (void);
extern int theme_save (const char *name);
extern int theme_rename (const char *old_name, const char *new_name);
extern int theme_delete (const char *name);
extern char *theme_make_backup (void);
extern char *theme_user_file_path (const char *name);
extern struct t_theme *theme_file_parse (const char *path);
extern void theme_free (struct t_theme *theme);
/* lifecycle: drop all contributions owned by a plugin or script */
extern void theme_unregister_plugin (struct t_weechat_plugin *plugin);
extern void theme_unregister_script (struct t_weechat_plugin *plugin,
const void *script);
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 */
+2 -2
View File
@@ -416,8 +416,8 @@ util_strftimeval (char *string, int max, const char *format, struct timeval *tv)
int
util_parse_time (const char *datetime, struct timeval *tv)
{
const char *pos_colon, *pos_hyphen, *pos_dot;
char *pos, *pos2, *string, str_usec[16], str_date[128];
char *string, *pos, *pos2, *pos_colon, *pos_hyphen, *pos_dot;
char str_usec[16], str_date[128];
struct tm tm_date, tm_date_gm, tm_date_local, *local_time;
time_t time_now, time_gm, time_local;
long long value;
+2 -2
View File
@@ -597,8 +597,8 @@ hook_command_exec (struct t_gui_buffer *buffer, int any_plugin,
struct t_hook *hook_plugin, *hook_other_plugin, *hook_other_plugin2;
struct t_hook *hook_incomplete_command;
struct t_hook_exec_cb hook_exec_cb;
char **argv, **argv_eol, *command_name;
const char *ptr_string, *pos;
char **argv, **argv_eol, *command_name, *pos;
const char *ptr_string;
int argc, rc, length_command_name, allow_incomplete_commands;
int count_other_plugin, count_incomplete_commands, flags;
+1 -2
View File
@@ -132,8 +132,7 @@ void
hook_signal_extract_flags (const char *signal, const char **ptr_signal,
int *stop_on_error, int *ignore_eat)
{
const char *pos;
char *str_flags, **flags;
char *pos, *str_flags, **flags;
int i, num_flags;
if (!signal || !ptr_signal || !stop_on_error || !ignore_eat)
+40 -13
View File
@@ -75,6 +75,7 @@
#include "core-secure-config.h"
#include "core-signal.h"
#include "core-string.h"
#include "core-theme.h"
#include "core-upgrade.h"
#include "core-url.h"
#include "core-utf8.h"
@@ -97,6 +98,7 @@ char *weechat_argv0 = NULL; /* WeeChat binary file name (argv[0])*/
int weechat_upgrading = 0; /* =1 if WeeChat is upgrading */
int weechat_first_start = 0; /* first start of WeeChat? */
time_t weechat_first_start_time = 0; /* start time (used by /uptime cmd) */
int weechat_term_theme_light = 0; /* 1 if light theme detected */
int weechat_upgrade_count = 0; /* number of /upgrade done */
struct timeval weechat_current_start_timeval; /* start time used to display */
/* duration of /upgrade */
@@ -182,22 +184,34 @@ weechat_startup_message (void)
if (weechat_first_start)
{
/* message on first run (when weechat.conf is created) */
gui_chat_printf (NULL, "");
gui_chat_printf (NULL, _("Welcome to WeeChat!"));
gui_chat_printf (
NULL,
_("Welcome to WeeChat!\n"
"\n"
"If you are discovering WeeChat, it is recommended to read at "
"least the quickstart guide, and the user's guide if you have "
"some time; they explain main WeeChat concepts.\n"
"All WeeChat docs are available at: https://weechat.org/doc/\n"
"\n"
"Moreover, there is inline help with /help on all commands and "
"options (use Tab key to complete the name).\n"
"The command /fset can help to customize WeeChat.\n"
"\n"
"You can add and connect to an IRC server with /server and "
_("If you are discovering WeeChat, it is recommended to "
"read at least the quickstart guide, and the user's guide if "
"you have some time; they explain main WeeChat concepts."));
gui_chat_printf (
NULL,
_("All WeeChat docs are available at: %s"),
WEECHAT_WEBSITE_DOC);
gui_chat_printf (
NULL,
_("Moreover, there is inline help with /help on all commands and "
"options (use Tab key to complete the name)."));
gui_chat_printf (
NULL,
_("The command /fset can help to customize WeeChat."));
gui_chat_printf (
NULL,
_("You can add and connect to an IRC server with /server and "
"/connect commands (see /help server)."));
if (weechat_term_theme_light)
{
gui_chat_printf (
NULL,
_("The \"light\" theme will be automatically applied. "
"Use /theme reset to switch back to the default dark theme."));
}
gui_chat_printf (NULL, "");
gui_chat_printf (NULL, "---");
gui_chat_printf (NULL, "");
@@ -368,6 +382,9 @@ weechat_init (int argc, char *argv[], void (*gui_init_cb)(void))
* weechat_current_start_timeval.tv_usec)
^ getpid ());
/* detect the terminal theme, before initializing the GUI */
weechat_term_theme_light = gui_term_theme_is_light ();
weeurl_init (); /* initialize URL */
string_init (); /* initialize string */
signal_init (); /* initialize signals */
@@ -384,6 +401,8 @@ weechat_init (int argc, char *argv[], void (*gui_init_cb)(void))
weechat_shutdown (EXIT_FAILURE, 0);
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 */
@@ -423,6 +442,13 @@ weechat_init (int argc, char *argv[], void (*gui_init_cb)(void))
weechat_doc_gen_ok = doc_generate (weechat_doc_gen_path);
weechat_quit = 1;
}
if (weechat_first_start && isatty (STDOUT_FILENO) && !weechat_headless && !weechat_doc_gen)
{
/* switch to "light" theme if terminal background was detected as "light" */
if (weechat_term_theme_light)
theme_apply ("light");
}
}
/*
@@ -449,6 +475,7 @@ weechat_end (void (*gui_end_cb)(int clean_exit))
unhook_all (); /* remove all hooks */
hdata_end (); /* end hdata */
secure_end (); /* end secured data */
theme_end (); /* end theme registry */
string_end (); /* end string */
weeurl_end ();
weechat_shutdown (-1, 0); /* end other things */
+1
View File
@@ -55,6 +55,7 @@
#define WEECHAT_COPYRIGHT_DATE "(C) 2003-2026"
#define WEECHAT_WEBSITE "https://weechat.org/"
#define WEECHAT_WEBSITE_DOC "https://weechat.org/doc/"
#define WEECHAT_WEBSITE_DOWNLOAD "https://weechat.org/download/"
#define WEECHAT_AUTHOR_NAME "Sébastien Helleu"
#define WEECHAT_AUTHOR_EMAIL "flashcode@flashtux.org"
+146
View File
@@ -25,6 +25,14 @@
#include "config.h"
#endif
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <sys/select.h>
#include <sys/time.h>
#include <termios.h>
#include <unistd.h>
#ifndef WEECHAT_HEADLESS
#ifdef HAVE_NCURSESW_CURSES_H
#ifdef __sun
@@ -37,6 +45,8 @@
#endif /* HAVE_NCURSESW_CURSES_H */
#endif /* WEECHAT_HEADLESS */
#include "../../core/weechat.h"
/*
* Set "eat_newline_glitch" variable.
@@ -56,3 +66,139 @@ gui_term_set_eat_newline_glitch (int value)
(void) value;
#endif
}
/*
* Auto-detects the terminal background as "light" or "dark".
*
* Best-effort, in order:
*
* 1. Environment variable COLORFGBG (set by rxvt, urxvt, Konsole,
* ...): "fg;bg" or "fg;default;bg"; the last ';'-separated
* component is the bg ANSI color index. 0-6 + 8 are dark,
* 7 + 9-15 are light.
*
* 2. OSC 11 escape query on /dev/tty: write "\033]11;?\033\\",
* wait up to 100 ms for a reply of the form
* "...rgb:RRRR/GGGG/BBBB..." (each component is 1-4 hex digits
* depending on the terminal). Classify the answer by Rec. 601
* luminance computed on the high nibble of each component
* (resolution is plenty for a light/dark binary decision and
* avoids width-normalization headaches).
*
* /dev/tty is used rather than stdin/stdout so a pipe redirection
* does not defeat detection. The select() timeout caps how long a
* silent terminal can stall startup. Headless mode and any I/O error
* short-circuit to the safe default 0 (dark), which is also returned
* when both probes are inconclusive.
*
* MUST be called before curses init: it briefly puts the tty in raw
* mode and reads/writes escape sequences directly.
*
* Returns 1 if a light background is detected, otherwise 0 (0 is the
* preferred value when detection is unsure).
*/
int
gui_term_theme_is_light (void)
{
const char *colorfgbg, *p;
char *endptr;
long bg;
int fd, n, i, len;
struct termios old_attr, new_attr;
fd_set rfds;
struct timeval tv;
char buf[256], *q, *qend;
unsigned long comp_high[3], luminance;
if (weechat_headless)
return 0;
/* 1. COLORFGBG */
colorfgbg = getenv ("COLORFGBG");
if (colorfgbg && colorfgbg[0])
{
p = strrchr (colorfgbg, ';');
if (p)
{
bg = strtol (p + 1, &endptr, 10);
if (endptr != p + 1 && *endptr == '\0')
{
if (bg == 7 || (bg >= 9 && bg <= 15))
return 1;
if ((bg >= 0 && bg <= 6) || bg == 8)
return 0;
}
}
}
/* 2. OSC 11 query on the controlling terminal */
fd = open ("/dev/tty", O_RDWR | O_NOCTTY);
if (fd < 0)
return 0;
if (tcgetattr (fd, &old_attr) != 0)
{
close (fd);
return 0;
}
new_attr = old_attr;
new_attr.c_lflag &= (tcflag_t) ~(ICANON | ECHO);
new_attr.c_cc[VMIN] = 0;
new_attr.c_cc[VTIME] = 0;
if (tcsetattr (fd, TCSANOW, &new_attr) != 0)
{
close (fd);
return 0;
}
n = -1;
if (write (fd, "\033]11;?\033\\", 8) == 8)
{
FD_ZERO (&rfds);
FD_SET (fd, &rfds);
tv.tv_sec = 0;
tv.tv_usec = 100000; /* 100 ms cap on terminals that won't reply */
if (select (fd + 1, &rfds, NULL, NULL, &tv) > 0)
n = read (fd, buf, sizeof (buf) - 1);
}
tcsetattr (fd, TCSANOW, &old_attr);
close (fd);
if (n <= 0)
return 0;
buf[n] = '\0';
q = strstr (buf, "rgb:");
if (!q)
return 0;
q += 4;
for (i = 0; i < 3; i++)
{
qend = q;
while ((*qend >= '0' && *qend <= '9')
|| (*qend >= 'a' && *qend <= 'f')
|| (*qend >= 'A' && *qend <= 'F'))
qend++;
len = (int)(qend - q);
if (len < 1 || len > 4)
return 0;
/* high nibble of this component: width-independent brightness */
comp_high[i] = strtoul (q, NULL, 16) >> ((len - 1) * 4);
q = qend;
if (i < 2)
{
if (*q != '/')
return 0;
q++;
}
}
/* Rec. 601 with coefficients summing to 1000; max = 15 * 1000 */
luminance = (299UL * comp_high[0]
+ 587UL * comp_high[1]
+ 114UL * comp_high[2]);
return (luminance > 7500) ? 1 : 0;
}
+3 -4
View File
@@ -47,7 +47,7 @@ void
daemonize (void)
{
pid_t pid;
int fd, i, rc;
int fd, i;
printf ("%s ", _("Running WeeChat in background..."));
@@ -77,9 +77,8 @@ daemonize (void)
close (i);
}
fd = open ("/dev/null", O_RDWR);
rc = dup (fd);
rc = dup (fd);
(void) rc;
(void) dup (fd);
(void) dup (fd);
}
/*
+1 -2
View File
@@ -138,8 +138,7 @@ gui_bar_item_custom_search (const char *item_name)
struct t_gui_bar_item_custom *
gui_bar_item_custom_search_with_option_name (const char *option_name)
{
const char *pos_option;
char *item_name;
char *item_name, *pos_option;
struct t_gui_bar_item_custom *ptr_item;
if (!option_name)
+9 -9
View File
@@ -1880,9 +1880,9 @@ gui_bar_item_buffer_nicklist_cb (const void *pointer, void *data,
{
if (strchr (ptr_nick->prefix_color, '.'))
{
config_file_search_with_string (
ptr_nick->prefix_color,
NULL, NULL, &ptr_option, NULL);
config_file_search_with_string (ptr_nick->prefix_color,
NULL, NULL, &ptr_option,
NULL);
if (ptr_option)
{
string_dyn_concat (
@@ -1907,9 +1907,9 @@ gui_bar_item_buffer_nicklist_cb (const void *pointer, void *data,
{
if (strchr (ptr_nick->color, '.'))
{
config_file_search_with_string (
ptr_nick->color,
NULL, NULL, &ptr_option, NULL);
config_file_search_with_string (ptr_nick->color,
NULL, NULL, &ptr_option,
NULL);
if (ptr_option)
{
string_dyn_concat (
@@ -1940,9 +1940,9 @@ gui_bar_item_buffer_nicklist_cb (const void *pointer, void *data,
{
if (strchr (ptr_group->color, '.'))
{
config_file_search_with_string (
ptr_group->color,
NULL, NULL, &ptr_option, NULL);
config_file_search_with_string (ptr_group->color,
NULL, NULL, &ptr_option,
NULL);
if (ptr_option)
{
string_dyn_concat (
+1 -2
View File
@@ -515,8 +515,7 @@ gui_bar_search (const char *name)
struct t_gui_bar *
gui_bar_search_with_option_name (const char *option_name)
{
const char *pos_option;
char *bar_name;
char *bar_name, *pos_option;
struct t_gui_bar *ptr_bar;
if (!option_name)
+2 -2
View File
@@ -118,8 +118,8 @@ gui_chat_init (void)
void
gui_chat_prefix_build (void)
{
const char *ptr_prefix, *pos_color;
char prefix[512];
const char *ptr_prefix;
char prefix[512], *pos_color;
int prefix_color[GUI_CHAT_NUM_PREFIXES] =
{ GUI_COLOR_CHAT_PREFIX_ERROR, GUI_COLOR_CHAT_PREFIX_NETWORK,
GUI_COLOR_CHAT_PREFIX_ACTION, GUI_COLOR_CHAT_PREFIX_JOIN,
+4 -3
View File
@@ -170,7 +170,8 @@ gui_color_search_config (const char *color_name)
/* search in any configuration file (example: "irc.color.message_quit") */
if (strchr (color_name, '.'))
{
config_file_search_with_string (color_name, NULL, NULL, &ptr_option, NULL);
config_file_search_with_string (color_name, NULL, NULL, &ptr_option,
NULL);
if (ptr_option)
return gui_color_from_option (ptr_option);
}
@@ -254,8 +255,8 @@ gui_color_get_custom (const char *color_name)
static char color[32][96];
static int index_color = 0;
char color_fg[32], color_bg[32];
char *str_fg, *error, *color_attr;
const char *ptr_color_name, *pos_delim, *pos_bg;
char *pos_delim, *str_fg, *pos_bg, *error, *color_attr;
const char *ptr_color_name;
/* attribute or other color name (GUI dependent) */
index_color = (index_color + 1) % 32;
+2 -2
View File
@@ -366,8 +366,8 @@ gui_filter_new (int enabled, const char *name, const char *buffer_name,
{
struct t_gui_filter *new_filter;
regex_t *regex1, *regex2;
char *regex_prefix, buf[512], str_error[1024];
const char *ptr_start_regex, *pos_regex_message, *pos_tab;
char *pos_tab, *regex_prefix, buf[512], str_error[1024];
const char *ptr_start_regex, *pos_regex_message;
int rc;
if (!name || !buffer_name || !tags || !regex)
+1 -1
View File
@@ -1076,7 +1076,7 @@ gui_key_set_area_type_name (const char *area,
int *area_type, char **area_name)
{
int focus, length;
const char *pos_end;
char *pos_end;
for (focus = 0; focus < GUI_KEY_NUM_FOCUS; focus++)
{
+1
View File
@@ -31,5 +31,6 @@ extern void gui_main_end (int clean_exit);
/* terminal functions (GUI dependent) */
extern void gui_term_set_eat_newline_glitch (int value);
extern int gui_term_theme_is_light (void);
#endif /* WEECHAT_GUI_MAIN_H */
+1
View File
@@ -27,6 +27,7 @@ add_library(buflist MODULE
buflist-config.c buflist-config.h
buflist-info.c buflist-info.h
buflist-mouse.c buflist-mouse.h
buflist-theme.c buflist-theme.h
)
set_target_properties(buflist PROPERTIES PREFIX "")
+15 -15
View File
@@ -645,7 +645,7 @@ buflist_config_init (void)
{
buflist_config_format_buffer = weechat_config_new_option (
buflist_config_file, buflist_config_section_format,
"buffer", "string",
"buffer", "string|themable",
N_("format of each line with a buffer "
"(note: content is evaluated, see /help buflist); "
"example: standard format for bar item \"buflist\" and only the "
@@ -663,7 +663,7 @@ buflist_config_init (void)
NULL, NULL, NULL);
buflist_config_format_buffer_current = weechat_config_new_option (
buflist_config_file, buflist_config_section_format,
"buffer_current", "string",
"buffer_current", "string|themable",
N_("format for the line with current buffer "
"(note: content is evaluated, see /help buflist)"),
NULL, 0, 0, "${color:,17}${format_buffer}", NULL, 0,
@@ -672,7 +672,7 @@ buflist_config_init (void)
NULL, NULL, NULL);
buflist_config_format_hotlist = weechat_config_new_option (
buflist_config_file, buflist_config_section_format,
"hotlist", "string",
"hotlist", "string|themable",
N_("format for hotlist "
"(note: content is evaluated, see /help buflist)"),
NULL, 0, 0,
@@ -683,7 +683,7 @@ buflist_config_init (void)
NULL, NULL, NULL);
buflist_config_format_hotlist_level[3] = weechat_config_new_option (
buflist_config_file, buflist_config_section_format,
"hotlist_highlight", "string",
"hotlist_highlight", "string|themable",
N_("format for a buffer with hotlist level \"highlight\" "
"(note: content is evaluated, see /help buflist)"),
NULL, 0, 0, "${color:magenta}", NULL, 0,
@@ -692,7 +692,7 @@ buflist_config_init (void)
NULL, NULL, NULL);
buflist_config_format_hotlist_level[0] = weechat_config_new_option (
buflist_config_file, buflist_config_section_format,
"hotlist_low", "string",
"hotlist_low", "string|themable",
N_("format for a buffer with hotlist level \"low\" "
"(note: content is evaluated, see /help buflist)"),
NULL, 0, 0, "${color:white}", NULL, 0,
@@ -701,7 +701,7 @@ buflist_config_init (void)
NULL, NULL, NULL);
buflist_config_format_hotlist_level[1] = weechat_config_new_option (
buflist_config_file, buflist_config_section_format,
"hotlist_message", "string",
"hotlist_message", "string|themable",
N_("format for a buffer with hotlist level \"message\" "
"(note: content is evaluated, see /help buflist)"),
NULL, 0, 0, "${color:brown}", NULL, 0,
@@ -710,7 +710,7 @@ buflist_config_init (void)
NULL, NULL, NULL);
buflist_config_format_hotlist_level_none = weechat_config_new_option (
buflist_config_file, buflist_config_section_format,
"hotlist_none", "string",
"hotlist_none", "string|themable",
N_("format for a buffer not in hotlist "
"(note: content is evaluated, see /help buflist)"),
NULL, 0, 0, "${color:default}", NULL, 0,
@@ -719,7 +719,7 @@ buflist_config_init (void)
NULL, NULL, NULL);
buflist_config_format_hotlist_level[2] = weechat_config_new_option (
buflist_config_file, buflist_config_section_format,
"hotlist_private", "string",
"hotlist_private", "string|themable",
N_("format for a buffer with hotlist level \"private\" "
"(note: content is evaluated, see /help buflist)"),
NULL, 0, 0, "${color:green}", NULL, 0,
@@ -728,7 +728,7 @@ buflist_config_init (void)
NULL, NULL, NULL);
buflist_config_format_hotlist_separator = weechat_config_new_option (
buflist_config_file, buflist_config_section_format,
"hotlist_separator", "string",
"hotlist_separator", "string|themable",
N_("separator for counts in hotlist "
"(note: content is evaluated, see /help buflist)"),
NULL, 0, 0, "${color:default},", NULL, 0,
@@ -737,7 +737,7 @@ buflist_config_init (void)
NULL, NULL, NULL);
buflist_config_format_indent = weechat_config_new_option (
buflist_config_file, buflist_config_section_format,
"indent", "string",
"indent", "string|themable",
N_("string displayed to indent channel, private and list buffers "
"(note: content is evaluated, see /help buflist)"),
NULL, 0, 0, " ", NULL, 0,
@@ -746,7 +746,7 @@ buflist_config_init (void)
NULL, NULL, NULL);
buflist_config_format_lag = weechat_config_new_option (
buflist_config_file, buflist_config_section_format,
"lag", "string",
"lag", "string|themable",
N_("format for lag on an IRC server buffer "
"(note: content is evaluated, see /help buflist)"),
NULL, 0, 0,
@@ -757,7 +757,7 @@ buflist_config_init (void)
NULL, NULL, NULL);
buflist_config_format_name = weechat_config_new_option (
buflist_config_file, buflist_config_section_format,
"name", "string",
"name", "string|themable",
N_("format for buffer name "
"(note: content is evaluated, see /help buflist)"),
NULL, 0, 0, "${name}", NULL, 0,
@@ -766,7 +766,7 @@ buflist_config_init (void)
NULL, NULL, NULL);
buflist_config_format_nick_prefix = weechat_config_new_option (
buflist_config_file, buflist_config_section_format,
"nick_prefix", "string",
"nick_prefix", "string|themable",
N_("format for nick prefix on a channel "
"(note: content is evaluated, see /help buflist)"),
NULL, 0, 0, "${color_nick_prefix}${nick_prefix}", NULL, 0,
@@ -775,7 +775,7 @@ buflist_config_init (void)
NULL, NULL, NULL);
buflist_config_format_number = weechat_config_new_option (
buflist_config_file, buflist_config_section_format,
"number", "string",
"number", "string|themable",
N_("format for buffer number, ${number} is the indented number "
"(note: content is evaluated, see /help buflist)"),
NULL, 0, 0,
@@ -786,7 +786,7 @@ buflist_config_init (void)
NULL, NULL, NULL);
buflist_config_format_tls_version = weechat_config_new_option (
buflist_config_file, buflist_config_section_format,
"tls_version", "string",
"tls_version", "string|themable",
N_("format for TLS version on an IRC server buffer "
"(note: content is evaluated, see /help buflist)"),
NULL, 0, 0,
+93
View File
@@ -0,0 +1,93 @@
/*
* SPDX-FileCopyrightText: 2026 Sébastien Helleu <flashcode@flashtux.org>
*
* 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 <https://www.gnu.org/licenses/>.
*/
/* buflist contribution to built-in themes. */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stddef.h>
#include "../weechat-plugin.h"
#include "buflist.h"
#include "buflist-theme.h"
/*
* buflist contribution to the "light" theme: format strings tuned for
* a light-background terminal. Each row is { option_full_name, value };
* the table is NULL-terminated.
*/
const char *buflist_theme_light[][2] =
{
{ "buflist.format.buffer_current",
"${color:,117}${format_buffer}" },
{ "buflist.format.hotlist_low",
"${color:default}" },
{ "buflist.format.hotlist_message",
"${color:94}" },
{ "buflist.format.lag",
" ${color:green}[${color:94}${lag}${color:green}]" },
{ "buflist.format.number",
"${color:28}${number}${if:${number_displayed}?.: }" },
{ NULL, NULL },
};
/*
* Registers buflist's contribution to one theme from a NULL-terminated
* table of {option, value} rows.
*/
void
buflist_theme_register (const char *name, const char *entries[][2])
{
struct t_hashtable *overrides;
int i;
if (!name || !entries)
return;
overrides = weechat_hashtable_new (32,
WEECHAT_HASHTABLE_STRING,
WEECHAT_HASHTABLE_STRING,
NULL, NULL);
if (!overrides)
return;
for (i = 0; entries[i][0]; i++)
weechat_hashtable_set (overrides, entries[i][0], entries[i][1]);
weechat_theme_register (name, overrides);
weechat_hashtable_free (overrides);
}
/*
* Registers all built-in theme contributions from buflist.
*/
void
buflist_theme_init (void)
{
buflist_theme_register ("light", buflist_theme_light);
}
+27
View File
@@ -0,0 +1,27 @@
/*
* SPDX-FileCopyrightText: 2026 Sébastien Helleu <flashcode@flashtux.org>
*
* 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 <https://www.gnu.org/licenses/>.
*/
#ifndef WEECHAT_PLUGIN_BUFLIST_THEME_H
#define WEECHAT_PLUGIN_BUFLIST_THEME_H
extern void buflist_theme_init (void);
#endif /* WEECHAT_PLUGIN_BUFLIST_THEME_H */
+3
View File
@@ -34,6 +34,7 @@
#include "buflist-config.h"
#include "buflist-info.h"
#include "buflist-mouse.h"
#include "buflist-theme.h"
WEECHAT_PLUGIN_NAME(BUFLIST_PLUGIN_NAME);
@@ -455,6 +456,8 @@ weechat_plugin_init (struct t_weechat_plugin *plugin, int argc, char *argv[])
buflist_config_read ();
buflist_theme_init ();
if (!buflist_bar_item_init ())
return WEECHAT_RC_ERROR;
+1
View File
@@ -25,6 +25,7 @@ add_library(exec MODULE
exec-command.c exec-command.h
exec-completion.c exec-completion.h
exec-config.c exec-config.h
exec-theme.c exec-theme.h
)
set_target_properties(exec PROPERTIES PREFIX "")
+70
View File
@@ -0,0 +1,70 @@
/*
* SPDX-FileCopyrightText: 2026 Sébastien Helleu <flashcode@flashtux.org>
*
* 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 <https://www.gnu.org/licenses/>.
*/
/* exec contribution to built-in themes. */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stddef.h>
#include "../weechat-plugin.h"
#include "exec.h"
#include "exec-theme.h"
const char *exec_theme_light[][2] =
{
{ "exec.color.flag_finished", "red" },
{ "exec.color.flag_running", "green" },
{ NULL, NULL },
};
void
exec_theme_register (const char *name, const char *entries[][2])
{
struct t_hashtable *overrides;
int i;
if (!name || !entries)
return;
overrides = weechat_hashtable_new (32,
WEECHAT_HASHTABLE_STRING,
WEECHAT_HASHTABLE_STRING,
NULL, NULL);
if (!overrides)
return;
for (i = 0; entries[i][0]; i++)
weechat_hashtable_set (overrides, entries[i][0], entries[i][1]);
weechat_theme_register (name, overrides);
weechat_hashtable_free (overrides);
}
void
exec_theme_init (void)
{
exec_theme_register ("light", exec_theme_light);
}
+27
View File
@@ -0,0 +1,27 @@
/*
* SPDX-FileCopyrightText: 2026 Sébastien Helleu <flashcode@flashtux.org>
*
* 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 <https://www.gnu.org/licenses/>.
*/
#ifndef WEECHAT_PLUGIN_EXEC_THEME_H
#define WEECHAT_PLUGIN_EXEC_THEME_H
extern void exec_theme_init (void);
#endif /* WEECHAT_PLUGIN_EXEC_THEME_H */
+3
View File
@@ -32,6 +32,7 @@
#include "exec-command.h"
#include "exec-completion.h"
#include "exec-config.h"
#include "exec-theme.h"
WEECHAT_PLUGIN_NAME(EXEC_PLUGIN_NAME);
@@ -742,6 +743,8 @@ weechat_plugin_init (struct t_weechat_plugin *plugin, int argc, char *argv[])
if (!exec_config_init ())
return WEECHAT_RC_ERROR;
exec_theme_init ();
exec_config_read ();
/* hook some signals */
+1
View File
@@ -29,6 +29,7 @@ add_library(fset MODULE
fset-info.c fset-info.h
fset-mouse.c fset-mouse.h
fset-option.c fset-option.h
fset-theme.c fset-theme.h
)
set_target_properties(fset PROPERTIES PREFIX "")
+3 -1
View File
@@ -702,7 +702,9 @@ fset_command_init (void)
N_("> `xxx`: show only options with \"xxx\" in name"),
N_("> `f:xxx`: show only configuration file \"xxx\""),
N_("> `t:xxx`: show only type \"xxx\" (bool/int/str/col/enum "
"or boolean/integer/string/color/enum)"),
"or boolean/integer/string/color/enum); the special value "
"\"themable\" matches all options with the themable flag, "
"regardless of type"),
N_("> `d`: show only changed options"),
N_("> `d:xxx`: show only changed options with \"xxx\" in "
"name"),
+1 -1
View File
@@ -572,7 +572,7 @@ fset_config_init (void)
NULL, NULL, NULL);
fset_config_format_option[1] = weechat_config_new_option (
fset_config_file, fset_config_section_format,
"option2", "string",
"option2", "string|themable",
N_("second format of each line, used when option "
"fset.look.format_number is set to 2 "
"(note: content is evaluated, see /help fset); "
+14 -1
View File
@@ -335,6 +335,10 @@ fset_option_match_filter (struct t_fset_option *fset_option, const char *filter)
}
else if (strncmp (filter, "t:", 2) == 0)
{
/* virtual cross-type value: match themable flag (any option type) */
if (weechat_strcasecmp (filter + 2, "themable") == 0)
return (fset_option->themable) ? 1 : 0;
/* filter by type */
return (
(weechat_strcasecmp (
@@ -426,7 +430,7 @@ fset_option_set_values (struct t_fset_option *fset_option,
const char **ptr_string_values;
void *ptr_default_value, *ptr_value;
struct t_config_option *ptr_parent_option;
int *ptr_type, *ptr_min, *ptr_max;
int *ptr_type, *ptr_themable, *ptr_min, *ptr_max;
char str_value[64], str_allowed_values[4096];
/* file */
@@ -466,6 +470,10 @@ fset_option_set_values (struct t_fset_option *fset_option,
ptr_type = weechat_config_option_get_pointer (option, "type");
fset_option->type = *ptr_type;
/* themable */
ptr_themable = weechat_config_option_get_pointer (option, "themable");
fset_option->themable = (ptr_themable) ? *ptr_themable : 0;
/* default value */
free (fset_option->default_value);
fset_option->default_value = NULL;
@@ -784,6 +792,7 @@ fset_option_alloc (struct t_config_option *option)
new_fset_option->name = NULL;
new_fset_option->parent_name = NULL;
new_fset_option->type = 0;
new_fset_option->themable = 0;
new_fset_option->default_value = NULL;
new_fset_option->value = NULL;
new_fset_option->parent_value = NULL;
@@ -1691,6 +1700,7 @@ fset_option_hdata_option_cb (const void *pointer, void *data,
WEECHAT_HDATA_VAR(struct t_fset_option, name, STRING, 0, NULL, NULL);
WEECHAT_HDATA_VAR(struct t_fset_option, parent_name, STRING, 0, NULL, NULL);
WEECHAT_HDATA_VAR(struct t_fset_option, type, INTEGER, 0, NULL, NULL);
WEECHAT_HDATA_VAR(struct t_fset_option, themable, INTEGER, 0, NULL, NULL);
WEECHAT_HDATA_VAR(struct t_fset_option, default_value, STRING, 0, NULL, NULL);
WEECHAT_HDATA_VAR(struct t_fset_option, value, STRING, 0, NULL, NULL);
WEECHAT_HDATA_VAR(struct t_fset_option, parent_value, STRING, 0, NULL, NULL);
@@ -1740,6 +1750,8 @@ fset_option_add_to_infolist (struct t_infolist *infolist,
return 0;
if (!weechat_infolist_new_var_string (ptr_item, "type_en", fset_option_type_string[fset_option->type]))
return 0;
if (!weechat_infolist_new_var_integer (ptr_item, "themable", fset_option->themable))
return 0;
if (!weechat_infolist_new_var_string (ptr_item, "default_value", fset_option->default_value))
return 0;
if (!weechat_infolist_new_var_string (ptr_item, "value", fset_option->value))
@@ -1793,6 +1805,7 @@ fset_option_print_log (void)
weechat_log_printf (" type. . . . . . . . . : %d ('%s')",
ptr_fset_option->type,
fset_option_type_string[ptr_fset_option->type]);
weechat_log_printf (" themable. . . . . . . : %d", ptr_fset_option->themable);
weechat_log_printf (" default_value . . . . : '%s'", ptr_fset_option->default_value);
weechat_log_printf (" value . . . . . . . . : '%s'", ptr_fset_option->value);
weechat_log_printf (" parent_value. . . . . : '%s'", ptr_fset_option->parent_value);
+1
View File
@@ -46,6 +46,7 @@ struct t_fset_option
char *name; /* option full name: file.sect.opt */
char *parent_name; /* parent option name */
enum t_fset_option_type type; /* option type */
int themable; /* 1 if option is themable */
char *default_value; /* option default value */
char *value; /* option value */
char *parent_value; /* parent option value */
+130
View File
@@ -0,0 +1,130 @@
/*
* SPDX-FileCopyrightText: 2026 Sébastien Helleu <flashcode@flashtux.org>
*
* 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 <https://www.gnu.org/licenses/>.
*/
/* fset contribution to built-in themes. */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stddef.h>
#include "../weechat-plugin.h"
#include "fset.h"
#include "fset-theme.h"
/*
* fset contribution to the "light" theme: option values tuned for a
* light-background terminal. Each row is { option_full_name, value };
* the table is NULL-terminated.
*/
const char *fset_theme_light[][2] =
{
{ "fset.color.allowed_values_selected", "default" },
{ "fset.color.color_name", "darkgray" },
{ "fset.color.color_name_selected", "darkgray" },
{ "fset.color.default_value_selected", "default" },
{ "fset.color.description_selected", "242" },
{ "fset.color.file_changed", "94" },
{ "fset.color.file_changed_selected", "94" },
{ "fset.color.file_selected", "default" },
{ "fset.color.help_default_value", "default" },
{ "fset.color.help_name", "default" },
{ "fset.color.index", "24" },
{ "fset.color.index_selected", "24" },
{ "fset.color.line_marked_bg1", "193" },
{ "fset.color.line_marked_bg2", "193" },
{ "fset.color.line_selected_bg1", "117" },
{ "fset.color.line_selected_bg2", "117" },
{ "fset.color.marked", "94" },
{ "fset.color.marked_selected", "94" },
{ "fset.color.max_selected", "default" },
{ "fset.color.min_selected", "default" },
{ "fset.color.name_changed", "red" },
{ "fset.color.name_changed_selected", "red" },
{ "fset.color.name_selected", "default" },
{ "fset.color.option_changed", "94" },
{ "fset.color.option_changed_selected", "94" },
{ "fset.color.option_selected", "default" },
{ "fset.color.parent_name_selected", "default" },
{ "fset.color.parent_value", "24" },
{ "fset.color.parent_value_selected", "24" },
{ "fset.color.quotes_changed_selected", "default" },
{ "fset.color.section_changed", "94" },
{ "fset.color.section_changed_selected", "94" },
{ "fset.color.section_selected", "default" },
{ "fset.color.string_values_selected", "default" },
{ "fset.color.title_count_options", "30" },
{ "fset.color.title_current_option", "30" },
{ "fset.color.title_filter", "18" },
{ "fset.color.title_marked_options", "94" },
{ "fset.color.title_sort", "darkgray" },
{ "fset.color.type", "58" },
{ "fset.color.type_selected", "58" },
{ "fset.color.unmarked_selected", "default" },
{ "fset.color.value", "20" },
{ "fset.color.value_changed", "red" },
{ "fset.color.value_changed_selected", "red" },
{ "fset.color.value_selected", "20" },
{ "fset.color.value_undef_selected", "magenta" },
{ NULL, NULL },
};
/*
* Registers fset's contribution to one theme from a NULL-terminated
* table of {option, value} rows.
*/
void
fset_theme_register (const char *name, const char *entries[][2])
{
struct t_hashtable *overrides;
int i;
if (!name || !entries)
return;
overrides = weechat_hashtable_new (32,
WEECHAT_HASHTABLE_STRING,
WEECHAT_HASHTABLE_STRING,
NULL, NULL);
if (!overrides)
return;
for (i = 0; entries[i][0]; i++)
weechat_hashtable_set (overrides, entries[i][0], entries[i][1]);
weechat_theme_register (name, overrides);
weechat_hashtable_free (overrides);
}
/*
* Registers all built-in theme contributions from fset.
*/
void
fset_theme_init (void)
{
fset_theme_register ("light", fset_theme_light);
}
+27
View File
@@ -0,0 +1,27 @@
/*
* SPDX-FileCopyrightText: 2026 Sébastien Helleu <flashcode@flashtux.org>
*
* 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 <https://www.gnu.org/licenses/>.
*/
#ifndef WEECHAT_PLUGIN_FSET_THEME_H
#define WEECHAT_PLUGIN_FSET_THEME_H
extern void fset_theme_init (void);
#endif /* WEECHAT_PLUGIN_FSET_THEME_H */
+3
View File
@@ -35,6 +35,7 @@
#include "fset-info.h"
#include "fset-mouse.h"
#include "fset-option.h"
#include "fset-theme.h"
WEECHAT_PLUGIN_NAME(FSET_PLUGIN_NAME);
@@ -126,6 +127,8 @@ weechat_plugin_init (struct t_weechat_plugin *plugin, int argc, char *argv[])
fset_config_read ();
fset_theme_init ();
if (!fset_bar_item_init ())
return WEECHAT_RC_ERROR;
+27
View File
@@ -2003,6 +2003,32 @@ weechat_guile_api_config_unset_plugin (SCM option)
API_RETURN_INT(rc);
}
SCM
weechat_guile_api_theme_register (SCM name, SCM overrides)
{
struct t_hashtable *c_overrides;
const char *result;
SCM return_value;
API_INIT_FUNC(1, "theme_register", API_RETURN_EMPTY);
if (!scm_is_string (name) || !scm_list_p (overrides))
API_WRONG_ARGS(API_RETURN_EMPTY);
c_overrides = weechat_guile_alist_to_hashtable (overrides,
WEECHAT_SCRIPT_HASHTABLE_DEFAULT_SIZE,
WEECHAT_HASHTABLE_STRING,
WEECHAT_HASHTABLE_STRING);
result = API_PTR2STR(plugin_script_api_theme_register (
weechat_guile_plugin,
guile_current_script,
API_SCM_TO_STRING(name), c_overrides));
weechat_hashtable_free (c_overrides);
API_RETURN_STRING(result);
}
SCM
weechat_guile_api_key_bind (SCM context, SCM keys)
{
@@ -5537,6 +5563,7 @@ weechat_guile_api_module_init (void *data)
API_DEF_FUNC(config_set_plugin, 2);
API_DEF_FUNC(config_set_desc_plugin, 2);
API_DEF_FUNC(config_unset_plugin, 1);
API_DEF_FUNC(theme_register, 2);
API_DEF_FUNC(key_bind, 2);
API_DEF_FUNC(key_unbind, 2);
API_DEF_FUNC(prefix, 1);
+1
View File
@@ -48,6 +48,7 @@ add_library(irc MODULE
irc-sasl.c irc-sasl.h
irc-server.c irc-server.h
irc-tag.c irc-tag.h
irc-theme.c irc-theme.h
irc-typing.c irc-typing.h
irc-upgrade.c irc-upgrade.h
)
+1 -2
View File
@@ -2925,8 +2925,7 @@ void
irc_command_join_server (struct t_irc_server *server, const char *arguments,
int manual_join, int noswitch)
{
const char *pos_space, *pos_keys;
char *new_args, **channels, **keys, *pos_channel;
char *new_args, **channels, **keys, *pos_space, *pos_keys, *pos_channel;
char *channel_name_lower;
int i, num_channels, num_keys, length;
time_t time_now;
+2 -3
View File
@@ -470,7 +470,7 @@ irc_completion_modelist_masks_cb (const void *pointer, void *data,
struct t_gui_buffer *buffer,
struct t_gui_completion *completion)
{
const char *pos;
char *pos;
struct t_irc_modelist *ptr_modelist;
struct t_irc_modelist_item *ptr_item;
@@ -512,8 +512,7 @@ irc_completion_modelist_numbers_cb (const void *pointer, void *data,
struct t_gui_buffer *buffer,
struct t_gui_completion *completion)
{
const char *pos;
char str_number[32];
char *pos, str_number[32];
struct t_irc_modelist *ptr_modelist;
struct t_irc_modelist_item *ptr_item;
+12 -14
View File
@@ -201,8 +201,7 @@ struct t_irc_server *
irc_config_get_server_from_option_name (const char *name)
{
struct t_irc_server *ptr_server;
const char *pos_option;
char *server_name;
char *pos_option, *server_name;
ptr_server = NULL;
@@ -275,7 +274,7 @@ irc_config_compute_nick_colors (void)
int
irc_config_display_channel_modes_arguments (const char *modes)
{
const char *pos_space, *pos;
char *pos_space, *pos;
const char *ptr_mode;
pos_space = strchr (modes, ' ');
@@ -2812,8 +2811,7 @@ irc_config_server_read_cb (const void *pointer, void *data,
{
struct t_irc_server *ptr_server;
int index_option, rc, i;
const char *pos_option;
char *server_name;
char *pos_option, *server_name;
/* make C compiler happy */
(void) pointer;
@@ -2942,9 +2940,9 @@ irc_config_update_cb (const void *pointer, void *data,
int version_read,
struct t_hashtable *data_read)
{
const char *ptr_config, *ptr_section, *ptr_option, *ptr_value, *pos_option;
const char *ptr_config, *ptr_section, *ptr_option, *ptr_value;
const char *option_autojoin_delay = "autojoin_delay";
char *new_option, *pos_new_option, *new_value;
char *new_option, *pos_option, *new_value;
int changes, length;
/* make C compiler happy */
@@ -2999,11 +2997,11 @@ irc_config_update_cb (const void *pointer, void *data,
new_option = strdup (ptr_option);
if (new_option)
{
pos_new_option = strrchr (new_option, '.');
if (pos_new_option)
pos_option = strrchr (new_option, '.');
if (pos_option)
{
pos_new_option++;
memcpy (pos_new_option, "tls", 3);
pos_option++;
memcpy (pos_option, "tls", 3);
weechat_printf (
NULL,
_("IRC option renamed: \"irc.%s.%s\" => \"irc.%s.%s\""),
@@ -3961,7 +3959,7 @@ irc_config_init (void)
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
irc_config_color_mirc_remap = weechat_config_new_option (
irc_config_file, irc_config_section_color,
"mirc_remap", "string",
"mirc_remap", "string|themable",
/* TRANSLATORS: please do not translate the list of WeeChat color names at the end of string */
N_("remap mirc colors in messages using a hashtable (used only "
"for standard colors, not RGB colors): keys are \"fg,bg\" as "
@@ -3979,7 +3977,7 @@ irc_config_init (void)
NULL, NULL, NULL);
irc_config_color_nick_prefixes = weechat_config_new_option (
irc_config_file, irc_config_section_color,
"nick_prefixes", "string",
"nick_prefixes", "string|themable",
N_("color for nick prefixes using mode char (o=op, h=halfop, "
"v=voice, ..), format is: \"o:color1;h:color2;v:color3\" (if a "
"mode is not found, WeeChat will try with next modes received "
@@ -4010,7 +4008,7 @@ irc_config_init (void)
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
irc_config_color_term_remap = weechat_config_new_option (
irc_config_file, irc_config_section_color,
"term_remap", "string",
"term_remap", "string|themable",
N_("remap terminal color numbers in messages using a hashtable "
"(used only for RGB colors as hexadecimal, which are first "
"translated to terminal color numbers): keys are \"fg,bg\" as "
+15 -16
View File
@@ -67,8 +67,8 @@ irc_info_info_irc_is_channel_cb (const void *pointer, void *data,
const char *info_name,
const char *arguments)
{
char *server;
const char *pos_channel, *pos_comma;
char *pos_comma, *server;
const char *pos_channel;
struct t_irc_server *ptr_server;
/* make C compiler happy */
@@ -106,8 +106,8 @@ irc_info_info_irc_is_nick_cb (const void *pointer, void *data,
const char *info_name,
const char *arguments)
{
char *server;
const char *pos_nick, *pos_comma;
char *pos_comma, *server;
const char *pos_nick;
struct t_irc_server *ptr_server;
/* make C compiler happy */
@@ -233,8 +233,8 @@ irc_info_info_irc_buffer_cb (const void *pointer, void *data,
const char *info_name,
const char *arguments)
{
char *server, *channel, *host;
const char *nick, *pos_comma, *pos_comma2;
char *pos_comma, *pos_comma2, *server, *channel, *host;
const char *nick;
struct t_irc_server *ptr_server;
struct t_irc_channel *ptr_channel;
@@ -332,8 +332,8 @@ irc_info_info_irc_server_isupport_cb (const void *pointer, void *data,
const char *info_name,
const char *arguments)
{
char *server;
const char *isupport_value, *pos_comma;
char *pos_comma, *server;
const char *isupport_value;
struct t_irc_server *ptr_server;
/* make C compiler happy */
@@ -373,8 +373,8 @@ irc_info_info_irc_server_isupport_value_cb (const void *pointer, void *data,
const char *info_name,
const char *arguments)
{
char *server;
const char *isupport_value, *pos_comma;
char *pos_comma, *server;
const char *isupport_value;
struct t_irc_server *ptr_server;
/* make C compiler happy */
@@ -414,8 +414,7 @@ irc_info_info_irc_server_cap_cb (const void *pointer, void *data,
const char *info_name,
const char *arguments)
{
char *server;
const char *pos_comma;
char *pos_comma, *server;
int has_cap;
struct t_irc_server *ptr_server;
@@ -456,8 +455,8 @@ irc_info_info_irc_server_cap_value_cb (const void *pointer, void *data,
const char *info_name,
const char *arguments)
{
char *server;
const char *cap_value, *pos_comma;
char *pos_comma, *server;
const char *cap_value;
struct t_irc_server *ptr_server;
/* make C compiler happy */
@@ -497,8 +496,8 @@ irc_info_info_irc_is_message_ignored_cb (const void *pointer, void *data,
const char *info_name,
const char *arguments)
{
char *server;
const char *pos_message, *pos_comma;
char *pos_comma, *server;
const char *pos_message;
struct t_irc_server *ptr_server;
/* make C compiler happy */
+1 -1
View File
@@ -457,7 +457,7 @@ irc_input_send_cb (const void *pointer, void *data,
const char *type_data, void *signal_data)
{
const char *ptr_string, *ptr_message;
const char *pos_semicol1, *pos_semicol2, *pos_semicol3, *pos_semicol4;
char *pos_semicol1, *pos_semicol2, *pos_semicol3, *pos_semicol4;
char *server, *channel, *options, *tags, *data_with_colors, **list_options;
int i, num_options, flags, force_user_message;
struct t_irc_server *ptr_server;
+7 -9
View File
@@ -707,8 +707,8 @@ const char *
irc_message_get_nick_from_host (const char *host)
{
static char nick[128];
char host2[128];
const char *ptr_host, *pos_space, *pos;
char host2[128], *pos_space, *pos;
const char *ptr_host;
if (!host)
return NULL;
@@ -756,8 +756,8 @@ const char *
irc_message_get_address_from_host (const char *host)
{
static char address[256];
char host2[256];
const char *ptr_host, *pos_space, *pos;
char host2[256], *pos_space, *pos;
const char *ptr_host;
if (!host)
return NULL;
@@ -1182,9 +1182,8 @@ irc_message_split_join (struct t_irc_message_split_context *context,
{
int channels_count, keys_count, length, length_no_channel;
int length_to_add, index_channel;
char **channels, **keys, *str;
char **channels, **keys, *pos, *str;
char msg_to_send[16384], keys_to_add[16384];
const char *pos;
max_length -= 2; /* by default: 512 - 2 = 510 bytes */
@@ -1511,7 +1510,7 @@ irc_message_split_privmsg_notice (struct t_irc_message_split_context *context,
int
irc_message_split_005 (struct t_irc_message_split_context *context,
const char *tags, const char *host, const char *command,
const char *target, char *arguments,
const char *target, const char *arguments,
int max_length)
{
char *pos, suffix[4096];
@@ -1571,8 +1570,7 @@ irc_message_split (struct t_irc_server *server, const char *message)
{
struct t_irc_message_split_context split_context;
char **argv, **argv_eol, *tags, *host, *command, *arguments, target[4096];
char monitor_action[3];
const char *pos;
char *pos, monitor_action[3];
int split_ok, split_privmsg, argc, index_args, max_length_nick;
int max_length_user, max_length_host, max_length_nick_user_host;
int split_msg_max_length, multiline, multiline_max_bytes;
+2 -2
View File
@@ -104,8 +104,8 @@ irc_mode_get_arguments_colors (const char *arguments)
char
irc_mode_get_chanmode_type (struct t_irc_server *server, char chanmode)
{
char chanmode_type;
const char *chanmodes, *ptr_chanmodes, *pos;
char chanmode_type, *pos;
const char *chanmodes, *ptr_chanmodes;
/*
* assume it is type 'B' if mode is in prefix
+3 -2
View File
@@ -785,8 +785,9 @@ int
irc_notify_hsignal_cb (const void *pointer, void *data, const char *signal,
struct t_hashtable *hashtable)
{
const char *error, *server, *pattern, *command, *output, *ptr_args;
char **messages, **nicks_sent, **nicks_recv, *irc_cmd, *arguments, *pos;
const char *error, *server, *pattern, *command, *output;
char **messages, **nicks_sent, **nicks_recv, *irc_cmd, *arguments;
char *ptr_args, *pos;
int i, j, num_messages, num_nicks_sent, num_nicks_recv, nick_was_sent;
int away_message_updated, no_such_nick;
struct t_irc_server *ptr_server;
+8 -7
View File
@@ -2499,8 +2499,8 @@ IRC_PROTOCOL_CALLBACK(note)
IRC_PROTOCOL_CALLBACK(notice)
{
char *notice_args, end_char, *channel, str_tags[1024];
const char *pos, *pos_target, *pos_args, *nick_address;
char *notice_args, *pos, end_char, *channel, str_tags[1024];
const char *pos_target, *pos_args, *nick_address;
struct t_irc_channel *ptr_channel;
struct t_irc_nick *ptr_nick;
int notify_private, is_channel, is_channel_orig, display_host;
@@ -7921,11 +7921,12 @@ irc_protocol_recv_command (struct t_irc_server *server,
int ignore_batch_tag)
{
int i, cmd_found, return_code, ignored;
char *pos_space, *tags;
struct t_irc_channel *ptr_channel;
t_irc_recv_func *cmd_recv_func;
const char *ptr_msg_after_tags, *ptr_batch_ref, *ptr_tag_time;
const char *pos_space, *nick1, *address1, *host1;
char *tags, *host, *host_no_color, *pos_space_host;
const char *nick1, *address1, *host1;
char *host, *host_no_color;
struct t_irc_protocol_ctxt ctxt;
struct timeval tv;
@@ -8197,9 +8198,9 @@ irc_protocol_recv_command (struct t_irc_server *server,
host = (host1) ? strdup (host1) : NULL;
if (host)
{
pos_space_host = strchr (host, ' ');
if (pos_space_host)
pos_space_host[0] = '\0';
pos_space = strchr (host, ' ');
if (pos_space)
pos_space[0] = '\0';
}
host_no_color = (host) ? irc_color_decode (host, 0) : NULL;
ctxt.host = (host) ?
+1 -1
View File
@@ -616,7 +616,7 @@ void
irc_redirect_init_command (struct t_irc_redirect *redirect,
const char *command)
{
const char *pos;
char *pos;
if (!redirect)
return;
+152 -148
View File
@@ -588,7 +588,7 @@ irc_server_sasl_enabled (struct t_irc_server *server)
char *
irc_server_get_name_without_port (const char *name)
{
const char *pos;
char *pos;
if (!name)
return NULL;
@@ -1134,7 +1134,7 @@ void
irc_server_set_prefix_modes_chars (struct t_irc_server *server,
const char *prefix)
{
const char *pos;
char *pos;
int i, old_length_chars, length_modes, length_chars;
if (!server || !prefix)
@@ -1379,7 +1379,8 @@ irc_server_get_prefix_chars (struct t_irc_server *server)
int
irc_server_get_prefix_mode_index (struct t_irc_server *server, char mode)
{
const char *prefix_modes, *pos;
const char *prefix_modes;
char *pos;
if (server)
{
@@ -1404,7 +1405,8 @@ int
irc_server_get_prefix_char_index (struct t_irc_server *server,
char prefix_char)
{
const char *prefix_chars, *pos;
const char *prefix_chars;
char *pos;
if (server)
{
@@ -2441,8 +2443,8 @@ irc_server_copy (struct t_irc_server *server, const char *new_name)
{
struct t_irc_server *new_server;
struct t_infolist *infolist;
const char *option_name, *pos;
char *mask;
char *mask, *pos;
const char *option_name;
int index_option;
/* check if another server exists with this name */
@@ -2500,9 +2502,9 @@ irc_server_copy (struct t_irc_server *server, const char *new_name)
int
irc_server_rename (struct t_irc_server *server, const char *new_name)
{
char *mask, *new_option_name, charset_modifier[1024];
char *mask, *pos_option, *new_option_name, charset_modifier[1024];
char *buffer_name;
const char *option_name, *pos_option;
const char *option_name;
struct t_infolist *infolist;
struct t_config_option *ptr_option;
struct t_irc_channel *ptr_channel;
@@ -2997,8 +2999,8 @@ irc_server_send_one_msg (struct t_irc_server *server, int flags,
const char *tags)
{
static char buffer[4096];
const char *ptr_chan_nick;
char *new_msg, *ptr_msg, *pos, *tags_to_send, *msg_encoded;
const char *ptr_msg, *ptr_chan_nick;
char *new_msg, *pos, *tags_to_send, *msg_encoded;
char str_modifier[128], modifier_data[1024];
int first_message, queue_msg, pos_channel, pos_text, pos_encode;
struct t_irc_redirect *ptr_redirect;
@@ -3011,148 +3013,150 @@ irc_server_send_one_msg (struct t_irc_server *server, int flags,
server->name,
message);
/* message dropped? */
if (new_msg && !new_msg[0])
/* no changes in new message */
if (new_msg && (strcmp (message, new_msg) == 0))
{
free (new_msg);
new_msg = NULL;
}
/* message not dropped? */
if (!new_msg || new_msg[0])
{
first_message = 1;
ptr_msg = (new_msg) ? new_msg : message;
msg_encoded = NULL;
irc_message_parse (server,
ptr_msg,
NULL, /* tags */
NULL, /* message_without_tags */
NULL, /* nick */
NULL, /* user */
NULL, /* host */
NULL, /* command */
NULL, /* channel */
NULL, /* arguments */
NULL, /* text */
NULL, /* params */
NULL, /* num_params */
NULL, /* pos_command */
NULL, /* pos_arguments */
&pos_channel,
&pos_text);
switch (IRC_SERVER_OPTION_ENUM(server,
IRC_SERVER_OPTION_CHARSET_MESSAGE))
{
case IRC_SERVER_CHARSET_MESSAGE_MESSAGE:
pos_encode = 0;
break;
case IRC_SERVER_CHARSET_MESSAGE_CHANNEL:
pos_encode = (pos_channel >= 0) ? pos_channel : pos_text;
break;
case IRC_SERVER_CHARSET_MESSAGE_TEXT:
pos_encode = pos_text;
break;
default:
pos_encode = 0;
break;
}
if (pos_encode >= 0)
{
ptr_chan_nick = (channel) ? channel : nick;
if (ptr_chan_nick)
{
snprintf (modifier_data, sizeof (modifier_data),
"%s.%s.%s",
weechat_plugin->name,
server->name,
ptr_chan_nick);
}
else
{
snprintf (modifier_data, sizeof (modifier_data),
"%s.%s",
weechat_plugin->name,
server->name);
}
/*
* when UTF8ONLY is enabled, clients must not send non-UTF-8 data
* to the server; the charset encoding below is then done only if
* UTF8ONLY is *NOT* enabled
* (see: https://ircv3.net/specs/extensions/utf8-only)
*/
if (!server->utf8only)
{
msg_encoded = irc_message_convert_charset (ptr_msg, pos_encode,
"charset_encode",
modifier_data);
}
}
if (msg_encoded)
ptr_msg = msg_encoded;
while (ptr_msg && ptr_msg[0])
{
pos = strchr (ptr_msg, '\n');
if (pos)
pos[0] = '\0';
snprintf (buffer, sizeof (buffer), "%s\r\n", ptr_msg);
if (flags & IRC_SERVER_SEND_OUTQ_PRIO_IMMEDIATE)
queue_msg = 0;
else if (flags & IRC_SERVER_SEND_OUTQ_PRIO_HIGH)
queue_msg = 1;
else if (flags & IRC_SERVER_SEND_OUTQ_PRIO_LOW)
queue_msg = 2;
else
{
/*
* if connected to server (message 001 received), consider
* it's low priority (otherwise send immediately)
*/
queue_msg = (server->is_connected) ? 2 : 0;
}
tags_to_send = irc_server_get_tags_to_send (tags);
ptr_redirect = irc_redirect_search_available (server);
/* queue message (do not send anything now) */
irc_server_outqueue_add (server,
queue_msg,
command,
(new_msg && first_message) ? message : NULL,
buffer,
(new_msg) ? 1 : 0,
tags_to_send,
ptr_redirect);
/* mark redirect as "used" */
if (ptr_redirect)
ptr_redirect->assigned_to_command = 1;
free (tags_to_send);
if (pos)
{
pos[0] = '\n';
ptr_msg = pos + 1;
}
else
ptr_msg = NULL;
first_message = 0;
}
free (msg_encoded);
}
else
{
irc_raw_print (server, IRC_RAW_FLAG_SEND | IRC_RAW_FLAG_MODIFIED,
_("(message dropped)"));
free (new_msg);
return;
}
if (!new_msg)
new_msg = strdup (message);
if (!new_msg)
return;
first_message = 1;
ptr_msg = new_msg;
msg_encoded = NULL;
irc_message_parse (server,
ptr_msg,
NULL, /* tags */
NULL, /* message_without_tags */
NULL, /* nick */
NULL, /* user */
NULL, /* host */
NULL, /* command */
NULL, /* channel */
NULL, /* arguments */
NULL, /* text */
NULL, /* params */
NULL, /* num_params */
NULL, /* pos_command */
NULL, /* pos_arguments */
&pos_channel,
&pos_text);
switch (IRC_SERVER_OPTION_ENUM(server,
IRC_SERVER_OPTION_CHARSET_MESSAGE))
{
case IRC_SERVER_CHARSET_MESSAGE_MESSAGE:
pos_encode = 0;
break;
case IRC_SERVER_CHARSET_MESSAGE_CHANNEL:
pos_encode = (pos_channel >= 0) ? pos_channel : pos_text;
break;
case IRC_SERVER_CHARSET_MESSAGE_TEXT:
pos_encode = pos_text;
break;
default:
pos_encode = 0;
break;
}
if (pos_encode >= 0)
{
ptr_chan_nick = (channel) ? channel : nick;
if (ptr_chan_nick)
{
snprintf (modifier_data, sizeof (modifier_data),
"%s.%s.%s",
weechat_plugin->name,
server->name,
ptr_chan_nick);
}
else
{
snprintf (modifier_data, sizeof (modifier_data),
"%s.%s",
weechat_plugin->name,
server->name);
}
/*
* when UTF8ONLY is enabled, clients must not send non-UTF-8 data
* to the server; the charset encoding below is then done only if
* UTF8ONLY is *NOT* enabled
* (see: https://ircv3.net/specs/extensions/utf8-only)
*/
if (!server->utf8only)
{
msg_encoded = irc_message_convert_charset (ptr_msg, pos_encode,
"charset_encode",
modifier_data);
}
}
if (msg_encoded)
ptr_msg = msg_encoded;
while (ptr_msg && ptr_msg[0])
{
pos = strchr (ptr_msg, '\n');
if (pos)
pos[0] = '\0';
snprintf (buffer, sizeof (buffer), "%s\r\n", ptr_msg);
if (flags & IRC_SERVER_SEND_OUTQ_PRIO_IMMEDIATE)
queue_msg = 0;
else if (flags & IRC_SERVER_SEND_OUTQ_PRIO_HIGH)
queue_msg = 1;
else if (flags & IRC_SERVER_SEND_OUTQ_PRIO_LOW)
queue_msg = 2;
else
{
/*
* if connected to server (message 001 received), consider
* it's low priority (otherwise send immediately)
*/
queue_msg = (server->is_connected) ? 2 : 0;
}
tags_to_send = irc_server_get_tags_to_send (tags);
ptr_redirect = irc_redirect_search_available (server);
/* queue message (do not send anything now) */
irc_server_outqueue_add (server,
queue_msg,
command,
(new_msg && first_message) ? message : NULL,
buffer,
(new_msg) ? 1 : 0,
tags_to_send,
ptr_redirect);
/* mark redirect as "used" */
if (ptr_redirect)
ptr_redirect->assigned_to_command = 1;
free (tags_to_send);
if (pos)
{
pos[0] = '\n';
ptr_msg = pos + 1;
}
else
ptr_msg = NULL;
first_message = 0;
}
free (msg_encoded);
free (new_msg);
}
@@ -3446,7 +3450,7 @@ irc_server_msgq_add_unterminated (struct t_irc_server *server,
*/
void
irc_server_msgq_add_buffer (struct t_irc_server *server, char *buffer)
irc_server_msgq_add_buffer (struct t_irc_server *server, const char *buffer)
{
char *pos_cr, *pos_lf;
+1 -1
View File
@@ -427,7 +427,7 @@ extern struct t_arraylist *irc_server_sendf (struct t_irc_server *server,
const char *tags,
const char *format, ...);
extern void irc_server_msgq_add_buffer (struct t_irc_server *server,
char *buffer);
const char *buffer);
extern void irc_server_msgq_flush (void);
extern void irc_server_set_buffer_title (struct t_irc_server *server);
extern struct t_gui_buffer *irc_server_create_buffer (struct t_irc_server *server);
+93
View File
@@ -0,0 +1,93 @@
/*
* SPDX-FileCopyrightText: 2026 Sébastien Helleu <flashcode@flashtux.org>
*
* 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 <https://www.gnu.org/licenses/>.
*/
/* IRC plugin contribution to built-in themes. */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stddef.h>
#include "../weechat-plugin.h"
#include "irc.h"
#include "irc-theme.h"
/*
* IRC contribution to the "light" theme: option values tuned for a
* light-background terminal. Each row is { option_full_name, value };
* the table is NULL-terminated.
*/
const char *irc_theme_light[][2] =
{
{ "irc.color.input_nick", "cyan" },
{ "irc.color.item_lag_finished", "94" },
{ "irc.color.item_tls_version_deprecated", "202" },
{ "irc.color.list_buffer_line_selected", "default" },
{ "irc.color.message_chghost", "94" },
{ "irc.color.message_setname", "94" },
{ "irc.color.nick_prefixes",
"y:red;q:red;a:cyan;o:green;h:magenta;v:94;*:blue" },
{ "irc.color.topic_new", "28" },
{ "irc.color.topic_old", "darkgray" },
{ NULL, NULL },
};
/*
* Registers IRC's contribution to one theme from a NULL-terminated
* table of {option, value} rows.
*/
void
irc_theme_register (const char *name, const char *entries[][2])
{
struct t_hashtable *overrides;
int i;
if (!name || !entries)
return;
overrides = weechat_hashtable_new (32,
WEECHAT_HASHTABLE_STRING,
WEECHAT_HASHTABLE_STRING,
NULL, NULL);
if (!overrides)
return;
for (i = 0; entries[i][0]; i++)
weechat_hashtable_set (overrides, entries[i][0], entries[i][1]);
weechat_theme_register (name, overrides);
weechat_hashtable_free (overrides);
}
/*
* Registers all built-in theme contributions from IRC.
*/
void
irc_theme_init (void)
{
irc_theme_register ("light", irc_theme_light);
}
+27
View File
@@ -0,0 +1,27 @@
/*
* SPDX-FileCopyrightText: 2026 Sébastien Helleu <flashcode@flashtux.org>
*
* 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 <https://www.gnu.org/licenses/>.
*/
#ifndef WEECHAT_PLUGIN_IRC_THEME_H
#define WEECHAT_PLUGIN_IRC_THEME_H
extern void irc_theme_init (void);
#endif /* WEECHAT_PLUGIN_IRC_THEME_H */
+3
View File
@@ -47,6 +47,7 @@
#include "irc-redirect.h"
#include "irc-server.h"
#include "irc-tag.h"
#include "irc-theme.h"
#include "irc-typing.h"
#include "irc-upgrade.h"
@@ -217,6 +218,8 @@ weechat_plugin_init (struct t_weechat_plugin *plugin, int argc, char *argv[])
irc_config_read ();
irc_theme_init ();
irc_list_init ();
irc_raw_init ();
+26
View File
@@ -1898,6 +1898,31 @@ API_FUNC(config_unset_plugin)
API_RETURN_INT(rc);
}
API_FUNC(theme_register)
{
struct t_hashtable *hashtable;
const char *result;
API_INIT_FUNC(1, "theme_register", "sh", API_RETURN_EMPTY);
v8::String::Utf8Value name(args[0]);
hashtable = weechat_js_object_to_hashtable (
args[1]->ToObject(),
WEECHAT_SCRIPT_HASHTABLE_DEFAULT_SIZE,
WEECHAT_HASHTABLE_STRING,
WEECHAT_HASHTABLE_STRING);
result = API_PTR2STR(plugin_script_api_theme_register (
weechat_js_plugin,
js_current_script,
*name, hashtable));
if (hashtable)
weechat_hashtable_free (hashtable);
API_RETURN_STRING(result);
}
API_FUNC(key_bind)
{
struct t_hashtable *hashtable;
@@ -5468,6 +5493,7 @@ WeechatJsV8::loadLibs()
API_DEF_FUNC(config_set_plugin);
API_DEF_FUNC(config_set_desc_plugin);
API_DEF_FUNC(config_unset_plugin);
API_DEF_FUNC(theme_register);
API_DEF_FUNC(key_bind);
API_DEF_FUNC(key_unbind);
API_DEF_FUNC(prefix);
+1
View File
@@ -27,6 +27,7 @@ add_library(logger MODULE
logger-config.c logger-config.h
logger-info.c logger-info.h
logger-tail.c logger-tail.h
logger-theme.c logger-theme.h
)
set_target_properties(logger PROPERTIES PREFIX "")
+70
View File
@@ -0,0 +1,70 @@
/*
* SPDX-FileCopyrightText: 2026 Sébastien Helleu <flashcode@flashtux.org>
*
* 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 <https://www.gnu.org/licenses/>.
*/
/* logger contribution to built-in themes. */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stddef.h>
#include "../weechat-plugin.h"
#include "logger.h"
#include "logger-theme.h"
const char *logger_theme_light[][2] =
{
{ "logger.color.backlog_end", "darkgray" },
{ "logger.color.backlog_line", "darkgray" },
{ NULL, NULL },
};
void
logger_theme_register (const char *name, const char *entries[][2])
{
struct t_hashtable *overrides;
int i;
if (!name || !entries)
return;
overrides = weechat_hashtable_new (32,
WEECHAT_HASHTABLE_STRING,
WEECHAT_HASHTABLE_STRING,
NULL, NULL);
if (!overrides)
return;
for (i = 0; entries[i][0]; i++)
weechat_hashtable_set (overrides, entries[i][0], entries[i][1]);
weechat_theme_register (name, overrides);
weechat_hashtable_free (overrides);
}
void
logger_theme_init (void)
{
logger_theme_register ("light", logger_theme_light);
}
+27
View File
@@ -0,0 +1,27 @@
/*
* SPDX-FileCopyrightText: 2026 Sébastien Helleu <flashcode@flashtux.org>
*
* 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 <https://www.gnu.org/licenses/>.
*/
#ifndef WEECHAT_PLUGIN_LOGGER_THEME_H
#define WEECHAT_PLUGIN_LOGGER_THEME_H
extern void logger_theme_init (void);
#endif /* WEECHAT_PLUGIN_LOGGER_THEME_H */
+3
View File
@@ -36,6 +36,7 @@
#include "logger-command.h"
#include "logger-config.h"
#include "logger-info.h"
#include "logger-theme.h"
WEECHAT_PLUGIN_NAME(LOGGER_PLUGIN_NAME);
@@ -785,6 +786,8 @@ weechat_plugin_init (struct t_weechat_plugin *plugin, int argc, char *argv[])
logger_config_read ();
logger_theme_init ();
logger_command_init ();
logger_buffer_start_all (1);

Some files were not shown because too many files have changed in this diff Show More