summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSébastien Helleu <flashcode@flashtux.org>2017-03-12 18:29:28 +0100
committerSébastien Helleu <flashcode@flashtux.org>2017-03-25 14:18:19 +0100
commit4ef8e61ca59e2db11aeb8d521cbe6f188ef60829 (patch)
treeab9928fb93238330e684d5dfc55ad870c3862f1e /src
parent77af4e0a87b9bfce61d1e4957166c3071cfa585e (diff)
downloadweechat-4ef8e61ca59e2db11aeb8d521cbe6f188ef60829.zip
buflist: add option buflist.look.sort
Diffstat (limited to 'src')
-rw-r--r--src/plugins/buflist/buflist-bar-item.c64
-rw-r--r--src/plugins/buflist/buflist-config.c77
-rw-r--r--src/plugins/buflist/buflist-config.h3
-rw-r--r--src/plugins/buflist/buflist.c216
-rw-r--r--src/plugins/buflist/buflist.h6
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 */