diff options
author | Sébastien Helleu <flashcode@flashtux.org> | 2017-06-02 20:33:35 +0200 |
---|---|---|
committer | Sébastien Helleu <flashcode@flashtux.org> | 2017-06-25 16:35:27 +0200 |
commit | d5aa8530b7c438036fe8bcc96f999e19caa0e9f8 (patch) | |
tree | 24aeceb90383fa728099b8b4c21d36842002e6fc | |
parent | 500e54578b26c502ab4a6d1e455d60c15844a965 (diff) | |
download | weechat-d5aa8530b7c438036fe8bcc96f999e19caa0e9f8.zip |
fset: fix crash on unset of multiple options
Rename option fset.look.unmark_after_action to fset.look.auto_unmark,
allow input "$$" to unmark all options and refresh.
-rw-r--r-- | src/plugins/fset/fset-buffer.c | 15 | ||||
-rw-r--r-- | src/plugins/fset/fset-command.c | 47 | ||||
-rw-r--r-- | src/plugins/fset/fset-config.c | 19 | ||||
-rw-r--r-- | src/plugins/fset/fset-config.h | 2 | ||||
-rw-r--r-- | src/plugins/fset/fset-info.c | 6 | ||||
-rw-r--r-- | src/plugins/fset/fset-option.c | 154 | ||||
-rw-r--r-- | src/plugins/fset/fset-option.h | 1 |
7 files changed, 178 insertions, 66 deletions
diff --git a/src/plugins/fset/fset-buffer.c b/src/plugins/fset/fset-buffer.c index fa9a6270d..eea256e35 100644 --- a/src/plugins/fset/fset-buffer.c +++ b/src/plugins/fset/fset-buffer.c @@ -116,6 +116,9 @@ fset_buffer_display_line (int y, struct t_fset_option *fset_option) int type, marked, add_quotes, add_quotes_parent; struct t_config_option *ptr_option_color_value, *ptr_option_color_quotes; + if (!fset_option) + return; + selected_line = (y == fset_buffer_selected_line) ? 1 : 0; default_value_undef = (fset_option->default_value == NULL) ? 1 : 0; @@ -523,7 +526,8 @@ fset_buffer_refresh (int clear) for (i = 0; i < num_options; i++) { ptr_fset_option = weechat_arraylist_get (fset_options, i); - fset_buffer_display_line (i, ptr_fset_option); + if (ptr_fset_option) + fset_buffer_display_line (i, ptr_fset_option); } fset_buffer_set_title (); @@ -712,6 +716,15 @@ fset_buffer_input_cb (const void *pointer, void *data, return WEECHAT_RC_OK; } + /* unmark all options and refresh buffer */ + if (strcmp (input_data, "$$") == 0) + { + fset_option_unmark_all (); + fset_option_get_options (); + fset_buffer_refresh (0); + return WEECHAT_RC_OK; + } + /* change sort of options */ if (strncmp (input_data, "s:", 2) == 0) { diff --git a/src/plugins/fset/fset-command.c b/src/plugins/fset/fset-command.c index c2c66090b..6cb9c2417 100644 --- a/src/plugins/fset/fset-command.c +++ b/src/plugins/fset/fset-command.c @@ -184,19 +184,19 @@ fset_command_fset (const void *pointer, void *data, { if (fset_option_count_marked > 0) { + fset_option_config_changed_timer = 1; num_options = weechat_arraylist_size (fset_options); for (i = 0; i < num_options; i++) { ptr_fset_option = weechat_arraylist_get (fset_options, i); - if (ptr_fset_option->marked) + if (ptr_fset_option && ptr_fset_option->marked) { ptr_option = weechat_config_get (ptr_fset_option->name); if (ptr_option) fset_option_toggle_value (ptr_fset_option, ptr_option); } } - if (weechat_config_boolean (fset_config_look_unmark_after_action)) - fset_option_unmark_all (); + fset_option_config_changed_timer = 0; } else { @@ -214,19 +214,19 @@ fset_command_fset (const void *pointer, void *data, if (fset_option_count_marked > 0) { + fset_option_config_changed_timer = 1; num_options = weechat_arraylist_size (fset_options); for (i = 0; i < num_options; i++) { ptr_fset_option = weechat_arraylist_get (fset_options, i); - if (ptr_fset_option->marked) + if (ptr_fset_option && ptr_fset_option->marked) { ptr_option = weechat_config_get (ptr_fset_option->name); if (ptr_option) fset_option_add_value (ptr_fset_option, ptr_option, value); } } - if (weechat_config_boolean (fset_config_look_unmark_after_action)) - fset_option_unmark_all (); + fset_option_config_changed_timer = 0; } else { @@ -240,19 +240,19 @@ fset_command_fset (const void *pointer, void *data, { if (fset_option_count_marked > 0) { + fset_option_config_changed_timer = 1; num_options = weechat_arraylist_size (fset_options); for (i = 0; i < num_options; i++) { ptr_fset_option = weechat_arraylist_get (fset_options, i); - if (ptr_fset_option->marked) + if (ptr_fset_option && ptr_fset_option->marked) { ptr_option = weechat_config_get (ptr_fset_option->name); if (ptr_option) fset_option_reset_value (ptr_fset_option, ptr_option); } } - if (weechat_config_boolean (fset_config_look_unmark_after_action)) - fset_option_unmark_all (); + fset_option_config_changed_timer = 0; } else { @@ -266,19 +266,19 @@ fset_command_fset (const void *pointer, void *data, { if (fset_option_count_marked > 0) { + fset_option_config_changed_timer = 1; num_options = weechat_arraylist_size (fset_options); for (i = 0; i < num_options; i++) { ptr_fset_option = weechat_arraylist_get (fset_options, i); - if (ptr_fset_option->marked) + if (ptr_fset_option && ptr_fset_option->marked) { ptr_option = weechat_config_get (ptr_fset_option->name); if (ptr_option) fset_option_unset_value (ptr_fset_option, ptr_option); } } - if (weechat_config_boolean (fset_config_look_unmark_after_action)) - fset_option_unmark_all (); + fset_option_config_changed_timer = 0; } else { @@ -540,17 +540,18 @@ fset_command_init () "${__name}, ${__type}, ...\n" "\n" "Keys and input on fset buffer:\n" - " alt+space t toggle boolean value\n" - " alt+'-' - subtract 1 from value (integer/color)\n" - " alt+'+' + add 1 to value (integer/color)\n" - " alt+f, alt+r r reset value\n" - " alt+f, alt+u u unset value\n" - " alt+enter s set value\n" - " alt+f, alt+a a append to value\n" - " alt+',' , mark/unmark option and move one line down\n" - " shift+down mark/unmark option and move one line down\n" - " shift+up mark/unmark option and move one line up\n" - " $ refresh options, unmark all options\n" + " alt+space t toggle boolean value\n" + " alt+'-' - subtract 1 from value (integer/color)\n" + " alt+'+' + add 1 to value (integer/color)\n" + " alt+f, alt+r r reset value\n" + " alt+f, alt+u u unset value\n" + " alt+enter s set value\n" + " alt+f, alt+a a append to value\n" + " alt+',' , mark/unmark option and move one line down\n" + " shift+down mark/unmark option and move one line down\n" + " shift+up mark/unmark option and move one line up\n" + " $ refresh options (keep marked options)\n" + " $$ refresh options (unmark all options)\n" " q close fset buffer\n" "\n" "Note: spaces at beginning of input are ignored, so for example " diff --git a/src/plugins/fset/fset-config.c b/src/plugins/fset/fset-config.c index 6ed3a27e4..63ee5c5ba 100644 --- a/src/plugins/fset/fset-config.c +++ b/src/plugins/fset/fset-config.c @@ -34,12 +34,12 @@ struct t_config_file *fset_config_file = NULL; /* fset config, look section */ +struct t_config_option *fset_config_look_auto_unmark; struct t_config_option *fset_config_look_condition_catch_set; struct t_config_option *fset_config_look_help_bar; struct t_config_option *fset_config_look_marked_string; struct t_config_option *fset_config_look_show_plugin_description; struct t_config_option *fset_config_look_sort; -struct t_config_option *fset_config_look_unmark_after_action; struct t_config_option *fset_config_look_unmarked_string; struct t_config_option *fset_config_look_use_keys; struct t_config_option *fset_config_look_use_mute; @@ -243,6 +243,15 @@ fset_config_init () return 0; } + fset_config_look_auto_unmark = weechat_config_new_option ( + fset_config_file, ptr_section, + "auto_unmark", "boolean", + N_("automatically unmark all options after an action on marked " + "options or after a refresh"), + NULL, 0, 0, "off", NULL, 0, + NULL, NULL, NULL, + NULL, NULL, NULL, + NULL, NULL, NULL); fset_config_look_condition_catch_set = weechat_config_new_option ( fset_config_file, ptr_section, "condition_catch_set", "string", @@ -294,14 +303,6 @@ fset_config_init () NULL, NULL, NULL, &fset_config_change_sort_cb, NULL, NULL, NULL, NULL, NULL); - fset_config_look_unmark_after_action = weechat_config_new_option ( - fset_config_file, ptr_section, - "unmark_after_action", "boolean", - N_("unmark all options after an action on marked options"), - NULL, 0, 0, "on", NULL, 0, - NULL, NULL, NULL, - NULL, NULL, NULL, - NULL, NULL, NULL); fset_config_look_unmarked_string = weechat_config_new_option ( fset_config_file, ptr_section, "unmarked_string", "string", diff --git a/src/plugins/fset/fset-config.h b/src/plugins/fset/fset-config.h index f72d7b512..7e60afc96 100644 --- a/src/plugins/fset/fset-config.h +++ b/src/plugins/fset/fset-config.h @@ -24,12 +24,12 @@ extern struct t_config_file *fset_config_file; +extern struct t_config_option *fset_config_look_auto_unmark; extern struct t_config_option *fset_config_look_condition_catch_set; extern struct t_config_option *fset_config_look_help_bar; extern struct t_config_option *fset_config_look_marked_string; extern struct t_config_option *fset_config_look_show_plugin_description; extern struct t_config_option *fset_config_look_sort; -extern struct t_config_option *fset_config_look_unmark_after_action; extern struct t_config_option *fset_config_look_unmarked_string; extern struct t_config_option *fset_config_look_use_keys; extern struct t_config_option *fset_config_look_use_mute; diff --git a/src/plugins/fset/fset-info.c b/src/plugins/fset/fset-info.c index bc6dce156..94ad5bcc3 100644 --- a/src/plugins/fset/fset-info.c +++ b/src/plugins/fset/fset-info.c @@ -71,8 +71,10 @@ fset_info_infolist_fset_option_cb (const void *pointer, void *data, for (i = 0; i < num_options; i++) { ptr_fset_option = weechat_arraylist_get (fset_options, i); - if (!arguments || !arguments[0] - || weechat_string_match (ptr_fset_option->name, arguments, 0)) + if (ptr_fset_option + && (!arguments || !arguments[0] + || weechat_string_match (ptr_fset_option->name, + arguments, 0))) { if (!fset_option_add_to_infolist (ptr_infolist, ptr_fset_option)) { diff --git a/src/plugins/fset/fset-option.c b/src/plugins/fset/fset-option.c index e53061b3a..51a64f2fc 100644 --- a/src/plugins/fset/fset-option.c +++ b/src/plugins/fset/fset-option.c @@ -34,6 +34,8 @@ struct t_arraylist *fset_options = NULL; int fset_option_count_marked = 0; struct t_hashtable *fset_option_max_length_field = NULL; char *fset_option_filter = NULL; +int fset_option_config_changed_timer = 0; +struct t_hook *fset_option_timer_hook = NULL; char *fset_option_type_string[FSET_OPTION_NUM_TYPES] = { N_("boolean"), N_("integer"), N_("string"), N_("color") }; @@ -94,7 +96,7 @@ fset_option_search_by_name (const char *name, int *line) for (i = 0; i < num_options; i++) { ptr_fset_option = weechat_arraylist_get (fset_options, i); - if (strcmp (ptr_fset_option->name, name) == 0) + if (ptr_fset_option && (strcmp (ptr_fset_option->name, name) == 0)) { if (line) *line = i; @@ -571,7 +573,8 @@ fset_option_set_max_length_fields_all () for (i = 0; i < num_options; i++) { ptr_fset_option = weechat_arraylist_get (fset_options, i); - fset_option_set_max_length_fields_option (ptr_fset_option); + if (ptr_fset_option) + fset_option_set_max_length_fields_option (ptr_fset_option); } } @@ -773,16 +776,39 @@ fset_option_get_hashtable_max_length_field () void fset_option_get_options () { - struct t_fset_option *new_fset_option; + struct t_fset_option *new_fset_option, *ptr_fset_option; struct t_config_file *ptr_config; struct t_config_section *ptr_section; struct t_config_option *ptr_option; - int num_options; + struct t_hashtable *marked_options; + int i, num_options; + + /* save marked options in a hashtable */ + if (!weechat_config_boolean (fset_config_look_auto_unmark)) + { + marked_options = weechat_hashtable_new (256, + WEECHAT_HASHTABLE_STRING, + WEECHAT_HASHTABLE_POINTER, + NULL, NULL); + num_options = weechat_arraylist_size (fset_options); + for (i = 0; i < num_options; i++) + { + ptr_fset_option = weechat_arraylist_get (fset_options, i); + if (ptr_fset_option && ptr_fset_option->marked) + weechat_hashtable_set (marked_options, ptr_fset_option->name, NULL); + } + } + else + { + marked_options = NULL; + } + /* clear options */ weechat_arraylist_clear (fset_options); fset_option_count_marked = 0; weechat_hashtable_remove_all (fset_option_max_length_field); + /* get options */ ptr_config = weechat_hdata_get_list (fset_hdata_config_file, "config_files"); while (ptr_config) @@ -810,10 +836,29 @@ fset_option_get_options () } num_options = weechat_arraylist_size (fset_options); + + /* check selected line */ if (num_options == 0) fset_buffer_selected_line = 0; else if (fset_buffer_selected_line >= num_options) fset_buffer_selected_line = num_options - 1; + + /* restore marked options */ + if (marked_options) + { + for (i = 0; i < num_options; i++) + { + ptr_fset_option = weechat_arraylist_get (fset_options, i); + if (ptr_fset_option + && weechat_hashtable_has_key (marked_options, + ptr_fset_option->name)) + { + ptr_fset_option->marked = 1; + fset_option_count_marked++; + } + } + weechat_hashtable_free (marked_options); + } } /* @@ -1003,44 +1048,29 @@ fset_option_unmark_all () for (i = 0; i < num_options; i++) { ptr_fset_option = weechat_arraylist_get (fset_options, i); - ptr_fset_option->marked = 0; + if (ptr_fset_option) + ptr_fset_option->marked = 0; } fset_option_count_marked = 0; fset_buffer_refresh (0); } /* - * Callback for config option changed. + * Refreshes the fset buffer after the change of an option. */ -int -fset_option_config_cb (const void *pointer, - void *data, - const char *option, - const char *value) +void +fset_option_config_changed (const char *option_name) { - const char *ptr_info; struct t_fset_option *ptr_fset_option; struct t_config_option *ptr_option; - int line, num_options, full_refresh; - - /* make C compiler happy */ - (void) pointer; - (void) data; - (void) value; - - /* do nothing if fset buffer is not opened */ - if (!fset_buffer) - return WEECHAT_RC_OK; - - /* do nothing if WeeChat is upgrading */ - ptr_info = weechat_info_get ("weechat_upgrading", NULL); - if (ptr_info && (strcmp (ptr_info, "1") == 0)) - return WEECHAT_RC_OK; + int full_refresh, line, num_options; full_refresh = 0; - ptr_fset_option = fset_option_search_by_name (option, &line); + ptr_fset_option = (option_name) ? + fset_option_search_by_name (option_name, &line) : NULL; + if (ptr_fset_option) { ptr_option = weechat_config_get (ptr_fset_option->name); @@ -1072,8 +1102,9 @@ fset_option_config_cb (const void *pointer, for (line = 0; line < num_options; line++) { ptr_fset_option = weechat_arraylist_get (fset_options, line); - if (ptr_fset_option->parent_name - && (strcmp (ptr_fset_option->parent_name, option) == 0)) + if (ptr_fset_option + && ptr_fset_option->parent_name + && (strcmp (ptr_fset_option->parent_name, option_name) == 0)) { ptr_option = weechat_config_get (ptr_fset_option->name); if (ptr_option) @@ -1083,6 +1114,67 @@ fset_option_config_cb (const void *pointer, fset_option_set_max_length_fields_all (); fset_buffer_refresh (0); } +} + +/* + * Callback for timer after an option is changed. + */ + +int +fset_option_config_timer_cb (const void *pointer, + void *data, + int remaining_calls) +{ + /* make C compiler happy */ + (void) pointer; + (void) remaining_calls; + + fset_option_config_changed ((const char *)data); + + fset_option_timer_hook = NULL; + + return WEECHAT_RC_OK; +} + +/* + * Callback for config option changed. + */ + +int +fset_option_config_cb (const void *pointer, + void *data, + const char *option, + const char *value) +{ + const char *ptr_info; + + /* make C compiler happy */ + (void) pointer; + (void) data; + (void) value; + + /* do nothing if fset buffer is not opened */ + if (!fset_buffer) + return WEECHAT_RC_OK; + + /* do nothing if WeeChat is upgrading */ + ptr_info = weechat_info_get ("weechat_upgrading", NULL); + if (ptr_info && (strcmp (ptr_info, "1") == 0)) + return WEECHAT_RC_OK; + + if (fset_option_config_changed_timer) + { + if (!fset_option_timer_hook) + { + fset_option_timer_hook = weechat_hook_timer ( + 1, 0, 1, + &fset_option_config_timer_cb, NULL, NULL); + } + } + else + { + fset_option_config_changed (option); + } return WEECHAT_RC_OK; } @@ -1186,6 +1278,8 @@ fset_option_print_log () for (i = 0; i < num_options; i++) { ptr_fset_option = weechat_arraylist_get (fset_options, i); + if (!ptr_fset_option) + continue; weechat_log_printf (""); weechat_log_printf ("[fset option (addr:0x%lx)]", ptr_fset_option); weechat_log_printf (" name. . . . . . . . . : '%s'", ptr_fset_option->name); diff --git a/src/plugins/fset/fset-option.h b/src/plugins/fset/fset-option.h index 21749cb3c..6240b1899 100644 --- a/src/plugins/fset/fset-option.h +++ b/src/plugins/fset/fset-option.h @@ -53,6 +53,7 @@ extern struct t_arraylist *fset_options; extern int fset_option_count_marked; extern struct t_hashtable *fset_option_max_length_field; extern char *fset_option_filter; +extern int fset_option_config_changed_timer; extern char *fset_option_type_string[]; extern char *fset_option_type_string_short[]; extern char *fset_option_type_string_tiny[]; |