Add a flag to reverse sort in the various choose modes, from Benjamin

Poirier in GitHub issue 1875.
This commit is contained in:
nicm
2019-08-16 11:49:12 +00:00
parent 5644d37876
commit 37583f0a69
7 changed files with 195 additions and 216 deletions

View File

@ -89,6 +89,7 @@ static const char *window_tree_sort_list[] = {
"name",
"time"
};
static struct mode_tree_sort_criteria *window_tree_sort;
enum window_tree_type {
WINDOW_TREE_NONE,
@ -184,62 +185,92 @@ window_tree_free_item(struct window_tree_itemdata *item)
}
static int
window_tree_cmp_session_name(const void *a0, const void *b0)
window_tree_cmp_session(const void *a0, const void *b0)
{
const struct session *const *a = a0;
const struct session *const *b = b0;
const struct session *const *a = a0;
const struct session *const *b = b0;
const struct session *sa = *a;
const struct session *sb = *b;
int result;
return (strcmp((*a)->name, (*b)->name));
switch (window_tree_sort->field) {
case WINDOW_TREE_BY_INDEX:
result = sa->id - sb->id;
break;
case WINDOW_TREE_BY_TIME:
if (timercmp(&sa->activity_time, &sb->activity_time, >)) {
result = -1;
break;
}
if (timercmp(&sa->activity_time, &sb->activity_time, <)) {
result = 1;
break;
}
/* FALLTHROUGH */
case WINDOW_TREE_BY_NAME:
result = strcmp(sa->name, sb->name);
break;
}
if (window_tree_sort->reversed)
result = -result;
return (result);
}
static int
window_tree_cmp_session_time(const void *a0, const void *b0)
window_tree_cmp_window(const void *a0, const void *b0)
{
const struct session *const *a = a0;
const struct session *const *b = b0;
const struct winlink *const *a = a0;
const struct winlink *const *b = b0;
const struct winlink *wla = *a;
const struct winlink *wlb = *b;
struct window *wa = wla->window;
struct window *wb = wlb->window;
int result;
if (timercmp(&(*a)->activity_time, &(*b)->activity_time, >))
return (-1);
if (timercmp(&(*a)->activity_time, &(*b)->activity_time, <))
return (1);
return (strcmp((*a)->name, (*b)->name));
switch (window_tree_sort->field) {
case WINDOW_TREE_BY_INDEX:
result = wla->idx - wlb->idx;
break;
case WINDOW_TREE_BY_TIME:
if (timercmp(&wa->activity_time, &wb->activity_time, >)) {
result = -1;
break;
}
if (timercmp(&wa->activity_time, &wb->activity_time, <)) {
result = 1;
break;
}
/* FALLTHROUGH */
case WINDOW_TREE_BY_NAME:
result = strcmp(wa->name, wb->name);
break;
}
if (window_tree_sort->reversed)
result = -result;
return (result);
}
static int
window_tree_cmp_window_name(const void *a0, const void *b0)
window_tree_cmp_pane(const void *a0, const void *b0)
{
const struct winlink *const *a = a0;
const struct winlink *const *b = b0;
const struct window_pane *const *a = a0;
const struct window_pane *const *b = b0;
int result;
return (strcmp((*a)->window->name, (*b)->window->name));
}
static int
window_tree_cmp_window_time(const void *a0, const void *b0)
{
const struct winlink *const *a = a0;
const struct winlink *const *b = b0;
if (timercmp(&(*a)->window->activity_time,
&(*b)->window->activity_time, >))
return (-1);
if (timercmp(&(*a)->window->activity_time,
&(*b)->window->activity_time, <))
return (1);
return (strcmp((*a)->window->name, (*b)->window->name));
}
static int
window_tree_cmp_pane_time(const void *a0, const void *b0)
{
const struct window_pane *const *a = a0;
const struct window_pane *const *b = b0;
if ((*a)->active_point < (*b)->active_point)
return (-1);
if ((*a)->active_point > (*b)->active_point)
return (1);
return (0);
if (window_tree_sort->field == WINDOW_TREE_BY_TIME)
result = (*a)->active_point - (*b)->active_point;
else {
/*
* Panes don't have names, so use number order for any other
* sort field.
*/
result = (*a)->id - (*b)->id;
}
if (window_tree_sort->reversed)
result *= -1;
return (result);
}
static void
@ -285,8 +316,9 @@ window_tree_filter_pane(struct session *s, struct winlink *wl,
}
static int
window_tree_build_window(struct session *s, struct winlink *wl, void* modedata,
u_int sort_type, struct mode_tree_item *parent, const char *filter)
window_tree_build_window(struct session *s, struct winlink *wl,
void* modedata, struct mode_tree_sort_criteria *sort_crit,
struct mode_tree_item *parent, const char *filter)
{
struct window_tree_modedata *data = modedata;
struct window_tree_itemdata *item;
@ -335,16 +367,8 @@ window_tree_build_window(struct session *s, struct winlink *wl, void* modedata,
if (n == 0)
goto empty;
switch (sort_type) {
case WINDOW_TREE_BY_INDEX:
break;
case WINDOW_TREE_BY_NAME:
/* Panes don't have names, so leave in number order. */
break;
case WINDOW_TREE_BY_TIME:
qsort(l, n, sizeof *l, window_tree_cmp_pane_time);
break;
}
window_tree_sort = sort_crit;
qsort(l, n, sizeof *l, window_tree_cmp_pane);
for (i = 0; i < n; i++)
window_tree_build_pane(s, wl, l[i], modedata, mti);
@ -360,7 +384,7 @@ empty:
static void
window_tree_build_session(struct session *s, void* modedata,
u_int sort_type, const char *filter)
struct mode_tree_sort_criteria *sort_crit, const char *filter)
{
struct window_tree_modedata *data = modedata;
struct window_tree_itemdata *item;
@ -392,20 +416,12 @@ window_tree_build_session(struct session *s, void* modedata,
l = xreallocarray(l, n + 1, sizeof *l);
l[n++] = wl;
}
switch (sort_type) {
case WINDOW_TREE_BY_INDEX:
break;
case WINDOW_TREE_BY_NAME:
qsort(l, n, sizeof *l, window_tree_cmp_window_name);
break;
case WINDOW_TREE_BY_TIME:
qsort(l, n, sizeof *l, window_tree_cmp_window_time);
break;
}
window_tree_sort = sort_crit;
qsort(l, n, sizeof *l, window_tree_cmp_window);
empty = 0;
for (i = 0; i < n; i++) {
if (!window_tree_build_window(s, l[i], modedata, sort_type, mti,
if (!window_tree_build_window(s, l[i], modedata, sort_crit, mti,
filter))
empty++;
}
@ -418,8 +434,8 @@ window_tree_build_session(struct session *s, void* modedata,
}
static void
window_tree_build(void *modedata, u_int sort_type, uint64_t *tag,
const char *filter)
window_tree_build(void *modedata, struct mode_tree_sort_criteria *sort_crit,
uint64_t *tag, const char *filter)
{
struct window_tree_modedata *data = modedata;
struct session *s, **l;
@ -446,19 +462,11 @@ window_tree_build(void *modedata, u_int sort_type, uint64_t *tag,
l = xreallocarray(l, n + 1, sizeof *l);
l[n++] = s;
}
switch (sort_type) {
case WINDOW_TREE_BY_INDEX:
break;
case WINDOW_TREE_BY_NAME:
qsort(l, n, sizeof *l, window_tree_cmp_session_name);
break;
case WINDOW_TREE_BY_TIME:
qsort(l, n, sizeof *l, window_tree_cmp_session_time);
break;
}
window_tree_sort = sort_crit;
qsort(l, n, sizeof *l, window_tree_cmp_session);
for (i = 0; i < n; i++)
window_tree_build_session(l[i], modedata, sort_type, filter);
window_tree_build_session(l[i], modedata, sort_crit, filter);
free(l);
switch (data->type) {