=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/tmux/window-tree.c,v retrieving revision 1.8 retrieving revision 1.9 diff -u -r1.8 -r1.9 --- src/usr.bin/tmux/window-tree.c 2017/06/30 22:37:35 1.8 +++ src/usr.bin/tmux/window-tree.c 2017/07/03 22:48:02 1.9 @@ -1,4 +1,4 @@ -/* $OpenBSD: window-tree.c,v 1.8 2017/06/30 22:37:35 nicm Exp $ */ +/* $OpenBSD: window-tree.c,v 1.9 2017/07/03 22:48:02 nicm Exp $ */ /* * Copyright (c) 2017 Nicholas Marriott @@ -415,68 +415,119 @@ struct options *oo = s->options; struct winlink *wl; struct window *w; - u_int i, n, each, width, left; + u_int loop, total, visible, each, width, offset; + u_int current, start, end, remaining, i; struct grid_cell gc; - int colour, active_colour; + int colour, active_colour, left, right; char *label; size_t len; - if (sx < 6) + if (sx == 0) return; - n = winlink_count(&s->windows); + total = winlink_count(&s->windows); memcpy(&gc, &grid_default_cell, sizeof gc); colour = options_get_number(oo, "display-panes-colour"); active_colour = options_get_number(oo, "display-panes-active-colour"); - each = sx / n; - if (each < 24) { - n = (sx - 6) / 24; - if (n == 0) - n = 1; - each = (sx - 6) / n; - left = sx - (n * each); + if (sx / total < 24) { + visible = sx / 24; + if (visible == 0) + visible = 1; + } else + visible = total; - screen_write_cursormove(ctx, sx - left, 0); + current = 0; + RB_FOREACH(wl, winlinks, &s->windows) { + if (wl == s->curw) + break; + current++; + } + + if (current < visible) { + start = 0; + end = visible; + } else if (current >= total - visible) { + start = total - visible; + end = total; + } else { + start = current - (visible / 2); + end = start + visible; + } + + left = (start != 0); + right = (end != total); + if (((left && right) && sx <= 6) || ((left || right) && sx <= 3)) + left = right = 0; + if (left && right) { + each = (sx - 6) / visible; + remaining = (sx - 6) - (visible * each); + } else if (left || right) { + each = (sx - 3) / visible; + remaining = (sx - 3) - (visible * each); + } else { + each = sx / visible; + remaining = sx - (visible * each); + } + if (each == 0) + return; + + if (left) { + screen_write_cursormove(ctx, 2, 0); screen_write_vline(ctx, sy, 0, 0); - screen_write_cursormove(ctx, sx - left + left / 2, sy / 2); - screen_write_puts(ctx, &grid_default_cell, "..."); + screen_write_cursormove(ctx, 0, sy / 2); + screen_write_puts(ctx, &grid_default_cell, "<"); + } + if (right) { + screen_write_cursormove(ctx, sx - 3, 0); + screen_write_vline(ctx, sy, 0, 0); + screen_write_cursormove(ctx, sx - 1, sy / 2); + screen_write_puts(ctx, &grid_default_cell, ">"); + } - if (each == 0) - return; - left = 0; - } else - left = sx - (n * each); + i = loop = 0; + RB_FOREACH(wl, winlinks, &s->windows) { + if (loop == end) + break; + if (loop < start) { + loop++; + continue; + } + w = wl->window; - wl = RB_MIN(winlinks, &s->windows); - for (i = 0; i < n; i++) { if (wl == s->curw) gc.fg = active_colour; else gc.fg = colour; - if (i == n - 1) - width = each + left; + + if (left) + offset = 3 + (i * each); else + offset = (i * each); + if (loop == end - 1) + width = each - 1 + remaining; + else width = each - 1; - w = wl->window; - screen_write_cursormove(ctx, i * each, 0); + screen_write_cursormove(ctx, offset, 0); screen_write_preview(ctx, &w->active->base, width, sy); xasprintf(&label, " %u:%s ", wl->idx, w->name); if (strlen(label) > width) xasprintf(&label, " %u ", wl->idx); len = strlen(label) / 2; - screen_write_cursormove(ctx, i * each + each / 2 - len, sy / 2); + screen_write_cursormove(ctx, offset + (each / 2) - len, sy / 2); if (len < width) screen_write_puts(ctx, &gc, "%s", label); free(label); - if (i != n - 1) { - screen_write_cursormove(ctx, i * each + width, 0); + if (loop != end - 1) { + screen_write_cursormove(ctx, offset + width, 0); screen_write_vline(ctx, sy, 0, 0); } - wl = RB_NEXT(winlinks, &s->windows, wl); + loop++; + + i++; } } @@ -486,65 +537,116 @@ { struct options *oo = s->options; struct window_pane *wp; - u_int i, n, each, width, left; + u_int loop, total, visible, each, width, offset; + u_int current, start, end, remaining, i; struct grid_cell gc; - int colour, active_colour; + int colour, active_colour, left, right; char *label; size_t len; - if (sx < 6) + if (sx == 0) return; - n = window_count_panes(w); + total = window_count_panes(w); memcpy(&gc, &grid_default_cell, sizeof gc); colour = options_get_number(oo, "display-panes-colour"); active_colour = options_get_number(oo, "display-panes-active-colour"); - each = sx / n; - if (each < 24) { - n = (sx - 6) / 24; - if (n == 0) - n = 1; - each = (sx - 6) / n; - left = sx - (n * each); + if (sx / total < 24) { + visible = sx / 24; + if (visible == 0) + visible = 1; + } else + visible = total; - screen_write_cursormove(ctx, sx - left, 0); + current = 0; + TAILQ_FOREACH(wp, &w->panes, entry) { + if (wp == w->active) + break; + current++; + } + + if (current < visible) { + start = 0; + end = visible; + } else if (current >= total - visible) { + start = total - visible; + end = total; + } else { + start = current - (visible / 2); + end = start + visible; + } + + left = (start != 0); + right = (end != total); + if (((left && right) && sx <= 6) || ((left || right) && sx <= 3)) + left = right = 0; + if (left && right) { + each = (sx - 6) / visible; + remaining = (sx - 6) - (visible * each); + } else if (left || right) { + each = (sx - 3) / visible; + remaining = (sx - 3) - (visible * each); + } else { + each = sx / visible; + remaining = sx - (visible * each); + } + if (each == 0) + return; + + if (left) { + screen_write_cursormove(ctx, 2, 0); screen_write_vline(ctx, sy, 0, 0); - screen_write_cursormove(ctx, sx - left + left / 2, sy / 2); - screen_write_puts(ctx, &grid_default_cell, "..."); + screen_write_cursormove(ctx, 0, sy / 2); + screen_write_puts(ctx, &grid_default_cell, "<"); + } + if (right) { + screen_write_cursormove(ctx, sx - 3, 0); + screen_write_vline(ctx, sy, 0, 0); + screen_write_cursormove(ctx, sx - 1, sy / 2); + screen_write_puts(ctx, &grid_default_cell, ">"); + } - if (each == 0) - return; - left = 0; - } else - left = sx - (n * each); + i = loop = 0; + TAILQ_FOREACH(wp, &w->panes, entry) { + if (loop == end) + break; + if (loop < start) { + loop++; + continue; + } - wp = TAILQ_FIRST(&w->panes); - for (i = 0; i < n; i++) { if (wp == w->active) gc.fg = active_colour; else gc.fg = colour; - if (i == n - 1) - width = each + left; + + if (left) + offset = 3 + (i * each); else + offset = (i * each); + if (loop == end - 1) + width = each - 1 + remaining; + else width = each - 1; - screen_write_cursormove(ctx, i * each, 0); + screen_write_cursormove(ctx, offset, 0); screen_write_preview(ctx, &wp->base, width, sy); - xasprintf(&label, " %u ", i); + xasprintf(&label, " %u ", loop); len = strlen(label) / 2; - screen_write_cursormove(ctx, i * each + each / 2 - len, sy / 2); + screen_write_cursormove(ctx, offset + (each / 2) - len, sy / 2); if (len < width) screen_write_puts(ctx, &gc, "%s", label); free(label); - if (i != n - 1) { - screen_write_cursormove(ctx, i * each + width, 0); + if (loop != end - 1) { + screen_write_cursormove(ctx, offset + width, 0); screen_write_vline(ctx, sy, 0, 0); } - wp = TAILQ_NEXT(wp, entry); + loop++; + + i++; } }