From 8c7b4282aee9663d570dbb285b5c65d5ab09e912 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Helleu?= Date: Wed, 31 May 2017 20:23:48 +0200 Subject: [PATCH] fset: hook command /set, add option fset.look.condition_catch_set --- src/plugins/fset/fset-command.c | 129 ++++++++++++++++++++++++++++++++ src/plugins/fset/fset-config.c | 16 ++++ src/plugins/fset/fset-config.h | 1 + src/plugins/fset/fset-option.c | 53 +++++++++---- src/plugins/fset/fset-option.h | 5 +- 5 files changed, 190 insertions(+), 14 deletions(-) diff --git a/src/plugins/fset/fset-command.c b/src/plugins/fset/fset-command.c index 3236a33b6..76c21029b 100644 --- a/src/plugins/fset/fset-command.c +++ b/src/plugins/fset/fset-command.c @@ -247,6 +247,134 @@ fset_command_fset (const void *pointer, void *data, return WEECHAT_RC_OK; } +/* + * Hooks execution of command "/set". + */ + +int +fset_command_run_set_cb (const void *pointer, void *data, + struct t_gui_buffer *buffer, const char *command) +{ + char **argv, *old_filter, *result, str_number[64]; + const char *ptr_condition; + int rc, argc, old_buffer_selected_line, condition_ok; + struct t_arraylist *old_options; + struct t_hashtable *old_max_length_field, *eval_extra_vars, *eval_options; + + /* make C compiler happy */ + (void) pointer; + (void) data; + (void) buffer; + + if (strncmp (command, "/set", 4) != 0) + return WEECHAT_RC_OK; + + ptr_condition = weechat_config_string (fset_config_look_condition_catch_set); + if (!ptr_condition || !ptr_condition[0]) + return WEECHAT_RC_OK; + + rc = WEECHAT_RC_OK; + + argv = weechat_string_split (command, " ", 0, 0, &argc); + + if (argc > 2) + goto end; + + /* + * ignore "diff" and "env" arguments for /set + * (we must not catch that in fset!) + */ + if ((argc > 1) + && ((weechat_strcasecmp (argv[1], "diff") == 0) + || (weechat_strcasecmp (argv[1], "env") == 0))) + { + goto end; + } + + /* backup current options/max length field/selected line/filter */ + old_options = fset_options; + fset_options = fset_option_get_arraylist_options (); + old_max_length_field = fset_option_max_length_field; + fset_option_max_length_field = fset_option_get_hashtable_max_length_field (); + old_filter = (fset_option_filter) ? strdup (fset_option_filter) : NULL; + fset_option_set_filter ((argc > 1) ? argv[1] : NULL); + old_buffer_selected_line = fset_buffer_selected_line; + fset_buffer_selected_line = 0; + + fset_option_get_options (); + + /* evaluate condition to catch /set command */ + condition_ok = 0; + eval_extra_vars = weechat_hashtable_new ( + 32, + WEECHAT_HASHTABLE_STRING, + WEECHAT_HASHTABLE_STRING, + NULL, + NULL); + eval_options = weechat_hashtable_new ( + 32, + WEECHAT_HASHTABLE_STRING, + WEECHAT_HASHTABLE_STRING, + NULL, NULL); + if (eval_extra_vars && eval_options) + { + snprintf (str_number, sizeof (str_number), + "%d", weechat_arraylist_size (fset_options)); + weechat_hashtable_set (eval_extra_vars, "count", str_number); + weechat_hashtable_set (eval_extra_vars, "name", + (argc > 1) ? argv[1] : ""); + weechat_hashtable_set (eval_options, "type", "condition"); + result = weechat_string_eval_expression (ptr_condition, + NULL, + eval_extra_vars, + eval_options); + condition_ok = (result && (strcmp (result, "1") == 0)); + if (result) + free (result); + } + if (eval_extra_vars) + weechat_hashtable_free (eval_extra_vars); + if (eval_options) + weechat_hashtable_free (eval_options); + + /* check condition to trigger the fset buffer */ + if (condition_ok) + { + if (old_options) + weechat_arraylist_free (old_options); + if (old_max_length_field) + weechat_hashtable_free (old_max_length_field); + if (old_filter) + free (old_filter); + + if (!fset_buffer) + fset_buffer_open (); + + fset_buffer_set_localvar_filter (); + fset_buffer_refresh (1); + weechat_buffer_set (fset_buffer, "display", "1"); + + rc = WEECHAT_RC_OK_EAT; + } + else + { + weechat_arraylist_free (fset_options); + fset_options = old_options; + weechat_hashtable_free (fset_option_max_length_field); + fset_option_max_length_field = old_max_length_field; + fset_option_set_filter (old_filter); + if (old_filter) + free (old_filter); + fset_buffer_selected_line = old_buffer_selected_line; + } + +end: + if (argv) + weechat_string_free_split (argv); + + return rc; +} + /* * Hooks fset commands. */ @@ -306,4 +434,5 @@ fset_command_init () " || -append" " || *|f:|s:|d:|d=|d==|=|==", &fset_command_fset, NULL, NULL); + weechat_hook_command_run ("/set", &fset_command_run_set_cb, NULL, NULL); } diff --git a/src/plugins/fset/fset-config.c b/src/plugins/fset/fset-config.c index 2e5999f93..059339cd0 100644 --- a/src/plugins/fset/fset-config.c +++ b/src/plugins/fset/fset-config.c @@ -33,6 +33,7 @@ struct t_config_file *fset_config_file = NULL; /* fset config, look section */ +struct t_config_option *fset_config_look_condition_catch_set; struct t_config_option *fset_config_look_enabled; struct t_config_option *fset_config_look_help_bar; struct t_config_option *fset_config_look_use_keys; @@ -187,6 +188,21 @@ fset_config_init () return 0; } + fset_config_look_condition_catch_set = weechat_config_new_option ( + fset_config_file, ptr_section, + "condition_catch_set", "string", + N_("condition to catch /set command and display results in the fset " + "buffer; following variables can be used: ${name} (name of option " + "given for the /set command), ${count} (number of options found " + "with the /set argument); an empty string disables the catch of " + "/set command; with value \"1\", the fset buffer is always used " + "with /set command"), + NULL, 0, 0, + "${count} >= 1", + NULL, 0, + NULL, NULL, NULL, + NULL, NULL, NULL, + NULL, NULL, NULL); fset_config_look_enabled = weechat_config_new_option ( fset_config_file, ptr_section, "enabled", "boolean", diff --git a/src/plugins/fset/fset-config.h b/src/plugins/fset/fset-config.h index fa38a2b7f..03608674c 100644 --- a/src/plugins/fset/fset-config.h +++ b/src/plugins/fset/fset-config.h @@ -24,6 +24,7 @@ extern struct t_config_file *fset_config_file; +extern struct t_config_option *fset_config_look_condition_catch_set; extern struct t_config_option *fset_config_look_enabled; extern struct t_config_option *fset_config_look_help_bar; extern struct t_config_option *fset_config_look_use_keys; diff --git a/src/plugins/fset/fset-option.c b/src/plugins/fset/fset-option.c index 62aad7266..fcccd8dcd 100644 --- a/src/plugins/fset/fset-option.c +++ b/src/plugins/fset/fset-option.c @@ -722,6 +722,30 @@ fset_option_free_cb (void *data, struct t_arraylist *arraylist, void *pointer) fset_option_free (fset_option); } +/* + * Gets the arraylist to store options. + */ + +struct t_arraylist * +fset_option_get_arraylist_options () +{ + return weechat_arraylist_new (100, 1, 0, + &fset_option_compare_options_cb, NULL, + &fset_option_free_cb, NULL); +} + +/* + * Gets the hashtable to store max length of fields. + */ + +struct t_hashtable * +fset_option_get_hashtable_max_length_field () +{ + return weechat_hashtable_new (32, + WEECHAT_HASHTABLE_STRING, + WEECHAT_HASHTABLE_INTEGER, + NULL, NULL); +} /* * Gets all options to display in fset buffer. @@ -772,6 +796,19 @@ fset_option_get_options () fset_buffer_selected_line = num_options - 1; } +/* + * Sets the filter. + */ + +void +fset_option_set_filter (const char *filter) +{ + if (fset_option_filter) + free (fset_option_filter); + fset_option_filter = (filter && (strcmp (filter, "*") != 0)) ? + strdup (filter) : NULL; +} + /* * Filters options. */ @@ -781,10 +818,7 @@ fset_option_filter_options (const char *filter) { fset_buffer_selected_line = 0; - if (fset_option_filter) - free (fset_option_filter); - fset_option_filter = (filter && (strcmp (filter, "*") != 0)) ? - strdup (filter) : NULL; + fset_option_set_filter (filter); fset_buffer_set_localvar_filter (); @@ -987,15 +1021,8 @@ fset_option_print_log () int fset_option_init () { - fset_option_max_length_field = weechat_hashtable_new ( - 32, - WEECHAT_HASHTABLE_STRING, - WEECHAT_HASHTABLE_INTEGER, - NULL, NULL); - - fset_options = weechat_arraylist_new (100, 1, 0, - &fset_option_compare_options_cb, NULL, - &fset_option_free_cb, NULL); + fset_options = fset_option_get_arraylist_options (); + fset_option_max_length_field = fset_option_get_hashtable_max_length_field (); return 1; } diff --git a/src/plugins/fset/fset-option.h b/src/plugins/fset/fset-option.h index 3c39aeba6..c08e240fe 100644 --- a/src/plugins/fset/fset-option.h +++ b/src/plugins/fset/fset-option.h @@ -47,8 +47,11 @@ extern struct t_fset_option *fset_option_search_by_name (const char *name, int *line); extern int fset_option_value_different_from_default (struct t_fset_option *option); extern void fset_option_free (struct t_fset_option *fset_option); +extern struct t_arraylist *fset_option_get_arraylist_options (); +extern struct t_hashtable *fset_option_get_hashtable_max_length_field (); extern void fset_option_get_options (); -extern void fset_option_filter_options (const char *search); +extern void fset_option_set_filter (const char *filter); +extern void fset_option_filter_options (const char *filter); extern int fset_option_config_cb (const void *pointer, void *data, const char *option,