From 3aef8b7292330da6d4a7dd97ddb261baca3f33e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Helleu?= Date: Sat, 19 Aug 2023 18:55:15 +0200 Subject: [PATCH] core: add options weechat.buffer.* to save buffer properties set by user (issue #352) --- ChangeLog.adoc | 1 + src/core/wee-config.c | 77 ++++++++++++++++++++++++++++++ src/core/wee-config.h | 1 + src/gui/gui-buffer.c | 59 ++++++++++++++++++++++- tests/unit/gui/test-gui-buffer.cpp | 37 ++++++++++++++ 5 files changed, 174 insertions(+), 1 deletion(-) diff --git a/ChangeLog.adoc b/ChangeLog.adoc index e76810c04..03cff7f67 100644 --- a/ChangeLog.adoc +++ b/ChangeLog.adoc @@ -16,6 +16,7 @@ For a list of important changes that require manual actions, please look at rele New features:: * core: add option type "enum" (issue #1973) + * core: add options weechat.buffer.* to save buffer properties set by user (issue #352) * core: add parameters and key bindings to move to edges of current area with commands `/cursor go` and `/cursor move` (issue #1282) * core: add variables "_chat_focused_line_bol" and "_chat_focused_line_eol" in focus data (issue #1955) * api: add info "buffer" (issue #1962) diff --git a/src/core/wee-config.c b/src/core/wee-config.c index 421cc6b0f..583c6249d 100644 --- a/src/core/wee-config.c +++ b/src/core/wee-config.c @@ -84,6 +84,7 @@ struct t_config_section *weechat_config_section_signal = NULL; struct t_config_section *weechat_config_section_bar = NULL; struct t_config_section *weechat_config_section_custom_bar_item = NULL; struct t_config_section *weechat_config_section_layout = NULL; +struct t_config_section *weechat_config_section_buffer = NULL; struct t_config_section *weechat_config_section_notify = NULL; struct t_config_section *weechat_config_section_filter = NULL; struct t_config_section *weechat_config_section_key[GUI_KEY_NUM_CONTEXTS] = { @@ -2482,6 +2483,72 @@ config_weechat_notify_change_cb (const void *pointer, void *data, gui_buffer_notify_set_all (); } +/* + * Callback called when an option is created in section "buffer". + */ + +int +config_weechat_buffer_create_option_cb (const void *pointer, void *data, + struct t_config_file *config_file, + struct t_config_section *section, + const char *option_name, + const char *value) +{ + struct t_config_option *ptr_option; + const char *pos; + char *buffer_mask, description[4096]; + int rc; + + /* make C compiler happy */ + (void) pointer; + (void) data; + + rc = WEECHAT_CONFIG_OPTION_SET_ERROR; + + if (option_name) + { + ptr_option = config_file_search_option (config_file, section, + option_name); + if (ptr_option) + { + rc = config_file_option_set (ptr_option, value, 1); + } + else + { + pos = strrchr (option_name, '.'); + if (pos) + { + buffer_mask = strndup (option_name, pos - option_name); + if (buffer_mask) + { + snprintf (description, sizeof (description), + _("set property \"%s\" on any buffer matching " + "mask \"%s\"; " + "content is evaluated, see /help eval; " + "${buffer} is a pointer to the buffer being " + "opened"), + pos + 1, + buffer_mask); + ptr_option = config_file_new_option ( + config_file, section, + option_name, "string", + description, + "", + 0, 0, "", value, 0, + NULL, NULL, NULL, + NULL, NULL, NULL, + NULL, NULL, NULL); + rc = (ptr_option) ? + WEECHAT_CONFIG_OPTION_SET_OK_SAME_VALUE : WEECHAT_CONFIG_OPTION_SET_ERROR; + free (buffer_mask); + } + } + } + } + + return rc; +} + /* * Callback called when an option is created in section "notify". */ @@ -4982,6 +5049,16 @@ config_weechat_init_options () NULL, NULL, NULL, NULL, NULL, NULL); + /* buffer */ + weechat_config_section_buffer = config_file_new_section ( + weechat_config_file, "buffer", + 1, 1, + NULL, NULL, NULL, + NULL, NULL, NULL, + NULL, NULL, NULL, + &config_weechat_buffer_create_option_cb, NULL, NULL, + NULL, NULL, NULL); + /* notify */ weechat_config_section_notify = config_file_new_section ( weechat_config_file, "notify", diff --git a/src/core/wee-config.h b/src/core/wee-config.h index 230158a8b..4aa511f79 100644 --- a/src/core/wee-config.h +++ b/src/core/wee-config.h @@ -142,6 +142,7 @@ extern struct t_config_section *weechat_config_section_signal; extern struct t_config_section *weechat_config_section_bar; extern struct t_config_section *weechat_config_section_custom_bar_item; extern struct t_config_section *weechat_config_section_layout; +extern struct t_config_section *weechat_config_section_buffer; extern struct t_config_section *weechat_config_section_notify; extern struct t_config_section *weechat_config_section_filter; extern struct t_config_section *weechat_config_section_key[]; diff --git a/src/gui/gui-buffer.c b/src/gui/gui-buffer.c index 612503603..76cec4ee3 100644 --- a/src/gui/gui-buffer.c +++ b/src/gui/gui-buffer.c @@ -36,6 +36,7 @@ #include "../core/weechat.h" #include "../core/wee-config.h" +#include "../core/wee-eval.h" #include "../core/wee-hashtable.h" #include "../core/wee-hdata.h" #include "../core/wee-hook.h" @@ -647,6 +648,59 @@ gui_buffer_apply_properties_cb (void *data, (const char *)value); } +/* + * Applies buffer properties defined in options "weechat.buffer.*". + */ + +void +gui_buffer_apply_config_properties (struct t_gui_buffer *buffer) +{ + struct t_config_option *ptr_option; + struct t_hashtable *pointers; + const char *pos; + char *buffer_mask, *value; + + pointers = NULL; + + for (ptr_option = weechat_config_section_buffer->options; ptr_option; + ptr_option = ptr_option->next_option) + { + pos = strrchr (ptr_option->name, '.'); + if (!pos) + continue; + buffer_mask = strndup (ptr_option->name, pos - ptr_option->name); + if (!buffer_mask) + continue; + if (string_match (buffer->full_name, buffer_mask, 1)) + { + if (!pointers) + { + pointers = hashtable_new ( + 32, + WEECHAT_HASHTABLE_STRING, + WEECHAT_HASHTABLE_POINTER, + NULL, NULL); + } + if (pointers) + { + hashtable_set (pointers, "buffer", buffer); + value = eval_expression ( + CONFIG_STRING(ptr_option), + pointers, NULL, NULL); + if (value) + { + gui_buffer_set (buffer, pos + 1, value); + free (value); + } + } + } + free (buffer_mask); + } + + if (pointers) + hashtable_free (pointers); +} + /* * Creates a new buffer in current window with some optional properties. * @@ -845,10 +899,13 @@ gui_buffer_new_props (struct t_weechat_plugin *plugin, /* assign this buffer to windows of layout */ gui_layout_window_assign_buffer (new_buffer); - /* apply properties */ + /* apply properties (from parameters) */ if (properties) hashtable_map (properties, &gui_buffer_apply_properties_cb, new_buffer); + /* apply properties (from options weechat.buffer.*) */ + gui_buffer_apply_config_properties (new_buffer); + if (first_buffer_creation) { gui_buffer_visited_add (new_buffer); diff --git a/tests/unit/gui/test-gui-buffer.cpp b/tests/unit/gui/test-gui-buffer.cpp index 1d9722c83..5d62fa0c2 100644 --- a/tests/unit/gui/test-gui-buffer.cpp +++ b/tests/unit/gui/test-gui-buffer.cpp @@ -413,6 +413,43 @@ TEST(GuiBuffer, ApplyPropertiesCb) /* TODO: write tests */ } +/* + * Tests functions: + * gui_buffer_apply_config_properties + */ + +TEST(GuiBuffer, ApplyConfigProperties) +{ + struct t_gui_buffer *buffer; + struct t_config_option *ptr_option; + + config_file_option_set_with_string ( + "weechat.buffer.core." TEST_BUFFER_NAME ".short_name", "t1"); + + buffer = gui_buffer_new (NULL, TEST_BUFFER_NAME, + NULL, NULL, NULL, + NULL, NULL, NULL); + CHECK(buffer); + + STRCMP_EQUAL("t1", buffer->short_name); + + gui_buffer_close (buffer); + + config_file_search_with_string ( + "weechat.buffer.core." TEST_BUFFER_NAME ".short_name", + NULL, NULL, &ptr_option, NULL); + config_file_option_unset (ptr_option); + + buffer = gui_buffer_new (NULL, TEST_BUFFER_NAME, + NULL, NULL, NULL, + NULL, NULL, NULL); + CHECK(buffer); + + POINTERS_EQUAL(NULL, buffer->short_name); + + gui_buffer_close (buffer); +} + /* * Test callback for buffer input. */