diff options
author | Sébastien Helleu <flashcode@flashtux.org> | 2017-03-12 18:29:28 +0100 |
---|---|---|
committer | Sébastien Helleu <flashcode@flashtux.org> | 2017-03-25 14:18:19 +0100 |
commit | 4ef8e61ca59e2db11aeb8d521cbe6f188ef60829 (patch) | |
tree | ab9928fb93238330e684d5dfc55ad870c3862f1e /src | |
parent | 77af4e0a87b9bfce61d1e4957166c3071cfa585e (diff) | |
download | weechat-4ef8e61ca59e2db11aeb8d521cbe6f188ef60829.zip |
buflist: add option buflist.look.sort
Diffstat (limited to 'src')
-rw-r--r-- | src/plugins/buflist/buflist-bar-item.c | 64 | ||||
-rw-r--r-- | src/plugins/buflist/buflist-config.c | 77 | ||||
-rw-r--r-- | src/plugins/buflist/buflist-config.h | 3 | ||||
-rw-r--r-- | src/plugins/buflist/buflist.c | 216 | ||||
-rw-r--r-- | src/plugins/buflist/buflist.h | 6 |
5 files changed, 330 insertions, 36 deletions
diff --git a/src/plugins/buflist/buflist-bar-item.c b/src/plugins/buflist/buflist-bar-item.c index 50a8b5d07..16f0f3775 100644 --- a/src/plugins/buflist/buflist-bar-item.c +++ b/src/plugins/buflist/buflist-bar-item.c @@ -46,9 +46,8 @@ buflist_bar_item_buflist_cb (const void *pointer, void *data, struct t_gui_buffer *buffer, struct t_hashtable *extra_info) { - struct t_hdata *hdata_buffer, *hdata_hotlist; - struct t_gui_buffer *ptr_buffer, *ptr_next_buffer, *ptr_current_buffer; - struct t_gui_buffer *ptr_buffer_hotlist; + struct t_arraylist *buffers; + struct t_gui_buffer *ptr_buffer, *ptr_current_buffer; struct t_gui_hotlist *ptr_hotlist; char **buflist, *str_buflist; char str_format_number[32], str_format_number_empty[32]; @@ -58,7 +57,8 @@ buflist_bar_item_buflist_cb (const void *pointer, void *data, const char *hotlist_priority_none = "none"; const char *hotlist_priority[4] = { "low", "message", "private", "highlight" }; - int length_max_number, current_buffer, number, prev_number, priority, rc; + int i, length_max_number, current_buffer, number, prev_number, priority; + int rc; /* make C compiler happy */ (void) pointer; @@ -77,53 +77,43 @@ buflist_bar_item_buflist_cb (const void *pointer, void *data, ptr_current_buffer = weechat_current_buffer (); - hdata_buffer = weechat_hdata_get ("buffer"); - ptr_buffer = weechat_hdata_get_list (hdata_buffer, "last_gui_buffer"); - - hdata_hotlist = weechat_hdata_get ("hotlist"); + ptr_buffer = weechat_hdata_get_list (buflist_hdata_buffer, + "last_gui_buffer"); length_max_number = snprintf ( str_number, sizeof (str_number), - "%d", weechat_hdata_integer (hdata_buffer, ptr_buffer, "number")); + "%d", + weechat_hdata_integer (buflist_hdata_buffer, ptr_buffer, "number")); snprintf (str_format_number, sizeof (str_format_number), "%%%dd", length_max_number); snprintf (str_format_number_empty, sizeof (str_format_number_empty), "%%-%ds", length_max_number); - ptr_buffer = weechat_hdata_get_list (hdata_buffer, "gui_buffers"); + buffers = buflist_sort_buffers (); - while (ptr_buffer) + for (i = 0; i < weechat_arraylist_size (buffers); i++) { - ptr_next_buffer = weechat_hdata_move (hdata_buffer, ptr_buffer, 1); + ptr_buffer = weechat_arraylist_get (buffers, i); current_buffer = (ptr_buffer == ptr_current_buffer); - /* search hotlist for this buffer (level and counts) */ - ptr_hotlist = weechat_hdata_get_list (hdata_hotlist, "gui_hotlist"); - while (ptr_hotlist) - { - ptr_buffer_hotlist = weechat_hdata_pointer (hdata_hotlist, - ptr_hotlist, - "buffer"); - if (ptr_buffer_hotlist == ptr_buffer) - break; - - ptr_hotlist = weechat_hdata_move (hdata_hotlist, ptr_hotlist, 1); - } + ptr_hotlist = buflist_search_hotlist_for_buffer (ptr_buffer); - ptr_name = weechat_hdata_string (hdata_buffer, ptr_buffer, - "short_name"); + ptr_name = weechat_hdata_string (buflist_hdata_buffer, + ptr_buffer, "short_name"); if (!ptr_name) - ptr_name = weechat_hdata_string (hdata_buffer, ptr_buffer, "name"); + ptr_name = weechat_hdata_string (buflist_hdata_buffer, + ptr_buffer, "name"); if (*buflist[0]) { if (!weechat_string_dyn_concat (buflist, "\n")) - return NULL; + goto error; } /* buffer number */ - number = weechat_hdata_integer (hdata_buffer, ptr_buffer, "number"); + number = weechat_hdata_integer (buflist_hdata_buffer, + ptr_buffer, "number"); if (number != prev_number) { snprintf (str_number, sizeof (str_number), @@ -162,8 +152,8 @@ buflist_bar_item_buflist_cb (const void *pointer, void *data, ptr_hotlist_priority = hotlist_priority_none; if (ptr_hotlist) { - priority = weechat_hdata_integer (hdata_hotlist, ptr_hotlist, - "priority"); + priority = weechat_hdata_integer (buflist_hdata_hotlist, + ptr_hotlist, "priority"); if ((priority >= 0) && (priority < 4)) { ptr_hotlist_format = weechat_config_string ( @@ -187,13 +177,19 @@ buflist_bar_item_buflist_cb (const void *pointer, void *data, rc = weechat_string_dyn_concat (buflist, line); free (line); if (!rc) - return NULL; - - ptr_buffer = ptr_next_buffer; + goto error; } str_buflist = *buflist; + + goto end; + +error: + str_buflist = NULL; + +end: weechat_string_dyn_free (buflist, 0); + weechat_arraylist_free (buffers); return str_buflist; } diff --git a/src/plugins/buflist/buflist-config.c b/src/plugins/buflist/buflist-config.c index b02d5e48d..70bc30d21 100644 --- a/src/plugins/buflist/buflist-config.c +++ b/src/plugins/buflist/buflist-config.c @@ -29,6 +29,10 @@ struct t_config_file *buflist_config_file = NULL; +/* buflist config, look section */ + +struct t_config_option *buflist_config_look_sort; + /* buflist config, format section */ struct t_config_option *buflist_config_format_buffer; @@ -36,9 +40,35 @@ struct t_config_option *buflist_config_format_buffer_current; struct t_config_option *buflist_config_format_hotlist[4]; struct t_config_option *buflist_config_format_hotlist_none; +char **buflist_config_sort_fields = NULL; +int buflist_config_sort_fields_count = 0; + + +/* + * Callback for changes on option "buflist.look.sort". + */ + +void +buflist_config_change_sort (const void *pointer, void *data, + struct t_config_option *option) +{ + /* make C compiler happy */ + (void) pointer; + (void) data; + (void) option; + + if (buflist_config_sort_fields) + weechat_string_free_split (buflist_config_sort_fields); + + buflist_config_sort_fields = weechat_string_split ( + weechat_config_string (buflist_config_look_sort), + ",", 0, 0, &buflist_config_sort_fields_count); + + weechat_bar_item_update (BUFLIST_BAR_ITEM_NAME); +} /* - * Callback for changes on option "irc.network.lag_min_show". + * Callback for changes on format options. */ void @@ -71,6 +101,33 @@ buflist_config_init () if (!buflist_config_file) return 0; + /* look */ + ptr_section = weechat_config_new_section (buflist_config_file, "look", + 0, 0, + NULL, NULL, NULL, + NULL, NULL, NULL, + NULL, NULL, NULL, + NULL, NULL, NULL, + NULL, NULL, NULL); + if (!ptr_section) + { + weechat_config_free (buflist_config_file); + return 0; + } + + buflist_config_look_sort = weechat_config_new_option ( + buflist_config_file, ptr_section, + "sort", "string", + N_("comma-separated list of fields to sort buffers; each field is " + "a hdata variable of buffer; char \"-\" can be used before field " + "to reverse order"), + NULL, 0, 0, + "number,-active", + NULL, 0, + NULL, NULL, NULL, + &buflist_config_change_sort, NULL, NULL, + NULL, NULL, NULL); + /* format */ ptr_section = weechat_config_new_section (buflist_config_file, "format", 0, 0, @@ -166,7 +223,16 @@ buflist_config_init () int buflist_config_read () { - return weechat_config_read (buflist_config_file); + int rc; + + rc = weechat_config_read (buflist_config_file); + + if (rc == WEECHAT_CONFIG_READ_OK) + { + buflist_config_change_sort (NULL, NULL, NULL); + } + + return rc; } /* @@ -187,4 +253,11 @@ void buflist_config_free () { weechat_config_free (buflist_config_file); + + if (buflist_config_sort_fields) + { + weechat_string_free_split (buflist_config_sort_fields); + buflist_config_sort_fields = NULL; + buflist_config_sort_fields_count = 0; + } } diff --git a/src/plugins/buflist/buflist-config.h b/src/plugins/buflist/buflist-config.h index 69964e544..61c9bf35a 100644 --- a/src/plugins/buflist/buflist-config.h +++ b/src/plugins/buflist/buflist-config.h @@ -29,6 +29,9 @@ extern struct t_config_option *buflist_config_format_buffer_current; extern struct t_config_option *buflist_config_format_hotlist[4]; extern struct t_config_option *buflist_config_format_hotlist_none; +extern char **buflist_config_sort_fields; +extern int buflist_config_sort_fields_count; + extern int buflist_config_init (); extern int buflist_config_read (); extern int buflist_config_write (); diff --git a/src/plugins/buflist/buflist.c b/src/plugins/buflist/buflist.c index 0d93a5997..ab5501310 100644 --- a/src/plugins/buflist/buflist.c +++ b/src/plugins/buflist/buflist.c @@ -20,6 +20,7 @@ */ #include <stdlib.h> +#include <string.h> #include "../weechat-plugin.h" #include "buflist.h" @@ -36,6 +37,218 @@ WEECHAT_PLUGIN_PRIORITY(8000); struct t_weechat_plugin *weechat_buflist_plugin = NULL; +struct t_hdata *buflist_hdata_buffer = NULL; +struct t_hdata *buflist_hdata_hotlist = NULL; + + +/* + * Searches the hotlist pointer for the buffer. + * + * Returns pointer to hotlit, NULL if buffer is not in hotlist. + */ + +struct t_gui_hotlist * +buflist_search_hotlist_for_buffer (struct t_gui_buffer *buffer) +{ + struct t_gui_hotlist *ptr_hotlist; + struct t_gui_buffer *ptr_buffer; + + ptr_hotlist = weechat_hdata_get_list (buflist_hdata_hotlist, + "gui_hotlist"); + while (ptr_hotlist) + { + ptr_buffer = weechat_hdata_pointer (buflist_hdata_hotlist, + ptr_hotlist, "buffer"); + if (ptr_buffer == buffer) + break; + ptr_hotlist = weechat_hdata_move (buflist_hdata_hotlist, + ptr_hotlist, 1); + } + return ptr_hotlist; +} + +/* + * Compares a hdata variable of two objects. + * + * Returns: + * -1: variable1 < variable2 + * 0: variable1 == variable2 + * 1: variable1 > variable2 + */ + +int +buflist_compare_hdata_var (struct t_hdata *hdata, + void *pointer1, void *pointer2, + const char *variable) +{ + int type, rc, int_value1, int_value2; + long long_value1, long_value2; + char char_value1, char_value2; + const char *pos, *str_value1, *str_value2; + void *ptr_value1, *ptr_value2; + time_t time_value1, time_value2; + + rc = 0; + + pos = strchr (variable, '|'); + type = weechat_hdata_get_var_type (hdata, (pos) ? pos + 1 : variable); + switch (type) + { + case WEECHAT_HDATA_CHAR: + char_value1 = weechat_hdata_char (hdata, pointer1, variable); + char_value2 = weechat_hdata_char (hdata, pointer2, variable); + rc = (char_value1 < char_value2) ? + -1 : ((char_value1 > char_value2) ? 1 : 0); + break; + case WEECHAT_HDATA_INTEGER: + int_value1 = weechat_hdata_integer (hdata, pointer1, variable); + int_value2 = weechat_hdata_integer (hdata, pointer2, variable); + rc = (int_value1 < int_value2) ? + -1 : ((int_value1 > int_value2) ? 1 : 0); + break; + case WEECHAT_HDATA_LONG: + long_value1 = weechat_hdata_long (hdata, pointer1, variable); + long_value2 = weechat_hdata_long (hdata, pointer2, variable); + rc = (long_value1 < long_value2) ? + -1 : ((long_value1 > long_value2) ? 1 : 0); + break; + case WEECHAT_HDATA_STRING: + case WEECHAT_HDATA_SHARED_STRING: + str_value1 = weechat_hdata_string (hdata, pointer1, variable); + str_value2 = weechat_hdata_string (hdata, pointer2, variable); + if (!str_value1 && !str_value2) + rc = 0; + else if (str_value1 && !str_value2) + rc = 1; + else if (!str_value1 && str_value2) + rc = -1; + else + { + rc = strcmp (str_value1, str_value2); + if (rc < 0) + rc = -1; + else if (rc > 0) + rc = 1; + } + break; + case WEECHAT_HDATA_POINTER: + ptr_value1 = weechat_hdata_pointer (hdata, pointer1, variable); + ptr_value2 = weechat_hdata_pointer (hdata, pointer2, variable); + rc = (ptr_value1 < ptr_value2) ? + -1 : ((ptr_value1 > ptr_value2) ? 1 : 0); + break; + case WEECHAT_HDATA_TIME: + time_value1 = weechat_hdata_time (hdata, pointer1, variable); + time_value2 = weechat_hdata_time (hdata, pointer2, variable); + rc = (time_value1 < time_value2) ? + -1 : ((time_value1 > time_value2) ? 1 : 0); + break; + } + + return rc; +} + +/* + * Compares two buffers in order to add them in the sorted arraylist. + * + * The comparison is made using the list of fields defined in the option + * "buflist.look.sort". + * + * Returns: + * -1: buffer1 < buffer2 + * 0: buffer1 == buffer2 + * 1: buffer1 > buffer2 + */ + +int +buflist_compare_buffers (void *data, struct t_arraylist *arraylist, + void *pointer1, void *pointer2) +{ + int i, reverse, rc, hotlist_scanned; + const char *ptr_field; + struct t_gui_hotlist *ptr_hotlist1, *ptr_hotlist2; + + /* make C compiler happy */ + (void) data; + (void) arraylist; + + hotlist_scanned = 0; + ptr_hotlist1 = NULL; + ptr_hotlist2 = NULL; + + for (i = 0; i < buflist_config_sort_fields_count; i++) + { + reverse = 1; + if (buflist_config_sort_fields[i][0] == '-') + { + ptr_field = buflist_config_sort_fields[i] + 1; + reverse = -1; + } + else + { + ptr_field = buflist_config_sort_fields[i]; + } + rc = 0; + if (strncmp (ptr_field, "hotlist.", 8) == 0) + { + if (!hotlist_scanned) + { + ptr_hotlist1 = buflist_search_hotlist_for_buffer (pointer1); + ptr_hotlist2 = buflist_search_hotlist_for_buffer (pointer2); + } + if (!ptr_hotlist1 && !ptr_hotlist2) + rc = 0; + else if (ptr_hotlist1 && !ptr_hotlist2) + rc = 1; + else if (!ptr_hotlist1 && ptr_hotlist2) + rc = -1; + else + { + rc = buflist_compare_hdata_var (buflist_hdata_hotlist, + pointer1, pointer2, + ptr_field + 8); + } + } + else + { + rc = buflist_compare_hdata_var (buflist_hdata_buffer, + pointer1, pointer2, + ptr_field); + } + rc *= reverse; + if (rc != 0) + return rc; + } + + return rc; +} + +/* + * Builds a list of pointers to buffers, sorted according to option + * "buflist.look.sort". + * + * Returns an arraylist that must be freed by weechat_arraylist_free after use. + */ + +struct t_arraylist * +buflist_sort_buffers () +{ + struct t_arraylist *buffers; + struct t_gui_buffer *ptr_buffer; + + buffers = weechat_arraylist_new (128, 1, 1, + &buflist_compare_buffers, NULL, + NULL, NULL); + + ptr_buffer = weechat_hdata_get_list (buflist_hdata_buffer, "gui_buffers"); + while (ptr_buffer) + { + weechat_arraylist_add (buffers, ptr_buffer); + ptr_buffer = weechat_hdata_move (buflist_hdata_buffer, ptr_buffer, 1); + } + + return buffers; +} /* * Callback for a signal on a buffer. @@ -79,6 +292,9 @@ weechat_plugin_init (struct t_weechat_plugin *plugin, int argc, char *argv[]) weechat_plugin = plugin; + buflist_hdata_buffer = weechat_hdata_get ("buffer"); + buflist_hdata_hotlist = weechat_hdata_get ("hotlist"); + if (!buflist_config_init ()) return WEECHAT_RC_ERROR; diff --git a/src/plugins/buflist/buflist.h b/src/plugins/buflist/buflist.h index bc63c527e..51af55c15 100644 --- a/src/plugins/buflist/buflist.h +++ b/src/plugins/buflist/buflist.h @@ -28,4 +28,10 @@ extern struct t_weechat_plugin *weechat_buflist_plugin; +extern struct t_hdata *buflist_hdata_buffer; +extern struct t_hdata *buflist_hdata_hotlist; + +extern struct t_gui_hotlist *buflist_search_hotlist_for_buffer (struct t_gui_buffer *buffer); +extern struct t_arraylist *buflist_sort_buffers (); + #endif /* WEECHAT_BUFLIST_H */ |