From 945339b443affdaaca260605e15b5a3b9a3c6e16 Mon Sep 17 00:00:00 2001 From: nicm Date: Tue, 28 Jan 2014 23:07:09 +0000 Subject: [PATCH] Allow replacing each of the many sets of separate foo-{fg,bg,attr} options with a single foo-style option. For example: set -g status-fg yellow set -g status-bg red set -g status-attr blink Becomes: set -g status-style fg=yellow,bg=red,blink The -a flag to set can be used to add to rather than replace a style. So: set -g status-bg red Becomes: set -ag status-style bg=red Currently this is fully backwards compatible (all *-{fg,bg,attr} options remain) but the plan is to deprecate them over time. From Tiago Cunha. --- Makefile | 1 + cmd-set-option.c | 28 +++++ grid.c | 1 - options-table.c | 269 +++++++++++++++++++++++++++++----------- options.c | 36 ++++++ screen-redraw.c | 20 +-- screen-write.c | 85 +------------ status.c | 118 +++--------------- style.c | 224 ++++++++++++++++++++++++++++++++++ tmux.1 | 310 ++++++++++++++++++++++++++--------------------- tmux.h | 36 ++++-- tty.c | 3 +- window-choose.c | 4 +- window-copy.c | 4 +- window.c | 10 -- 15 files changed, 710 insertions(+), 439 deletions(-) create mode 100644 style.c diff --git a/Makefile b/Makefile index a0736bdf..e566bb2a 100644 --- a/Makefile +++ b/Makefile @@ -113,6 +113,7 @@ SRCS= arguments.c \ session.c \ signal.c \ status.c \ + style.c \ tmux.c \ tty-acs.c \ tty-keys.c \ diff --git a/cmd-set-option.c b/cmd-set-option.c index 1b25fac0..b661913f 100644 --- a/cmd-set-option.c +++ b/cmd-set-option.c @@ -60,6 +60,9 @@ struct options_entry *cmd_set_option_flag(struct cmd *, struct cmd_q *, struct options_entry *cmd_set_option_choice(struct cmd *, struct cmd_q *, const struct options_table_entry *, struct options *, const char *); +struct options_entry *cmd_set_option_style(struct cmd *, struct cmd_q *, + const struct options_table_entry *, struct options *, + const char *); const struct cmd_entry cmd_set_option_entry = { "set-option", "set", @@ -304,9 +307,11 @@ cmd_set_option_set(struct cmd *self, struct cmd_q *cmdq, break; case OPTIONS_TABLE_COLOUR: o = cmd_set_option_colour(self, cmdq, oe, oo, value); + style_update_new(oo, o->name, oe->style); break; case OPTIONS_TABLE_ATTRIBUTES: o = cmd_set_option_attributes(self, cmdq, oe, oo, value); + style_update_new(oo, o->name, oe->style); break; case OPTIONS_TABLE_FLAG: o = cmd_set_option_flag(self, cmdq, oe, oo, value); @@ -314,6 +319,9 @@ cmd_set_option_set(struct cmd *self, struct cmd_q *cmdq, case OPTIONS_TABLE_CHOICE: o = cmd_set_option_choice(self, cmdq, oe, oo, value); break; + case OPTIONS_TABLE_STYLE: + o = cmd_set_option_style(self, cmdq, oe, oo, value); + break; } if (o == NULL) return (-1); @@ -462,3 +470,23 @@ cmd_set_option_choice(unused struct cmd *self, struct cmd_q *cmdq, return (options_set_number(oo, oe->name, choice)); } + +/* Set a style option. */ +struct options_entry * +cmd_set_option_style(struct cmd *self, struct cmd_q *cmdq, + const struct options_table_entry *oe, struct options *oo, + const char *value) +{ + struct args *args = self->args; + struct options_entry *o; + int append; + + append = args_has(args, 'a'); + if ((o = options_set_style(oo, oe->name, value, append)) == NULL) { + cmdq_error(cmdq, "bad style: %s", value); + return (NULL); + } + + style_update_old(oo, oe->name, &o->style); + return (o); +} diff --git a/grid.c b/grid.c index 852423b5..fb838adf 100644 --- a/grid.c +++ b/grid.c @@ -37,7 +37,6 @@ /* Default grid cell data. */ const struct grid_cell grid_default_cell = { 0, 0, 8, 8, (1 << 4) | 1, " " }; -const struct grid_cell grid_marker_cell = { 0, 0, 8, 8, (1 << 4) | 1, "_" }; #define grid_put_cell(gd, px, py, gc) do { \ memcpy(&gd->linedata[py].celldata[px], \ diff --git a/options-table.c b/options-table.c index 97ca90be..4480b344 100644 --- a/options-table.c +++ b/options-table.c @@ -196,32 +196,43 @@ const struct options_table_entry session_options_table[] = { { .name = "message-attr", .type = OPTIONS_TABLE_ATTRIBUTES, - .default_num = 0 + .default_num = 0, + .style = "message-style" }, { .name = "message-bg", .type = OPTIONS_TABLE_COLOUR, - .default_num = 3 + .default_num = 3, + .style = "message-style" }, { .name = "message-command-attr", .type = OPTIONS_TABLE_ATTRIBUTES, - .default_num = 0 + .default_num = 0, + .style = "message-command-style" }, { .name = "message-command-bg", .type = OPTIONS_TABLE_COLOUR, - .default_num = 0 + .default_num = 0, + .style = "message-command-style" }, { .name = "message-command-fg", .type = OPTIONS_TABLE_COLOUR, - .default_num = 3 + .default_num = 3, + .style = "message-command-style" + }, + + { .name = "message-command-style", + .type = OPTIONS_TABLE_STYLE, + .default_str = "bg=black,fg=yellow" }, { .name = "message-fg", .type = OPTIONS_TABLE_COLOUR, - .default_num = 0 + .default_num = 0, + .style = "message-style" }, { .name = "message-limit", @@ -231,6 +242,11 @@ const struct options_table_entry session_options_table[] = { .default_num = 20 }, + { .name = "message-style", + .type = OPTIONS_TABLE_STYLE, + .default_str = "bg=yellow,fg=black" + }, + { .name = "mouse-resize-pane", .type = OPTIONS_TABLE_FLAG, .default_num = 0 @@ -253,22 +269,36 @@ const struct options_table_entry session_options_table[] = { { .name = "pane-active-border-bg", .type = OPTIONS_TABLE_COLOUR, - .default_num = 8 + .default_num = 8, + .style = "pane-active-border-style" }, { .name = "pane-active-border-fg", .type = OPTIONS_TABLE_COLOUR, - .default_num = 2 + .default_num = 2, + .style = "pane-active-border-style" + }, + + { .name = "pane-active-border-style", + .type = OPTIONS_TABLE_STYLE, + .default_str = "fg=green" }, { .name = "pane-border-bg", .type = OPTIONS_TABLE_COLOUR, - .default_num = 8 + .default_num = 8, + .style = "pane-border-style" }, { .name = "pane-border-fg", .type = OPTIONS_TABLE_COLOUR, - .default_num = 8 + .default_num = 8, + .style = "pane-border-style" + }, + + { .name = "pane-border-style", + .type = OPTIONS_TABLE_STYLE, + .default_str = "default" }, { .name = "prefix", @@ -315,17 +345,20 @@ const struct options_table_entry session_options_table[] = { { .name = "status-attr", .type = OPTIONS_TABLE_ATTRIBUTES, - .default_num = 0 + .default_num = 0, + .style = "status-style" }, { .name = "status-bg", .type = OPTIONS_TABLE_COLOUR, - .default_num = 2 + .default_num = 2, + .style = "status-style" }, { .name = "status-fg", .type = OPTIONS_TABLE_COLOUR, - .default_num = 0 + .default_num = 0, + .style = "status-style" }, { .name = "status-interval", @@ -354,17 +387,20 @@ const struct options_table_entry session_options_table[] = { { .name = "status-left-attr", .type = OPTIONS_TABLE_ATTRIBUTES, - .default_num = 0 + .default_num = 0, + .style = "status-left-style" }, { .name = "status-left-bg", .type = OPTIONS_TABLE_COLOUR, - .default_num = 8 + .default_num = 8, + .style = "status-left-style" }, { .name = "status-left-fg", .type = OPTIONS_TABLE_COLOUR, - .default_num = 8 + .default_num = 8, + .style = "status-left-style" }, { .name = "status-left-length", @@ -374,6 +410,11 @@ const struct options_table_entry session_options_table[] = { .default_num = 10 }, + { .name = "status-left-style", + .type = OPTIONS_TABLE_STYLE, + .default_str = "default" + }, + { .name = "status-position", .type = OPTIONS_TABLE_CHOICE, .choices = options_table_status_position_list, @@ -387,17 +428,20 @@ const struct options_table_entry session_options_table[] = { { .name = "status-right-attr", .type = OPTIONS_TABLE_ATTRIBUTES, - .default_num = 0 + .default_num = 0, + .style = "status-right-style" }, { .name = "status-right-bg", .type = OPTIONS_TABLE_COLOUR, - .default_num = 8 + .default_num = 8, + .style = "status-right-style" }, { .name = "status-right-fg", .type = OPTIONS_TABLE_COLOUR, - .default_num = 8 + .default_num = 8, + .style = "status-right-style" }, { .name = "status-right-length", @@ -407,6 +451,16 @@ const struct options_table_entry session_options_table[] = { .default_num = 40 }, + { .name = "status-right-style", + .type = OPTIONS_TABLE_STYLE, + .default_str = "default" + }, + + { .name = "status-style", + .type = OPTIONS_TABLE_STYLE, + .default_str = "bg=green,fg=black" + }, + { .name = "status-utf8", .type = OPTIONS_TABLE_FLAG, .default_num = 0 /* overridden in main() */ @@ -537,17 +591,20 @@ const struct options_table_entry window_options_table[] = { { .name = "mode-attr", .type = OPTIONS_TABLE_ATTRIBUTES, - .default_num = 0 + .default_num = 0, + .style = "mode-style" }, { .name = "mode-bg", .type = OPTIONS_TABLE_COLOUR, - .default_num = 3 + .default_num = 3, + .style = "mode-style" }, { .name = "mode-fg", .type = OPTIONS_TABLE_COLOUR, - .default_num = 0 + .default_num = 0, + .style = "mode-style" }, { .name = "mode-keys", @@ -562,6 +619,11 @@ const struct options_table_entry window_options_table[] = { .default_num = 0 }, + { .name = "mode-style", + .type = OPTIONS_TABLE_STYLE, + .default_str = "bg=yellow,fg=black" + }, + { .name = "monitor-activity", .type = OPTIONS_TABLE_FLAG, .default_num = 0 @@ -617,72 +679,101 @@ const struct options_table_entry window_options_table[] = { { .name = "window-status-activity-attr", .type = OPTIONS_TABLE_ATTRIBUTES, - .default_num = GRID_ATTR_REVERSE + .default_num = GRID_ATTR_REVERSE, + .style = "window-status-activity-style" }, { .name = "window-status-activity-bg", .type = OPTIONS_TABLE_COLOUR, - .default_num = 8 + .default_num = 8, + .style = "window-status-activity-style" }, { .name = "window-status-activity-fg", .type = OPTIONS_TABLE_COLOUR, - .default_num = 8 + .default_num = 8, + .style = "window-status-activity-style" }, - { .name = "window-status-bell-attr", - .type = OPTIONS_TABLE_ATTRIBUTES, - .default_num = GRID_ATTR_REVERSE - }, - - { .name = "window-status-bell-bg", - .type = OPTIONS_TABLE_COLOUR, - .default_num = 8 - }, - - { .name = "window-status-bell-fg", - .type = OPTIONS_TABLE_COLOUR, - .default_num = 8 - }, - - { .name = "window-status-content-attr", - .type = OPTIONS_TABLE_ATTRIBUTES, - .default_num = GRID_ATTR_REVERSE - }, - - { .name = "window-status-content-bg", - .type = OPTIONS_TABLE_COLOUR, - .default_num = 8 - }, - - { .name = "window-status-content-fg", - .type = OPTIONS_TABLE_COLOUR, - .default_num = 8 + { .name = "window-status-activity-style", + .type = OPTIONS_TABLE_STYLE, + .default_str = "reverse" }, { .name = "window-status-attr", .type = OPTIONS_TABLE_ATTRIBUTES, - .default_num = 0 + .default_num = 0, + .style = "window-status-style" + }, + + { .name = "window-status-bell-attr", + .type = OPTIONS_TABLE_ATTRIBUTES, + .default_num = GRID_ATTR_REVERSE, + .style = "window-status-bell-style" + }, + + { .name = "window-status-bell-bg", + .type = OPTIONS_TABLE_COLOUR, + .default_num = 8, + .style = "window-status-bell-style" + }, + + { .name = "window-status-bell-fg", + .type = OPTIONS_TABLE_COLOUR, + .default_num = 8, + .style = "window-status-bell-style" + }, + + { .name = "window-status-bell-style", + .type = OPTIONS_TABLE_STYLE, + .default_str = "reverse" }, { .name = "window-status-bg", .type = OPTIONS_TABLE_COLOUR, - .default_num = 8 + .default_num = 8, + .style = "window-status-style" + }, + + { .name = "window-status-content-attr", + .type = OPTIONS_TABLE_ATTRIBUTES, + .default_num = GRID_ATTR_REVERSE, + .style = "window-status-content-style" + }, + + { .name = "window-status-content-bg", + .type = OPTIONS_TABLE_COLOUR, + .default_num = 8, + .style = "window-status-content-style" + }, + + { .name = "window-status-content-fg", + .type = OPTIONS_TABLE_COLOUR, + .default_num = 8, + .style = "window-status-content-style" + }, + + { .name = "window-status-content-style", + .type = OPTIONS_TABLE_STYLE, + .default_str = "reverse" }, { .name = "window-status-current-attr", .type = OPTIONS_TABLE_ATTRIBUTES, - .default_num = 0 + .default_num = 0, + .style = "window-status-current-style" }, { .name = "window-status-current-bg", .type = OPTIONS_TABLE_COLOUR, - .default_num = 8 + .default_num = 8, + .style = "window-status-current-style" }, { .name = "window-status-current-fg", .type = OPTIONS_TABLE_COLOUR, - .default_num = 8 + .default_num = 8, + .style = "window-status-current-style" }, { .name = "window-status-current-format", @@ -690,24 +781,15 @@ const struct options_table_entry window_options_table[] = { .default_str = "#I:#W#F" }, - { .name = "window-status-last-attr", - .type = OPTIONS_TABLE_ATTRIBUTES, - .default_num = 0 - }, - - { .name = "window-status-last-bg", - .type = OPTIONS_TABLE_COLOUR, - .default_num = 8 - }, - - { .name = "window-status-last-fg", - .type = OPTIONS_TABLE_COLOUR, - .default_num = 8 + { .name = "window-status-current-style", + .type = OPTIONS_TABLE_STYLE, + .default_str = "default" }, { .name = "window-status-fg", .type = OPTIONS_TABLE_COLOUR, - .default_num = 8 + .default_num = 8, + .style = "window-status-style" }, { .name = "window-status-format", @@ -715,11 +797,39 @@ const struct options_table_entry window_options_table[] = { .default_str = "#I:#W#F" }, + { .name = "window-status-last-attr", + .type = OPTIONS_TABLE_ATTRIBUTES, + .default_num = 0, + .style = "window-status-last-style" + }, + + { .name = "window-status-last-bg", + .type = OPTIONS_TABLE_COLOUR, + .default_num = 8, + .style = "window-status-last-style" + }, + + { .name = "window-status-last-fg", + .type = OPTIONS_TABLE_COLOUR, + .default_num = 8, + .style = "window-status-last-style" + }, + + { .name = "window-status-last-style", + .type = OPTIONS_TABLE_STYLE, + .default_str = "default" + }, + { .name = "window-status-separator", .type = OPTIONS_TABLE_STRING, .default_str = " " }, + { .name = "window-status-style", + .type = OPTIONS_TABLE_STYLE, + .default_str = "default" + }, + { .name = "wrap-search", .type = OPTIONS_TABLE_FLAG, .default_num = 1 @@ -741,10 +851,17 @@ options_table_populate_tree( const struct options_table_entry *oe; for (oe = table; oe->name != NULL; oe++) { - if (oe->default_str != NULL) + switch (oe->type) { + case OPTIONS_TABLE_STRING: options_set_string(oo, oe->name, "%s", oe->default_str); - else + break; + case OPTIONS_TABLE_STYLE: + options_set_style(oo, oe->name, oe->default_str); + break; + default: options_set_number(oo, oe->name, oe->default_num); + break; + } } } @@ -789,6 +906,10 @@ options_table_print_entry(const struct options_table_entry *oe, s = oe->choices[o->num]; xsnprintf(out, sizeof out, "%s", s); break; + case OPTIONS_TABLE_STYLE: + s = style_tostring(&o->style); + xsnprintf(out, sizeof out, "%s", s); + break; } return (out); } diff --git a/options.c b/options.c index 51a6608e..699dd9b0 100644 --- a/options.c +++ b/options.c @@ -109,6 +109,7 @@ options_set_string(struct options *oo, const char *name, const char *fmt, ...) o = xmalloc(sizeof *o); o->name = xstrdup(name); RB_INSERT(options_tree, &oo->tree, o); + memcpy(&o->style, &grid_default_cell, sizeof o->style); } else if (o->type == OPTIONS_STRING) free(o->str); @@ -140,6 +141,7 @@ options_set_number(struct options *oo, const char *name, long long value) o = xmalloc(sizeof *o); o->name = xstrdup(name); RB_INSERT(options_tree, &oo->tree, o); + memcpy(&o->style, &grid_default_cell, sizeof o->style); } else if (o->type == OPTIONS_STRING) free(o->str); @@ -159,3 +161,37 @@ options_get_number(struct options *oo, const char *name) fatalx("option not a number"); return (o->num); } + +struct options_entry * +options_set_style(struct options *oo, const char *name, const char *value, + int append) +{ + struct options_entry *o; + + if ((o = options_find1(oo, name)) == NULL) { + o = xmalloc(sizeof *o); + o->name = xstrdup(name); + RB_INSERT(options_tree, &oo->tree, o); + } else if (o->type == OPTIONS_STRING) + free(o->str); + + if (!append) + memcpy(&o->style, &grid_default_cell, sizeof o->style); + + o->type = OPTIONS_STYLE; + if (style_parse(&grid_default_cell, &o->style, value) == -1) + return (NULL); + return (o); +} + +struct grid_cell * +options_get_style(struct options *oo, const char *name) +{ + struct options_entry *o; + + if ((o = options_find(oo, name)) == NULL) + fatalx("missing option"); + if (o->type != OPTIONS_STYLE) + fatalx("option not a style"); + return (&o->style); +} diff --git a/screen-redraw.c b/screen-redraw.c index 4601c6f3..a67cb952 100644 --- a/screen-redraw.c +++ b/screen-redraw.c @@ -224,7 +224,7 @@ screen_redraw_screen(struct client *c, int status_only, int borders_only) struct window_pane *wp; struct grid_cell active_gc, other_gc; u_int i, j, type, top; - int status, spos, fg, bg; + int status, spos; /* Suspended clients should not be updated. */ if (c->flags & CLIENT_SUSPENDED) @@ -251,17 +251,9 @@ screen_redraw_screen(struct client *c, int status_only, int borders_only) } /* Set up pane border attributes. */ - memcpy(&other_gc, &grid_marker_cell, sizeof other_gc); - memcpy(&active_gc, &grid_marker_cell, sizeof active_gc); - active_gc.attr = other_gc.attr = GRID_ATTR_CHARSET; - fg = options_get_number(oo, "pane-border-fg"); - colour_set_fg(&other_gc, fg); - bg = options_get_number(oo, "pane-border-bg"); - colour_set_bg(&other_gc, bg); - fg = options_get_number(oo, "pane-active-border-fg"); - colour_set_fg(&active_gc, fg); - bg = options_get_number(oo, "pane-active-border-bg"); - colour_set_bg(&active_gc, bg); + style_apply(&other_gc, oo, "pane-border-style"); + style_apply(&active_gc, oo, "pane-active-border-style"); + active_gc.attr = other_gc.attr = GRID_ATTR_CHARSET; /* nuke existing */ /* Draw background and borders. */ for (j = 0; j < tty->sy - status; j++) { @@ -368,7 +360,7 @@ screen_redraw_draw_number(struct client *c, struct window_pane *wp) px -= len * 3; py -= 2; - memcpy(&gc, &grid_marker_cell, sizeof gc); + memcpy(&gc, &grid_default_cell, sizeof gc); if (w->active == wp) colour_set_bg(&gc, active_colour); else @@ -395,7 +387,7 @@ screen_redraw_draw_number(struct client *c, struct window_pane *wp) tty_cursor(tty, xoff + wp->sx - len, yoff); draw_text: - memcpy(&gc, &grid_marker_cell, sizeof gc); + memcpy(&gc, &grid_default_cell, sizeof gc); if (w->active == wp) colour_set_fg(&gc, active_colour); else diff --git a/screen-write.c b/screen-write.c index 7fcfc5ee..3da145e8 100644 --- a/screen-write.c +++ b/screen-write.c @@ -248,7 +248,7 @@ screen_write_cnputs(struct screen_write_ctx *ctx, } *last = '\0'; - screen_write_parsestyle(gc, &lgc, ptr); + style_parse(gc, &lgc, ptr); ptr = last + 1; continue; } @@ -288,89 +288,6 @@ screen_write_cnputs(struct screen_write_ctx *ctx, free(msg); } -/* Parse an embedded style of the form "fg=colour,bg=colour,bright,...". */ -void -screen_write_parsestyle( - struct grid_cell *defgc, struct grid_cell *gc, const char *in) -{ - const char delimiters[] = " ,"; - char tmp[32]; - int val; - size_t end; - u_char fg, bg, attr, flags; - - if (*in == '\0') - return; - if (strchr(delimiters, in[strlen(in) - 1]) != NULL) - return; - - fg = gc->fg; - bg = gc->bg; - attr = gc->attr; - flags = gc->flags; - do { - end = strcspn(in, delimiters); - if (end > (sizeof tmp) - 1) - return; - memcpy(tmp, in, end); - tmp[end] = '\0'; - - if (strcasecmp(tmp, "default") == 0) { - fg = defgc->fg; - bg = defgc->bg; - attr = defgc->attr; - flags &= ~(GRID_FLAG_FG256|GRID_FLAG_BG256); - flags |= - defgc->flags & (GRID_FLAG_FG256|GRID_FLAG_BG256); - } else if (end > 3 && strncasecmp(tmp + 1, "g=", 2) == 0) { - if ((val = colour_fromstring(tmp + 3)) == -1) - return; - if (*in == 'f' || *in == 'F') { - if (val != 8) { - if (val & 0x100) { - flags |= GRID_FLAG_FG256; - val &= ~0x100; - } else - flags &= ~GRID_FLAG_FG256; - fg = val; - } else { - fg = defgc->fg; - flags &= ~GRID_FLAG_FG256; - flags |= defgc->flags & GRID_FLAG_FG256; - } - } else if (*in == 'b' || *in == 'B') { - if (val != 8) { - if (val & 0x100) { - flags |= GRID_FLAG_BG256; - val &= ~0x100; - } else - flags &= ~GRID_FLAG_BG256; - bg = val; - } else { - bg = defgc->bg; - flags &= ~GRID_FLAG_BG256; - flags |= defgc->flags & GRID_FLAG_BG256; - } - } else - return; - } else if (end > 2 && strncasecmp(tmp, "no", 2) == 0) { - if ((val = attributes_fromstring(tmp + 2)) == -1) - return; - attr &= ~val; - } else { - if ((val = attributes_fromstring(tmp)) == -1) - return; - attr |= val; - } - - in += end + strspn(in + end, delimiters); - } while (*in != '\0'); - gc->fg = fg; - gc->bg = bg; - gc->attr = attr; - gc->flags = flags; -} - /* Copy from another screen. */ void screen_write_copy(struct screen_write_ctx *ctx, diff --git a/status.c b/status.c index c5572b74..e14c1a81 100644 --- a/status.c +++ b/status.c @@ -80,18 +80,9 @@ status_redraw_get_left(struct client *c, { struct session *s = c->session; char *left; - int fg, bg, attr; size_t leftlen; - fg = options_get_number(&s->options, "status-left-fg"); - if (fg != 8) - colour_set_fg(gc, fg); - bg = options_get_number(&s->options, "status-left-bg"); - if (bg != 8) - colour_set_bg(gc, bg); - attr = options_get_number(&s->options, "status-left-attr"); - if (attr != 0) - gc->attr = attr; + style_apply_update(gc, &s->options, "status-left-style"); left = status_replace(c, NULL, NULL, NULL, options_get_string(&s->options, "status-left"), t, 1); @@ -110,18 +101,9 @@ status_redraw_get_right(struct client *c, { struct session *s = c->session; char *right; - int fg, bg, attr; size_t rightlen; - fg = options_get_number(&s->options, "status-right-fg"); - if (fg != 8) - colour_set_fg(gc, fg); - bg = options_get_number(&s->options, "status-right-bg"); - if (bg != 8) - colour_set_bg(gc, bg); - attr = options_get_number(&s->options, "status-right-attr"); - if (attr != 0) - gc->attr = attr; + style_apply_update(gc, &s->options, "status-right-style"); right = status_replace(c, NULL, NULL, NULL, options_get_string(&s->options, "status-right"), t, 1); @@ -177,10 +159,7 @@ status_redraw(struct client *c) t = c->status_timer.tv_sec; /* Set up default colour. */ - memcpy(&stdgc, &grid_default_cell, sizeof gc); - colour_set_fg(&stdgc, options_get_number(&s->options, "status-fg")); - colour_set_bg(&stdgc, options_get_number(&s->options, "status-bg")); - stdgc.attr |= options_get_number(&s->options, "status-attr"); + style_apply(&stdgc, &s->options, "status-style"); /* Create the target screen. */ memcpy(&old_status, &c->status, sizeof old_status); @@ -646,73 +625,22 @@ status_print( struct session *s = c->session; const char *fmt; char *text; - int fg, bg, attr; - fg = options_get_number(oo, "window-status-fg"); - if (fg != 8) - colour_set_fg(gc, fg); - bg = options_get_number(oo, "window-status-bg"); - if (bg != 8) - colour_set_bg(gc, bg); - attr = options_get_number(oo, "window-status-attr"); - if (attr != 0) - gc->attr = attr; + style_apply_update(gc, oo, "window-status-style"); fmt = options_get_string(oo, "window-status-format"); if (wl == s->curw) { - fg = options_get_number(oo, "window-status-current-fg"); - if (fg != 8) - colour_set_fg(gc, fg); - bg = options_get_number(oo, "window-status-current-bg"); - if (bg != 8) - colour_set_bg(gc, bg); - attr = options_get_number(oo, "window-status-current-attr"); - if (attr != 0) - gc->attr = attr; + style_apply_update(gc, oo, "window-status-current-style"); fmt = options_get_string(oo, "window-status-current-format"); } - if (wl == TAILQ_FIRST(&s->lastw)) { - fg = options_get_number(oo, "window-status-last-fg"); - if (fg != 8) - colour_set_fg(gc, fg); - bg = options_get_number(oo, "window-status-last-bg"); - if (bg != 8) - colour_set_bg(gc, bg); - attr = options_get_number(oo, "window-status-last-attr"); - if (attr != 0) - gc->attr = attr; - } + if (wl == TAILQ_FIRST(&s->lastw)) + style_apply_update(gc, oo, "window-status-last-style"); - if (wl->flags & WINLINK_BELL) { - fg = options_get_number(oo, "window-status-bell-fg"); - if (fg != 8) - colour_set_fg(gc, fg); - bg = options_get_number(oo, "window-status-bell-bg"); - if (bg != 8) - colour_set_bg(gc, bg); - attr = options_get_number(oo, "window-status-bell-attr"); - if (attr != 0) - gc->attr = attr; - } else if (wl->flags & WINLINK_CONTENT) { - fg = options_get_number(oo, "window-status-content-fg"); - if (fg != 8) - colour_set_fg(gc, fg); - bg = options_get_number(oo, "window-status-content-bg"); - if (bg != 8) - colour_set_bg(gc, bg); - attr = options_get_number(oo, "window-status-content-attr"); - if (attr != 0) - gc->attr = attr; - } else if (wl->flags & (WINLINK_ACTIVITY|WINLINK_SILENCE)) { - fg = options_get_number(oo, "window-status-activity-fg"); - if (fg != 8) - colour_set_fg(gc, fg); - bg = options_get_number(oo, "window-status-activity-bg"); - if (bg != 8) - colour_set_bg(gc, bg); - attr = options_get_number(oo, "window-status-activity-attr"); - if (attr != 0) - gc->attr = attr; - } + if (wl->flags & WINLINK_BELL) + style_apply_update(gc, oo, "window-status-bell-style"); + else if (wl->flags & WINLINK_CONTENT) + style_apply_update(gc, oo, "window-status-content-style"); + else if (wl->flags & (WINLINK_ACTIVITY|WINLINK_SILENCE)) + style_apply_update(gc, oo, "window-status-activity-style"); text = status_replace(c, NULL, wl, NULL, fmt, t, 1); return (text); @@ -814,10 +742,7 @@ status_message_redraw(struct client *c) if (len > c->tty.sx) len = c->tty.sx; - memcpy(&gc, &grid_default_cell, sizeof gc); - colour_set_fg(&gc, options_get_number(&s->options, "message-fg")); - colour_set_bg(&gc, options_get_number(&s->options, "message-bg")); - gc.attr |= options_get_number(&s->options, "message-attr"); + style_apply(&gc, &s->options, "message-style"); screen_write_start(&ctx, NULL, &c->status); @@ -935,18 +860,11 @@ status_prompt_redraw(struct client *c) len = c->tty.sx; off = 0; - memcpy(&gc, &grid_default_cell, sizeof gc); - /* Change colours for command mode. */ - if (c->prompt_mdata.mode == 1) { - colour_set_fg(&gc, options_get_number(&s->options, "message-command-fg")); - colour_set_bg(&gc, options_get_number(&s->options, "message-command-bg")); - gc.attr |= options_get_number(&s->options, "message-command-attr"); - } else { - colour_set_fg(&gc, options_get_number(&s->options, "message-fg")); - colour_set_bg(&gc, options_get_number(&s->options, "message-bg")); - gc.attr |= options_get_number(&s->options, "message-attr"); - } + if (c->prompt_mdata.mode == 1) + style_apply(&gc, &s->options, "message-command-style"); + else + style_apply(&gc, &s->options, "message-style"); screen_write_start(&ctx, NULL, &c->status); diff --git a/style.c b/style.c new file mode 100644 index 00000000..97d5576e --- /dev/null +++ b/style.c @@ -0,0 +1,224 @@ +/* $OpenBSD$ */ + +/* + * Copyright (c) 2007 Nicholas Marriott + * Copyright (c) 2014 Tiago Cunha + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include + +#include "tmux.h" + +/* Parse an embedded style of the form "fg=colour,bg=colour,bright,...". */ +int +style_parse(const struct grid_cell *defgc, struct grid_cell *gc, + const char *in) +{ + const char delimiters[] = " ,"; + char tmp[32]; + int val; + size_t end; + u_char fg, bg, attr, flags; + + if (*in == '\0') + return (0); + if (strchr(delimiters, in[strlen(in) - 1]) != NULL) + return (-1); + + fg = gc->fg; + bg = gc->bg; + attr = gc->attr; + flags = gc->flags; + do { + end = strcspn(in, delimiters); + if (end > (sizeof tmp) - 1) + return (-1); + memcpy(tmp, in, end); + tmp[end] = '\0'; + + if (strcasecmp(tmp, "default") == 0) { + fg = defgc->fg; + bg = defgc->bg; + attr = defgc->attr; + flags &= ~(GRID_FLAG_FG256|GRID_FLAG_BG256); + flags |= + defgc->flags & (GRID_FLAG_FG256|GRID_FLAG_BG256); + } else if (end > 3 && strncasecmp(tmp + 1, "g=", 2) == 0) { + if ((val = colour_fromstring(tmp + 3)) == -1) + return (-1); + if (*in == 'f' || *in == 'F') { + if (val != 8) { + if (val & 0x100) { + flags |= GRID_FLAG_FG256; + val &= ~0x100; + } else + flags &= ~GRID_FLAG_FG256; + fg = val; + } else { + fg = defgc->fg; + flags &= ~GRID_FLAG_FG256; + flags |= defgc->flags & GRID_FLAG_FG256; + } + } else if (*in == 'b' || *in == 'B') { + if (val != 8) { + if (val & 0x100) { + flags |= GRID_FLAG_BG256; + val &= ~0x100; + } else + flags &= ~GRID_FLAG_BG256; + bg = val; + } else { + bg = defgc->bg; + flags &= ~GRID_FLAG_BG256; + flags |= defgc->flags & GRID_FLAG_BG256; + } + } else + return (-1); + } else if (strcasecmp(tmp, "none") == 0) + attr = 0; + else if (end > 2 && strncasecmp(tmp, "no", 2) == 0) { + if ((val = attributes_fromstring(tmp + 2)) == -1) + return (-1); + attr &= ~val; + } else { + if ((val = attributes_fromstring(tmp)) == -1) + return (-1); + attr |= val; + } + + in += end + strspn(in + end, delimiters); + } while (*in != '\0'); + gc->fg = fg; + gc->bg = bg; + gc->attr = attr; + gc->flags = flags; + + return (0); +} + +/* Convert style to a string. */ +const char * +style_tostring(struct grid_cell *gc) +{ + int c, off = 0, comma = 0; + static char s[256]; + + *s = '\0'; + + if (gc->fg != 8) { + if (gc->flags & GRID_FLAG_FG256) + c = gc->fg | 0x100; + else + c = gc->fg; + off += xsnprintf(s, sizeof s, "fg=%s", colour_tostring(c)); + comma = 1; + } + + if (gc->bg != 8) { + if (gc->flags & GRID_FLAG_BG256) + c = gc->bg | 0x100; + else + c = gc->bg; + off += xsnprintf(s + off, sizeof s - off, "%sbg=%s", + comma ? "," : "", colour_tostring(c)); + comma = 1; + } + + if (gc->attr != 0 && gc->attr != GRID_ATTR_CHARSET) { + xsnprintf(s + off, sizeof s - off, "%s%s", + comma ? "," : "", attributes_tostring(gc->attr)); + } + + if (*s == '\0') + return ("default"); + return (s); +} + +/* Synchronize new -style option with the old one. */ +void +style_update_new(struct options *oo, const char *name, const char *newname) +{ + int value; + struct grid_cell *gc; + + /* It's a colour or attribute, but with no -style equivalent. */ + if (newname == NULL) + return; + + gc = options_get_style(oo, newname); + value = options_get_number(oo, name); + + if (strstr(name, "-bg") != NULL) + colour_set_bg(gc, value); + else if (strstr(name, "-fg") != NULL) + colour_set_fg(gc, value); + else if (strstr(name, "-attr") != NULL) + gc->attr = value; +} + +/* Synchronize all the old options with the new -style one. */ +void +style_update_old(struct options *oo, const char *name, struct grid_cell *gc) +{ + char newname[128]; + int c, size; + + size = strrchr(name, '-') - name; + + if (gc->flags & GRID_FLAG_BG256) + c = gc->bg | 0x100; + else + c = gc->bg; + xsnprintf(newname, sizeof newname, "%.*s-bg", size, name); + options_set_number(oo, newname, c); + + if (gc->flags & GRID_FLAG_FG256) + c = gc->fg | 0x100; + else + c = gc->fg; + xsnprintf(newname, sizeof newname, "%.*s-fg", size, name); + options_set_number(oo, newname, c); + + xsnprintf(newname, sizeof newname, "%.*s-attr", size, name); + options_set_number(oo, newname, gc->attr); +} + +/* Apply a style. */ +void +style_apply(struct grid_cell *gc, struct options *oo, const char *name) +{ + struct grid_cell *gcp; + + memcpy(gc, &grid_default_cell, sizeof *gc); + gcp = options_get_style(oo, name); + colour_set_fg(gc, gcp->fg); + colour_set_bg(gc, gcp->bg); + gc->attr |= gcp->attr; +} + +/* Apply a style, updating if default. */ +void +style_apply_update(struct grid_cell *gc, struct options *oo, const char *name) +{ + struct grid_cell *gcp; + + gcp = options_get_style(oo, name); + if (gcp->fg != 8) + colour_set_fg(gc, gcp->fg); + if (gcp->bg != 8) + colour_set_bg(gc, gcp->bg); + if (gcp->attr != 0) + gc->attr |= gcp->attr; +} diff --git a/tmux.1 b/tmux.1 index e44a44a6..e0b27b6d 100644 --- a/tmux.1 +++ b/tmux.1 @@ -2060,11 +2060,6 @@ otherwise a session option. If .Fl g is specified, the global session or window option is set. -With -.Fl a , -and if the option expects a string, -.Ar value -is appended to the existing setting. The .Fl u flag unsets an option, so a session inherits the option from the global @@ -2081,6 +2076,32 @@ flag suppresses the informational message (as if the .Ic quiet server option was set). .Pp +With +.Fl a , +and if the option expects a string or a style, +.Ar value +is appended to the existing setting. +For example: +.Bd -literal -offset indent +set -g status-left "foo" +set -ag status-left "bar" +.Ed +.Pp +Will result in +.Ql foobar . +And: +.Bd -literal -offset indent +set -g status-style "bg=red" +set -ag status-style "fg=blue" +.Ed +.Pp +Will result in a red background +.Em and +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 @@ -2272,26 +2293,18 @@ the entire server will lock after .Em all sessions would have locked. This has no effect as a session option; it must be set as a global option. -.It Ic message-attr Ar attributes -Set status line message attributes, where -.Ar attributes -is either -.Ic none -or a comma-delimited list of one or more of: -.Ic bright -(or -.Ic bold ) , -.Ic dim , -.Ic underscore , -.Ic blink , -.Ic reverse , -.Ic hidden , -or -.Ic italics . -.It Ic message-bg Ar colour -Set status line message background colour, where -.Ar colour -is one of: +.It Ic message-command-style Ar style +Set status line message command style, where +.Ar style +is a comma-separated list of characteristics to be specified. +.Pp +These may be +.Ql bg=colour +to set the background colour, +.Ql fg=colour +to set the foreground colour, and a list of attributes as specified below. +.Pp +The colour is one of: .Ic black , .Ic red , .Ic green , @@ -2312,18 +2325,46 @@ from the 256-colour set, or a hexadecimal RGB string such as .Ql #ffffff , which chooses the closest match from the default 256-colour set. -.It Ic message-command-attr Ar attributes -Set status line message attributes when in command mode. -.It Ic message-command-bg Ar colour -Set status line message background colour when in command mode. -.It Ic message-command-fg Ar colour -Set status line message foreground colour when in command mode. -.It Ic message-fg Ar colour -Set status line message foreground colour. +.Pp +The attributes is either +.Ic none +or a comma-delimited list of one or more of: +.Ic bright +(or +.Ic bold ) , +.Ic dim , +.Ic underscore , +.Ic blink , +.Ic reverse , +.Ic hidden , +or +.Ic italics , +to turn an attribute on, or an attribute prefixed with +.Ql no +to turn one off. +.Pp +Examples are: +.Bd -literal -offset indent +fg=yellow,bold,underscore,blink +bg=black,fg=default,noreverse +.Ed +.Pp +With the +.Fl a +flag to the +.Ic set-option +command the new style is added otherwise the existing style is replaced. .It Ic message-limit Ar number Set the number of error or information messages to save in the message log for each client. The default is 20. +.It Ic message-style Ar style +Set status line message style. +For how to specify +.Ar style , +see the +.Ic message-command-style +option. .It Xo Ic mouse-resize-pane .Op Ic on | off .Xc @@ -2347,12 +2388,22 @@ window. .Op Ic on | off .Xc If enabled, request mouse input as UTF-8 on UTF-8 terminals. -.It Ic pane-active-border-bg Ar colour -.It Ic pane-active-border-fg Ar colour -Set the pane border colour for the currently active pane. -.It Ic pane-border-bg Ar colour -.It Ic pane-border-fg Ar colour -Set the pane border colour for panes aside from the active pane. +.It Ic pane-active-border-style Ar style +Set the pane border style for the currently active pane. +For how to specify +.Ar style , +see the +.Ic message-command-style +option. +Attributes are ignored. +.It Ic pane-border-style Ar style +Set the pane border style for paneas aside from the active pane. +For how to specify +.Ar style , +see the +.Ic message-command-style +option. +Attributes are ignored. .It Ic prefix Ar key Set the key accepted as a prefix key. .It Ic prefix2 Ar key @@ -2418,12 +2469,6 @@ option. .Op Ic on | off .Xc Show or hide the status line. -.It Ic status-attr Ar attributes -Set status line attributes. -.It Ic status-bg Ar colour -Set status line background colour. -.It Ic status-fg Ar colour -Set status line foreground colour. .It Ic status-interval Ar interval Update the status bar every .Ar interval @@ -2481,19 +2526,10 @@ section). For details on how the names and titles can be set see the .Sx "NAMES AND TITLES" section. +For a list of allowed attributes see the +.Ic message-command-style +option. .Pp -#[attributes] allows a comma-separated list of attributes to be specified, -these may be -.Ql fg=colour -to set the foreground colour, -.Ql bg=colour -to set the background colour, the name of one of the attributes (listed under -the -.Ic message-attr -option) to turn an attribute on, or an attribute prefixed with -.Ql no -to turn one off, for example -.Ic nobright . Examples are: .Bd -literal -offset indent #(sysctl vm.loadavg) @@ -2509,17 +2545,18 @@ By default, UTF-8 in is not interpreted, to enable UTF-8, use the .Ic status-utf8 option. -.It Ic status-left-attr Ar attributes -Set the attribute of the left part of the status line. -.It Ic status-left-bg Ar colour -Set the background colour of the left part of the status line. -.It Ic status-left-fg Ar colour -Set the foreground colour of the left part of the status line. .It Ic status-left-length Ar length Set the maximum .Ar length of the left component of the status bar. The default is 10. +.It Ic status-left-style Ar style +Set the style of the left part of the status line. +For how to specify +.Ar style , +see the +.Ic message-command-style +option. .It Xo Ic status-position .Op Ic top | bottom .Xc @@ -2538,17 +2575,25 @@ will be passed to character pairs are replaced, and UTF-8 is dependent on the .Ic status-utf8 option. -.It Ic status-right-attr Ar attributes -Set the attribute of the right part of the status line. -.It Ic status-right-bg Ar colour -Set the background colour of the right part of the status line. -.It Ic status-right-fg Ar colour -Set the foreground colour of the right part of the status line. .It Ic status-right-length Ar length Set the maximum .Ar length of the right component of the status bar. The default is 40. +.It Ic status-right-style Ar style +Set the style of the right part of the status line. +For how to specify +.Ar style , +see the +.Ic message-command-style +option. +.It Ic status-style Ar style +Set status line style. +For how to specify +.Ar style , +see the +.Ic message-command-style +option. .It Xo Ic status-utf8 .Op Ic on | off .Xc @@ -2775,15 +2820,6 @@ or .Ic main-vertical layouts. .Pp -.It Ic mode-attr Ar attributes -Set window modes attributes. -.Pp -.It Ic mode-bg Ar colour -Set window modes background colour. -.Pp -.It Ic mode-fg Ar colour -Set window modes foreground colour. -.Pp .It Xo Ic mode-keys .Op Ic vi | emacs .Xc @@ -2809,6 +2845,14 @@ If set to the mouse behaves as set to on, but cannot be used to enter copy mode. .Pp +.It Ic mode-style Ar style +Set window modes style. +For how to specify +.Ar style , +see the +.Ic message-command-style +option. +.Pp .It Xo Ic monitor-activity .Op Ic on | off .Xc @@ -2879,64 +2923,42 @@ Instructs .Nm to expect UTF-8 sequences to appear in this window. .Pp -.It Ic window-status-bell-attr Ar attributes -Set status line attributes for windows which have a bell alert. +.It Ic window-status-activity-style Ar style +Set status line style for windows with an activity alert. +For how to specify +.Ar style , +see the +.Ic message-command-style +option. .Pp -.It Ic window-status-bell-bg Ar colour -Set status line background colour for windows with a bell alert. +.It Ic window-status-bell-style Ar style +Set status line style for windows with a bell alert. +For how to specify +.Ar style , +see the +.Ic message-command-style +option. .Pp -.It Ic window-status-bell-fg Ar colour -Set status line foreground colour for windows with a bell alert. -.Pp -.It Ic window-status-content-attr Ar attributes -Set status line attributes for windows which have a content alert. -.Pp -.It Ic window-status-content-bg Ar colour -Set status line background colour for windows with a content alert. -.Pp -.It Ic window-status-content-fg Ar colour -Set status line foreground colour for windows with a content alert. -.Pp -.It Ic window-status-activity-attr Ar attributes -Set status line attributes for windows which have an activity (or silence) alert. -.Pp -.It Ic window-status-activity-bg Ar colour -Set status line background colour for windows with an activity alert. -.Pp -.It Ic window-status-activity-fg Ar colour -Set status line foreground colour for windows with an activity alert. -.Pp -.It Ic window-status-attr Ar attributes -Set status line attributes for a single window. -.Pp -.It Ic window-status-bg Ar colour -Set status line background colour for a single window. -.Pp -.It Ic window-status-current-attr Ar attributes -Set status line attributes for the currently active window. -.Pp -.It Ic window-status-current-bg Ar colour -Set status line background colour for the currently active window. -.Pp -.It Ic window-status-current-fg Ar colour -Set status line foreground colour for the currently active window. +.It Ic window-status-content-style Ar style +Set status line style for windows with a content alert. +For how to specify +.Ar style , +see the +.Ic message-command-style +option. .Pp .It Ic window-status-current-format Ar string Like .Ar window-status-format , but is the format used when the window is the current window. .Pp -.It Ic window-status-last-attr Ar attributes -Set status line attributes for the last active window. -.Pp -.It Ic window-status-last-bg Ar colour -Set status line background colour for the last active window. -.Pp -.It Ic window-status-last-fg Ar colour -Set status line foreground colour for the last active window. -.Pp -.It Ic window-status-fg Ar colour -Set status line foreground colour for a single window. +.It Ic window-status-current-style Ar style +Set status line style for the currently active window. +For how to specify +.Ar style , +see the +.Ic message-command-style +option. .Pp .It Ic window-status-format Ar string Set the format in which the window is displayed in the status line window list. @@ -2946,10 +2968,26 @@ option for details of special character sequences available. The default is .Ql #I:#W#F . .Pp +.It Ic window-status-last-style Ar style +Set status line style for the last active window. +For how to specify +.Ar style , +see the +.Ic message-command-style +option. +.Pp .It Ic window-status-separator Ar string Sets the separator drawn between windows in the status line. The default is a single space character. .Pp +.It Ic window-status-style Ar style +Set status line style for a single window. +For how to specify +.Ar style , +see the +.Ic message-command-style +option. +.Pp .It Xo Ic xterm-keys .Op Ic on | off .Xc @@ -3288,16 +3326,10 @@ content) is present. .Pp The colour and attributes of the status line may be configured, the entire status line using the -.Ic status-attr , -.Ic status-fg -and -.Ic status-bg -session options and individual windows using the -.Ic window-status-attr , -.Ic window-status-fg -and -.Ic window-status-bg -window options. +.Ic status-style +session option and individual windows using the +.Ic window-status-style +window option. .Pp The status line is automatically refreshed at interval if it has changed, the interval may be controlled with the @@ -3798,7 +3830,7 @@ bind-key C-a send-prefix Turning the status line off, or changing its colour: .Bd -literal -offset indent set-option -g status off -set-option -g status-bg blue +set-option -g status-style bg=blue .Ed .Pp Setting other options, such as the default command, diff --git a/tmux.h b/tmux.h index b28f10a0..b8fd445c 100644 --- a/tmux.h +++ b/tmux.h @@ -726,11 +726,12 @@ struct options_entry { enum { OPTIONS_STRING, OPTIONS_NUMBER, - OPTIONS_DATA, + OPTIONS_STYLE } type; - char *str; - long long num; + char *str; + long long num; + struct grid_cell style; RB_ENTRY(options_entry) entry; }; @@ -1453,7 +1454,8 @@ enum options_table_type { OPTIONS_TABLE_COLOUR, OPTIONS_TABLE_ATTRIBUTES, OPTIONS_TABLE_FLAG, - OPTIONS_TABLE_CHOICE + OPTIONS_TABLE_CHOICE, + OPTIONS_TABLE_STYLE }; struct options_table_entry { @@ -1466,6 +1468,8 @@ struct options_table_entry { const char *default_str; long long default_num; + + const char *style; }; /* Tree of format entries. */ @@ -1577,12 +1581,15 @@ void options_free(struct options *); struct options_entry *options_find1(struct options *, const char *); struct options_entry *options_find(struct options *, const char *); void options_remove(struct options *, const char *); -struct options_entry *printflike3 options_set_string( - struct options *, const char *, const char *, ...); +struct options_entry *printflike3 options_set_string(struct options *, + const char *, const char *, ...); char *options_get_string(struct options *, const char *); -struct options_entry *options_set_number( - struct options *, const char *, long long); +struct options_entry *options_set_number(struct options *, const char *, + long long); long long options_get_number(struct options *, const char *); +struct options_entry *options_set_style(struct options *, const char *, + const char *, int); +struct grid_cell *options_get_style(struct options *, const char *); /* options-table.c */ extern const struct options_table_entry server_options_table[]; @@ -2042,8 +2049,6 @@ void printflike5 screen_write_nputs(struct screen_write_ctx *, ssize_t, struct grid_cell *, int, const char *, ...); void screen_write_vnputs(struct screen_write_ctx *, ssize_t, struct grid_cell *, int, const char *, va_list); -void screen_write_parsestyle( - struct grid_cell *, struct grid_cell *, const char *); void screen_write_putc( struct screen_write_ctx *, struct grid_cell *, u_char); void screen_write_copy(struct screen_write_ctx *, @@ -2173,7 +2178,6 @@ struct window_pane *window_pane_find_right(struct window_pane *); void window_set_name(struct window *, const char *); void window_remove_ref(struct window *); void winlink_clear_flags(struct winlink *); -void window_mode_attrs(struct grid_cell *, struct options *); /* layout.c */ u_int layout_count_cells(struct layout_cell *); @@ -2345,4 +2349,14 @@ int xvasprintf(char **, const char *, va_list); int printflike3 xsnprintf(char *, size_t, const char *, ...); int xvsnprintf(char *, size_t, const char *, va_list); +/* style.c */ +int style_parse(const struct grid_cell *, + struct grid_cell *, const char *); +const char *style_tostring(struct grid_cell *); +void style_update_new(struct options *, const char *, const char *); +void style_update_old(struct options *, const char *, + struct grid_cell *); +void style_apply(struct grid_cell *, struct options *, const char *); +void style_apply_update(struct grid_cell *, struct options *, const char *); + #endif /* TMUX_H */ diff --git a/tty.c b/tty.c index 53b415ff..f5a85992 100644 --- a/tty.c +++ b/tty.c @@ -1354,8 +1354,7 @@ tty_attributes(struct tty *tty, const struct grid_cell *gc) tty_putcode(tty, TTYC_BOLD); if (changed & GRID_ATTR_DIM) tty_putcode(tty, TTYC_DIM); - if (changed & GRID_ATTR_ITALICS) - { + if (changed & GRID_ATTR_ITALICS) { if (tty_term_has(tty->term, TTYC_SITM)) tty_putcode(tty, TTYC_SITM); else diff --git a/window-choose.c b/window-choose.c index 77add5e4..0cf7f66b 100644 --- a/window-choose.c +++ b/window-choose.c @@ -736,7 +736,7 @@ window_choose_write_line( utf8flag = options_get_number(&wp->window->options, "utf8"); memcpy(&gc, &grid_default_cell, sizeof gc); if (data->selected == data->top + py) - window_mode_attrs(&gc, oo); + style_apply(&gc, oo, "mode-style"); screen_write_cursormove(ctx, 0, py); if (data->top + py < ARRAY_LENGTH(&data->list)) { @@ -763,7 +763,7 @@ window_choose_write_line( screen_write_putc(ctx, &gc, ' '); if (data->input_type != WINDOW_CHOOSE_NORMAL) { - window_mode_attrs(&gc, oo); + style_apply(&gc, oo, "mode-style"); xoff = xsnprintf(hdr, sizeof hdr, "%s: %s", data->input_prompt, data->input_str); diff --git a/window-copy.c b/window-copy.c index 48cd4b33..df4ca55a 100644 --- a/window-copy.c +++ b/window-copy.c @@ -1173,7 +1173,7 @@ window_copy_write_line( char hdr[512]; size_t last, xoff = 0, size = 0, limit; - window_mode_attrs(&gc, oo); + style_apply(&gc, oo, "mode-style"); last = screen_size_y(s) - 1; if (py == 0) { @@ -1290,7 +1290,7 @@ window_copy_update_selection(struct window_pane *wp, int may_redraw) return (0); /* Set colours. */ - window_mode_attrs(&gc, oo); + style_apply(&gc, oo, "mode-style"); /* Find top of screen. */ ty = screen_hsize(data->backing) - data->oy; diff --git a/window.c b/window.c index dcb2a5f1..1e11cace 100644 --- a/window.c +++ b/window.c @@ -1315,13 +1315,3 @@ winlink_clear_flags(struct winlink *wl) } } } - -/* Set the grid_cell with fg/bg/attr information when window is in a mode. */ -void -window_mode_attrs(struct grid_cell *gc, struct options *oo) -{ - memcpy(gc, &grid_default_cell, sizeof *gc); - colour_set_fg(gc, options_get_number(oo, "mode-fg")); - colour_set_bg(gc, options_get_number(oo, "mode-bg")); - gc->attr |= options_get_number(oo, "mode-attr"); -}