From b994a645e3308f100c9735af386d1ec43b34f5cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Helleu?= Date: Tue, 26 May 2026 19:01:11 +0200 Subject: [PATCH] core: add theme name completion Add two completion items hooked alongside "layouts_names": - "theme_themes_all": all theme names (built-ins from the registry plus every *.theme file in /themes/, including backup-*.theme). Used by tab-complete on /theme apply and /theme info. - "theme_themes_user": user theme files only (excludes built-ins and backup-*.theme). Used by tab-complete on /theme save and /theme delete, so users cannot accidentally try to overwrite a built-in name or save a name colliding with the reserved backup prefix. Both callbacks share a small dir_exec_on_files-based helper to filter the themes directory. The /theme command's completion template in core-command.c is updated to reference these new items. --- src/core/core-command.c | 8 +-- src/core/core-completion.c | 118 +++++++++++++++++++++++++++++++++++++ 2 files changed, 122 insertions(+), 4 deletions(-) diff --git a/src/core/core-command.c b/src/core/core-command.c index fac20d565..24c7879ec 100644 --- a/src/core/core-command.c +++ b/src/core/core-command.c @@ -10112,10 +10112,10 @@ command_init (void) "backup-. This is controlled by the option " "weechat.look.theme_backup.")), "list -backups" - " || apply" - " || save -full" - " || delete" - " || info", + " || apply %(theme_themes_all)" + " || save %(theme_themes_user) -full" + " || delete %(theme_themes_user)" + " || info %(theme_themes_all)", &command_theme, NULL, NULL); hook_command ( NULL, "toggle", diff --git a/src/core/core-completion.c b/src/core/core-completion.c index a925f7063..bdcde1fe5 100644 --- a/src/core/core-completion.c +++ b/src/core/core-completion.c @@ -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,117 @@ 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 /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 a secured data to completion list. */ @@ -2365,6 +2477,12 @@ 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, "secured_data", N_("names of secured data (file sec.conf, section data)"), &completion_list_add_secured_data_cb, NULL, NULL);