mirror of
https://github.com/weechat/weechat.git
synced 2026-06-12 14:14:48 +02:00
buflist: add option buflist.look.sort
This commit is contained in:
@@ -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 = buflist_search_hotlist_for_buffer (ptr_buffer);
|
||||
|
||||
ptr_hotlist = weechat_hdata_move (hdata_hotlist, ptr_hotlist, 1);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -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 "irc.network.lag_min_show".
|
||||
* 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 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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 ();
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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 */
|
||||
|
||||
Reference in New Issue
Block a user