Merge branch 'obsd-master'

pull/1805/head
Thomas Adam 2019-06-20 15:02:26 +01:00
commit f8ad72b2ee
16 changed files with 300 additions and 278 deletions

View File

@ -77,6 +77,8 @@ cmd_break_pane_exec(struct cmd *self, struct cmdq_item *item)
layout_close_pane(wp); layout_close_pane(wp);
w = wp->window = window_create(w->sx, w->sy); w = wp->window = window_create(w->sx, w->sy);
options_set_parent(wp->options, w->options);
wp->flags |= PANE_STYLECHANGED;
TAILQ_INSERT_HEAD(&w->panes, wp, entry); TAILQ_INSERT_HEAD(&w->panes, wp, entry);
w->active = wp; w->active = wp;

View File

@ -139,6 +139,8 @@ cmd_join_pane_exec(struct cmd *self, struct cmdq_item *item)
TAILQ_REMOVE(&src_w->panes, src_wp, entry); TAILQ_REMOVE(&src_w->panes, src_wp, entry);
src_wp->window = dst_w; src_wp->window = dst_w;
options_set_parent(src_wp->options, dst_w->options);
src_wp->flags |= PANE_STYLECHANGED;
TAILQ_INSERT_AFTER(&dst_w->panes, dst_wp, src_wp, entry); TAILQ_INSERT_AFTER(&dst_w->panes, dst_wp, src_wp, entry);
layout_assign_pane(lc, src_wp); layout_assign_pane(lc, src_wp);

View File

