Here is latest, notably fixing a redraw bug with status lines at bottom
and merging pane-status and pane-status-position.
Index: cmd-set-option.c
===================================================================
RCS file: /cvs/src/usr.bin/tmux/cmd-set-option.c,v
retrieving revision 1.74
diff -u -p -r1.74 cmd-set-option.c
--- cmd-set-option.c 24 Apr 2015 23:17:11 -0000 1.74
+++ cmd-set-option.c 25 Apr 2015 21:03:17 -0000
@@ -183,6 +183,12 @@ cmd_set_option_exec(struct cmd *self, st
}
}
+ /* When the pane-status option has been changed, resize panes. */
+ if (strcmp(oe->name, "pane-status") == 0) {
+ RB_FOREACH(w, windows, &windows)
+ layout_fix_panes(w, w->sx, w->sy);
+ }
+
/* Update sizes and redraw. May not need it but meh. */
recalculate_sizes();
TAILQ_FOREACH(c, &clients, entry) {
Index: layout.c
===================================================================
RCS file: /cvs/src/usr.bin/tmux/layout.c,v
retrieving revision 1.23
diff -u -p -r1.23 layout.c
--- layout.c 19 Apr 2015 21:34:21 -0000 1.23
+++ layout.c 25 Apr 2015 21:03:17 -0000
@@ -34,6 +34,7 @@
int layout_resize_pane_grow(struct layout_cell *, enum layout_type, int);
int layout_resize_pane_shrink(struct layout_cell *, enum layout_type, int);
+int layout_need_status(struct layout_cell *, int);
struct layout_cell *
layout_create_cell(struct layout_cell *lcparent)
@@ -163,6 +164,30 @@ layout_fix_offsets(struct layout_cell *l
}
}
+/*
+ * Returns 1 if we need to reserve space for the pane status line. This is the
+ * case for the most upper panes only.
+ */
+int
+layout_need_status(struct layout_cell *lc, int at_top)
+{
+ struct layout_cell *first_lc;
+
+ if (lc->parent) {
+ if (lc->parent->type == LAYOUT_LEFTRIGHT)
+ return (layout_need_status(lc->parent, at_top));
+
+ if (at_top)
+ first_lc = TAILQ_FIRST(&lc->parent->cells);
+ else
+ first_lc = TAILQ_LAST(&lc->parent->cells,layout_cells);
+ if (lc == first_lc)
+ return (layout_need_status(lc->parent, at_top));
+ return (0);
+ }
+ return (1);
+}
+
/* Update pane offsets and sizes based on their cells. */
void
layout_fix_panes(struct window *w, u_int wsx, u_int wsy)
@@ -170,13 +195,25 @@ layout_fix_panes(struct window *w, u_int
struct window_pane *wp;
struct layout_cell *lc;
u_int sx, sy;
+ int shift, status, at_top;
+ status = options_get_number(&w->options, "pane-status");
+ at_top = (status == 1);
TAILQ_FOREACH(wp, &w->panes, entry) {
if ((lc = wp->layout_cell) == NULL)
continue;
+
+ if (status != 0)
+ shift = layout_need_status(lc, at_top);
+ else
+ shift = 0;
+
wp->xoff = lc->xoff;
wp->yoff = lc->yoff;
+ if (shift && at_top)
+ wp->yoff += 1;
+
/*
* Layout cells are limited by the smallest size of other cells
* within the same row or column; if this isn't the case
@@ -213,6 +250,9 @@ layout_fix_panes(struct window *w, u_int
if (sy < 2)
sy = lc->sy;
}
+
+ if (shift)
+ sy -= 1;
window_pane_resize(wp, sx, sy);
}
Index: options-table.c
===================================================================
RCS file: /cvs/src/usr.bin/tmux/options-table.c,v
retrieving revision 1.55
diff -u -p -r1.55 options-table.c
--- options-table.c 19 Apr 2015 21:34:21 -0000 1.55
+++ options-table.c 25 Apr 2015 21:03:17 -0000
@@ -51,6 +51,9 @@ const char *options_table_status_positio
const char *options_table_bell_action_list[] = {
"none", "any", "current", NULL
};
+const char *options_table_pane_status_list[] = {
+ "off", "top", "bottom", NULL
+};
/* Server options. */
const struct options_table_entry server_options_table[] = {
@@ -610,6 +613,11 @@ const struct options_table_entry window_
.default_str = "fg=green"
},
+ { .name = "pane-active-status-style",
+ .type = OPTIONS_TABLE_STYLE,
+ .default_str = "bg=green"
+ },
+
{ .name = "pane-base-index",
.type = OPTIONS_TABLE_NUMBER,
.minimum = 0,
@@ -632,6 +640,22 @@ const struct options_table_entry window_
{ .name = "pane-border-style",
.type = OPTIONS_TABLE_STYLE,
.default_str = "default"
+ },
+
+ { .name = "pane-status",
+ .type = OPTIONS_TABLE_CHOICE,
+ .choices = options_table_pane_status_list,
+ .default_num = 0
+ },
+
+ { .name = "pane-status-format",
+ .type = OPTIONS_TABLE_STRING,
+ .default_str = "#{pane_index} \"#{pane_title}\""
+ },
+
+ { .name = "pane-status-style",
+ .type = OPTIONS_TABLE_STYLE,
+ .default_str = "fg=green"
},
{ .name = "remain-on-exit",
Index: screen-redraw.c
===================================================================
RCS file: /cvs/src/usr.bin/tmux/screen-redraw.c,v
retrieving revision 1.30
diff -u -p -r1.30 screen-redraw.c
--- screen-redraw.c 19 Apr 2015 21:05:27 -0000 1.30
+++ screen-redraw.c 25 Apr 2015 21:03:17 -0000
@@ -24,12 +24,16 @@
int screen_redraw_cell_border1(struct window_pane *, u_int, u_int);
int screen_redraw_cell_border(struct client *, u_int, u_int);
-int screen_redraw_check_cell(struct client *, u_int, u_int,
+int screen_redraw_check_cell(struct client *, u_int, u_int, int,
struct window_pane **);
-int screen_redraw_check_active(u_int, u_int, int, struct window *,
+int screen_redraw_check_active(u_int, u_int, int, int, struct window *,
struct window_pane *);
-void screen_redraw_draw_borders(struct client *, int, u_int);
+int screen_redraw_make_pane_status(struct client *, struct window *,
+ struct window_pane *);
+void screen_redraw_draw_pane_status(struct client *, int);
+
+void screen_redraw_draw_borders(struct client *, int, int, u_int);
void screen_redraw_draw_panes(struct client *, u_int);
void screen_redraw_draw_status(struct client *, u_int);
void screen_redraw_draw_number(struct client *, struct window_pane *);
@@ -50,6 +54,10 @@ void screen_redraw_draw_number(struct cl
#define CELL_BORDERS " xqlkmjwvtun~"
+#define CELL_STATUS_OFF 0
+#define CELL_STATUS_TOP 1
+#define CELL_STATUS_BOTTOM 2
+
/* Check if cell is on the border of a particular pane. */
int
screen_redraw_cell_border1(struct window_pane *wp, u_int px, u_int py)
@@ -100,16 +108,33 @@ screen_redraw_cell_border(struct client
/* Check if cell inside a pane. */
int
-screen_redraw_check_cell(struct client *c, u_int px, u_int py,
+screen_redraw_check_cell(struct client *c, u_int px, u_int py, int pane_status,
struct window_pane **wpp)
{
struct window *w = c->session->curw->window;
struct window_pane *wp;
int borders;
+ u_int right, line;
if (px > w->sx || py > w->sy)
return (CELL_OUTSIDE);
+ if (pane_status != CELL_STATUS_OFF) {
+ TAILQ_FOREACH(wp, &w->panes, entry) {
+ if (!window_pane_visible(wp))
+ continue;
+
+ if (pane_status == CELL_STATUS_TOP)
+ line = wp->yoff - 1;
+ else
+ line = wp->yoff + wp->sy;
+ right = wp->xoff + 2 + wp->status_size - 1;
+
+ if (py == line && px >= wp->xoff + 2 && px <= right)
+ return (CELL_INSIDE);
+ }
+ }
+
TAILQ_FOREACH(wp, &w->panes, entry) {
if (!window_pane_visible(wp))
continue;
@@ -135,8 +160,13 @@ screen_redraw_check_cell(struct client *
borders |= 8;
if (px <= w->sx && screen_redraw_cell_border(c, px + 1, py))
borders |= 4;
- if (py == 0 || screen_redraw_cell_border(c, px, py - 1))
- borders |= 2;
+ if (pane_status == CELL_STATUS_TOP) {
+ if (py != 0 && screen_redraw_cell_border(c, px, py - 1))
+ borders |= 2;
+ } else {
+ if (py == 0 || screen_redraw_cell_border(c, px, py - 1))
+ borders |= 2;
+ }
if (py <= w->sy && screen_redraw_cell_border(c, px, py + 1))
borders |= 1;
@@ -177,8 +207,8 @@ screen_redraw_check_cell(struct client *
/* Check active pane indicator. */
int
-screen_redraw_check_active(u_int px, u_int py, int type, struct window *w,
- struct window_pane *wp)
+screen_redraw_check_active(u_int px, u_int py, int type, int pane_status,
+ struct window *w, struct window_pane *wp)
{
/* Is this off the active pane border? */
if (screen_redraw_cell_border1(w->active, px, py) != 1)
@@ -192,6 +222,10 @@ screen_redraw_check_active(u_int px, u_i
if (wp == NULL || (type == CELL_OUTSIDE || type == CELL_INSIDE))
return (1);
+ /* With status lines mark the entire line. */
+ if (pane_status != CELL_STATUS_OFF)
+ return (1);
+
/* Check if the pane covers the whole width. */
if (wp->xoff == 0 && wp->sx == w->sx) {
/* This can either be the top pane or the bottom pane. */
@@ -214,7 +248,81 @@ screen_redraw_check_active(u_int px, u_i
return (0);
}
- return (type);
+ return (1);
+}
+
+/* Update pane status. */
+int
+screen_redraw_make_pane_status(struct client *c, struct window *w,
+ struct window_pane *wp)
+{
+ struct options *oo = &w->options;
+ struct grid_cell gc;
+ int utf8flag;
+ const char *fmt;
+ struct format_tree *ft;
+ char *out;
+ size_t outlen, old_size = wp->status_size;
+ struct screen_write_ctx ctx;
+
+ if (wp == w->active)
+ style_apply(&gc, oo, "pane-active-status-style");
+ else
+ style_apply(&gc, oo, "pane-status-style");
+
+ fmt = options_get_string(oo, "pane-status-format");
+
+ ft = format_create();
+ format_defaults(ft, c, NULL, NULL, wp);
+
+ screen_free(&wp->status_screen);
+ screen_init(&wp->status_screen, wp->sx, 1, 0);
+ wp->status_screen.mode = 0;
+
+ utf8flag = options_get_number(oo, "utf8");
+
+ out = format_expand(ft, fmt);
+ outlen = screen_write_cstrlen(utf8flag, "%s", out);
+ if (outlen > wp->sx - 4)
+ outlen = wp->sx - 4;
+ screen_resize(&wp->status_screen, outlen, 1, 0);
+
+ screen_write_start(&ctx, NULL, &wp->status_screen);
+ screen_write_cursormove(&ctx, 0, 0);
+ screen_write_clearline(&ctx);
+ screen_write_nputs(&ctx, outlen, &gc, utf8flag, "%s", out);
+ screen_write_stop(&ctx);
+
+ format_free(ft);
+
+ wp->status_size = outlen;
+ return (wp->status_size != old_size);
+}
+
+/* Draw pane status. */
+void
+screen_redraw_draw_pane_status(struct client *c, int pane_status)
+{
+ struct window *w = c->session->curw->window;
+ struct options *oo = &c->session->options;
+ struct tty *tty = &c->tty;
+ struct window_pane *wp;
+ int spos;
+ u_int yoff;
+
+ spos = options_get_number(oo, "status-position");
+ TAILQ_FOREACH(wp, &w->panes, entry) {
+ if (pane_status == CELL_STATUS_TOP)
+ yoff = wp->yoff - 1;
+ else
+ yoff = wp->yoff + wp->sy;
+ if (spos == 0)
+ yoff += 1;
+
+ tty_draw_line(tty, NULL, &wp->status_screen, 0, wp->xoff + 2,
+ yoff);
+ }
+ tty_cursor(tty, 0, 0);
}
/* Redraw entire screen. */
@@ -222,10 +330,12 @@ void
screen_redraw_screen(struct client *c, int draw_panes, int draw_status,
int draw_borders)
{
- struct options *oo = &c->session->options;
- struct tty *tty = &c->tty;
- u_int top;
- int status, spos;
+ struct options *oo = &c->session->options;
+ struct tty *tty = &c->tty;
+ struct window *w = c->session->curw->window;
+ struct window_pane *wp;
+ u_int top;
+ int status, pane_status, spos;
/* Suspended clients should not be updated. */
if (c->flags & CLIENT_SUSPENDED)
@@ -243,12 +353,24 @@ screen_redraw_screen(struct client *c, i
if (!status)
draw_status = 0;
+ /* Update pane status lines. */
+ pane_status = options_get_number(&w->options, "pane-status");
+ if (pane_status != CELL_STATUS_OFF && (draw_borders || draw_status)) {
+ TAILQ_FOREACH(wp, &w->panes, entry) {
+ if (screen_redraw_make_pane_status(c, w, wp))
+ draw_borders = draw_status = 1;
+ }
+ }
+
+ /* Draw the elements. */
if (draw_borders)
- screen_redraw_draw_borders(c, status, top);
+ screen_redraw_draw_borders(c, status, pane_status, top);
if (draw_panes)
screen_redraw_draw_panes(c, top);
if (draw_status)
screen_redraw_draw_status(c, top);
+ if (pane_status != CELL_STATUS_OFF && (draw_borders || draw_status))
+ screen_redraw_draw_pane_status(c, pane_status);
tty_reset(tty);
}
@@ -272,7 +394,8 @@ screen_redraw_pane(struct client *c, str
/* Draw the borders. */
void
-screen_redraw_draw_borders(struct client *c, int status, u_int top)
+screen_redraw_draw_borders(struct client *c, int status, int pane_status,
+ u_int top)
{
struct window *w = c->session->curw->window;
struct options *oo = &w->options;
@@ -316,13 +439,15 @@ screen_redraw_draw_borders(struct client
for (j = 0; j < tty->sy - status; j++) {
for (i = 0; i < tty->sx; i++) {
- type = screen_redraw_check_cell(c, i, j, &wp);
+ type = screen_redraw_check_cell(c, i, j, pane_status,
+ &wp);
if (type == CELL_INSIDE)
continue;
if (type == CELL_OUTSIDE &&
small && i > msgx && j == msgy)
continue;
- if (screen_redraw_check_active(i, j, type, w, wp))
+ if (screen_redraw_check_active(i, j, type, pane_status,
+ w, wp))
tty_attributes(tty, &active_gc, NULL);
else
tty_attributes(tty, &other_gc, NULL);
Index: server-client.c
===================================================================
RCS file: /cvs/src/usr.bin/tmux/server-client.c,v
retrieving revision 1.136
diff -u -p -r1.136 server-client.c
--- server-client.c 25 Apr 2015 18:33:59 -0000 1.136
+++ server-client.c 25 Apr 2015 21:03:18 -0000
@@ -876,7 +876,7 @@ server_client_check_redraw(struct client
{
struct session *s = c->session;
struct window_pane *wp;
- int flags, redraw;
+ int flags, masked, redraw;
if (c->flags & (CLIENT_CONTROL|CLIENT_SUSPENDED))
return;
@@ -912,11 +912,13 @@ server_client_check_redraw(struct client
}
}
- if (c->flags & CLIENT_BORDERS)
+ masked = c->flags & (CLIENT_BORDERS|CLIENT_STATUS);
+ if (masked == CLIENT_BORDERS)
screen_redraw_screen(c, 0, 0, 1);
-
- if (c->flags & CLIENT_STATUS)
+ else if (masked == CLIENT_STATUS)
screen_redraw_screen(c, 0, 1, 0);
+ else if (masked != 0)
+ screen_redraw_screen(c, 0, 1, 1);
c->tty.flags |= flags;
Index: tmux.1
===================================================================
RCS file: /cvs/src/usr.bin/tmux/tmux.1,v
retrieving revision 1.422
diff -u -p -r1.422 tmux.1
--- tmux.1 21 Apr 2015 22:32:40 -0000 1.422
+++ tmux.1 25 Apr 2015 21:03:19 -0000
@@ -2954,6 +2954,9 @@ see the
option.
Attributes are ignored.
.Pp
+.It Ic pane-active-status-style
+Set the style of the active pane's status line.
+.Pp
.It Ic pane-base-index Ar index
Like
.Ic base-index ,
@@ -2967,6 +2970,18 @@ see the
.Ic message-command-style
option.
Attributes are ignored.
+.Pp
+.It Xo Ic pane-status
+.Op Ic off | top | bottom
+.Xc
+Turn pane status lines off or set their position.
+A pane's status line is shown on the pane border.
+.Pp
+.It Ic pane-status-format Ar format
+Set the text shown in pane status lines.
+.Pp
+.It Ic pane-status-style Ar style
+Set the style of pane status lines.
.Pp
.It Xo Ic remain-on-exit
.Op Ic on | off
Index: tmux.h
===================================================================
RCS file: /cvs/src/usr.bin/tmux/tmux.h,v
retrieving revision 1.501
diff -u -p -r1.501 tmux.h
--- tmux.h 25 Apr 2015 18:33:59 -0000 1.501
+++ tmux.h 25 Apr 2015 21:03:19 -0000
@@ -936,6 +936,9 @@ struct window_pane {
struct screen *screen;
struct screen base;
+ struct screen status_screen;
+ size_t status_size;
+
/* Saved in alternative screen mode. */
u_int saved_cx;
u_int saved_cy;
Index: window.c
===================================================================
RCS file: /cvs/src/usr.bin/tmux/window.c,v
retrieving revision 1.126
diff -u -p -r1.126 window.c
--- window.c 25 Apr 2015 18:56:05 -0000 1.126
+++ window.c 25 Apr 2015 21:03:19 -0000
@@ -732,6 +732,8 @@ window_pane_create(struct window *w, u_i
screen_init(&wp->base, sx, sy, hlimit);
wp->screen = &wp->base;
+ screen_init(&wp->status_screen, 1, 1, 0);
+
input_init(wp);
return (wp);
On Sat, Apr 25, 2015 at 09:31:44PM +0100, Nicholas Marriott wrote:
> Hi
>
> I like the other diff a bit more than yours so I think I will go with
> it, does it meet your needs too, or any comments?
>
>
>
> On Mon, Apr 20, 2015 at 09:02:52AM -0400, John O'Meara wrote:
> > Hi list,
> >
> > I had made a patch for myself to add a per-pane status bar a few weeks
> > ago, and saw yesterday that there was a ticket open for a similar
> > feature.
> > Nicholas pointed out that he had already done work on this, but suggested
> > I post my patch anyway.
> >
> > Firstly, sorry for duplicating effort. I hope this patch is helpful but I
> > understand if it isn't.
> >
> > Secondly, the ticket does request top-of-pane title, where my patch
> > currently only does bottom-of-pane, but it uses the expansion system that
> > the regular status line uses, so the pane title and whatever else might
> > be
> > wanted can go there (I use pane-tty and pane-title, for example). If it
> > is
> > desired for this patch to move forward, I will work on adding a
> > pane-status-position option to allow it to be placed top-of-pane (as well
> > as other suggestions I receive)
> >
> > The patch works by decreasing the pane height by 1 when pane-status is
> > enabled, and drawing the pane status line in the opened up space.
> > Adjustments are made for border drawing, window selection, and mouse
> > movements to work properly with the adjusted pane size. Redrawing is
> > handled similar to the regular status line, in that the statuses are
> > pre-rendered in memory and only sent to the screen if they differ from
> > the
> > last render. Rendering is per-client to allow things like client-tty
> > expansions to work correctly.
> >
> > Usage is documented in the man page, and the default options move the
> > pane-title from status-right to pane-status-format (leaving only the time
> > in status-right), allowing for a quick example when run with default
> > settings.
> >
> > Thanks,
> >
> > -- John O'Meara
>
> > diff --git a/layout.c b/layout.c
> > index b91b86c..c66ca00 100644
> > --- a/layout.c
> > +++ b/layout.c
> > @@ -170,6 +170,9 @@ layout_fix_panes(struct window *w, u_int wsx, u_int wsy)
> > struct window_pane *wp;
> > struct layout_cell *lc;
> > u_int sx, sy;
> > + int has_pane_status;
> > +
> > + has_pane_status = options_get_number(&w->options, "pane-status");
> >
> > TAILQ_FOREACH(wp, &w->panes, entry) {
> > if ((lc = wp->layout_cell) == NULL)
> > @@ -207,9 +210,9 @@ layout_fix_panes(struct window *w, u_int wsx, u_int wsy)
> > * is two because scroll regions cannot be one line.
> > */
> > if (lc->yoff >= wsy || lc->yoff + lc->sy < wsy)
> > - sy = lc->sy;
> > + sy = lc->sy - has_pane_status;
> > else {
> > - sy = wsy - lc->yoff;
> > + sy = wsy - lc->yoff - has_pane_status;
> > if (sy < 2)
> > sy = lc->sy;
> > }
> > @@ -527,9 +530,12 @@ layout_resize_pane_mouse(struct client *c)
> > struct window_pane *wp;
> > struct mouse_event *m = &c->tty.mouse;
> > int pane_border;
> > + int has_pane_status;
> >
> > w = c->session->curw->window;
> >
> > + has_pane_status = options_get_number(&w->options, "pane-status");
> > +
> > pane_border = 0;
> > if (m->event & MOUSE_EVENT_DRAG && m->flags & MOUSE_RESIZE_PANE) {
> > TAILQ_FOREACH(wp, &w->panes, entry) {
> > @@ -538,12 +544,12 @@ layout_resize_pane_mouse(struct client *c)
> >
> > if (wp->xoff + wp->sx == m->lx &&
> > wp->yoff <= 1 + m->ly &&
> > - wp->yoff + wp->sy >= m->ly) {
> > + wp->yoff + wp->sy + has_pane_status >= m->ly) {
> > layout_resize_pane(wp, LAYOUT_LEFTRIGHT,
> > m->x - m->lx);
> > pane_border = 1;
> > }
> > - if (wp->yoff + wp->sy == m->ly &&
> > + if (wp->yoff + wp->sy + has_pane_status == m->ly &&
> > wp->xoff <= 1 + m->lx &&
> > wp->xoff + wp->sx >= m->lx) {
> > layout_resize_pane(wp, LAYOUT_TOPBOTTOM,
> > @@ -557,8 +563,8 @@ layout_resize_pane_mouse(struct client *c)
> > TAILQ_FOREACH(wp, &w->panes, entry) {
> > if ((wp->xoff + wp->sx == m->x &&
> > wp->yoff <= 1 + m->y &&
> > - wp->yoff + wp->sy >= m->y) ||
> > - (wp->yoff + wp->sy == m->y &&
> > + wp->yoff + wp->sy + has_pane_status >= m->y) ||
> > + (wp->yoff + wp->sy + has_pane_status == m->y &&
> > wp->xoff <= 1 + m->x &&
> > wp->xoff + wp->sx >= m->x)) {
> > pane_border = 1;
> > diff --git a/options-table.c b/options-table.c
> > index 2bcf29b..be9af3f 100644
> > --- a/options-table.c
> > +++ b/options-table.c
> > @@ -396,7 +396,7 @@ const struct options_table_entry
> > session_options_table[] = {
> >
> > { .name = "status-right",
> > .type = OPTIONS_TABLE_STRING,
> > - .default_str = " \"#{=21:pane_title}\" %H:%M %d-%b-%y"
> > + .default_str = "%H:%M %d-%b-%y"
> > },
> >
> > { .name = "status-right-attr",
> > @@ -652,6 +652,39 @@ const struct options_table_entry
> > window_options_table[] = {
> > .default_str = "default"
> > },
> >
> > + { .name = "pane-status",
> > + .type = OPTIONS_TABLE_FLAG,
> > + .default_num = 1
> > + },
> > +
> > + { .name = "pane-status-attr",
> > + .type = OPTIONS_TABLE_ATTRIBUTES,
> > + .default_num = 0,
> > + .style = "pane-status-style"
> > + },
> > +
> > + { .name = "pane-status-bg",
> > + .type = OPTIONS_TABLE_COLOUR,
> > + .default_num = 2,
> > + .style = "pane-status-style"
> > + },
> > +
> > + { .name = "pane-status-fg",
> > + .type = OPTIONS_TABLE_COLOUR,
> > + .default_num = 0,
> > + .style = "pane-status-style"
> > + },
> > +
> > + { .name = "pane-status-format",
> > + .type = OPTIONS_TABLE_STRING,
> > + .default_str = "[#T]"
> > + },
> > +
> > + { .name = "pane-status-style",
> > + .type = OPTIONS_TABLE_STYLE,
> > + .default_str = "default"
> > + },
> > +
> > { .name = "remain-on-exit",
> > .type = OPTIONS_TABLE_FLAG,
> > .default_num = 0
> > diff --git a/resize.c b/resize.c
> > index 9ad73c8..edf44d5 100644
> > --- a/resize.c
> > +++ b/resize.c
> > @@ -128,8 +128,16 @@ recalculate_sizes(void)
> > forced |= WINDOW_FORCEHEIGHT;
> > }
> >
> > +#if 0 /* This optimization to not resize panes if the window size doesn't
> > + change fails to handle the case where pane sizes may have changed
> > + due to options like 'pane-status' changing. Unfortunately, we
> > + can't at this point know if this function was called because of an
> > + option change, let alone specific option changes. For now, we'll
> > + just skip the optimization and take the computational hit rather
> > + than have a stale display. */
> > if (w->sx == ssx && w->sy == ssy)
> > continue;
> > +#endif
> > log_debug("window size %u,%u (was %u,%u)", ssx, ssy, w->sx,
> > w->sy);
> >
> > diff --git a/screen-redraw.c b/screen-redraw.c
> > index c2b2ece..a36a2fe 100644
> > --- a/screen-redraw.c
> > +++ b/screen-redraw.c
> > @@ -54,13 +54,17 @@ void screen_redraw_draw_number(struct client *,
> > struct window_pane *);
> > int
> > screen_redraw_cell_border1(struct window_pane *wp, u_int px, u_int py)
> > {
> > + int has_pane_status;
> > +
> > + has_pane_status = options_get_number(&wp->window->options,
> > "pane-status");
> > +
> > /* Inside pane. */
> > if (px >= wp->xoff && px < wp->xoff + wp->sx &&
> > - py >= wp->yoff && py < wp->yoff + wp->sy)
> > + py >= wp->yoff && py < wp->yoff + wp->sy + has_pane_status)
> > return (0);
> >
> > /* Left/right borders. */
> > - if ((wp->yoff == 0 || py >= wp->yoff - 1) && py <= wp->yoff + wp->sy) {
> > + if ((wp->yoff == 0 || py >= wp->yoff - 1 + has_pane_status) && py <=
> > wp->yoff + wp->sy + has_pane_status) {
> > if (wp->xoff != 0 && px == wp->xoff - 1)
> > return (1);
> > if (px == wp->xoff + wp->sx)
> > @@ -71,7 +75,7 @@ screen_redraw_cell_border1(struct window_pane *wp, u_int
> > px, u_int py)
> > if ((wp->xoff == 0 || px >= wp->xoff - 1) && px <= wp->xoff + wp->sx) {
> > if (wp->yoff != 0 && py == wp->yoff - 1)
> > return (1);
> > - if (py == wp->yoff + wp->sy)
> > + if (py == wp->yoff + wp->sy + has_pane_status)
> > return (1);
> > }
> >
> > @@ -106,6 +110,9 @@ screen_redraw_check_cell(struct client *c, u_int px,
> > u_int py,
> > struct window *w = c->session->curw->window;
> > struct window_pane *wp;
> > int borders;
> > + int has_pane_status;
> > +
> > + has_pane_status = options_get_number(&w->options, "pane-status");
> >
> > if (px > w->sx || py > w->sy)
> > return (CELL_OUTSIDE);
> > @@ -119,7 +126,7 @@ screen_redraw_check_cell(struct client *c, u_int px,
> > u_int py,
> > if ((wp->xoff != 0 && px < wp->xoff - 1) ||
> > px > wp->xoff + wp->sx ||
> > (wp->yoff != 0 && py < wp->yoff - 1) ||
> > - py > wp->yoff + wp->sy)
> > + py > wp->yoff + wp->sy + has_pane_status)
> > continue;
> >
> > /* If definitely inside, return so. */
> > @@ -180,6 +187,10 @@ int
> > screen_redraw_check_active(u_int px, u_int py, int type, struct window *w,
> > struct window_pane *wp)
> > {
> > + int has_pane_status;
> > +
> > + has_pane_status = options_get_number(&wp->window->options,
> > "pane-status");
> > +
> > /* Is this off the active pane border? */
> > if (screen_redraw_cell_border1(w->active, px, py) != 1)
> > return (0);
> > @@ -204,7 +215,7 @@ screen_redraw_check_active(u_int px, u_int py, int
> > type, struct window *w,
> > }
> >
> > /* Check if the pane covers the whole height. */
> > - if (wp->yoff == 0 && wp->sy == w->sy) {
> > + if (wp->yoff == 0 && wp->sy + has_pane_status == w->sy) {
> > /* This can either be the left pane or the right pane. */
> > if (wp->xoff == 0) { /* left pane */
> > if (wp == w->active)
> > @@ -217,6 +228,24 @@ screen_redraw_check_active(u_int px, u_int py, int
> > type, struct window *w,
> > return (type);
> > }
> >
> > +void
> > +screen_redraw_draw_pane_status(struct client *c, u_int top)
> > +{
> > + struct window *w = c->session->curw->window;
> > + struct window_pane *wp;
> > + struct pane_status *ps = TAILQ_FIRST(&c->pane_statuses);
> > +
> > + TAILQ_FOREACH(wp, &w->panes, entry) {
> > + if (!window_pane_visible(wp))
> > + continue;
> > + if (!ps) {
> > + fatalx("pane status not found");
> > + }
> > + tty_draw_line(&c->tty, &ps->status, 0, wp->xoff, top + wp->yoff
> > + wp->sy);
> > + ps = TAILQ_NEXT(ps, entry);
> > + }
> > +}
> > +
> > /* Redraw entire screen. */
> > void
> > screen_redraw_screen(struct client *c, int draw_panes, int draw_status,
> > @@ -226,6 +255,7 @@ screen_redraw_screen(struct client *c, int draw_panes,
> > int draw_status,
> > struct tty *tty = &c->tty;
> > u_int top;
> > int status, spos;
> > + int draw_pane_status;
> >
> > /* Suspended clients should not be updated. */
> > if (c->flags & CLIENT_SUSPENDED)
> > @@ -238,6 +268,10 @@ screen_redraw_screen(struct client *c, int draw_panes,
> > int draw_status,
> > else
> > status = options_get_number(oo, "status");
> > top = 0;
> > + if (draw_status &&
> > options_get_number(&c->session->curw->window->options, "pane-status"))
> > + draw_pane_status = 1;
> > + else
> > + draw_pane_status = 0;
> > if (status && spos == 0)
> > top = 1;
> > if (!status)
> > @@ -249,6 +283,9 @@ screen_redraw_screen(struct client *c, int draw_panes,
> > int draw_status,
> > screen_redraw_draw_panes(c, top);
> > if (draw_status)
> > screen_redraw_draw_status(c, top);
> > + if (draw_pane_status){
> > + screen_redraw_draw_pane_status(c, top);
> > + }
> > tty_reset(tty);
> > }
> >
> > diff --git a/server-client.c b/server-client.c
> > index f7ce35c..fa278af 100644
> > --- a/server-client.c
> > +++ b/server-client.c
> > @@ -749,6 +749,7 @@ server_client_check_redraw(struct client *c)
> > redraw = status_prompt_redraw(c);
> > else
> > redraw = status_redraw(c);
> > + redraw |= pane_status_redraw(c);
> > if (!redraw)
> > c->flags &= ~CLIENT_STATUS;
> > }
> > diff --git a/status.c b/status.c
> > index 5f8895f..b7546bb 100644
> > --- a/status.c
> > +++ b/status.c
> > @@ -38,7 +38,7 @@ void status_job_free(void *);
> > void status_job_callback(struct job *);
> > char *status_print(struct client *, struct winlink *, time_t,
> > struct grid_cell *);
> > -char *status_replace(struct client *, struct winlink *, const char *,
> > time_t);
> > +char *status_replace(struct client *, struct winlink *, struct
> > window_pane *wp, const char *, time_t);
> > void status_replace1(struct client *, char **, char **, char *,
> > size_t);
> > void status_message_callback(int, short, void *);
> >
> > @@ -87,7 +87,7 @@ status_redraw_get_left(struct client *c, time_t t, int
> > utf8flag,
> > style_apply_update(gc, &s->options, "status-left-style");
> >
> > template = options_get_string(&s->options, "status-left");
> > - left = status_replace(c, NULL, template, t);
> > + left = status_replace(c, NULL, NULL, template, t);
> >
> > *size = options_get_number(&s->options, "status-left-length");
> > leftlen = screen_write_cstrlen(utf8flag, "%s", left);
> > @@ -109,7 +109,7 @@ status_redraw_get_right(struct client *c, time_t t, int
> > utf8flag,
> > style_apply_update(gc, &s->options, "status-right-style");
> >
> > template = options_get_string(&s->options, "status-right");
> > - right = status_replace(c, NULL, template, t);
> > + right = status_replace(c, NULL, NULL, template, t);
> >
> > *size = options_get_number(&s->options, "status-right-length");
> > rightlen = screen_write_cstrlen(utf8flag, "%s", right);
> > @@ -362,6 +362,86 @@ out:
> > return (1);
> > }
> >
> > +/* Draw status for panes */
> > +int
> > +pane_status_redraw(struct client *c)
> > +{
> > + struct screen_write_ctx ctx;
> > + int utf8flag;
> > + struct grid_cell stdgc;
> > + char *msg;
> > + struct window *w = c->session->curw->window;
> > + struct window_pane *wp;
> > + struct pane_statuses old_pane_statuses;
> > + struct pane_status *pane_status;
> > + struct pane_status *t;
> > + int diff = 0;
> > + unsigned int len;
> > +
> > + if (options_get_number(&w->options, "pane-status") == 0) {
> > + return 0;
> > + }
> > +
> > + memcpy(&old_pane_statuses, &c->pane_statuses, sizeof old_pane_statuses);
> > + TAILQ_INIT(&c->pane_statuses);
> > +
> > + utf8flag = options_get_number(&c->session->options, "status-utf8");
> > +
> > + /* Create set of statuses for each pane */
> > + TAILQ_FOREACH(wp, &w->panes, entry) {
> > + if (!window_pane_visible(wp))
> > + continue;
> > + pane_status = malloc(sizeof *pane_status);
> > + if (!pane_status) {
> > + continue;
> > + }
> > + memcpy(&stdgc, &grid_default_cell, sizeof stdgc);
> > + colour_set_fg(&stdgc, options_get_number(&wp->window->options,
> > "pane-status-fg"));
> > + colour_set_bg(&stdgc, options_get_number(&wp->window->options,
> > "pane-status-bg"));
> > + stdgc.attr |= options_get_number(&wp->window->options,
> > "pane-status-attr");
> > + screen_init(&pane_status->status, wp->sx, 1, 0);
> > + msg = status_replace(c, NULL, wp,
> > options_get_string(&wp->window->options, "pane-status-format"), time(NULL));
> > + len = screen_write_strlen(utf8flag, "%s", msg);
> > + if (len > wp->sx) {
> > + len = wp->sx;
> > + }
> > + screen_write_start(&ctx, NULL, &pane_status->status);
> > + screen_write_cursormove(&ctx, 0, 0);
> > + screen_write_cnputs(&ctx, len, &stdgc, utf8flag, "%s", msg);
> > + screen_write_stop(&ctx);
> > + free(msg);
> > + TAILQ_INSERT_TAIL(&c->pane_statuses, pane_status, entry);
> > + }
> > +
> > + /* Check if any of the status lines have changed, or if the number
> > + * of status lines have changed. */
> > + {
> > + struct pane_status *old;
> > + struct pane_status *new;
> > + old = TAILQ_FIRST(&old_pane_statuses);
> > + new = TAILQ_FIRST(&c->pane_statuses);
> > + while (old != TAILQ_END(&old_pane_statuses) && new !=
> > TAILQ_END(&c->pane_statuses)) {
> > + if (grid_compare(old->status.grid, new->status.grid) !=
> > 0) {
> > + //screen_free(&old_status);
> > + diff = 1;
> > + }
> > + //screen_free(&old_status);
> > + old = TAILQ_NEXT(old, entry);
> > + new = TAILQ_NEXT(new, entry);
> > + }
> > + if (old != TAILQ_END(&old_pane_statuses) || new !=
> > TAILQ_END(&c->pane_statuses)) {
> > + diff = 1;
> > + }
> > + }
> > + /* discard old */
> > + TAILQ_FOREACH_SAFE(pane_status, &old_pane_statuses, entry, t) {
> > + screen_free(&pane_status->status);
> > + free(pane_status);
> > + }
> > + return diff;
> > +}
> > +
> > +
> > /* Replace a single special sequence (prefixed by #). */
> > void
> > status_replace1(struct client *c, char **iptr, char **optr, char *out,
> > @@ -431,7 +511,7 @@ skip_to:
> >
> > /* Replace special sequences in fmt. */
> > char *
> > -status_replace(struct client *c, struct winlink *wl, const char *fmt,
> > time_t t)
> > +status_replace(struct client *c, struct winlink *wl, struct window_pane
> > *wp, const char *fmt, time_t t)
> > {
> > static char out[BUFSIZ];
> > char in[BUFSIZ], ch, *iptr, *optr, *expanded;
> > @@ -461,7 +541,7 @@ status_replace(struct client *c, struct winlink *wl,
> > const char *fmt, time_t t)
> > *optr = '\0';
> >
> > ft = format_create();
> > - format_defaults(ft, c, NULL, wl, NULL);
> > + format_defaults(ft, c, NULL, wl, wp);
> > expanded = format_expand(ft, out);
> > format_free(ft);
> > return (expanded);
> > @@ -626,7 +706,7 @@ status_print(struct client *c, struct winlink *wl,
> > time_t t,
> > else if (wl->flags & (WINLINK_ACTIVITY|WINLINK_SILENCE))
> > style_apply_update(gc, oo, "window-status-activity-style");
> >
> > - text = status_replace(c, wl, fmt, t);
> > + text = status_replace(c, wl, NULL, fmt, t);
> > return (text);
> > }
> >
> > diff --git a/tmux.1 b/tmux.1
> > index 8a0879b..b277376 100644
> > --- a/tmux.1
> > +++ b/tmux.1
> > @@ -2617,7 +2617,7 @@ Set the position of the status line.
> > Display
> > .Ar string
> > to the right of the status bar.
> > -By default, the current window title in double quotes, the date and the
> > time
> > +By default, the date and the time
> > are shown.
> > As with
> > .Ic status-left ,
> > @@ -2918,6 +2918,33 @@ see the
> > option.
> > Attributes are ignored.
> > .Pp
> > +.It Xo Ic pane-status
> > +.Op Ic on | off
> > +.Xc
> > +Show or hide a status line at the bottom of each pane.
> > +.Pp
> > +.It Ic pane-status-format Ar string
> > +Display
> > +.Ar string
> > +in the status bar of each pane in the window.
> > +By default, the pane title is shown in brackets.
> > +As with
> > +.Ic status-left ,
> > +.Ar string
> > +will be passed to
> > +.Xr strftime 3 ,
> > +character pairs are replaced, and UTF-8 is dependent on the
> > +.Ic status-utf8
> > +option.
> > +.Pp
> > +.It Ic pane-status-style Ar style
> > +Set the pane status line style.
> > +For how to specify
> > +.Ar style ,
> > +see the
> > +.Ic message-command-style
> > +opption.
> > +.Pp
> > .It Xo Ic remain-on-exit
> > .Op Ic on | off
> > .Xc
> > diff --git a/tmux.h b/tmux.h
> > index e296ac7..bc1e659 100644
> > --- a/tmux.h
> > +++ b/tmux.h
> > @@ -923,6 +923,12 @@ TAILQ_HEAD(window_panes, window_pane);
> > RB_HEAD(window_pane_tree, window_pane);
> > ARRAY_DECL(window_pane_list, struct window_pane *);
> >
> > +struct pane_status {
> > + struct screen status;
> > + TAILQ_ENTRY(pane_status) entry;
> > +};
> > +TAILQ_HEAD(pane_statuses, pane_status);
> > +
> > /* Window structure. */
> > struct window {
> > u_int id;
> > @@ -1283,6 +1289,7 @@ struct client {
> > struct status_out_tree status_new;
> > struct timeval status_timer;
> > struct screen status;
> > + struct pane_statuses pane_statuses;
> >
> > #define CLIENT_TERMINAL 0x1
> > #define CLIENT_PREFIX 0x2
> > @@ -1923,6 +1930,7 @@ void status_free_jobs(struct status_out_tree *);
> > void status_update_jobs(struct client *);
> > void status_set_window_at(struct client *, u_int);
> > int status_redraw(struct client *);
> > +int pane_status_redraw(struct client *c);
> > void printflike(2, 3) status_message_set(struct client *, const char *,
> > ...);
> > void status_message_clear(struct client *);
> > int status_message_redraw(struct client *);
> > @@ -2058,6 +2066,7 @@ void screen_write_setselection(struct
> > screen_write_ctx *, u_char *, u_int);
> > void screen_write_rawstring(struct screen_write_ctx *, u_char *,
> > u_int);
> >
> > /* screen-redraw.c */
> > +void screen_redraw_draw_pane_status(struct client *c, u_int top);
> > void screen_redraw_screen(struct client *, int, int, int);
> > void screen_redraw_pane(struct client *, struct window_pane *);
> >
> > diff --git a/window.c b/window.c
> > index fff2cfc..b7e6f53 100644
> > --- a/window.c
> > +++ b/window.c
> > @@ -1180,6 +1180,9 @@ window_pane_find_up(struct window_pane *wp)
> > u_int edge, left, right, end;
> > struct window_pane_list list;
> > int found;
> > + int has_pane_status;
> > +
> > + has_pane_status = options_get_number(&wp->window->options,
> > "pane-status");
> >
> > if (wp == NULL || !window_pane_visible(wp))
> > return (NULL);
> > @@ -1195,7 +1198,7 @@ window_pane_find_up(struct window_pane *wp)
> > TAILQ_FOREACH(next, &wp->window->panes, entry) {
> > if (next == wp || !window_pane_visible(next))
> > continue;
> > - if (next->yoff + next->sy + 1 != edge)
> > + if (next->yoff + next->sy + 1 + has_pane_status != edge)
> > continue;
> > end = next->xoff + next->sx - 1;
> >
> > @@ -1223,12 +1226,15 @@ window_pane_find_down(struct window_pane *wp)
> > u_int edge, left, right, end;
> > struct window_pane_list list;
> > int found;
> > + int has_pane_status;
> > +
> > + has_pane_status = options_get_number(&wp->window->options,
> > "pane-status");
> >
> > if (wp == NULL || !window_pane_visible(wp))
> > return (NULL);
> > ARRAY_INIT(&list);
> >
> > - edge = wp->yoff + wp->sy + 1;
> > + edge = wp->yoff + wp->sy + 1 + has_pane_status;
> > if (edge >= wp->window->sy)
> > edge = 0;
> >
>
> > ------------------------------------------------------------------------------
> > BPM Camp - Free Virtual Workshop May 6th at 10am PDT/1PM EDT
> > Develop your own process in accordance with the BPMN 2 standard
> > Learn Process modeling best practices with Bonita BPM through live exercises
> > http://www.bonitasoft.com/be-part-of-it/events/bpm-camp-virtual- event?utm_
> > source=Sourceforge_BPM_Camp_5_6_15&utm_medium=email&utm_campaign=VA_SF
>
> > _______________________________________________
> > tmux-users mailing list
> > [email protected]
> > https://lists.sourceforge.net/lists/listinfo/tmux-users
>
------------------------------------------------------------------------------
One dashboard for servers and applications across Physical-Virtual-Cloud
Widest out-of-the-box monitoring support with 50+ applications
Performance metrics, stats and reports that give you Actionable Insights
Deep dive visibility with transaction tracing using APM Insight.
http://ad.doubleclick.net/ddm/clk/290420510;117567292;y
_______________________________________________
tmux-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/tmux-users