I've attached a new patch. There are 2 new window options,
window-style and window-active-style, that allow you to set the
window's color and the window's active pane color. The display-panes
command can still be used to set an explicit pane color with -P.
tty_attributes now takes a window pane argument, and tty_draw_lines
doesn't mess with the grid cells itself. tty_reset calls
tty_attributes, but I'm not sure I understood exactly what you were
looking for here.
diff --git a/cmd-display-panes.c b/cmd-display-panes.c
index 9ce8971..9d87893 100644
--- a/cmd-display-panes.c
+++ b/cmd-display-panes.c
@@ -18,18 +18,21 @@
#include <sys/types.h>
+#include <stdlib.h>
+#include <string.h>
+
#include "tmux.h"
/*
- * Display panes on a client.
+ * Display panes on a client, or get/set pane default fg/bg colours.
*/
enum cmd_retval cmd_display_panes_exec(struct cmd *, struct cmd_q *);
const struct cmd_entry cmd_display_panes_entry = {
"display-panes", "displayp",
- "t:", 0, 0,
- CMD_TARGET_CLIENT_USAGE,
+ "gt:P:", 0, 0,
+ "[-g] [-P style] " CMD_TARGET_CLIENT_USAGE,
0,
cmd_display_panes_exec
};
@@ -37,13 +40,52 @@ const struct cmd_entry cmd_display_panes_entry = {
enum cmd_retval
cmd_display_panes_exec(struct cmd *self, struct cmd_q *cmdq)
{
- struct args *args = self->args;
- struct client *c;
+ struct args *args = self->args;
+ struct client *c;
+ struct session *s;
+ struct winlink *wl;
+ struct window_pane *wp;
+ int nflags = 0;
+ const char *str;
+
+ if (args_has(args, 'g')) nflags++;
+ if (args_has(args, 'P')) nflags++;
+
+ if (nflags == 0) {
+
+ if ((c = cmd_find_client(cmdq, args_get(args, 't'), 0)) == NULL)
+ return (CMD_RETURN_ERROR);
+
+ server_set_identify(c);
+
+ return (CMD_RETURN_NORMAL);
+ }
- if ((c = cmd_find_client(cmdq, args_get(args, 't'), 0)) == NULL)
+
+ if ((wl = cmd_find_pane(cmdq, args_get(args, 't'), &s, &wp)) == NULL)
return (CMD_RETURN_ERROR);
- server_set_identify(c);
+ if (args_has(args, 'g')) {
+
+ if (nflags > 1) {
+ cmdq_error(cmdq, "don't use -P with -g");
+ return (CMD_RETURN_ERROR);
+ }
+
+ cmdq_print(cmdq, "%s", style_tostring(&wp->colgc));
+
+ return (CMD_RETURN_NORMAL);
+ }
+
+ if (args_has(args, 'P')) {
+ str = args_get(args, 'P');
+ if (style_parse(&grid_default_cell, &wp->colgc, str) == -1) {
+ cmdq_error(cmdq, "bad style: %s", str);
+ return (CMD_RETURN_ERROR);
+ }
+
+ wp->flags |= PANE_REDRAW;
+ }
return (CMD_RETURN_NORMAL);
}
diff --git a/options-table.c b/options-table.c
index 2bcf29b..d7057bf 100644
--- a/options-table.c
+++ b/options-table.c
@@ -667,6 +667,16 @@ const struct options_table_entry window_options_table[] = {
.default_num = 0 /* overridden in main() */
},
+ { .name = "window-active-style",
+ .type = OPTIONS_TABLE_STYLE,
+ .default_str = "default"
+ },
+
+ { .name = "window-style",
+ .type = OPTIONS_TABLE_STYLE,
+ .default_str = "default"
+ },
+
{ .name = "window-status-activity-attr",
.type = OPTIONS_TABLE_ATTRIBUTES,
.default_num = GRID_ATTR_REVERSE,
diff --git a/screen-redraw.c b/screen-redraw.c
index c2b2ece..ab0b4b3 100644
--- a/screen-redraw.c
+++ b/screen-redraw.c
@@ -249,7 +249,7 @@ 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);
- tty_reset(tty);
+ tty_reset(tty, NULL);
}
/* Draw a single pane. */
@@ -266,8 +266,8 @@ screen_redraw_pane(struct client *c, struct window_pane *wp)
yoff++;
for (i = 0; i < wp->sy; i++)
- tty_draw_line(&c->tty, wp->screen, i, wp->xoff, yoff);
- tty_reset(&c->tty);
+ tty_draw_line(&c->tty, wp->screen, i, wp->xoff, yoff, wp);
+ tty_reset(&c->tty, NULL);
}
/* Draw the borders. */
@@ -323,9 +323,9 @@ screen_redraw_draw_borders(struct client *c, int status, u_int top)
small && i > msgx && j == msgy)
continue;
if (screen_redraw_check_active(i, j, type, w, wp))
- tty_attributes(tty, &active_gc);
+ tty_attributes(tty, &active_gc, wp);
else
- tty_attributes(tty, &other_gc);
+ tty_attributes(tty, &other_gc, wp);
tty_cursor(tty, i, top + j);
tty_putc(tty, CELL_BORDERS[type]);
}
@@ -333,7 +333,7 @@ screen_redraw_draw_borders(struct client *c, int status, u_int top)
if (small) {
memcpy(&msg_gc, &grid_default_cell, sizeof msg_gc);
- tty_attributes(tty, &msg_gc);
+ tty_attributes(tty, &msg_gc, wp);
tty_cursor(tty, msgx, msgy);
tty_puts(tty, msg);
}
@@ -354,7 +354,7 @@ screen_redraw_draw_panes(struct client *c, u_int top)
continue;
s = wp->screen;
for (i = 0; i < wp->sy; i++)
- tty_draw_line(tty, s, i, wp->xoff, top + wp->yoff);
+ tty_draw_line(tty, s, i, wp->xoff, top + wp->yoff, wp);
if (c->flags & CLIENT_IDENTIFY)
screen_redraw_draw_number(c, wp);
}
@@ -367,9 +367,9 @@ screen_redraw_draw_status(struct client *c, u_int top)
struct tty *tty = &c->tty;
if (top)
- tty_draw_line(tty, &c->status, 0, 0, 0);
+ tty_draw_line(tty, &c->status, 0, 0, 0, NULL);
else
- tty_draw_line(tty, &c->status, 0, 0, tty->sy - 1);
+ tty_draw_line(tty, &c->status, 0, 0, tty->sy - 1, NULL);
}
/* Draw number on a pane. */
@@ -411,7 +411,7 @@ screen_redraw_draw_number(struct client *c, struct window_pane *wp)
colour_set_bg(&gc, active_colour);
else
colour_set_bg(&gc, colour);
- tty_attributes(tty, &gc);
+ tty_attributes(tty, &gc, wp);
for (ptr = buf; *ptr != '\0'; ptr++) {
if (*ptr < '0' || *ptr > '9')
continue;
@@ -438,7 +438,7 @@ draw_text:
colour_set_fg(&gc, active_colour);
else
colour_set_fg(&gc, colour);
- tty_attributes(tty, &gc);
+ tty_attributes(tty, &gc, wp);
tty_puts(tty, buf);
tty_cursor(tty, 0, 0);
diff --git a/server-client.c b/server-client.c
index 3ca9907..3206b6e 100644
--- a/server-client.c
+++ b/server-client.c
@@ -691,7 +691,7 @@ server_client_reset_state(struct client *c)
/* Set the terminal mode and reset attributes. */
tty_update_mode(&c->tty, mode, s);
- tty_reset(&c->tty);
+ tty_reset(&c->tty, NULL);
}
/* Repeat time callback. */
diff --git a/tmux.h b/tmux.h
index e296ac7..3bd781a 100644
--- a/tmux.h
+++ b/tmux.h
@@ -900,6 +900,9 @@ struct window_pane {
struct input_ctx ictx;
+ /* Default fg/bg grid cell colours */
+ struct grid_cell colgc;
+
int pipe_fd;
struct bufferevent *pipe_event;
size_t pipe_off;
@@ -1604,8 +1607,9 @@ void environ_push(struct environ *);
/* tty.c */
void tty_init_termios(int, struct termios *, struct bufferevent *);
void tty_raw(struct tty *, const char *);
-void tty_attributes(struct tty *, const struct grid_cell *);
-void tty_reset(struct tty *);
+void tty_attributes(struct tty *, const struct grid_cell *,
+ const struct window_pane *);
+void tty_reset(struct tty *, const struct window_pane *);
void tty_region_pane(struct tty *, const struct tty_ctx *, u_int, u_int);
void tty_region(struct tty *, u_int, u_int);
void tty_cursor_pane(struct tty *, const struct tty_ctx *, u_int, u_int);
@@ -1628,7 +1632,8 @@ void tty_stop_tty(struct tty *);
void tty_set_title(struct tty *, const char *);
void tty_update_mode(struct tty *, int, struct screen *);
void tty_force_cursor_colour(struct tty *, const char *);
-void tty_draw_line(struct tty *, struct screen *, u_int, u_int, u_int);
+void tty_draw_line(struct tty *, struct screen *, u_int, u_int, u_int,
+ const struct window_pane *);
int tty_open(struct tty *, char **);
void tty_close(struct tty *);
void tty_free(struct tty *);
diff --git a/tty.c b/tty.c
index 1bb8981..a3f7c83 100644
--- a/tty.c
+++ b/tty.c
@@ -47,7 +47,9 @@ void tty_redraw_region(struct tty *, const struct tty_ctx *);
void tty_emulate_repeat(
struct tty *, enum tty_code_code, enum tty_code_code, u_int);
void tty_repeat_space(struct tty *, u_int);
-void tty_cell(struct tty *, const struct grid_cell *);
+void tty_cell(struct tty *, const struct grid_cell *,
+ const struct window_pane *);
+void tty_default_colours(struct grid_cell *, const struct window_pane *);
#define tty_use_acs(tty) \
(tty_term_has((tty)->term, TTYC_ACSC) && !((tty)->flags & TTY_UTF8))
@@ -604,15 +606,16 @@ tty_redraw_region(struct tty *tty, const struct tty_ctx *ctx)
if (ctx->ocy < ctx->orupper || ctx->ocy > ctx->orlower) {
for (i = ctx->ocy; i < screen_size_y(s); i++)
- tty_draw_line(tty, s, i, ctx->xoff, ctx->yoff);
+ tty_draw_line(tty, s, i, ctx->xoff, ctx->yoff, wp);
} else {
for (i = ctx->orupper; i <= ctx->orlower; i++)
- tty_draw_line(tty, s, i, ctx->xoff, ctx->yoff);
+ tty_draw_line(tty, s, i, ctx->xoff, ctx->yoff, wp);
}
}
void
-tty_draw_line(struct tty *tty, struct screen *s, u_int py, u_int ox, u_int oy)
+tty_draw_line(struct tty *tty, struct screen *s, u_int py, u_int ox, u_int oy,
+ const struct window_pane *wp)
{
const struct grid_cell *gc;
struct grid_line *gl;
@@ -650,16 +653,16 @@ tty_draw_line(struct tty *tty, struct screen *s, u_int py, u_int ox, u_int oy)
~(GRID_FLAG_FG256|GRID_FLAG_BG256);
tmpgc.flags |= s->sel.cell.flags &
(GRID_FLAG_FG256|GRID_FLAG_BG256);
- tty_cell(tty, &tmpgc);
+ tty_cell(tty, &tmpgc, wp);
} else
- tty_cell(tty, gc);
+ tty_cell(tty, gc, wp);
}
if (sx >= tty->sx) {
tty_update_mode(tty, tty->mode, s);
return;
}
- tty_reset(tty);
+ tty_reset(tty, wp);
tty_cursor(tty, ox + sx, oy + py);
if (sx != screen_size_x(s) && ox + screen_size_x(s) >= tty->sx &&
@@ -713,11 +716,12 @@ tty_cmd_insertcharacter(struct tty *tty, const struct tty_ctx *ctx)
struct window_pane *wp = ctx->wp;
if (!tty_pane_full_width(tty, ctx)) {
- tty_draw_line(tty, wp->screen, ctx->ocy, ctx->xoff, ctx->yoff);
+ tty_draw_line(tty, wp->screen, ctx->ocy, ctx->xoff, ctx->yoff,
+ wp);
return;
}
- tty_reset(tty);
+ tty_reset(tty, wp);
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
@@ -725,7 +729,8 @@ tty_cmd_insertcharacter(struct tty *tty, const struct tty_ctx *ctx)
tty_term_has(tty->term, TTYC_ICH1))
tty_emulate_repeat(tty, TTYC_ICH, TTYC_ICH1, ctx->num);
else
- tty_draw_line(tty, wp->screen, ctx->ocy, ctx->xoff, ctx->yoff);
+ tty_draw_line(tty, wp->screen, ctx->ocy, ctx->xoff, ctx->yoff,
+ wp);
}
void
@@ -736,11 +741,12 @@ tty_cmd_deletecharacter(struct tty *tty, const struct tty_ctx *ctx)
if (!tty_pane_full_width(tty, ctx) ||
(!tty_term_has(tty->term, TTYC_DCH) &&
!tty_term_has(tty->term, TTYC_DCH1))) {
- tty_draw_line(tty, wp->screen, ctx->ocy, ctx->xoff, ctx->yoff);
+ tty_draw_line(tty, wp->screen, ctx->ocy, ctx->xoff, ctx->yoff,
+ wp);
return;
}
- tty_reset(tty);
+ tty_reset(tty, wp);
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
@@ -754,7 +760,7 @@ tty_cmd_clearcharacter(struct tty *tty, const struct tty_ctx *ctx)
{
u_int i;
- tty_reset(tty);
+ tty_reset(tty, ctx->wp);
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
@@ -776,7 +782,7 @@ tty_cmd_insertline(struct tty *tty, const struct tty_ctx *ctx)
return;
}
- tty_reset(tty);
+ tty_reset(tty, ctx->wp);
tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower);
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
@@ -794,7 +800,7 @@ tty_cmd_deleteline(struct tty *tty, const struct tty_ctx *ctx)
return;
}
- tty_reset(tty);
+ tty_reset(tty, ctx->wp);
tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower);
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
@@ -808,7 +814,7 @@ tty_cmd_clearline(struct tty *tty, const struct tty_ctx *ctx)
struct window_pane *wp = ctx->wp;
struct screen *s = wp->screen;
- tty_reset(tty);
+ tty_reset(tty, wp);
tty_cursor_pane(tty, ctx, 0, ctx->ocy);
@@ -824,7 +830,7 @@ tty_cmd_clearendofline(struct tty *tty, const struct tty_ctx *ctx)
struct window_pane *wp = ctx->wp;
struct screen *s = wp->screen;
- tty_reset(tty);
+ tty_reset(tty, wp);
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
@@ -837,7 +843,7 @@ tty_cmd_clearendofline(struct tty *tty, const struct tty_ctx *ctx)
void
tty_cmd_clearstartofline(struct tty *tty, const struct tty_ctx *ctx)
{
- tty_reset(tty);
+ tty_reset(tty, ctx->wp);
if (ctx->xoff == 0 && tty_term_has(tty->term, TTYC_EL1)) {
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
@@ -861,7 +867,7 @@ tty_cmd_reverseindex(struct tty *tty, const struct tty_ctx *ctx)
return;
}
- tty_reset(tty);
+ tty_reset(tty, ctx->wp);
tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower);
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->orupper);
@@ -894,7 +900,7 @@ tty_cmd_linefeed(struct tty *tty, const struct tty_ctx *ctx)
if (ctx->num && !(tty->term->flags & TERM_EARLYWRAP))
return;
- tty_reset(tty);
+ tty_reset(tty, wp);
tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower);
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
@@ -909,7 +915,7 @@ tty_cmd_clearendofscreen(struct tty *tty, const struct tty_ctx *ctx)
struct screen *s = wp->screen;
u_int i, j;
- tty_reset(tty);
+ tty_reset(tty, wp);
tty_region_pane(tty, ctx, 0, screen_size_y(s) - 1);
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
@@ -942,7 +948,7 @@ tty_cmd_clearstartofscreen(struct tty *tty, const struct tty_ctx *ctx)
struct screen *s = wp->screen;
u_int i, j;
- tty_reset(tty);
+ tty_reset(tty, wp);
tty_region_pane(tty, ctx, 0, screen_size_y(s) - 1);
tty_cursor_pane(tty, ctx, 0, 0);
@@ -969,7 +975,7 @@ tty_cmd_clearscreen(struct tty *tty, const struct tty_ctx *ctx)
struct screen *s = wp->screen;
u_int i, j;
- tty_reset(tty);
+ tty_reset(tty, wp);
tty_region_pane(tty, ctx, 0, screen_size_y(s) - 1);
tty_cursor_pane(tty, ctx, 0, 0);
@@ -997,7 +1003,7 @@ tty_cmd_alignmenttest(struct tty *tty, const struct tty_ctx *ctx)
struct screen *s = wp->screen;
u_int i, j;
- tty_reset(tty);
+ tty_reset(tty, wp);
tty_region_pane(tty, ctx, 0, screen_size_y(s) - 1);
@@ -1038,12 +1044,12 @@ tty_cmd_cell(struct tty *tty, const struct tty_ctx *ctx)
*/
cx = screen_size_x(s) - grid_cell_width(&ctx->last_cell);
tty_cursor_pane(tty, ctx, cx, ctx->ocy);
- tty_cell(tty, &ctx->last_cell);
+ tty_cell(tty, &ctx->last_cell, wp);
}
} else
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
- tty_cell(tty, ctx->cell);
+ tty_cell(tty, ctx->cell, wp);
}
void
@@ -1055,7 +1061,7 @@ tty_cmd_utf8character(struct tty *tty, const struct tty_ctx *ctx)
* Cannot rely on not being a partial character, so just redraw the
* whole line.
*/
- tty_draw_line(tty, wp->screen, ctx->ocy, ctx->xoff, ctx->yoff);
+ tty_draw_line(tty, wp->screen, ctx->ocy, ctx->xoff, ctx->yoff, wp);
}
void
@@ -1088,12 +1094,13 @@ tty_cmd_rawstring(struct tty *tty, const struct tty_ctx *ctx)
tty->cx = tty->cy = UINT_MAX;
tty->rupper = tty->rlower = UINT_MAX;
- tty_reset(tty);
+ tty_reset(tty, ctx->wp);
tty_cursor(tty, 0, 0);
}
void
-tty_cell(struct tty *tty, const struct grid_cell *gc)
+tty_cell(struct tty *tty, const struct grid_cell *gc,
+ const struct window_pane *wp)
{
struct utf8_data ud;
u_int i;
@@ -1108,7 +1115,7 @@ tty_cell(struct tty *tty, const struct grid_cell *gc)
return;
/* Set the attributes. */
- tty_attributes(tty, gc);
+ tty_attributes(tty, gc, wp);
/* Get the cell and if ASCII write with putc to do ACS translation. */
grid_cell_get(gc, &ud);
@@ -1131,17 +1138,22 @@ tty_cell(struct tty *tty, const struct grid_cell *gc)
}
void
-tty_reset(struct tty *tty)
+tty_reset(struct tty *tty, const struct window_pane *wp)
{
struct grid_cell *gc = &tty->cell;
+ struct grid_cell colgc;
- if (memcmp(gc, &grid_default_cell, sizeof *gc) == 0)
+ memcpy(&colgc, &grid_default_cell, sizeof colgc);
+ tty_default_colours(&colgc, wp);
+
+ if (memcmp(gc, &colgc, sizeof *gc) == 0)
return;
if ((gc->attr & GRID_ATTR_CHARSET) && tty_use_acs(tty))
tty_putcode(tty, TTYC_RMACS);
tty_putcode(tty, TTYC_SGR0);
memcpy(gc, &grid_default_cell, sizeof *gc);
+ tty_attributes(tty, &colgc, wp);
}
/* Set region inside pane. */
@@ -1312,12 +1324,14 @@ out:
}
void
-tty_attributes(struct tty *tty, const struct grid_cell *gc)
+tty_attributes(struct tty *tty, const struct grid_cell *gc,
+ const struct window_pane *wp)
{
struct grid_cell *tc = &tty->cell, gc2;
u_char changed;
memcpy(&gc2, gc, sizeof gc2);
+ tty_default_colours(&gc2, wp);
/*
* If no setab, try to use the reverse attribute as a best-effort for a
@@ -1340,7 +1354,7 @@ tty_attributes(struct tty *tty, const struct grid_cell *gc)
/* If any bits are being cleared, reset everything. */
if (tc->attr & ~gc2.attr)
- tty_reset(tty);
+ tty_reset(tty, wp);
/*
* Set the colours. This may call tty_reset() (so it comes next) and
@@ -1409,7 +1423,7 @@ tty_colours(struct tty *tty, const struct grid_cell *gc)
*/
have_ax = tty_term_has(tty->term, TTYC_AX);
if (!have_ax && tty_term_has(tty->term, TTYC_OP))
- tty_reset(tty);
+ tty_reset(tty, NULL);
else {
if (fg_default &&
(tc->fg != 8 || tc->flags & GRID_FLAG_FG256)) {
@@ -1614,3 +1628,44 @@ tty_bell(struct tty *tty)
{
tty_putcode(tty, TTYC_BEL);
}
+
+void
+tty_default_colours(struct grid_cell *gc, const struct window_pane *wp)
+{
+ const struct grid_cell *agc, *pgc, *wgc;
+
+ if (wp == NULL)
+ return;
+
+ pgc = &wp->colgc;
+ agc = options_get_style(&wp->window->options, "window-active-style");
+ wgc = options_get_style(&wp->window->options, "window-style");
+
+ if (gc->fg == 8 && !(gc->flags & GRID_FLAG_FG256)) {
+ if (pgc->fg != 8 || (pgc->flags & GRID_FLAG_FG256)) {
+ gc->fg = pgc->fg;
+ gc->flags |= (pgc->flags & GRID_FLAG_FG256);
+ } else if (wp == wp->window->active &&
+ (agc->fg != 8 || (agc->flags & GRID_FLAG_FG256))) {
+ gc->fg = agc->fg;
+ gc->flags |= (agc->flags & GRID_FLAG_FG256);
+ } else {
+ gc->fg = wgc->fg;
+ gc->flags |= (wgc->flags & GRID_FLAG_FG256);
+ }
+ }
+
+ if (gc->bg == 8 && !(gc->flags & GRID_FLAG_BG256)) {
+ if (pgc->bg != 8 || (pgc->flags & GRID_FLAG_BG256)) {
+ gc->bg = pgc->bg;
+ gc->flags |= (pgc->flags & GRID_FLAG_BG256);
+ } else if (wp == wp->window->active &&
+ (agc->bg != 8 || (agc->flags & GRID_FLAG_BG256))) {
+ gc->bg = agc->bg;
+ gc->flags |= (agc->flags & GRID_FLAG_BG256);
+ } else {
+ gc->bg = wgc->bg;
+ gc->flags |= (wgc->flags & GRID_FLAG_BG256);
+ }
+ }
+}
diff --git a/window.c b/window.c
index fff2cfc..cc1377f 100644
--- a/window.c
+++ b/window.c
@@ -704,6 +704,8 @@ window_pane_create(struct window *w, u_int sx, u_int sy, u_int hlimit)
wp->saved_grid = NULL;
+ memcpy(&wp->colgc, &grid_default_cell, sizeof grid_default_cell);
+
screen_init(&wp->base, sx, sy, hlimit);
wp->screen = &wp->base;
------------------------------------------------------------------------------
Download BIRT iHub F-Type - The Free Enterprise-Grade BIRT Server
from Actuate! Instantly Supercharge Your Business Reports and Dashboards
with Interactivity, Sharing, Native Excel Exports, App Integration & more
Get technology previously reserved for billion-dollar corporations, FREE
http://pubads.g.doubleclick.net/gampad/clk?id=190641631&iu=/4140/ostg.clktrk
_______________________________________________
tmux-users mailing list
tmux-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/tmux-users