@ -33,8 +33,8 @@ const struct cmd_entry cmd_select_pane_entry = {
.name = "select-pane", .name = "select-pane",
.alias = "selectp", .alias = "selectp",
.args = { "DdegLlMmP:RT:t:U", 0, 0 }, .args = { "DdegLlMmP:RT:t:U", 0, 0 }, /* -P and -g deprecated */
.usage = "[-DdegLlMmRU] [-P style] [-T title] " CMD_TARGET_PANE_USAGE, .usage = "[-DdeLlMmRU] [-T title] " CMD_TARGET_PANE_USAGE,
.target = { 't', CMD_FIND_PANE, 0 }, .target = { 't', CMD_FIND_PANE, 0 },
@ -90,9 +90,10 @@ cmd_select_pane_exec(struct cmd *self, struct cmdq_item *item)
struct window *w = wl->window; struct window *w = wl->window;
struct session *s = item->target.s; struct session *s = item->target.s;
struct window_pane *wp = item->target.wp, *lastwp, *markedwp; struct window_pane *wp = item->target.wp, *lastwp, *markedwp;
struct style *sy = &wp->style;
char *pane_title; char *pane_title;
const char *style; const char *style;
struct style *sy;
struct options_entry *o;
if (self->entry == &cmd_last_pane_entry || args_has(args, 'l')) { if (self->entry == &cmd_last_pane_entry || args_has(args, 'l')) {
lastwp = w->last; lastwp = w->last;
@ -144,15 +145,18 @@ cmd_select_pane_exec(struct cmd *self, struct cmdq_item *item)
if (args_has(self->args, 'P') || args_has(self->args, 'g')) { if (args_has(self->args, 'P') || args_has(self->args, 'g')) {
if ((style = args_get(args, 'P')) != NULL) { if ((style = args_get(args, 'P')) != NULL) {
style_set(sy, &grid_default_cell); o = options_set_style(wp->options, "window-style", 0,
if (style_parse(sy, &grid_default_cell, style) == -1) { style);
if (o == NULL) {
cmdq_error(item, "bad style: %s", style); cmdq_error(item, "bad style: %s", style);
return (CMD_RETURN_ERROR); return (CMD_RETURN_ERROR);
} }
wp->flags |= PANE_REDRAW; wp->flags |= (PANE_REDRAW|PANE_STYLECHANGED);
} }
if (args_has(self->args, 'g')) if (args_has(self->args, 'g')) {
sy = options_get_style(wp->options, "window-style");
cmdq_print(item, "%s", style_tostring(sy)); cmdq_print(item, "%s", style_tostring(sy));
}
return (CMD_RETURN_NORMAL); return (CMD_RETURN_NORMAL);
} }

View File

@ -43,10 +43,10 @@ const struct cmd_entry cmd_set_option_entry = {
.name = "set-option", .name = "set-option",
.alias = "set", .alias = "set",
.args = { "aFgoqst:uw", 1, 2 }, .args = { "aFgopqst:uw", 1, 2 },
.usage = "[-aFgosquw] [-t target-window] option [value]", .usage = "[-aFgopqsuw] " CMD_TARGET_PANE_USAGE " option [value]",
.target = { 't', CMD_FIND_WINDOW, CMD_FIND_CANFAIL }, .target = { 't', CMD_FIND_PANE, CMD_FIND_CANFAIL },
.flags = CMD_AFTERHOOK, .flags = CMD_AFTERHOOK,
.exec = cmd_set_option_exec .exec = cmd_set_option_exec
@ -88,11 +88,12 @@ cmd_set_option_exec(struct cmd *self, struct cmdq_item *item)
struct session *s = fs->s; struct session *s = fs->s;
struct winlink *wl = fs->wl; struct winlink *wl = fs->wl;
struct window *w; struct window *w;
enum options_table_scope scope; struct window_pane *wp;
struct options *oo; struct options *oo;
struct options_entry *parent, *o; struct options_entry *parent, *o;
char *name, *argument, *value = NULL, *cause; char *name, *argument, *value = NULL, *cause;
int window, idx, already, error, ambiguous; int window, idx, already, error, ambiguous;
int scope;
struct style *sy; struct style *sy;
window = (self->entry == &cmd_set_window_option_entry); window = (self->entry == &cmd_set_window_option_entry);
@ -249,8 +250,8 @@ cmd_set_option_exec(struct cmd *self, struct cmdq_item *item)
alerts_reset_all(); alerts_reset_all();
if (strcmp(name, "window-style") == 0 || if (strcmp(name, "window-style") == 0 ||
strcmp(name, "window-active-style") == 0) { strcmp(name, "window-active-style") == 0) {
RB_FOREACH(w, windows, &windows) RB_FOREACH(wp, window_pane_tree, &all_window_panes)
w->flags |= WINDOW_STYLECHANGED; wp->flags |= PANE_STYLECHANGED;
} }
if (strcmp(name, "pane-border-status") == 0) { if (strcmp(name, "pane-border-status") == 0) {
RB_FOREACH(w, windows, &windows) RB_FOREACH(w, windows, &windows)

View File

@ -32,16 +32,16 @@ static enum cmd_retval cmd_show_options_exec(struct cmd *, struct cmdq_item *);
static void cmd_show_options_print(struct cmd *, struct cmdq_item *, static void cmd_show_options_print(struct cmd *, struct cmdq_item *,
struct options_entry *, int, int); struct options_entry *, int, int);
static enum cmd_retval cmd_show_options_all(struct cmd *, struct cmdq_item *, static enum cmd_retval cmd_show_options_all(struct cmd *, struct cmdq_item *,
enum options_table_scope, struct options *); int, struct options *);
const struct cmd_entry cmd_show_options_entry = { const struct cmd_entry cmd_show_options_entry = {
.name = "show-options", .name = "show-options",
.alias = "show", .alias = "show",
.args = { "AgHqst:vw", 0, 1 }, .args = { "AgHpqst:vw", 0, 1 },
.usage = "[-AgHqsvw] [-t target-session|target-window] [option]", .usage = "[-AgHpqsvw] " CMD_TARGET_PANE_USAGE " [option]",
.target = { 't', CMD_FIND_WINDOW, CMD_FIND_CANFAIL }, .target = { 't', CMD_FIND_PANE, CMD_FIND_CANFAIL },
.flags = CMD_AFTERHOOK, .flags = CMD_AFTERHOOK,
.exec = cmd_show_options_exec .exec = cmd_show_options_exec
@ -82,9 +82,8 @@ cmd_show_options_exec(struct cmd *self, struct cmdq_item *item)
struct session *s = item->target.s; struct session *s = item->target.s;
struct winlink *wl = item->target.wl; struct winlink *wl = item->target.wl;
struct options *oo; struct options *oo;
enum options_table_scope scope;
char *argument, *name = NULL, *cause; char *argument, *name = NULL, *cause;
int window, idx, ambiguous, parent; int window, idx, ambiguous, parent, scope;
struct options_entry *o; struct options_entry *o;
window = (self->entry == &cmd_show_window_options_entry); window = (self->entry == &cmd_show_window_options_entry);
@ -190,17 +189,18 @@ cmd_show_options_print(struct cmd *self, struct cmdq_item *item,
} }
static enum cmd_retval static enum cmd_retval
cmd_show_options_all(struct cmd *self, struct cmdq_item *item, cmd_show_options_all(struct cmd *self, struct cmdq_item *item, int scope,
enum options_table_scope scope, struct options *oo) struct options *oo)
{ {
const struct options_table_entry *oe; const struct options_table_entry *oe;
struct options_entry *o; struct options_entry *o;
struct options_array_item *a; struct options_array_item *a;
const char *name;
u_int idx; u_int idx;
int parent; int parent;
for (oe = options_table; oe->name != NULL; oe++) { for (oe = options_table; oe->name != NULL; oe++) {
if (oe->scope != scope) if (~oe->scope & scope)
continue; continue;
if ((self->entry != &cmd_show_hooks_entry && if ((self->entry != &cmd_show_hooks_entry &&
@ -227,15 +227,17 @@ cmd_show_options_all(struct cmd *self, struct cmdq_item *item,
cmd_show_options_print(self, item, o, -1, parent); cmd_show_options_print(self, item, o, -1, parent);
else if ((a = options_array_first(o)) == NULL) { else if ((a = options_array_first(o)) == NULL) {
if (!args_has(self->args, 'v')) { if (!args_has(self->args, 'v')) {
name = options_name(o);
if (parent) if (parent)
cmdq_print(item, "%s*", options_name(o)); cmdq_print(item, "%s*", name);
else else
cmdq_print(item, "%s", options_name(o)); cmdq_print(item, "%s", name);
} }
} else { } else {
while (a != NULL) { while (a != NULL) {
idx = options_array_item_index(a); idx = options_array_item_index(a);
cmd_show_options_print(self, item, o, idx, parent); cmd_show_options_print(self, item, o, idx,
parent);
a = options_array_next(a); a = options_array_next(a);
} }
} }

View File

@ -90,7 +90,11 @@ cmd_swap_pane_exec(struct cmd *self, struct cmdq_item *item)
src_wp->layout_cell = dst_lc; src_wp->layout_cell = dst_lc;
src_wp->window = dst_w; src_wp->window = dst_w;
options_set_parent(src_wp->options, dst_w->options);
src_wp->flags |= PANE_STYLECHANGED;
dst_wp->window = src_w; dst_wp->window = src_w;
options_set_parent(dst_wp->options, src_w->options);
dst_wp->flags |= PANE_STYLECHANGED;
sx = src_wp->sx; sy = src_wp->sy; sx = src_wp->sx; sy = src_wp->sy;
xoff = src_wp->xoff; yoff = src_wp->yoff; xoff = src_wp->xoff; yoff = src_wp->yoff;

View File

@ -1068,6 +1068,8 @@ format_find(struct format_tree *ft, const char *key, int modifiers)
if (~modifiers & FORMAT_TIMESTRING) { if (~modifiers & FORMAT_TIMESTRING) {
o = options_parse_get(global_options, key, &idx, 0); o = options_parse_get(global_options, key, &idx, 0);
if (o == NULL && ft->wp != NULL)
o = options_parse_get(ft->wp->options, key, &idx, 0);
if (o == NULL && ft->w != NULL) if (o == NULL && ft->w != NULL)
o = options_parse_get(ft->w->options, key, &idx, 0); o = options_parse_get(ft->w->options, key, &idx, 0);
if (o == NULL) if (o == NULL)

16
input.c
View File

@ -2347,12 +2347,14 @@ input_osc_10(struct input_ctx *ictx, const char *p)
{ {
struct window_pane *wp = ictx->wp; struct window_pane *wp = ictx->wp;
u_int r, g, b; u_int r, g, b;
char tmp[16];
if (sscanf(p, "rgb:%2x/%2x/%2x", &r, &g, &b) != 3) if (sscanf(p, "rgb:%2x/%2x/%2x", &r, &g, &b) != 3)
goto bad; goto bad;
xsnprintf(tmp, sizeof tmp, "fg=#%02x%02x%02x", r, g, b);
wp->style.gc.fg = colour_join_rgb(r, g, b); options_set_style(wp->options, "window-style", 1, tmp);
wp->flags |= PANE_REDRAW; options_set_style(wp->options, "window-active-style", 1, tmp);
wp->flags |= (PANE_REDRAW|PANE_STYLECHANGED);
return; return;
@ -2366,12 +2368,14 @@ input_osc_11(struct input_ctx *ictx, const char *p)
{ {
struct window_pane *wp = ictx->wp; struct window_pane *wp = ictx->wp;
u_int r, g, b; u_int r, g, b;
char tmp[16];
if (sscanf(p, "rgb:%2x/%2x/%2x", &r, &g, &b) != 3) if (sscanf(p, "rgb:%2x/%2x/%2x", &r, &g, &b) != 3)
goto bad; goto bad;
xsnprintf(tmp, sizeof tmp, "bg=#%02x%02x%02x", r, g, b);
wp->style.gc.bg = colour_join_rgb(r, g, b); options_set_style(wp->options, "window-style", 1, tmp);
wp->flags |= PANE_REDRAW; options_set_style(wp->options, "window-active-style", 1, tmp);
wp->flags |= (PANE_REDRAW|PANE_STYLECHANGED);
return; return;

View File

@ -699,7 +699,7 @@ const struct options_table_entry options_table[] = {
{ .name = "remain-on-exit", { .name = "remain-on-exit",
.type = OPTIONS_TABLE_FLAG, .type = OPTIONS_TABLE_FLAG,
.scope = OPTIONS_TABLE_WINDOW, .scope = OPTIONS_TABLE_WINDOW|OPTIONS_TABLE_PANE,
.default_num = 0 .default_num = 0
}, },
@ -711,7 +711,7 @@ const struct options_table_entry options_table[] = {
{ .name = "window-active-style", { .name = "window-active-style",
.type = OPTIONS_TABLE_STYLE, .type = OPTIONS_TABLE_STYLE,
.scope = OPTIONS_TABLE_WINDOW, .scope = OPTIONS_TABLE_WINDOW|OPTIONS_TABLE_PANE,
.default_str = "default" .default_str = "default"
}, },
@ -724,7 +724,7 @@ const struct options_table_entry options_table[] = {
{ .name = "window-style", { .name = "window-style",
.type = OPTIONS_TABLE_STYLE, .type = OPTIONS_TABLE_STYLE,
.scope = OPTIONS_TABLE_WINDOW, .scope = OPTIONS_TABLE_WINDOW|OPTIONS_TABLE_PANE,
.default_str = "default" .default_str = "default"
}, },

100
options.c
View File

@ -100,7 +100,7 @@ options_parent_table_entry(struct options *oo, const char *s)
if (oo->parent == NULL) if (oo->parent == NULL)
fatalx("no parent options for %s", s); fatalx("no parent options for %s", s);
o = options_get_only(oo->parent, s); o = options_get(oo->parent, s);
if (o == NULL) if (o == NULL)
fatalx("%s not in parent options", s); fatalx("%s not in parent options", s);
return (o->tableentry); return (o->tableentry);
@ -178,6 +178,12 @@ options_free(struct options *oo)
free(oo); free(oo);
} }
void
options_set_parent(struct options *oo, struct options *parent)
{
oo->parent = parent;
}
struct options_entry * struct options_entry *
options_first(struct options *oo) options_first(struct options *oo)
{ {
@ -545,7 +551,7 @@ options_parse_get(struct options *oo, const char *s, int *idx, int only)
} }
char * char *
options_match(const char *s, int *idx, int* ambiguous) options_match(const char *s, int *idx, int *ambiguous)
{ {
const struct options_table_entry *oe, *found; const struct options_table_entry *oe, *found;
char *name; char *name;
@ -725,70 +731,96 @@ options_set_style(struct options *oo, const char *name, int append,
return (o); return (o);
} }
enum options_table_scope int
options_scope_from_name(struct args *args, int window, options_scope_from_name(struct args *args, int window,
const char *name, struct cmd_find_state *fs, struct options **oo, const char *name, struct cmd_find_state *fs, struct options **oo,
char **cause) char **cause)
{ {
struct session *s = fs->s; struct session *s = fs->s;
struct winlink *wl = fs->wl; struct winlink *wl = fs->wl;
const char *target = args_get(args, 't'); struct window_pane *wp = fs->wp;
enum options_table_scope scope; const char *target = args_get(args, 't');
const struct options_table_entry *oe;
int scope;
if (*name == '@') if (*name == '@')
return (options_scope_from_flags(args, window, fs, oo, cause)); return (options_scope_from_flags(args, window, fs, oo, cause));
if (options_get_only(global_options, name) != NULL) for (oe = options_table; oe->name != NULL; oe++) {
scope = OPTIONS_TABLE_SERVER; if (strcmp(oe->name, name) == 0)
else if (options_get_only(global_s_options, name) != NULL) break;
scope = OPTIONS_TABLE_SESSION; }
else if (options_get_only(global_w_options, name) != NULL) if (oe->name == NULL) {
scope = OPTIONS_TABLE_WINDOW;
else {
xasprintf(cause, "unknown option: %s", name); xasprintf(cause, "unknown option: %s", name);
return (OPTIONS_TABLE_NONE); return (OPTIONS_TABLE_NONE);
} }
scope = oe->scope;
if (scope == OPTIONS_TABLE_SERVER) switch (scope) {
case OPTIONS_TABLE_SERVER:
*oo = global_options; *oo = global_options;
else if (scope == OPTIONS_TABLE_SESSION) { break;
case OPTIONS_TABLE_SESSION:
if (args_has(args, 'g')) if (args_has(args, 'g'))
*oo = global_s_options; *oo = global_s_options;
else if (s == NULL) { else if (s == NULL && target != NULL)
if (target != NULL) xasprintf(cause, "no such session: %s", target);
xasprintf(cause, "no such session: %s", target); else if (s == NULL)
else xasprintf(cause, "no current session");
xasprintf(cause, "no current session"); else
} else
*oo = s->options; *oo = s->options;
} else if (scope == OPTIONS_TABLE_WINDOW) { break;
case OPTIONS_TABLE_WINDOW|OPTIONS_TABLE_PANE:
if (args_has(args, 'p')) {
if (wp == NULL && target != NULL)
xasprintf(cause, "no such pane: %s", target);
else if (wp == NULL)
xasprintf(cause, "no current pane");
else
*oo = wp->options;
break;
}
scope = OPTIONS_TABLE_WINDOW;
/* FALLTHROUGH */
case OPTIONS_TABLE_WINDOW:
if (args_has(args, 'g')) if (args_has(args, 'g'))
*oo = global_w_options; *oo = global_w_options;
else if (wl == NULL) { else if (wl == NULL && target != NULL)
if (target != NULL) xasprintf(cause, "no such window: %s", target);
xasprintf(cause, "no such window: %s", target); else if (wl == NULL)
else xasprintf(cause, "no current window");
xasprintf(cause, "no current window"); else
} else
*oo = wl->window->options; *oo = wl->window->options;
break;
} }
return (scope); return (scope);
} }
enum options_table_scope int
options_scope_from_flags(struct args *args, int window, options_scope_from_flags(struct args *args, int window,
struct cmd_find_state *fs, struct options **oo, char **cause) struct cmd_find_state *fs, struct options **oo, char **cause)
{ {
struct session *s = fs->s; struct session *s = fs->s;
struct winlink *wl = fs->wl; struct winlink *wl = fs->wl;
const char *target = args_get(args, 't'); struct window_pane *wp = fs->wp;
const char *target = args_get(args, 't');
if (args_has(args, 's')) { if (args_has(args, 's')) {
*oo = global_options; *oo = global_options;
return (OPTIONS_TABLE_SERVER); return (OPTIONS_TABLE_SERVER);
} }
if (window || args_has(args, 'w')) { if (args_has(args, 'p')) {
if (wp == NULL) {
if (target != NULL)
xasprintf(cause, "no such pane: %s", target);
else
xasprintf(cause, "no current pane");
return (OPTIONS_TABLE_NONE);
}
*oo = wp->options;
return (OPTIONS_TABLE_PANE);
} else if (window || args_has(args, 'w')) {
if (args_has(args, 'g')) { if (args_has(args, 'g')) {
*oo = global_w_options; *oo = global_w_options;
return (OPTIONS_TABLE_WINDOW); return (OPTIONS_TABLE_WINDOW);

View File

@ -308,7 +308,7 @@ server_destroy_pane(struct window_pane *wp, int notify)
wp->fd = -1; wp->fd = -1;
} }
if (options_get_number(w->options, "remain-on-exit")) { if (options_get_number(wp->options, "remain-on-exit")) {
if (~wp->flags & PANE_STATUSREADY) if (~wp->flags & PANE_STATUSREADY)
return; return;

255
tmux.1
View File

@ -881,7 +881,7 @@ refresh-client -t/dev/ttyp2
rename-session -tfirst newname rename-session -tfirst newname
set-window-option -t:0 monitor-activity on set-option -wt:0 monitor-activity on
new-window ; split-window -d new-window ; split-window -d
@ -2328,8 +2328,7 @@ applies the last set layout if possible (undoes the most recent layout change).
.Fl E .Fl E
spreads the current pane and any panes next to it out evenly. spreads the current pane and any panes next to it out evenly.
.It Xo Ic select-pane .It Xo Ic select-pane
.Op Fl DdegLlMmRU .Op Fl DdeLlMmRU
.Op Fl P Ar style
.Op Fl T Ar title .Op Fl T Ar title
.Op Fl t Ar target-pane .Op Fl t Ar target-pane
.Xc .Xc
@ -2356,6 +2355,8 @@ command.
enables or enables or
.Fl d .Fl d
disables input to the pane. disables input to the pane.
.Fl T
sets the pane title.
.Pp .Pp
.Fl m .Fl m
and and
@ -2370,25 +2371,6 @@ to
.Ic swap-pane .Ic swap-pane
and and
.Ic swap-window . .Ic swap-window .
.Pp
Each pane has a style: by default the
.Ic window-style
and
.Ic window-active-style
options are used,
.Ic select-pane
.Fl P
sets the style for a single pane.
For example, to set the pane 1 background to red:
.Bd -literal -offset indent
select-pane -t:.1 -P 'bg=red'
.Ed
.Pp
.Fl g
shows the current pane style.
.Pp
.Fl T
sets the pane title.
.It Xo Ic select-window .It Xo Ic select-window
.Op Fl lnpT .Op Fl lnpT
.Op Fl t Ar target-window .Op Fl t Ar target-window
@ -2707,16 +2689,17 @@ is present, all key bindings are removed.
The appearance and behaviour of The appearance and behaviour of
.Nm .Nm
may be modified by changing the value of various options. may be modified by changing the value of various options.
There are three types of option: There are four types of option:
.Em server options , .Em server options ,
.Em session options .Em session options
.Em window options
and and
.Em window options . .Em pane options .
.Pp .Pp
The The
.Nm .Nm
server has a set of global options which do not apply to any particular server has a set of global options which do not apply to any particular
window or session. window or session or pane.
These are altered with the These are altered with the
.Ic set-option .Ic set-option
.Fl s .Fl s
@ -2738,16 +2721,29 @@ The available server and session options are listed under the
.Ic set-option .Ic set-option
command. command.
.Pp .Pp
Similarly, a set of window options is attached to each window, and there is Similarly, a set of window options is attached to each window and a set of pane
a set of global window options from which any unset options are inherited. options to each pane.
Window options are altered with the Pane options inherit from window options.
.Ic set-window-option This means any pane option may be set as a window option to apply the option to
command and can be listed with the all panes in the window without the option set, for example these commands will
.Ic show-window-options set the background colour to red for all panes except pane 0:
command. .Bd -literal -offset indent
All window options are documented with the set -w window-style bg=red
.Ic set-window-option set -pt:.0 window-style bg=blue
command. .Ed
.Pp
There is also a set of global window options from which any unset window or
pane options are inherited.
Window and pane options are altered with
.Ic set-option
.Fl w
and
.Fl p
commands and displayed with
.Ic show-option
.Fl w
and
.Fl p .
.Pp .Pp
.Nm .Nm
also supports user options which are prefixed with a also supports user options which are prefixed with a
@ -2765,26 +2761,27 @@ abc123
Commands which set options are as follows: Commands which set options are as follows:
.Bl -tag -width Ds .Bl -tag -width Ds
.It Xo Ic set-option .It Xo Ic set-option
.Op Fl aFgoqsuw .Op Fl aFgopqsuw
.Op Fl t Ar target-session | Ar target-window .Op Fl t Ar target-pane
.Ar option Ar value .Ar option Ar value
.Xc .Xc
.D1 (alias: Ic set ) .D1 (alias: Ic set )
Set a window option with Set a pane option with
.Fl w .Fl p ,
(equivalent to the a window option with
.Ic set-window-option .Fl w ,
command),
a server option with a server option with
.Fl s , .Fl s ,
otherwise a session option. otherwise a session option.
If the option is not a user option, If the option is not a user option,
.Fl w .Fl w
and or
.Fl s .Fl s
are unnecessary - may be unnecessary -
.Nm .Nm
will infer the type from the option name. will infer the type from the option name, assuming
.Fl w
for pane options.
If If
.Fl g .Fl g
is given, the global session or window option is set. is given, the global session or window option is set.
@ -2829,13 +2826,49 @@ blue foreground.
Without Without
.Fl a , .Fl a ,
the result would be the default background and a blue foreground. the result would be the default background and a blue foreground.
.Pp .It Xo Ic show-options
Available window options are listed under .Op Fl AgHpqsvw
.Ic set-window-option . .Op Fl t Ar target-pane
.Pp .Op Ar option
.Xc
.D1 (alias: Ic show )
Show the pane options (or a single option if
.Ar option
is provided) with
.Fl p ,
the window options with
.Fl w ,
the server options with
.Fl s ,
otherwise the session options.
If the option is not a user option,
.Fl w
or
.Fl s
may be unnecessary -
.Nm
will infer the type from the option name, assuming
.Fl w
for pane options.
Global session or window options are listed if
.Fl g
is used.
.Fl v
shows only the option value, not the name.
If
.Fl q
is set, no error will be returned if
.Ar option
is unset.
.Fl H
includes hooks (omitted by default).
.Fl A
includes options inherited from a parent set of options, such options are
marked with an asterisk.
.Ar value .Ar value
depends on the option and may be a number, a string, or a flag (on, off, or depends on the option and may be a number, a string, or a flag (on, off, or
omitted to toggle). omitted to toggle).
.El
.Pp .Pp
Available server options are: Available server options are:
.Bl -tag -width Ds .Bl -tag -width Ds
@ -3362,26 +3395,8 @@ copy mode.
The default is The default is
.Ql \ -_@ . .Ql \ -_@ .
.El .El
.It Xo Ic set-window-option
.Op Fl aFgoqu
.Op Fl t Ar target-window
.Ar option Ar value
.Xc
.D1 (alias: Ic setw )
Set a window option.
The
.Fl a ,
.Fl F ,
.Fl g ,
.Fl o ,
.Fl q
and
.Fl u
flags work similarly to the
.Ic set-option
command.
.Pp .Pp
Supported window options are: Available window options are:
.Pp .Pp
.Bl -tag -width Ds -compact .Bl -tag -width Ds -compact
.It Xo Ic aggressive-resize .It Xo Ic aggressive-resize
@ -3441,7 +3456,7 @@ or later with
or with a terminal escape sequence. or with a terminal escape sequence.
It may be switched off globally with: It may be switched off globally with:
.Bd -literal -offset indent .Bd -literal -offset indent
set-window-option -g automatic-rename off set-option -wg automatic-rename off
.Ed .Ed
.Pp .Pp
.It Ic automatic-rename-format Ar format .It Ic automatic-rename-format Ar format
@ -3558,29 +3573,12 @@ see the
section. section.
Attributes are ignored. Attributes are ignored.
.Pp .Pp
.It Xo Ic remain-on-exit
.Op Ic on | off
.Xc
A window with this flag set is not destroyed when the program running in it
exits.
The window may be reactivated with the
.Ic respawn-window
command.
.Pp
.It Xo Ic synchronize-panes .It Xo Ic synchronize-panes
.Op Ic on | off .Op Ic on | off
.Xc .Xc
Duplicate input to any pane to all other panes in the same window (only Duplicate input to any pane to all other panes in the same window (only
for panes that are not in any special mode). for panes that are not in any special mode).
.Pp .Pp
.It Ic window-active-style Ar style
Set the style for the window's active pane.
For how to specify
.Ar style ,
see the
.Sx STYLES
section.
.Pp
.It Ic window-status-activity-style Ar style .It Ic window-status-activity-style Ar style
Set status line style for windows with an activity alert. Set status line style for windows with an activity alert.
For how to specify For how to specify
@ -3660,14 +3658,6 @@ command and the
.Ic aggressive-resize .Ic aggressive-resize
option. option.
.Pp .Pp
.It Ic window-style Ar style
Set the default window style.
For how to specify
.Ar style ,
see the
.Sx STYLES
section.
.Pp
.It Xo Ic wrap-search .It Xo Ic wrap-search
.Op Ic on | off .Op Ic on | off
.Xc .Xc
@ -3684,57 +3674,34 @@ will generate
function key sequences; these have a number included to indicate modifiers such function key sequences; these have a number included to indicate modifiers such
as Shift, Alt or Ctrl. as Shift, Alt or Ctrl.
.El .El
.It Xo Ic show-options .Pp
.Op Fl AgHqsvw Available pane options are:
.Op Fl t Ar target-session | Ar target-window .Pp
.Op Ar option .Bl -tag -width Ds -compact
.It Xo Ic remain-on-exit
.Op Ic on | off
.Xc .Xc
.D1 (alias: Ic show ) A pane with this flag set is not destroyed when the program running in it
Show the window options (or a single window option if given) with exits.
.Fl w The pane may be reactivated with the
(equivalent to .Ic respawn-pane
.Ic show-window-options ) , command.
the server options with .Pp
.Fl s , .It Ic window-active-style Ar style
otherwise the session options for Set the pane style when it is the active pane.
.Ar target session . For how to specify
If .Ar style ,
.Ar option see the
is given and is not a user option, .Sx STYLES
.Fl w section.
and .Pp
.Fl s .It Ic window-style Ar style
are unnecessary - Set the pane style.
.Nm For how to specify
will infer the type from the option name. .Ar style ,
Global session or window options are listed if see the
.Fl g .Sx STYLES
is used. section.
.Fl v
shows only the option value, not the name.
If
.Fl q
is set, no error will be returned if
.Ar option
is unset.
.Fl H
includes hooks (omitted by default).
.Fl A
includes options inherited from a parent set of options, such options are
marked with an asterisk.
.It Xo Ic show-window-options
.Op Fl gv
.Op Fl t Ar target-window
.Op Ar option
.Xc
.D1 (alias: Ic showw )
List the window options or a single option for
.Ar target-window ,
or the global window options if
.Fl g
is used.
.Fl v
shows only the option value, not the name.
.El .El
.Sh HOOKS .Sh HOOKS
.Nm .Nm

6
tmux.c
View File

@ -321,11 +321,11 @@ main(int argc, char **argv)
global_s_options = options_create(NULL); global_s_options = options_create(NULL);
global_w_options = options_create(NULL); global_w_options = options_create(NULL);
for (oe = options_table; oe->name != NULL; oe++) { for (oe = options_table; oe->name != NULL; oe++) {
if (oe->scope == OPTIONS_TABLE_SERVER) if (oe->scope & OPTIONS_TABLE_SERVER)
options_default(global_options, oe); options_default(global_options, oe);
if (oe->scope == OPTIONS_TABLE_SESSION) if (oe->scope & OPTIONS_TABLE_SESSION)
options_default(global_s_options, oe); options_default(global_s_options, oe);
if (oe->scope == OPTIONS_TABLE_WINDOW) if (oe->scope & OPTIONS_TABLE_WINDOW)
options_default(global_w_options, oe); options_default(global_w_options, oe);
} }

27
tmux.h
View File

@ -812,6 +812,7 @@ struct window_pane {
u_int active_point; u_int active_point;
struct window *window; struct window *window;
struct options *options;
struct layout_cell *layout_cell; struct layout_cell *layout_cell;
struct layout_cell *saved_layout_cell; struct layout_cell *saved_layout_cell;
@ -838,6 +839,7 @@ struct window_pane {
#define PANE_STATUSREADY 0x200 #define PANE_STATUSREADY 0x200
#define PANE_STATUSDRAWN 0x400 #define PANE_STATUSDRAWN 0x400
#define PANE_EMPTY 0x800 #define PANE_EMPTY 0x800
#define PANE_STYLECHANGED 0x1000
int argc; int argc;
char **argv; char **argv;
@ -856,7 +858,8 @@ struct window_pane {
struct input_ctx *ictx; struct input_ctx *ictx;
struct style style; struct style cached_style;
struct style cached_active_style;
int *palette; int *palette;
int pipe_fd; int pipe_fd;
@ -916,7 +919,6 @@ struct window {
#define WINDOW_ACTIVITY 0x2 #define WINDOW_ACTIVITY 0x2
#define WINDOW_SILENCE 0x4 #define WINDOW_SILENCE 0x4
#define WINDOW_ZOOMED 0x8 #define WINDOW_ZOOMED 0x8
#define WINDOW_STYLECHANGED 0x10
#define WINDOW_ALERTFLAGS (WINDOW_BELL|WINDOW_ACTIVITY|WINDOW_SILENCE) #define WINDOW_ALERTFLAGS (WINDOW_BELL|WINDOW_ACTIVITY|WINDOW_SILENCE)
int alerts_queued; int alerts_queued;
@ -924,9 +926,6 @@ struct window {
struct options *options; struct options *options;
struct style style;
struct style active_style;
u_int references; u_int references;
TAILQ_HEAD(, winlink) winlinks; TAILQ_HEAD(, winlink) winlinks;
@ -1607,12 +1606,11 @@ enum options_table_type {
OPTIONS_TABLE_COMMAND OPTIONS_TABLE_COMMAND
}; };
enum options_table_scope { #define OPTIONS_TABLE_NONE 0
OPTIONS_TABLE_NONE, #define OPTIONS_TABLE_SERVER 0x1
OPTIONS_TABLE_SERVER, #define OPTIONS_TABLE_SESSION 0x2
OPTIONS_TABLE_SESSION, #define OPTIONS_TABLE_WINDOW 0x4
OPTIONS_TABLE_WINDOW #define OPTIONS_TABLE_PANE 0x8
};
#define OPTIONS_TABLE_IS_ARRAY 0x1 #define OPTIONS_TABLE_IS_ARRAY 0x1
#define OPTIONS_TABLE_IS_HOOK 0x2 #define OPTIONS_TABLE_IS_HOOK 0x2
@ -1620,7 +1618,7 @@ enum options_table_scope {
struct options_table_entry { struct options_table_entry {
const char *name; const char *name;
enum options_table_type type; enum options_table_type type;
enum options_table_scope scope; int scope;
int flags; int flags;
u_int minimum; u_int minimum;
@ -1782,6 +1780,7 @@ void notify_pane(const char *, struct window_pane *);
/* options.c */ /* options.c */
struct options *options_create(struct options *); struct options *options_create(struct options *);
void options_free(struct options *); void options_free(struct options *);
void options_set_parent(struct options *, struct options *);
struct options_entry *options_first(struct options *); struct options_entry *options_first(struct options *);
struct options_entry *options_next(struct options_entry *); struct options_entry *options_next(struct options_entry *);
struct options_entry *options_empty(struct options *, struct options_entry *options_empty(struct options *,
@ -1821,10 +1820,10 @@ struct options_entry *options_set_number(struct options *, const char *,
long long); long long);
struct options_entry *options_set_style(struct options *, const char *, int, struct options_entry *options_set_style(struct options *, const char *, int,
const char *); const char *);
enum options_table_scope options_scope_from_name(struct args *, int, int options_scope_from_name(struct args *, int,
const char *, struct cmd_find_state *, struct options **, const char *, struct cmd_find_state *, struct options **,
char **); char **);
enum options_table_scope options_scope_from_flags(struct args *, int, int options_scope_from_flags(struct args *, int,
struct cmd_find_state *, struct options **, char **); struct cmd_find_state *, struct options **, char **);
/* options-table.c */ /* options-table.c */

44
tty.c
View File

@ -2132,7 +2132,7 @@ tty_attributes(struct tty *tty, const struct grid_cell *gc,
/* Ignore cell if it is the same as the last one. */ /* Ignore cell if it is the same as the last one. */
if (wp != NULL && if (wp != NULL &&
(int)wp->id == tty->last_wp && (int)wp->id == tty->last_wp &&
~(wp->window->flags & WINDOW_STYLECHANGED) && ~(wp->flags & PANE_STYLECHANGED) &&
gc->attr == tty->last_cell.attr && gc->attr == tty->last_cell.attr &&
gc->fg == tty->last_cell.fg && gc->fg == tty->last_cell.fg &&
gc->bg == tty->last_cell.bg) gc->bg == tty->last_cell.bg)
@ -2514,30 +2514,28 @@ fallback_256:
static void static void
tty_default_colours(struct grid_cell *gc, struct window_pane *wp) tty_default_colours(struct grid_cell *gc, struct window_pane *wp)
{ {
struct window *w = wp->window; struct options *oo = wp->options;
struct options *oo = w->options; struct style *style, *active_style;
struct style *active, *pane, *window; int c;
int c;
if (w->flags & WINDOW_STYLECHANGED) { if (wp->flags & PANE_STYLECHANGED) {
w->flags &= ~WINDOW_STYLECHANGED; wp->flags &= ~PANE_STYLECHANGED;
active = options_get_style(oo, "window-active-style");
style_copy(&w->active_style, active); active_style = options_get_style(oo, "window-active-style");
window = options_get_style(oo, "window-style"); style = options_get_style(oo, "window-style");
style_copy(&w->style, window);
style_copy(&wp->cached_active_style, active_style);
style_copy(&wp->cached_style, style);
} else { } else {
active = &w->active_style; active_style = &wp->cached_active_style;
window = &w->style; style = &wp->cached_style;
} }
pane = &wp->style;
if (gc->fg == 8) { if (gc->fg == 8) {
if (pane->gc.fg != 8) if (wp == wp->window->active && active_style->gc.fg != 8)
gc->fg = pane->gc.fg; gc->fg = active_style->gc.fg;
else if (wp == w->active && active->gc.fg != 8)
gc->fg = active->gc.fg;
else else
gc->fg = window->gc.fg; gc->fg = style->gc.fg;
if (gc->fg != 8) { if (gc->fg != 8) {
c = window_pane_get_palette(wp, gc->fg); c = window_pane_get_palette(wp, gc->fg);
@ -2547,12 +2545,10 @@ tty_default_colours(struct grid_cell *gc, struct window_pane *wp)
} }
if (gc->bg == 8) { if (gc->bg == 8) {
if (pane->gc.bg != 8) if (wp == wp->window->active && active_style->gc.bg != 8)
gc->bg = pane->gc.bg; gc->bg = active_style->gc.bg;
else if (wp == w->active && active->gc.bg != 8)
gc->bg = active->gc.bg;
else else
gc->bg = window->gc.bg; gc->bg = style->gc.bg;
if (gc->bg != 8) { if (gc->bg != 8) {
c = window_pane_get_palette(wp, gc->bg); c = window_pane_get_palette(wp, gc->bg);

View File

@ -311,7 +311,7 @@ window_create(u_int sx, u_int sy)
w = xcalloc(1, sizeof *w); w = xcalloc(1, sizeof *w);
w->name = NULL; w->name = NULL;
w->flags = WINDOW_STYLECHANGED; w->flags = 0;
TAILQ_INIT(&w->panes); TAILQ_INIT(&w->panes);
w->active = NULL; w->active = NULL;
@ -448,31 +448,37 @@ window_set_active_pane(struct window *w, struct window_pane *wp, int notify)
void void
window_redraw_active_switch(struct window *w, struct window_pane *wp) window_redraw_active_switch(struct window *w, struct window_pane *wp)
{ {
struct style *sy; struct style *sy1, *sy2;
int c1, c2;
if (wp == w->active) if (wp == w->active)
return; return;
/* for (;;) {
* If window-style and window-active-style are the same, we don't need /*
* to redraw panes when switching active panes. * If the active and inactive styles or palettes are different,
*/ * need to redraw the panes.
sy = options_get_style(w->options, "window-active-style"); */
if (style_equal(sy, options_get_style(w->options, "window-style"))) sy1 = &wp->cached_style;
return; sy2 = &wp->cached_active_style;
if (!style_equal(sy1, sy2))
/* wp->flags |= PANE_REDRAW;
* If the now active or inactive pane do not have a custom style or if else {
* the palette is different, they need to be redrawn. c1 = window_pane_get_palette(wp, sy1->gc.fg);
*/ c2 = window_pane_get_palette(wp, sy2->gc.fg);
if (window_pane_get_palette(w->active, w->active->style.gc.fg) != -1 || if (c1 != c2)
window_pane_get_palette(w->active, w->active->style.gc.bg) != -1 || wp->flags |= PANE_REDRAW;
style_is_default(&w->active->style)) else {
w->active->flags |= PANE_REDRAW; c1 = window_pane_get_palette(wp, sy1->gc.bg);
if (window_pane_get_palette(wp, wp->style.gc.fg) != -1 || c2 = window_pane_get_palette(wp, sy2->gc.bg);
window_pane_get_palette(wp, wp->style.gc.bg) != -1 || if (c1 != c2)
style_is_default(&wp->style)) wp->flags |= PANE_REDRAW;
wp->flags |= PANE_REDRAW; }
}
if (wp == w->active)
break;
wp = w->active;
}
} }
struct window_pane * struct window_pane *
@ -776,6 +782,8 @@ window_pane_create(struct window *w, u_int sx, u_int sy, u_int hlimit)
wp = xcalloc(1, sizeof *wp); wp = xcalloc(1, sizeof *wp);
wp->window = w; wp->window = w;
wp->options = options_create(w->options);
wp->flags = PANE_STYLECHANGED;
wp->id = next_window_pane_id++; wp->id = next_window_pane_id++;
RB_INSERT(window_pane_tree, &all_window_panes, wp); RB_INSERT(window_pane_tree, &all_window_panes, wp);
@ -806,8 +814,6 @@ window_pane_create(struct window *w, u_int sx, u_int sy, u_int hlimit)
wp->saved_cx = UINT_MAX; wp->saved_cx = UINT_MAX;
wp->saved_cy = UINT_MAX; wp->saved_cy = UINT_MAX;
style_set(&wp->style, &grid_default_cell);
screen_init(&wp->base, sx, sy, hlimit); screen_init(&wp->base, sx, sy, hlimit);
wp->screen = &wp->base; wp->screen = &wp->base;
@ -853,6 +859,7 @@ window_pane_destroy(struct window_pane *wp)
RB_REMOVE(window_pane_tree, &all_window_panes, wp); RB_REMOVE(window_pane_tree, &all_window_panes, wp);
options_free(wp->options);
free((void *)wp->cwd); free((void *)wp->cwd);
free(wp->shell); free(wp->shell);
cmd_free_argv(wp->argc, wp->argv); cmd_free_argv(wp->argc, wp->argv);