Add a per-pane option set. Pane options inherit from window options (so

there should be no change to existing behaviour) and are set and shown
with set-option -p and show-options -p.

Change remain-on-exit and window-style/window-active-style to be pane
options (some others will be changed later).

This makes select-pane -P and -g unnecessary so no longer document them
(they still work) and no longer document set-window-option and
show-window-options in favour of set-option -w and show-options -w.
pull/1805/head
nicm 2019-06-20 11:59:59 +00:00
parent c1ede507d9
commit 5f92f92908
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);
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);
w->active = wp;

View File

@ -140,6 +140,8 @@ cmd_join_pane_exec(struct cmd *self, struct cmdq_item *item)
TAILQ_REMOVE(&src_w->panes, src_wp, entry);
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);
layout_assign_pane(lc, src_wp);

View File

@ -33,8 +33,8 @@ const struct cmd_entry cmd_select_pane_entry = {
.name = "select-pane",
.alias = "selectp",
.args = { "DdegLlMmP:RT:t:U", 0, 0 },
.usage = "[-DdegLlMmRU] [-P style] [-T title] " CMD_TARGET_PANE_USAGE,
.args = { "DdegLlMmP:RT:t:U", 0, 0 }, /* -P and -g deprecated */
.usage = "[-DdeLlMmRU] [-T title] " CMD_TARGET_PANE_USAGE,
.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 session *s = item->target.s;
struct window_pane *wp = item->target.wp, *lastwp, *markedwp;
struct style *sy = &wp->style;
char *pane_title;
const char *style;
struct style *sy;
struct options_entry *o;
if (self->entry == &cmd_last_pane_entry || args_has(args, 'l')) {
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 ((style = args_get(args, 'P')) != NULL) {
style_set(sy, &grid_default_cell);
if (style_parse(sy, &grid_default_cell, style) == -1) {
o = options_set_style(wp->options, "window-style", 0,
style);
if (o == NULL) {
cmdq_error(item, "bad style: %s", style);
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));
}
return (CMD_RETURN_NORMAL);
}

View File

@ -43,10 +43,10 @@ const struct cmd_entry cmd_set_option_entry = {
.name = "set-option",
.alias = "set",
.args = { "aFgoqst:uw", 1, 2 },
.usage = "[-aFgosquw] [-t target-window] option [value]",
.args = { "aFgopqst:uw", 1, 2 },
.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,
.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 winlink *wl = fs->wl;
struct window *w;
enum options_table_scope scope;
struct window_pane *wp;
struct options *oo;
struct options_entry *parent, *o;
char *name, *argument, *value = NULL, *cause;
int window, idx, already, error, ambiguous;
int scope;
struct style *sy;
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();
if (strcmp(name, "window-style") == 0 ||
strcmp(name, "window-active-style") == 0) {
RB_FOREACH(w, windows, &windows)
w->flags |= WINDOW_STYLECHANGED;
RB_FOREACH(wp, window_pane_tree, &all_window_panes)
wp->flags |= PANE_STYLECHANGED;
}
if (strcmp(name, "pane-border-status") == 0) {
RB_FOREACH(w, windows, &windows)

View File

@ -33,16 +33,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 *,
struct options_entry *, int, int);
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 = {
.name = "show-options",
.alias = "show",
.args = { "AgHqst:vw", 0, 1 },
.usage = "[-AgHqsvw] [-t target-session|target-window] [option]",
.args = { "AgHpqst:vw", 0, 1 },
.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,
.exec = cmd_show_options_exec
@ -83,9 +83,8 @@ cmd_show_options_exec(struct cmd *self, struct cmdq_item *item)
struct session *s = item->target.s;
struct winlink *wl = item->target.wl;
struct options *oo;
enum options_table_scope scope;
char *argument, *name = NULL, *cause;
int window, idx, ambiguous, parent;
int window, idx, ambiguous, parent, scope;
struct options_entry *o;
window = (self->entry == &cmd_show_window_options_entry);
@ -191,17 +190,18 @@ cmd_show_options_print(struct cmd *self, struct cmdq_item *item,
}
static enum cmd_retval
cmd_show_options_all(struct cmd *self, struct cmdq_item *item,
enum options_table_scope scope, struct options *oo)
cmd_show_options_all(struct cmd *self, struct cmdq_item *item, int scope,
struct options *oo)
{
const struct options_table_entry *oe;
struct options_entry *o;
struct options_array_item *a;
const char *name;
u_int idx;
int parent;
for (oe = options_table; oe->name != NULL; oe++) {
if (oe->scope != scope)
if (~oe->scope & scope)
continue;
if ((self->entry != &cmd_show_hooks_entry &&
@ -228,15 +228,17 @@ cmd_show_options_all(struct cmd *self, struct cmdq_item *item,
cmd_show_options_print(self, item, o, -1, parent);
else if ((a = options_array_first(o)) == NULL) {
if (!args_has(self->args, 'v')) {
name = options_name(o);
if (parent)
cmdq_print(item, "%s*", options_name(o));
cmdq_print(item, "%s*", name);
else
cmdq_print(item, "%s", options_name(o));
cmdq_print(item, "%s", name);
}
} else {
while (a != NULL) {
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);
}
}

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->window = dst_w;
options_set_parent(src_wp->options, dst_w->options);
src_wp->flags |= PANE_STYLECHANGED;
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;
xoff = src_wp->xoff; yoff = src_wp->yoff;

View File

@ -1052,6 +1052,8 @@ format_find(struct format_tree *ft, const char *key, int modifiers)
if (~modifiers & FORMAT_TIMESTRING) {
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)
o = options_parse_get(ft->w->options, key, &idx, 0);
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;
u_int r, g, b;
char tmp[16];
if (sscanf(p, "rgb:%2x/%2x/%2x", &r, &g, &b) != 3)
goto bad;
wp->style.gc.fg = colour_join_rgb(r, g, b);
wp->flags |= PANE_REDRAW;
xsnprintf(tmp, sizeof tmp, "fg=#%02x%02x%02x", r, g, b);
options_set_style(wp->options, "window-style", 1, tmp);
options_set_style(wp->options, "window-active-style", 1, tmp);
wp->flags |= (PANE_REDRAW|PANE_STYLECHANGED);
return;
@ -2366,12 +2368,14 @@ input_osc_11(struct input_ctx *ictx, const char *p)
{
struct window_pane *wp = ictx->wp;
u_int r, g, b;
char tmp[16];
if (sscanf(p, "rgb:%2x/%2x/%2x", &r, &g, &b) != 3)
goto bad;
wp->style.gc.bg = colour_join_rgb(r, g, b);
wp->flags |= PANE_REDRAW;
xsnprintf(tmp, sizeof tmp, "bg=#%02x%02x%02x", r, g, b);
options_set_style(wp->options, "window-style", 1, tmp);
options_set_style(wp->options, "window-active-style", 1, tmp);
wp->flags |= (PANE_REDRAW|PANE_STYLECHANGED);
return;

View File

@ -700,7 +700,7 @@ const struct options_table_entry options_table[] = {
{ .name = "remain-on-exit",
.type = OPTIONS_TABLE_FLAG,
.scope = OPTIONS_TABLE_WINDOW,
.scope = OPTIONS_TABLE_WINDOW|OPTIONS_TABLE_PANE,
.default_num = 0
},
@ -712,7 +712,7 @@ const struct options_table_entry options_table[] = {
{ .name = "window-active-style",
.type = OPTIONS_TABLE_STYLE,
.scope = OPTIONS_TABLE_WINDOW,
.scope = OPTIONS_TABLE_WINDOW|OPTIONS_TABLE_PANE,
.default_str = "default"
},
@ -725,7 +725,7 @@ const struct options_table_entry options_table[] = {
{ .name = "window-style",
.type = OPTIONS_TABLE_STYLE,
.scope = OPTIONS_TABLE_WINDOW,
.scope = OPTIONS_TABLE_WINDOW|OPTIONS_TABLE_PANE,
.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)
fatalx("no parent options for %s", s);
o = options_get_only(oo->parent, s);
o = options_get(oo->parent, s);
if (o == NULL)
fatalx("%s not in parent options", s);
return (o->tableentry);
@ -178,6 +178,12 @@ options_free(struct options *oo)
free(oo);
}
void
options_set_parent(struct options *oo, struct options *parent)
{
oo->parent = parent;
}
struct options_entry *
options_first(struct options *oo)
{
@ -545,7 +551,7 @@ options_parse_get(struct options *oo, const char *s, int *idx, int only)
}
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;
char *name;
@ -725,70 +731,96 @@ options_set_style(struct options *oo, const char *name, int append,
return (o);
}
enum options_table_scope
int
options_scope_from_name(struct args *args, int window,
const char *name, struct cmd_find_state *fs, struct options **oo,
char **cause)
{
struct session *s = fs->s;
struct winlink *wl = fs->wl;
const char *target = args_get(args, 't');
enum options_table_scope scope;
struct session *s = fs->s;
struct winlink *wl = fs->wl;
struct window_pane *wp = fs->wp;
const char *target = args_get(args, 't');
const struct options_table_entry *oe;
int scope;
if (*name == '@')
return (options_scope_from_flags(args, window, fs, oo, cause));
if (options_get_only(global_options, name) != NULL)
scope = OPTIONS_TABLE_SERVER;
else if (options_get_only(global_s_options, name) != NULL)
scope = OPTIONS_TABLE_SESSION;
else if (options_get_only(global_w_options, name) != NULL)
scope = OPTIONS_TABLE_WINDOW;
else {
for (oe = options_table; oe->name != NULL; oe++) {
if (strcmp(oe->name, name) == 0)
break;
}
if (oe->name == NULL) {
xasprintf(cause, "unknown option: %s", name);
return (OPTIONS_TABLE_NONE);
}
scope = oe->scope;
if (scope == OPTIONS_TABLE_SERVER)
switch (scope) {
case OPTIONS_TABLE_SERVER:
*oo = global_options;
else if (scope == OPTIONS_TABLE_SESSION) {
break;
case OPTIONS_TABLE_SESSION:
if (args_has(args, 'g'))
*oo = global_s_options;
else if (s == NULL) {
if (target != NULL)
xasprintf(cause, "no such session: %s", target);
else
xasprintf(cause, "no current session");
} else
else if (s == NULL && target != NULL)
xasprintf(cause, "no such session: %s", target);
else if (s == NULL)
xasprintf(cause, "no current session");
else
*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'))
*oo = global_w_options;
else if (wl == NULL) {
if (target != NULL)
xasprintf(cause, "no such window: %s", target);
else
xasprintf(cause, "no current window");
} else
else if (wl == NULL && target != NULL)
xasprintf(cause, "no such window: %s", target);
else if (wl == NULL)
xasprintf(cause, "no current window");
else
*oo = wl->window->options;
break;
}
return (scope);
}
enum options_table_scope
int
options_scope_from_flags(struct args *args, int window,
struct cmd_find_state *fs, struct options **oo, char **cause)
{
struct session *s = fs->s;
struct winlink *wl = fs->wl;
const char *target = args_get(args, 't');
struct session *s = fs->s;
struct winlink *wl = fs->wl;
struct window_pane *wp = fs->wp;
const char *target = args_get(args, 't');
if (args_has(args, 's')) {
*oo = global_options;
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')) {
*oo = global_w_options;
return (OPTIONS_TABLE_WINDOW);

View File

@ -307,7 +307,7 @@ server_destroy_pane(struct window_pane *wp, int notify)
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)
return;

255
tmux.1
View File

@ -876,7 +876,7 @@ refresh-client -t/dev/ttyp2
rename-session -tfirst newname
set-window-option -t:0 monitor-activity on
set-option -wt:0 monitor-activity on
new-window ; split-window -d
@ -2323,8 +2323,7 @@ applies the last set layout if possible (undoes the most recent layout change).
.Fl E
spreads the current pane and any panes next to it out evenly.
.It Xo Ic select-pane
.Op Fl DdegLlMmRU
.Op Fl P Ar style
.Op Fl DdeLlMmRU
.Op Fl T Ar title
.Op Fl t Ar target-pane
.Xc
@ -2351,6 +2350,8 @@ command.
enables or
.Fl d
disables input to the pane.
.Fl T
sets the pane title.
.Pp
.Fl m
and
@ -2365,25 +2366,6 @@ to
.Ic swap-pane
and
.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
.Op Fl lnpT
.Op Fl t Ar target-window
@ -2702,16 +2684,17 @@ is present, all key bindings are removed.
The appearance and behaviour of
.Nm
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 session options
.Em window options
and
.Em window options .
.Em pane options .
.Pp
The
.Nm
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
.Ic set-option
.Fl s
@ -2733,16 +2716,29 @@ The available server and session options are listed under the
.Ic set-option
command.
.Pp
Similarly, a set of window options is attached to each window, and there is
a set of global window options from which any unset options are inherited.
Window options are altered with the
.Ic set-window-option
command and can be listed with the
.Ic show-window-options
command.
All window options are documented with the
.Ic set-window-option
command.
Similarly, a set of window options is attached to each window and a set of pane
options to each pane.
Pane options inherit from window options.
This means any pane option may be set as a window option to apply the option to
all panes in the window without the option set, for example these commands will
set the background colour to red for all panes except pane 0:
.Bd -literal -offset indent
set -w window-style bg=red
set -pt:.0 window-style bg=blue
.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
.Nm
also supports user options which are prefixed with a
@ -2760,26 +2756,27 @@ abc123
Commands which set options are as follows:
.Bl -tag -width Ds
.It Xo Ic set-option
.Op Fl aFgoqsuw
.Op Fl t Ar target-session | Ar target-window
.Op Fl aFgopqsuw
.Op Fl t Ar target-pane
.Ar option Ar value
.Xc
.D1 (alias: Ic set )
Set a window option with
.Fl w
(equivalent to the
.Ic set-window-option
command),
Set a pane option with
.Fl p ,
a window option with
.Fl w ,
a server option with
.Fl s ,
otherwise a session option.
If the option is not a user option,
.Fl w
and
or
.Fl s
are unnecessary -
may be unnecessary -
.Nm
will infer the type from the option name.
will infer the type from the option name, assuming
.Fl w
for pane options.
If
.Fl g
is given, the global session or window option is set.
@ -2824,13 +2821,49 @@ blue foreground.
Without
.Fl a ,
the result would be the default background and a blue foreground.
.Pp
Available window options are listed under
.Ic set-window-option .
.Pp
.It Xo Ic show-options
.Op Fl AgHpqsvw
.Op Fl t Ar target-pane
.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
depends on the option and may be a number, a string, or a flag (on, off, or
omitted to toggle).
.El
.Pp
Available server options are:
.Bl -tag -width Ds
@ -3357,26 +3390,8 @@ copy mode.
The default is
.Ql \ -_@ .
.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
Supported window options are:
Available window options are:
.Pp
.Bl -tag -width Ds -compact
.It Xo Ic aggressive-resize
@ -3436,7 +3451,7 @@ or later with
or with a terminal escape sequence.
It may be switched off globally with:
.Bd -literal -offset indent
set-window-option -g automatic-rename off
set-option -wg automatic-rename off
.Ed
.Pp
.It Ic automatic-rename-format Ar format
@ -3553,29 +3568,12 @@ see the
section.
Attributes are ignored.
.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
.Op Ic on | off
.Xc
Duplicate input to any pane to all other panes in the same window (only
for panes that are not in any special mode).
.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
Set status line style for windows with an activity alert.
For how to specify
@ -3655,14 +3653,6 @@ command and the
.Ic aggressive-resize
option.
.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
.Op Ic on | off
.Xc
@ -3679,57 +3669,34 @@ will generate
function key sequences; these have a number included to indicate modifiers such
as Shift, Alt or Ctrl.
.El
.It Xo Ic show-options
.Op Fl AgHqsvw
.Op Fl t Ar target-session | Ar target-window
.Op Ar option
.Pp
Available pane options are:
.Pp
.Bl -tag -width Ds -compact
.It Xo Ic remain-on-exit
.Op Ic on | off
.Xc
.D1 (alias: Ic show )
Show the window options (or a single window option if given) with
.Fl w
(equivalent to
.Ic show-window-options ) ,
the server options with
.Fl s ,
otherwise the session options for
.Ar target session .
If
.Ar option
is given and is not a user option,
.Fl w
and
.Fl s
are unnecessary -
.Nm
will infer the type from the option name.
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.
.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.
A pane with this flag set is not destroyed when the program running in it
exits.
The pane may be reactivated with the
.Ic respawn-pane
command.
.Pp
.It Ic window-active-style Ar style
Set the pane style when it is the active pane.
For how to specify
.Ar style ,
see the
.Sx STYLES
section.
.Pp
.It Ic window-style Ar style
Set the pane style.
For how to specify
.Ar style ,
see the
.Sx STYLES
section.
.El
.Sh HOOKS
.Nm

6
tmux.c
View File

@ -321,11 +321,11 @@ main(int argc, char **argv)
global_s_options = options_create(NULL);
global_w_options = options_create(NULL);
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);
if (oe->scope == OPTIONS_TABLE_SESSION)
if (oe->scope & OPTIONS_TABLE_SESSION)
options_default(global_s_options, oe);
if (oe->scope == OPTIONS_TABLE_WINDOW)
if (oe->scope & OPTIONS_TABLE_WINDOW)
options_default(global_w_options, oe);
}

27
tmux.h
View File

@ -810,6 +810,7 @@ struct window_pane {
u_int active_point;
struct window *window;
struct options *options;
struct layout_cell *layout_cell;
struct layout_cell *saved_layout_cell;
@ -836,6 +837,7 @@ struct window_pane {
#define PANE_STATUSREADY 0x200
#define PANE_STATUSDRAWN 0x400
#define PANE_EMPTY 0x800
#define PANE_STYLECHANGED 0x1000
int argc;
char **argv;
@ -854,7 +856,8 @@ struct window_pane {
struct input_ctx *ictx;
struct style style;
struct style cached_style;
struct style cached_active_style;
int *palette;
int pipe_fd;
@ -914,7 +917,6 @@ struct window {
#define WINDOW_ACTIVITY 0x2
#define WINDOW_SILENCE 0x4
#define WINDOW_ZOOMED 0x8
#define WINDOW_STYLECHANGED 0x10
#define WINDOW_ALERTFLAGS (WINDOW_BELL|WINDOW_ACTIVITY|WINDOW_SILENCE)
int alerts_queued;
@ -922,9 +924,6 @@ struct window {
struct options *options;
struct style style;
struct style active_style;
u_int references;
TAILQ_HEAD(, winlink) winlinks;
@ -1605,12 +1604,11 @@ enum options_table_type {
OPTIONS_TABLE_COMMAND
};
enum options_table_scope {
OPTIONS_TABLE_NONE,
OPTIONS_TABLE_SERVER,
OPTIONS_TABLE_SESSION,
OPTIONS_TABLE_WINDOW
};
#define OPTIONS_TABLE_NONE 0
#define OPTIONS_TABLE_SERVER 0x1
#define OPTIONS_TABLE_SESSION 0x2
#define OPTIONS_TABLE_WINDOW 0x4
#define OPTIONS_TABLE_PANE 0x8
#define OPTIONS_TABLE_IS_ARRAY 0x1
#define OPTIONS_TABLE_IS_HOOK 0x2
@ -1618,7 +1616,7 @@ enum options_table_scope {
struct options_table_entry {
const char *name;
enum options_table_type type;
enum options_table_scope scope;
int scope;
int flags;
u_int minimum;
@ -1780,6 +1778,7 @@ void notify_pane(const char *, struct window_pane *);
/* options.c */
struct options *options_create(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_next(struct options_entry *);
struct options_entry *options_empty(struct options *,
@ -1819,10 +1818,10 @@ struct options_entry *options_set_number(struct options *, const char *,
long long);
struct options_entry *options_set_style(struct options *, const char *, int,
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 **,
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 **);
/* 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. */
if (wp != NULL &&
(int)wp->id == tty->last_wp &&
~(wp->window->flags & WINDOW_STYLECHANGED) &&
~(wp->flags & PANE_STYLECHANGED) &&
gc->attr == tty->last_cell.attr &&
gc->fg == tty->last_cell.fg &&
gc->bg == tty->last_cell.bg)
@ -2514,30 +2514,28 @@ fallback_256:
static void
tty_default_colours(struct grid_cell *gc, struct window_pane *wp)
{
struct window *w = wp->window;
struct options *oo = w->options;
struct style *active, *pane, *window;
int c;
struct options *oo = wp->options;
struct style *style, *active_style;
int c;
if (w->flags & WINDOW_STYLECHANGED) {
w->flags &= ~WINDOW_STYLECHANGED;
active = options_get_style(oo, "window-active-style");
style_copy(&w->active_style, active);
window = options_get_style(oo, "window-style");
style_copy(&w->style, window);
if (wp->flags & PANE_STYLECHANGED) {
wp->flags &= ~PANE_STYLECHANGED;
active_style = options_get_style(oo, "window-active-style");
style = options_get_style(oo, "window-style");
style_copy(&wp->cached_active_style, active_style);
style_copy(&wp->cached_style, style);
} else {
active = &w->active_style;
window = &w->style;
active_style = &wp->cached_active_style;
style = &wp->cached_style;
}
pane = &wp->style;
if (gc->fg == 8) {
if (pane->gc.fg != 8)
gc->fg = pane->gc.fg;
else if (wp == w->active && active->gc.fg != 8)
gc->fg = active->gc.fg;
if (wp == wp->window->active && active_style->gc.fg != 8)
gc->fg = active_style->gc.fg;
else
gc->fg = window->gc.fg;
gc->fg = style->gc.fg;
if (gc->fg != 8) {
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 (pane->gc.bg != 8)
gc->bg = pane->gc.bg;
else if (wp == w->active && active->gc.bg != 8)
gc->bg = active->gc.bg;
if (wp == wp->window->active && active_style->gc.bg != 8)
gc->bg = active_style->gc.bg;
else
gc->bg = window->gc.bg;
gc->bg = style->gc.bg;
if (gc->bg != 8) {
c = window_pane_get_palette(wp, gc->bg);

View File

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