summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSébastien Helleu <flashcode@flashtux.org>2017-06-02 20:33:35 +0200
committerSébastien Helleu <flashcode@flashtux.org>2017-06-25 16:35:27 +0200
commitd5aa8530b7c438036fe8bcc96f999e19caa0e9f8 (patch)
tree24aeceb90383fa728099b8b4c21d36842002e6fc
parent500e54578b26c502ab4a6d1e455d60c15844a965 (diff)
downloadweechat-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.c15
-rw-r--r--src/plugins/fset/fset-command.c47
-rw-r--r--src/plugins/fset/fset-config.c19
-rw-r--r--src/plugins/fset/fset-config.h2
-rw-r--r--src/plugins/fset/fset-info.c6
-rw-r--r--src/plugins/fset/fset-option.c154
-rw-r--r--src/plugins/fset/fset-option.h1
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[];