summaryrefslogtreecommitdiffstats
path: root/window-tree.c
diff options
context:
space:
mode:
authornicm <nicm>2019-08-16 11:49:12 +0000
committernicm <nicm>2019-08-16 11:49:12 +0000
commit37583f0a69d22668bdd47e0b30b61d8dac74bdf6 (patch)
tree6f2230c68121094ff70e15407120b0b55ae92f80 /window-tree.c
parent5644d37876faf69ecf9f34cbd52e6cdfab83cf79 (diff)
Add a flag to reverse sort in the various choose modes, from Benjamin
Poirier in GitHub issue 1875.
Diffstat (limited to 'window-tree.c')
-rw-r--r--window-tree.c168
1 files changed, 88 insertions, 80 deletions
diff --git a/window-tree.c b/window-tree.c
index b9fc4a6a..a0127c2f 100644
--- a/window-tree.c
+++ b/window-tree.c
@@ -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));
-}
-
-static int
-window_tree_cmp_session_time(const void *a0, const void *b0)
-{
- const struct session *const *a = a0;
- const struct session *const *b = b0;
+ 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 (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));
+ 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_window(const void *a0, const void *b0)
{
- const struct winlink *const *a = a0;
- const struct winlink *const *b = b0;
-
- return (strcmp((*a)->window->name, (*b)->window->name));
-}
+ 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;
+
+ 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;
+ }
-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));
+ if (window_tree_sort->reversed)
+ result = -result;
+ return (result);
}
static int
-window_tree_cmp_pane_time(const void *a0, const void *b0)
+window_tree_cmp_pane(const void *a0, const void *b0)
{
- const struct window_pane *const *a = a0;
- const struct window_pane *const *b = b0;
+ const struct window_pane *const *a = a0;
+ const struct window_pane *const *b = b0;
+ int result;
- 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) {