mirror of
https://github.com/weechat/weechat.git
synced 2026-06-12 14:14:48 +02:00
Compare commits
46 Commits
5f4c25052c
...
2e88586ade
| Author | SHA1 | Date | |
|---|---|---|---|
| 2e88586ade | |||
| 91e926ee22 | |||
| e5542a58fc | |||
| 94e5b65ecb | |||
| 6360925e55 | |||
| bb2b1f9870 | |||
| 2bbcd8a68f | |||
| ad3b7b825c | |||
| 3858e6e1c8 | |||
| 7bb23896e7 | |||
| 2a94a90b36 | |||
| 75bd55d17c | |||
| 84f5fd92d6 | |||
| 018f9797d7 | |||
| 7934778ae3 | |||
| 466a93054e | |||
| 0036138243 | |||
| 097f910f77 | |||
| adaa7e8f87 | |||
| f117b74933 | |||
| 47addb88b6 | |||
| 14616347c8 | |||
| 2a3082636c | |||
| ff4d9d638c | |||
| f49ac1aaf9 | |||
| 18c4993424 | |||
| 8be6cff05f | |||
| 144d79f331 | |||
| 74faa91578 | |||
| 1bad1f60d7 | |||
| 6b5b0d8915 | |||
| a7b41b6321 | |||
| e1a6fba1b4 | |||
| 540dd7d612 | |||
| 426caf4bdf | |||
| c307087e2d | |||
| 51a1149852 | |||
| d74993a42c | |||
| 51464e400f | |||
| 1c5e6c3fc2 | |||
| e563dfc903 | |||
| befbcceb7f | |||
| 56f9ad68fb | |||
| 328f86affc | |||
| f4dc30ec58 | |||
| 23291acb7b |
@@ -12,9 +12,17 @@ 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)
|
||||
- relay/api: add field "last_read_line_id" in GET /api/buffers
|
||||
|
||||
### Added
|
||||
|
||||
- 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))
|
||||
|
||||
### Fixed
|
||||
@@ -24,10 +32,15 @@ SPDX-License-Identifier: GPL-3.0-or-later
|
||||
- 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))
|
||||
- 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))
|
||||
- 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))
|
||||
- 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))
|
||||
|
||||
## Version 4.9.1 (2026-05-31)
|
||||
|
||||
|
||||
+1
-1
@@ -30,7 +30,7 @@ if(ENABLE_MAN OR ENABLE_DOC)
|
||||
set(SCRIPTING_LANG de en fr it ja pl sr)
|
||||
set(FAQ_LANG de en es fr it ja pl sr)
|
||||
set(QUICKSTART_LANG cs de en es fr it ja pl ru sr)
|
||||
set(RELAY_API_LANG en fr)
|
||||
set(RELAY_API_LANG en fr sr)
|
||||
set(RELAY_WEECHAT_LANG en fr ja sr)
|
||||
set(DEV_LANG en fr ja sr)
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -541,7 +541,8 @@ HTTP/1.1 200 OK
|
||||
"plugin": "core",
|
||||
"name": "weechat"
|
||||
},
|
||||
"keys": []
|
||||
"keys": [],
|
||||
"last_read_line_id": -1
|
||||
},
|
||||
{
|
||||
"id": 1709932823423765,
|
||||
@@ -571,7 +572,8 @@ HTTP/1.1 200 OK
|
||||
"tls_version": "TLS1.3",
|
||||
"host": "~alice@example.com"
|
||||
},
|
||||
"keys": []
|
||||
"keys": [],
|
||||
"last_read_line_id": -1
|
||||
},
|
||||
{
|
||||
"id": 1709932823649069,
|
||||
@@ -599,7 +601,8 @@ HTTP/1.1 200 OK
|
||||
"nick": "alice",
|
||||
"host": "~alice@example.com"
|
||||
},
|
||||
"keys": []
|
||||
"keys": [],
|
||||
"last_read_line_id": -1
|
||||
}
|
||||
]
|
||||
----
|
||||
@@ -655,7 +658,8 @@ HTTP/1.1 200 OK
|
||||
"message": "Plugins loaded: alias, buflist, charset, exec, fifo, fset, guile, irc, javascript, logger, lua, perl, php, python, relay, ruby, script, spell, tcl, trigger, typing, xfer",
|
||||
"tags": []
|
||||
}
|
||||
]
|
||||
],
|
||||
"last_read_line_id": -1
|
||||
}
|
||||
----
|
||||
|
||||
@@ -702,6 +706,7 @@ HTTP/1.1 200 OK
|
||||
"host": "~alice@example.com"
|
||||
},
|
||||
"keys": [],
|
||||
"last_read_line_id": -1,
|
||||
"nicklist_root": {
|
||||
"id": 0,
|
||||
"parent_group_id": -1,
|
||||
@@ -900,7 +905,8 @@ HTTP/1.1 200 OK
|
||||
"key": "up",
|
||||
"command": "/fset -up"
|
||||
}
|
||||
]
|
||||
],
|
||||
"last_read_line_id": -1
|
||||
}
|
||||
----
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -551,7 +551,8 @@ HTTP/1.1 200 OK
|
||||
"plugin": "core",
|
||||
"name": "weechat"
|
||||
},
|
||||
"keys": []
|
||||
"keys": [],
|
||||
"last_read_line_id": -1
|
||||
},
|
||||
{
|
||||
"id": 1709932823423765,
|
||||
@@ -580,7 +581,8 @@ HTTP/1.1 200 OK
|
||||
"tls_version": "TLS1.3",
|
||||
"host": "~alice@example.com"
|
||||
},
|
||||
"keys": []
|
||||
"keys": [],
|
||||
"last_read_line_id": -1
|
||||
},
|
||||
{
|
||||
"id": 1709932823649069,
|
||||
@@ -607,7 +609,8 @@ HTTP/1.1 200 OK
|
||||
"nick": "alice",
|
||||
"host": "~alice@example.com"
|
||||
},
|
||||
"keys": []
|
||||
"keys": [],
|
||||
"last_read_line_id": -1
|
||||
}
|
||||
]
|
||||
----
|
||||
@@ -663,7 +666,8 @@ HTTP/1.1 200 OK
|
||||
"message": "Plugins loaded: alias, buflist, charset, exec, fifo, fset, guile, irc, javascript, logger, lua, perl, php, python, relay, ruby, script, spell, tcl, trigger, typing, xfer",
|
||||
"tags": []
|
||||
}
|
||||
]
|
||||
],
|
||||
"last_read_line_id": -1
|
||||
}
|
||||
----
|
||||
|
||||
@@ -709,6 +713,7 @@ HTTP/1.1 200 OK
|
||||
"host": "~alice@example.com"
|
||||
},
|
||||
"keys": [],
|
||||
"last_read_line_id": -1,
|
||||
"nicklist_root": {
|
||||
"id": 0,
|
||||
"parent_group_id": -1,
|
||||
@@ -906,7 +911,8 @@ HTTP/1.1 200 OK
|
||||
"key": "up",
|
||||
"command": "/fset -up"
|
||||
}
|
||||
]
|
||||
],
|
||||
"last_read_line_id": -1
|
||||
}
|
||||
----
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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]]
|
||||
=== キー割り当て
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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]]
|
||||
=== Тастерске пречице
|
||||
|
||||
|
||||
@@ -543,7 +543,8 @@ HTTP/1.1 200 OK
|
||||
"plugin": "core",
|
||||
"name": "weechat"
|
||||
},
|
||||
"keys": []
|
||||
"keys": [],
|
||||
"last_read_line_id": -1
|
||||
},
|
||||
{
|
||||
"id": 1709932823423765,
|
||||
@@ -573,7 +574,8 @@ HTTP/1.1 200 OK
|
||||
"tls_version": "TLS1.3",
|
||||
"host": "~alice@example.com"
|
||||
},
|
||||
"keys": []
|
||||
"keys": [],
|
||||
"last_read_line_id": -1
|
||||
},
|
||||
{
|
||||
"id": 1709932823649069,
|
||||
@@ -601,7 +603,8 @@ HTTP/1.1 200 OK
|
||||
"nick": "alice",
|
||||
"host": "~alice@example.com"
|
||||
},
|
||||
"keys": []
|
||||
"keys": [],
|
||||
"last_read_line_id": -1
|
||||
}
|
||||
]
|
||||
----
|
||||
@@ -657,7 +660,8 @@ HTTP/1.1 200 OK
|
||||
"message": "Учитани додаци: alias, buflist, charset, exec, fifo, fset, guile, irc, javascript, logger, lua, perl, php, python, relay, ruby, script, spell, tcl, trigger, typing, xfer",
|
||||
"tags": []
|
||||
}
|
||||
]
|
||||
],
|
||||
"last_read_line_id": -1
|
||||
}
|
||||
----
|
||||
|
||||
@@ -704,6 +708,7 @@ HTTP/1.1 200 OK
|
||||
"host": "~alice@example.com"
|
||||
},
|
||||
"keys": [],
|
||||
"last_read_line_id": -1,
|
||||
"nicklist_root": {
|
||||
"id": 0,
|
||||
"parent_group_id": -1,
|
||||
@@ -902,7 +907,8 @@ HTTP/1.1 200 OK
|
||||
"key": "up",
|
||||
"command": "/fset -up"
|
||||
}
|
||||
]
|
||||
],
|
||||
"last_read_line_id": -1
|
||||
}
|
||||
----
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"),
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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,16 +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;
|
||||
char *pos, *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)
|
||||
{
|
||||
@@ -734,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;
|
||||
@@ -744,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
|
||||
@@ -784,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);
|
||||
@@ -969,6 +996,7 @@ error:
|
||||
end:
|
||||
free (option_name);
|
||||
free (parent_name);
|
||||
free (type_name);
|
||||
return new_option;
|
||||
}
|
||||
|
||||
@@ -2438,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)
|
||||
@@ -4247,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);
|
||||
@@ -4359,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);
|
||||
@@ -4523,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);
|
||||
|
||||
@@ -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 */
|
||||
|
||||
+37
-14
@@ -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);
|
||||
@@ -3446,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 "
|
||||
@@ -3470,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 "
|
||||
@@ -3637,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 "
|
||||
@@ -3650,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 "
|
||||
@@ -3967,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)"),
|
||||
@@ -4022,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 "
|
||||
@@ -4114,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)"),
|
||||
@@ -4124,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)"),
|
||||
@@ -4134,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)"),
|
||||
@@ -4144,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)"),
|
||||
@@ -4154,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)"),
|
||||
@@ -4423,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",
|
||||
@@ -4643,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: "
|
||||
@@ -4914,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 "
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
@@ -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 */
|
||||
+40
-13
@@ -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 */
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 "")
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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 */
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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 "")
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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 */
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 "")
|
||||
|
||||
|
||||
@@ -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"),
|
||||
|
||||
@@ -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); "
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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 */
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
)
|
||||
|
||||
@@ -3959,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 "
|
||||
@@ -3977,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 "
|
||||
@@ -4008,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 "
|
||||
|
||||
@@ -857,7 +857,7 @@ irc_ctcp_recv_dcc (struct t_irc_protocol_ctxt *ctxt, const char *arguments)
|
||||
* double-quote
|
||||
*/
|
||||
pos = strrchr (pos_file, '"');
|
||||
if (!pos || (pos == pos_file))
|
||||
if (!pos || (pos == pos_file) || !pos[1])
|
||||
{
|
||||
weechat_printf (
|
||||
ctxt->server->buffer,
|
||||
@@ -1032,7 +1032,7 @@ irc_ctcp_recv_dcc (struct t_irc_protocol_ctxt *ctxt, const char *arguments)
|
||||
* double-quote
|
||||
*/
|
||||
pos = strrchr (pos_file, '"');
|
||||
if (!pos || (pos == pos_file))
|
||||
if (!pos || (pos == pos_file) || !pos[1])
|
||||
{
|
||||
weechat_printf (
|
||||
ctxt->server->buffer,
|
||||
@@ -1176,7 +1176,7 @@ irc_ctcp_recv_dcc (struct t_irc_protocol_ctxt *ctxt, const char *arguments)
|
||||
* double-quote
|
||||
*/
|
||||
pos = strrchr (pos_file, '"');
|
||||
if (!pos || (pos == pos_file))
|
||||
if (!pos || (pos == pos_file) || !pos[1])
|
||||
{
|
||||
weechat_printf (
|
||||
ctxt->server->buffer,
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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 */
|
||||
@@ -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 ();
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 "")
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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 */
|
||||
@@ -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);
|
||||
|
||||
@@ -2081,6 +2081,32 @@ API_FUNC(config_unset_plugin)
|
||||
API_RETURN_INT(rc);
|
||||
}
|
||||
|
||||
API_FUNC(theme_register)
|
||||
{
|
||||
const char *name;
|
||||
struct t_hashtable *hashtable;
|
||||
const char *result;
|
||||
|
||||
API_INIT_FUNC(1, "theme_register", API_RETURN_EMPTY);
|
||||
if (lua_gettop (L) < 2)
|
||||
API_WRONG_ARGS(API_RETURN_EMPTY);
|
||||
|
||||
name = lua_tostring (L, -2);
|
||||
hashtable = weechat_lua_tohashtable (L, -1,
|
||||
WEECHAT_SCRIPT_HASHTABLE_DEFAULT_SIZE,
|
||||
WEECHAT_HASHTABLE_STRING,
|
||||
WEECHAT_HASHTABLE_STRING);
|
||||
|
||||
result = API_PTR2STR(plugin_script_api_theme_register (
|
||||
weechat_lua_plugin,
|
||||
lua_current_script,
|
||||
name, hashtable));
|
||||
|
||||
weechat_hashtable_free (hashtable);
|
||||
|
||||
API_RETURN_STRING(result);
|
||||
}
|
||||
|
||||
API_FUNC(key_bind)
|
||||
{
|
||||
const char *context;
|
||||
@@ -5849,6 +5875,7 @@ const struct luaL_Reg weechat_lua_api_funcs[] = {
|
||||
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),
|
||||
|
||||
@@ -2000,6 +2000,33 @@ API_FUNC(config_unset_plugin)
|
||||
API_RETURN_INT(rc);
|
||||
}
|
||||
|
||||
API_FUNC(theme_register)
|
||||
{
|
||||
char *name;
|
||||
struct t_hashtable *hashtable;
|
||||
const char *result;
|
||||
dXSARGS;
|
||||
|
||||
API_INIT_FUNC(1, "theme_register", API_RETURN_EMPTY);
|
||||
if (items < 2)
|
||||
API_WRONG_ARGS(API_RETURN_EMPTY);
|
||||
|
||||
name = SvPV_nolen (ST (0));
|
||||
hashtable = weechat_perl_hash_to_hashtable (ST (1),
|
||||
WEECHAT_SCRIPT_HASHTABLE_DEFAULT_SIZE,
|
||||
WEECHAT_HASHTABLE_STRING,
|
||||
WEECHAT_HASHTABLE_STRING);
|
||||
|
||||
result = API_PTR2STR(plugin_script_api_theme_register (
|
||||
weechat_perl_plugin,
|
||||
perl_current_script,
|
||||
name, hashtable));
|
||||
|
||||
weechat_hashtable_free (hashtable);
|
||||
|
||||
API_RETURN_STRING(result);
|
||||
}
|
||||
|
||||
API_FUNC(key_bind)
|
||||
{
|
||||
char *context;
|
||||
@@ -5801,6 +5828,7 @@ weechat_perl_api_init (pTHX)
|
||||
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);
|
||||
|
||||
@@ -2175,6 +2175,35 @@ API_FUNC(config_unset_plugin)
|
||||
API_RETURN_INT(result);
|
||||
}
|
||||
|
||||
API_FUNC(theme_register)
|
||||
{
|
||||
zend_string *z_name;
|
||||
zval *z_overrides;
|
||||
char *name;
|
||||
struct t_hashtable *overrides;
|
||||
const char *result;
|
||||
|
||||
API_INIT_FUNC(1, "theme_register", API_RETURN_EMPTY);
|
||||
if (zend_parse_parameters (ZEND_NUM_ARGS(), "Sa", &z_name,
|
||||
&z_overrides) == FAILURE)
|
||||
API_WRONG_ARGS(API_RETURN_EMPTY);
|
||||
|
||||
name = ZSTR_VAL(z_name);
|
||||
overrides = weechat_php_array_to_hashtable (z_overrides,
|
||||
WEECHAT_SCRIPT_HASHTABLE_DEFAULT_SIZE,
|
||||
WEECHAT_HASHTABLE_STRING,
|
||||
WEECHAT_HASHTABLE_STRING);
|
||||
|
||||
result = API_PTR2STR(plugin_script_api_theme_register (
|
||||
weechat_php_plugin,
|
||||
php_current_script,
|
||||
(const char *)name, overrides));
|
||||
|
||||
weechat_hashtable_free (overrides);
|
||||
|
||||
API_RETURN_STRING(result);
|
||||
}
|
||||
|
||||
API_FUNC(key_bind)
|
||||
{
|
||||
zend_string *z_context;
|
||||
|
||||
@@ -132,6 +132,7 @@ PHP_FUNCTION(weechat_config_is_set_plugin);
|
||||
PHP_FUNCTION(weechat_config_set_plugin);
|
||||
PHP_FUNCTION(weechat_config_set_desc_plugin);
|
||||
PHP_FUNCTION(weechat_config_unset_plugin);
|
||||
PHP_FUNCTION(weechat_theme_register);
|
||||
PHP_FUNCTION(weechat_key_bind);
|
||||
PHP_FUNCTION(weechat_key_unbind);
|
||||
PHP_FUNCTION(weechat_prefix);
|
||||
|
||||
@@ -190,6 +190,7 @@ const zend_function_entry weechat_functions[] = {
|
||||
PHP_FE(weechat_config_set_plugin, arginfo_weechat_config_set_plugin)
|
||||
PHP_FE(weechat_config_set_desc_plugin, arginfo_weechat_config_set_desc_plugin)
|
||||
PHP_FE(weechat_config_unset_plugin, arginfo_weechat_config_unset_plugin)
|
||||
PHP_FE(weechat_theme_register, arginfo_weechat_theme_register)
|
||||
PHP_FE(weechat_key_bind, arginfo_weechat_key_bind)
|
||||
PHP_FE(weechat_key_unbind, arginfo_weechat_key_unbind)
|
||||
PHP_FE(weechat_prefix, arginfo_weechat_prefix)
|
||||
|
||||
@@ -233,6 +233,11 @@ ZEND_END_ARG_INFO()
|
||||
|
||||
#define arginfo_weechat_config_unset_plugin arginfo_weechat_charset_set
|
||||
|
||||
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_weechat_theme_register, 0, 2, IS_STRING, 0)
|
||||
ZEND_ARG_TYPE_INFO(0, p0, IS_STRING, 0)
|
||||
ZEND_ARG_TYPE_INFO(0, p1, IS_ARRAY, 0)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_weechat_key_bind, 0, 2, IS_LONG, 0)
|
||||
ZEND_ARG_TYPE_INFO(0, p0, IS_STRING, 0)
|
||||
ZEND_ARG_TYPE_INFO(0, p1, IS_ARRAY, 0)
|
||||
|
||||
@@ -194,6 +194,8 @@ ZEND_END_ARG_INFO()
|
||||
|
||||
#define arginfo_weechat_config_unset_plugin arginfo_weechat_plugin_get_name
|
||||
|
||||
#define arginfo_weechat_theme_register arginfo_weechat_iconv_to_internal
|
||||
|
||||
#define arginfo_weechat_key_bind arginfo_weechat_iconv_to_internal
|
||||
|
||||
#define arginfo_weechat_key_unbind arginfo_weechat_iconv_to_internal
|
||||
|
||||
@@ -1568,6 +1568,28 @@ plugin_script_api_config_unset_plugin (struct t_weechat_plugin *weechat_plugin,
|
||||
return return_code;
|
||||
}
|
||||
|
||||
/*
|
||||
* Register theme overrides on behalf of a script.
|
||||
*
|
||||
* Forwards to weechat_plugin->theme_register with the script pointer
|
||||
* as the owner, so the contribution can be auto-purged when the
|
||||
* script unloads (see plugin_script_remove_themes).
|
||||
*/
|
||||
|
||||
struct t_theme *
|
||||
plugin_script_api_theme_register (struct t_weechat_plugin *weechat_plugin,
|
||||
struct t_plugin_script *script,
|
||||
const char *name,
|
||||
struct t_hashtable *overrides)
|
||||
{
|
||||
if (!script)
|
||||
return NULL;
|
||||
return (weechat_plugin->theme_register) (weechat_plugin,
|
||||
script,
|
||||
name,
|
||||
overrides);
|
||||
}
|
||||
|
||||
/*
|
||||
* Create an upgrade file.
|
||||
*
|
||||
|
||||
@@ -438,6 +438,10 @@ extern void plugin_script_api_config_set_desc_plugin (struct t_weechat_plugin *w
|
||||
extern int plugin_script_api_config_unset_plugin (struct t_weechat_plugin *weechat_plugin,
|
||||
struct t_plugin_script *script,
|
||||
const char *option);
|
||||
extern struct t_theme *plugin_script_api_theme_register (struct t_weechat_plugin *weechat_plugin,
|
||||
struct t_plugin_script *script,
|
||||
const char *name,
|
||||
struct t_hashtable *overrides);
|
||||
extern struct t_upgrade_file *plugin_script_api_upgrade_new (struct t_weechat_plugin *weechat_plugin,
|
||||
struct t_plugin_script *script,
|
||||
const char *filename,
|
||||
|
||||
@@ -1080,6 +1080,18 @@ plugin_script_free (struct t_plugin_script *script)
|
||||
free (script);
|
||||
}
|
||||
|
||||
/*
|
||||
* Remove all theme contributions registered by this script.
|
||||
*/
|
||||
|
||||
void
|
||||
plugin_script_remove_themes (struct t_weechat_plugin *weechat_plugin,
|
||||
struct t_plugin_script *script)
|
||||
{
|
||||
weechat_theme_unregister_script (script);
|
||||
(void) weechat_plugin; /* used implicitly via the macro */
|
||||
}
|
||||
|
||||
/*
|
||||
* Remove a script from list of scripts.
|
||||
*/
|
||||
@@ -1101,6 +1113,8 @@ plugin_script_remove (struct t_weechat_plugin *weechat_plugin,
|
||||
|
||||
plugin_script_remove_configs (weechat_plugin, script);
|
||||
|
||||
plugin_script_remove_themes (weechat_plugin, script);
|
||||
|
||||
/*
|
||||
* remove again all hooks created by this script (just in case new hooks
|
||||
* were created by the calls above)
|
||||
|
||||
@@ -50,6 +50,7 @@
|
||||
#include "../core/core-log.h"
|
||||
#include "../core/core-network.h"
|
||||
#include "../core/core-string.h"
|
||||
#include "../core/core-theme.h"
|
||||
#include "../core/core-upgrade-file.h"
|
||||
#include "../core/core-utf8.h"
|
||||
#include "../core/core-util.h"
|
||||
@@ -799,6 +800,9 @@ plugin_load (const char *filename, int init_plugin, int argc, char **argv)
|
||||
new_plugin->config_set_desc_plugin = &plugin_api_config_set_desc_plugin;
|
||||
new_plugin->config_unset_plugin = &plugin_api_config_unset_plugin;
|
||||
|
||||
new_plugin->theme_register = &theme_register;
|
||||
new_plugin->theme_unregister_script = &theme_unregister_script;
|
||||
|
||||
new_plugin->key_bind = &gui_key_bind_plugin;
|
||||
new_plugin->key_unbind = &gui_key_unbind_plugin;
|
||||
|
||||
@@ -1214,6 +1218,9 @@ plugin_remove (struct t_weechat_plugin *plugin)
|
||||
/* remove all configuration files */
|
||||
config_file_free_all_plugin (plugin);
|
||||
|
||||
/* remove all theme contributions registered by this plugin */
|
||||
theme_unregister_plugin (plugin);
|
||||
|
||||
/* remove all hooks */
|
||||
unhook_all_plugin (plugin, NULL);
|
||||
|
||||
|
||||
@@ -2001,6 +2001,34 @@ API_FUNC(config_unset_plugin)
|
||||
API_RETURN_INT(rc);
|
||||
}
|
||||
|
||||
API_FUNC(theme_register)
|
||||
{
|
||||
char *name;
|
||||
PyObject *dict;
|
||||
struct t_hashtable *hashtable;
|
||||
const char *result;
|
||||
|
||||
API_INIT_FUNC(1, "theme_register", API_RETURN_EMPTY);
|
||||
name = NULL;
|
||||
dict = NULL;
|
||||
if (!PyArg_ParseTuple (args, "sO", &name, &dict))
|
||||
API_WRONG_ARGS(API_RETURN_EMPTY);
|
||||
|
||||
hashtable = weechat_python_dict_to_hashtable (dict,
|
||||
WEECHAT_SCRIPT_HASHTABLE_DEFAULT_SIZE,
|
||||
WEECHAT_HASHTABLE_STRING,
|
||||
WEECHAT_HASHTABLE_STRING);
|
||||
|
||||
result = API_PTR2STR(plugin_script_api_theme_register (
|
||||
weechat_python_plugin,
|
||||
python_current_script,
|
||||
name, hashtable));
|
||||
|
||||
weechat_hashtable_free (hashtable);
|
||||
|
||||
API_RETURN_STRING(result);
|
||||
}
|
||||
|
||||
API_FUNC(key_bind)
|
||||
{
|
||||
char *context;
|
||||
@@ -5729,6 +5757,7 @@ PyMethodDef weechat_python_funcs[] =
|
||||
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),
|
||||
|
||||
@@ -1143,6 +1143,19 @@ def config_unset_plugin(option_name: str) -> int:
|
||||
...
|
||||
|
||||
|
||||
def theme_register(name: str, overrides: Dict[str, str]) -> str:
|
||||
"""`theme_register in WeeChat plugin API reference <https://weechat.org/doc/weechat/api/#_theme_register>`_
|
||||
::
|
||||
|
||||
# example
|
||||
weechat.theme_register("light", {
|
||||
"irc.color.input_nick": "cyan",
|
||||
"irc.color.topic_old": "darkgray",
|
||||
})
|
||||
"""
|
||||
...
|
||||
|
||||
|
||||
def key_bind(context: str, keys: Dict[str, str]) -> int:
|
||||
"""`key_bind in WeeChat plugin API reference <https://weechat.org/doc/weechat/api/#_key_bind>`_
|
||||
::
|
||||
|
||||
@@ -34,6 +34,7 @@ set(RELAY_SRC
|
||||
relay-raw.c relay-raw.h
|
||||
relay-remote.c relay-remote.h
|
||||
relay-server.c relay-server.h
|
||||
relay-theme.c relay-theme.h
|
||||
relay-upgrade.c relay-upgrade.h
|
||||
relay-websocket.c relay-websocket.h
|
||||
# irc relay
|
||||
|
||||
@@ -350,9 +350,13 @@ relay_api_msg_buffer_to_json (struct t_gui_buffer *buffer,
|
||||
{
|
||||
struct t_hdata *hdata;
|
||||
struct t_gui_buffer *pointer;
|
||||
struct t_gui_lines *ptr_lines;
|
||||
struct t_gui_line *ptr_line;
|
||||
struct t_gui_line_data *ptr_line_data;
|
||||
cJSON *json, *json_local_vars, *json_lines, *json_nicklist_root;
|
||||
const char *ptr_string;
|
||||
char *string;
|
||||
int last_read_line_id;
|
||||
|
||||
hdata = relay_hdata_buffer;
|
||||
pointer = buffer;
|
||||
@@ -405,6 +409,24 @@ relay_api_msg_buffer_to_json (struct t_gui_buffer *buffer,
|
||||
if (json_lines)
|
||||
cJSON_AddItemToObject (json, "lines", json_lines);
|
||||
}
|
||||
last_read_line_id = -1;
|
||||
ptr_lines = weechat_hdata_pointer (relay_hdata_buffer, buffer, "own_lines");
|
||||
if (ptr_lines)
|
||||
{
|
||||
ptr_line = weechat_hdata_pointer (relay_hdata_lines, ptr_lines, "last_read_line");
|
||||
if (ptr_line)
|
||||
{
|
||||
ptr_line_data = weechat_hdata_pointer (relay_hdata_line, ptr_line, "data");
|
||||
if (ptr_line_data)
|
||||
{
|
||||
last_read_line_id = weechat_hdata_integer (relay_hdata_line_data,
|
||||
ptr_line_data, "id");
|
||||
}
|
||||
}
|
||||
}
|
||||
cJSON_AddItemToObject (
|
||||
json, "last_read_line_id",
|
||||
cJSON_CreateNumber (last_read_line_id));
|
||||
|
||||
/* nicks */
|
||||
if (nicks)
|
||||
|
||||
@@ -26,8 +26,8 @@ struct t_relay_client;
|
||||
enum t_relay_status;
|
||||
|
||||
#define RELAY_API_VERSION_MAJOR 0
|
||||
#define RELAY_API_VERSION_MINOR 4
|
||||
#define RELAY_API_VERSION_PATCH 1
|
||||
#define RELAY_API_VERSION_MINOR 5
|
||||
#define RELAY_API_VERSION_PATCH 0
|
||||
#define RELAY_API_VERSION_NUMBER \
|
||||
((RELAY_API_VERSION_MAJOR << 16) \
|
||||
+ (RELAY_API_VERSION_MINOR << 8) \
|
||||
|
||||
@@ -17,7 +17,7 @@ info:
|
||||
license:
|
||||
name: CC BY-NC-SA 4.0
|
||||
url: https://creativecommons.org/licenses/by-nc-sa/4.0/
|
||||
version: 0.4.1
|
||||
version: 0.5.0
|
||||
|
||||
externalDocs:
|
||||
url: https://weechat.org/doc/
|
||||
@@ -1043,6 +1043,11 @@ components:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/Line'
|
||||
last_read_line_id:
|
||||
type: integer
|
||||
format: int64
|
||||
description: identifier of the last line read in the buffer (-1 if read marker is not displayed)
|
||||
example: -1
|
||||
nicklist_root:
|
||||
$ref: '#/components/schemas/NickGroup'
|
||||
required:
|
||||
|
||||
@@ -1909,7 +1909,7 @@ relay_config_init (void)
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
relay_config_api_remote_input_cmd_local = weechat_config_new_option (
|
||||
relay_config_file, relay_config_section_api,
|
||||
"remote_input_cmd_local", "string",
|
||||
"remote_input_cmd_local", "string|themable",
|
||||
N_("text displayed after user input when the command would be "
|
||||
"executed locally (NOT sent to the remote WeeChat) "
|
||||
"(note: content is evaluated, see /help eval)"),
|
||||
@@ -1917,7 +1917,7 @@ relay_config_init (void)
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
relay_config_api_remote_input_cmd_remote = weechat_config_new_option (
|
||||
relay_config_file, relay_config_section_api,
|
||||
"remote_input_cmd_remote", "string",
|
||||
"remote_input_cmd_remote", "string|themable",
|
||||
N_("text displayed after user input when the command would be "
|
||||
"executed on the remote WeeChat (NOT executed locally) "
|
||||
"(note: content is evaluated, see /help eval)"),
|
||||
|
||||
@@ -1006,6 +1006,14 @@ relay_http_recv (struct t_relay_client *client, const char *data, int size)
|
||||
|
||||
if (client->partial_message)
|
||||
{
|
||||
/*
|
||||
* limit the size of the partial message: once the maximum is reached,
|
||||
* ignore the extra data (protection against a client sending a huge
|
||||
* amount of data without any end-of-line and dribbling it, which would
|
||||
* consume all the memory)
|
||||
*/
|
||||
if (strlen (client->partial_message) >= RELAY_HTTP_PARTIAL_MESSAGE_MAX_LENGTH)
|
||||
return;
|
||||
new_partial = realloc (client->partial_message,
|
||||
strlen (client->partial_message) +
|
||||
strlen (data) + 1);
|
||||
@@ -1708,7 +1716,7 @@ relay_http_print_log_request (struct t_relay_http_request *request)
|
||||
weechat_log_printf (" path_items. . . . . . . : %p", request->path_items);
|
||||
if (request->path_items)
|
||||
{
|
||||
for (i = 0; request->path_items[0]; i++)
|
||||
for (i = 0; request->path_items[i]; i++)
|
||||
{
|
||||
weechat_log_printf (" '%s'", request->path_items[i]);
|
||||
}
|
||||
|
||||
@@ -64,6 +64,15 @@ enum t_relay_client_http_status
|
||||
*/
|
||||
#define RELAY_HTTP_BODY_MAX_LENGTH (8 * 1024 * 1024)
|
||||
|
||||
/*
|
||||
* maximum length of the partial message accumulated while reading an HTTP
|
||||
* request: once this limit is reached, the extra data is ignored; this
|
||||
* protects against a client sending a huge amount of data without any
|
||||
* end-of-line (an unterminated method or header line), which would consume
|
||||
* all the memory
|
||||
*/
|
||||
#define RELAY_HTTP_PARTIAL_MESSAGE_MAX_LENGTH (8 * 1024 * 1024)
|
||||
|
||||
struct t_relay_http_request
|
||||
{
|
||||
enum t_relay_client_http_status status; /* HTTP status */
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
/* relay contribution to built-in themes. */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "../weechat-plugin.h"
|
||||
#include "relay.h"
|
||||
#include "relay-theme.h"
|
||||
|
||||
|
||||
const char *relay_theme_light[][2] =
|
||||
{
|
||||
{ "relay.color.status_auth_failed", "magenta" },
|
||||
{ "relay.color.status_authenticating", "202" },
|
||||
{ "relay.color.status_connecting", "default" },
|
||||
{ "relay.color.status_disconnected", "red" },
|
||||
{ "relay.color.text_selected", "default" },
|
||||
{ NULL, NULL },
|
||||
};
|
||||
|
||||
void
|
||||
relay_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
|
||||
relay_theme_init (void)
|
||||
{
|
||||
relay_theme_register ("light", relay_theme_light);
|
||||
}
|
||||
@@ -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_RELAY_THEME_H
|
||||
#define WEECHAT_PLUGIN_RELAY_THEME_H
|
||||
|
||||
extern void relay_theme_init (void);
|
||||
|
||||
#endif /* WEECHAT_PLUGIN_RELAY_THEME_H */
|
||||
@@ -38,6 +38,7 @@
|
||||
#include "relay-raw.h"
|
||||
#include "relay-remote.h"
|
||||
#include "relay-server.h"
|
||||
#include "relay-theme.h"
|
||||
#include "relay-upgrade.h"
|
||||
|
||||
|
||||
@@ -376,6 +377,8 @@ weechat_plugin_init (struct t_weechat_plugin *plugin, int argc, char *argv[])
|
||||
|
||||
relay_config_read ();
|
||||
|
||||
relay_theme_init ();
|
||||
|
||||
relay_network_init ();
|
||||
|
||||
relay_command_init ();
|
||||
|
||||
@@ -2478,6 +2478,36 @@ weechat_ruby_api_config_unset_plugin (VALUE class, VALUE option)
|
||||
API_RETURN_INT(rc);
|
||||
}
|
||||
|
||||
static VALUE
|
||||
weechat_ruby_api_theme_register (VALUE class, VALUE name, VALUE overrides)
|
||||
{
|
||||
char *c_name;
|
||||
struct t_hashtable *c_overrides;
|
||||
const char *result;
|
||||
|
||||
API_INIT_FUNC(1, "theme_register", API_RETURN_EMPTY);
|
||||
if (NIL_P (name) || NIL_P (overrides))
|
||||
API_WRONG_ARGS(API_RETURN_EMPTY);
|
||||
|
||||
Check_Type (name, T_STRING);
|
||||
Check_Type (overrides, T_HASH);
|
||||
|
||||
c_name = StringValuePtr (name);
|
||||
c_overrides = weechat_ruby_hash_to_hashtable (overrides,
|
||||
WEECHAT_SCRIPT_HASHTABLE_DEFAULT_SIZE,
|
||||
WEECHAT_HASHTABLE_STRING,
|
||||
WEECHAT_HASHTABLE_STRING);
|
||||
|
||||
result = API_PTR2STR(plugin_script_api_theme_register (
|
||||
weechat_ruby_plugin,
|
||||
ruby_current_script,
|
||||
c_name, c_overrides));
|
||||
|
||||
weechat_hashtable_free (c_overrides);
|
||||
|
||||
API_RETURN_STRING(result);
|
||||
}
|
||||
|
||||
static VALUE
|
||||
weechat_ruby_api_key_bind (VALUE class, VALUE context, VALUE keys)
|
||||
{
|
||||
@@ -7078,6 +7108,7 @@ weechat_ruby_api_init (VALUE ruby_mWeechat)
|
||||
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);
|
||||
|
||||
@@ -29,6 +29,7 @@ add_library(script MODULE
|
||||
script-info.c script-info.h
|
||||
script-mouse.c script-mouse.h
|
||||
script-repo.c script-repo.h
|
||||
script-theme.c script-theme.h
|
||||
)
|
||||
set_target_properties(script PROPERTIES PREFIX "")
|
||||
|
||||
|
||||
@@ -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/>.
|
||||
*/
|
||||
|
||||
/* script contribution to built-in themes. */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "../weechat-plugin.h"
|
||||
#include "script.h"
|
||||
#include "script-theme.h"
|
||||
|
||||
|
||||
const char *script_theme_light[][2] =
|
||||
{
|
||||
{ "script.color.status_autoloaded", "default" },
|
||||
{ "script.color.status_held", "202" },
|
||||
{ "script.color.status_installed", "21" },
|
||||
{ "script.color.status_obsolete", "magenta" },
|
||||
{ "script.color.status_popular", "94" },
|
||||
{ "script.color.status_running", "23" },
|
||||
{ "script.color.status_unknown", "red" },
|
||||
{ "script.color.text_bg_selected", "117" },
|
||||
{ "script.color.text_date", "darkgray" },
|
||||
{ "script.color.text_date_selected", "darkgray" },
|
||||
{ "script.color.text_delimiters", "251" },
|
||||
{ "script.color.text_description", "default" },
|
||||
{ "script.color.text_description_selected", "default" },
|
||||
{ "script.color.text_extension", "lightblue" },
|
||||
{ "script.color.text_extension_selected", "lightblue" },
|
||||
{ "script.color.text_name", "18" },
|
||||
{ "script.color.text_name_selected", "18" },
|
||||
{ "script.color.text_selected", "default" },
|
||||
{ "script.color.text_tags", "94" },
|
||||
{ "script.color.text_tags_selected", "94" },
|
||||
{ "script.color.text_version", "58" },
|
||||
{ "script.color.text_version_loaded", "default" },
|
||||
{ "script.color.text_version_loaded_selected", "default" },
|
||||
{ "script.color.text_version_selected", "58" },
|
||||
{ NULL, NULL },
|
||||
};
|
||||
|
||||
void
|
||||
script_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
|
||||
script_theme_init (void)
|
||||
{
|
||||
script_theme_register ("light", script_theme_light);
|
||||
}
|
||||
@@ -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_SCRIPT_THEME_H
|
||||
#define WEECHAT_PLUGIN_SCRIPT_THEME_H
|
||||
|
||||
extern void script_theme_init (void);
|
||||
|
||||
#endif /* WEECHAT_PLUGIN_SCRIPT_THEME_H */
|
||||
@@ -37,6 +37,7 @@
|
||||
#include "script-info.h"
|
||||
#include "script-mouse.h"
|
||||
#include "script-repo.h"
|
||||
#include "script-theme.h"
|
||||
|
||||
|
||||
WEECHAT_PLUGIN_NAME(SCRIPT_PLUGIN_NAME);
|
||||
@@ -352,6 +353,8 @@ weechat_plugin_init (struct t_weechat_plugin *plugin, int argc, char *argv[])
|
||||
|
||||
script_config_read ();
|
||||
|
||||
script_theme_init ();
|
||||
|
||||
weechat_mkdir_home ("${weechat_cache_dir}/" SCRIPT_PLUGIN_NAME, 0755);
|
||||
|
||||
script_command_init ();
|
||||
|
||||
@@ -34,6 +34,7 @@ add_library(spell MODULE
|
||||
spell-config.c spell-config.h
|
||||
spell-info.c spell-info.h
|
||||
spell-speller.c spell-speller.h
|
||||
spell-theme.c spell-theme.h
|
||||
)
|
||||
set_target_properties(spell PROPERTIES PREFIX "")
|
||||
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
/* spell contribution to built-in themes. */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "../weechat-plugin.h"
|
||||
#include "spell.h"
|
||||
#include "spell-theme.h"
|
||||
|
||||
|
||||
const char *spell_theme_light[][2] =
|
||||
{
|
||||
{ "spell.color.misspelled", "red" },
|
||||
{ NULL, NULL },
|
||||
};
|
||||
|
||||
void
|
||||
spell_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
|
||||
spell_theme_init (void)
|
||||
{
|
||||
spell_theme_register ("light", spell_theme_light);
|
||||
}
|
||||
@@ -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_SPELL_THEME_H
|
||||
#define WEECHAT_PLUGIN_SPELL_THEME_H
|
||||
|
||||
extern void spell_theme_init (void);
|
||||
|
||||
#endif /* WEECHAT_PLUGIN_SPELL_THEME_H */
|
||||
@@ -43,6 +43,7 @@
|
||||
#include "spell-config.h"
|
||||
#include "spell-info.h"
|
||||
#include "spell-speller.h"
|
||||
#include "spell-theme.h"
|
||||
|
||||
|
||||
WEECHAT_PLUGIN_NAME(SPELL_PLUGIN_NAME);
|
||||
@@ -1196,6 +1197,8 @@ weechat_plugin_init (struct t_weechat_plugin *plugin, int argc, char *argv[])
|
||||
|
||||
spell_config_read ();
|
||||
|
||||
spell_theme_init ();
|
||||
|
||||
spell_command_init ();
|
||||
|
||||
spell_completion_init ();
|
||||
|
||||
@@ -2035,6 +2035,32 @@ API_FUNC(config_unset_plugin)
|
||||
API_RETURN_INT(rc);
|
||||
}
|
||||
|
||||
API_FUNC(theme_register)
|
||||
{
|
||||
char *name;
|
||||
struct t_hashtable *hashtable;
|
||||
const char *result;
|
||||
|
||||
API_INIT_FUNC(1, "theme_register", API_RETURN_EMPTY);
|
||||
if (objc < 3)
|
||||
API_WRONG_ARGS(API_RETURN_EMPTY);
|
||||
|
||||
name = Tcl_GetString (objv[1]);
|
||||
hashtable = weechat_tcl_dict_to_hashtable (interp, objv[2],
|
||||
WEECHAT_SCRIPT_HASHTABLE_DEFAULT_SIZE,
|
||||
WEECHAT_HASHTABLE_STRING,
|
||||
WEECHAT_HASHTABLE_STRING);
|
||||
|
||||
result = API_PTR2STR(plugin_script_api_theme_register (
|
||||
weechat_tcl_plugin,
|
||||
tcl_current_script,
|
||||
name, hashtable));
|
||||
|
||||
weechat_hashtable_free (hashtable);
|
||||
|
||||
API_RETURN_STRING(result);
|
||||
}
|
||||
|
||||
API_FUNC(key_bind)
|
||||
{
|
||||
char *context;
|
||||
@@ -5806,6 +5832,7 @@ void weechat_tcl_api_init (Tcl_Interp *interp)
|
||||
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);
|
||||
|
||||
@@ -26,6 +26,7 @@ add_library(trigger MODULE
|
||||
trigger-command.c trigger-command.h
|
||||
trigger-completion.c trigger-completion.h
|
||||
trigger-config.c trigger-config.h
|
||||
trigger-theme.c trigger-theme.h
|
||||
)
|
||||
set_target_properties(trigger PROPERTIES PREFIX "")
|
||||
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
/* trigger contribution to built-in themes. */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "../weechat-plugin.h"
|
||||
#include "trigger.h"
|
||||
#include "trigger-theme.h"
|
||||
|
||||
|
||||
const char *trigger_theme_light[][2] =
|
||||
{
|
||||
{ "trigger.color.flag_command", "green" },
|
||||
{ "trigger.color.flag_conditions", "94" },
|
||||
{ "trigger.color.flag_post_action", "blue" },
|
||||
{ "trigger.color.flag_regex", "cyan" },
|
||||
{ "trigger.color.flag_return_code", "magenta" },
|
||||
{ "trigger.color.regex", "default" },
|
||||
{ NULL, NULL },
|
||||
};
|
||||
|
||||
void
|
||||
trigger_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
|
||||
trigger_theme_init (void)
|
||||
{
|
||||
trigger_theme_register ("light", trigger_theme_light);
|
||||
}
|
||||
@@ -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_TRIGGER_THEME_H
|
||||
#define WEECHAT_PLUGIN_TRIGGER_THEME_H
|
||||
|
||||
extern void trigger_theme_init (void);
|
||||
|
||||
#endif /* WEECHAT_PLUGIN_TRIGGER_THEME_H */
|
||||
@@ -34,6 +34,7 @@
|
||||
#include "trigger-command.h"
|
||||
#include "trigger-completion.h"
|
||||
#include "trigger-config.h"
|
||||
#include "trigger-theme.h"
|
||||
|
||||
|
||||
WEECHAT_PLUGIN_NAME(TRIGGER_PLUGIN_NAME);
|
||||
@@ -1385,6 +1386,8 @@ weechat_plugin_init (struct t_weechat_plugin *plugin, int argc, char *argv[])
|
||||
|
||||
trigger_config_read ();
|
||||
|
||||
trigger_theme_init ();
|
||||
|
||||
/* hook some signals */
|
||||
weechat_hook_signal ("debug_dump", &trigger_debug_dump_cb, NULL, NULL);
|
||||
|
||||
|
||||
@@ -62,6 +62,7 @@ struct t_hashtable;
|
||||
struct t_hdata;
|
||||
struct t_infolist;
|
||||
struct t_infolist_item;
|
||||
struct t_theme;
|
||||
struct t_upgrade_file;
|
||||
struct t_weelist;
|
||||
struct t_weelist_item;
|
||||
@@ -76,7 +77,7 @@ struct t_weelist_item;
|
||||
* please change the date with current one; for a second change at same
|
||||
* date, increment the 01, otherwise please keep 01.
|
||||
*/
|
||||
#define WEECHAT_PLUGIN_API_VERSION "20260530-01"
|
||||
#define WEECHAT_PLUGIN_API_VERSION "20260531-02"
|
||||
|
||||
/* macros for defining plugin infos */
|
||||
#define WEECHAT_PLUGIN_NAME(__name) \
|
||||
@@ -728,6 +729,14 @@ struct t_weechat_plugin
|
||||
int (*config_unset_plugin) (struct t_weechat_plugin *plugin,
|
||||
const char *option_name);
|
||||
|
||||
/* themes */
|
||||
struct t_theme *(*theme_register) (struct t_weechat_plugin *plugin,
|
||||
const void *script,
|
||||
const char *name,
|
||||
struct t_hashtable *overrides);
|
||||
void (*theme_unregister_script) (struct t_weechat_plugin *plugin,
|
||||
const void *script);
|
||||
|
||||
/* key bindings */
|
||||
int (*key_bind) (const char *context, struct t_hashtable *keys);
|
||||
int (*key_unbind) (const char *context, const char *key);
|
||||
@@ -1855,6 +1864,13 @@ extern int weechat_plugin_end (struct t_weechat_plugin *plugin);
|
||||
#define weechat_config_unset_plugin(__option) \
|
||||
(weechat_plugin->config_unset_plugin)(weechat_plugin, __option)
|
||||
|
||||
/* themes */
|
||||
#define weechat_theme_register(__name, __overrides) \
|
||||
(weechat_plugin->theme_register)(weechat_plugin, NULL, \
|
||||
__name, __overrides)
|
||||
#define weechat_theme_unregister_script(__script) \
|
||||
(weechat_plugin->theme_unregister_script)(weechat_plugin, __script)
|
||||
|
||||
/* key bindings */
|
||||
#define weechat_key_bind(__context, __keys) \
|
||||
(weechat_plugin->key_bind)(__context, __keys)
|
||||
|
||||
@@ -30,6 +30,7 @@ add_library(xfer MODULE
|
||||
xfer-file.c xfer-file.h
|
||||
xfer-info.c xfer-info.h
|
||||
xfer-network.c xfer-network.h
|
||||
xfer-theme.c xfer-theme.h
|
||||
xfer-upgrade.c xfer-upgrade.h
|
||||
)
|
||||
set_target_properties(xfer PROPERTIES PREFIX "")
|
||||
|
||||
@@ -162,7 +162,7 @@ xfer_chat_recv_cb (const void *pointer, void *data, int fd)
|
||||
{
|
||||
ctcp_action = 0;
|
||||
length = strlen (ptr_buf);
|
||||
if (ptr_buf[length - 1] == '\r')
|
||||
if ((length > 0) && (ptr_buf[length - 1] == '\r'))
|
||||
{
|
||||
ptr_buf[length - 1] = '\0';
|
||||
length--;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user