diff --git a/cmd-display-panes.c b/cmd-display-panes.c index c9f185d59..f8991dfe1 100644 --- a/cmd-display-panes.c +++ b/cmd-display-panes.c @@ -133,7 +133,8 @@ cmd_display_panes_draw_pane(struct cmd_display_panes_ctx *ctx, struct grid_cell fgc, bgc; u_int pane, idx, px, py, i, j, xoff, yoff, sx, sy; u_int cx, cy; - int colour, active_colour; + const char *name; + struct format_tree *ft; char buf[16], lbuf[16], *ptr; size_t len, llen; @@ -191,18 +192,16 @@ cmd_display_panes_draw_pane(struct cmd_display_panes_ctx *ctx, if (sx < len) return; - colour = options_get_number(oo, "display-panes-colour"); - active_colour = options_get_number(oo, "display-panes-active-colour"); + if (w->active == wp) + name = "display-panes-active-colour"; + else + name = "display-panes-colour"; + ft = format_create_defaults(NULL, c, s, NULL, wp); + style_apply(&fgc, oo, name, ft); + format_free(ft); - memcpy(&fgc, &grid_default_cell, sizeof fgc); memcpy(&bgc, &grid_default_cell, sizeof bgc); - if (w->active == wp) { - fgc.fg = active_colour; - bgc.bg = active_colour; - } else { - fgc.fg = colour; - bgc.bg = colour; - } + bgc.bg = fgc.fg; if (pane > 9 && pane < 35) llen = xsnprintf(lbuf, sizeof lbuf, "%c", 'a' + (pane - 10)); diff --git a/options-table.c b/options-table.c index 0d7b20c53..6050c24a0 100644 --- a/options-table.c +++ b/options-table.c @@ -328,9 +328,10 @@ const struct options_table_entry options_table[] = { }, { .name = "cursor-colour", - .type = OPTIONS_TABLE_COLOUR, + .type = OPTIONS_TABLE_STRING, .scope = OPTIONS_TABLE_WINDOW|OPTIONS_TABLE_PANE, - .default_num = -1, + .flags = OPTIONS_TABLE_IS_COLOUR, + .default_str = "", .text = "Colour of the cursor." }, @@ -635,16 +636,18 @@ const struct options_table_entry options_table[] = { }, { .name = "display-panes-active-colour", - .type = OPTIONS_TABLE_COLOUR, + .type = OPTIONS_TABLE_STRING, .scope = OPTIONS_TABLE_SESSION, - .default_num = 1, + .flags = OPTIONS_TABLE_IS_COLOUR, + .default_str = "red", .text = "Colour of the active pane for 'display-panes'." }, { .name = "display-panes-colour", - .type = OPTIONS_TABLE_COLOUR, + .type = OPTIONS_TABLE_STRING, .scope = OPTIONS_TABLE_SESSION, - .default_num = 4, + .flags = OPTIONS_TABLE_IS_COLOUR, + .default_str = "blue", .text = "Colour of not active panes for 'display-panes'." }, @@ -991,9 +994,10 @@ const struct options_table_entry options_table[] = { }, { .name = "prompt-cursor-colour", - .type = OPTIONS_TABLE_COLOUR, + .type = OPTIONS_TABLE_STRING, .scope = OPTIONS_TABLE_SESSION, - .default_num = -1, + .flags = OPTIONS_TABLE_IS_COLOUR, + .default_str = "", .text = "Colour of the cursor when in the command prompt." }, @@ -1145,9 +1149,10 @@ const struct options_table_entry options_table[] = { }, { .name = "clock-mode-colour", - .type = OPTIONS_TABLE_COLOUR, + .type = OPTIONS_TABLE_STRING, .scope = OPTIONS_TABLE_WINDOW, - .default_num = 4, + .flags = OPTIONS_TABLE_IS_COLOUR, + .default_str = "blue", .text = "Colour of the clock in clock mode." }, diff --git a/options.c b/options.c index a4081a8d2..b9e319acf 100644 --- a/options.c +++ b/options.c @@ -989,9 +989,12 @@ struct style * options_string_to_style(struct options *oo, const char *name, struct format_tree *ft) { - struct options_entry *o; - const char *s; - char *expanded; + struct options_entry *o; + const struct options_table_entry *oe; + const struct grid_cell *dgc = &grid_default_cell; + const char *s; + char *expanded; + int failed; o = options_get(oo, name); if (o == NULL || !OPTIONS_IS_STRING(o)) @@ -1000,20 +1003,27 @@ options_string_to_style(struct options *oo, const char *name, if (o->cached) return (&o->style); s = o->value.string; + oe = o->tableentry; log_debug("%s: %s is '%s'", __func__, name, s); - style_set(&o->style, &grid_default_cell); + style_set(&o->style, dgc); o->cached = (strstr(s, "#{") == NULL); if (ft != NULL && !o->cached) { expanded = format_expand(ft, s); - if (style_parse(&o->style, &grid_default_cell, expanded) != 0) { - free(expanded); - return (NULL); - } + if (oe != NULL && (oe->flags & OPTIONS_TABLE_IS_COLOUR)) + failed = style_parse_colour(&o->style, dgc, expanded); + else + failed = style_parse(&o->style, dgc, expanded); free(expanded); + if (failed != 0) + return (NULL); } else { - if (style_parse(&o->style, &grid_default_cell, s) != 0) + if (oe != NULL && (oe->flags & OPTIONS_TABLE_IS_COLOUR)) + failed = style_parse_colour(&o->style, dgc, s); + else + failed = style_parse(&o->style, dgc, s); + if (failed != 0) return (NULL); } return (&o->style); @@ -1041,6 +1051,12 @@ options_from_string_check(const struct options_table_entry *oe, xasprintf(cause, "invalid style: %s", value); return (-1); } + if ((oe->flags & OPTIONS_TABLE_IS_COLOUR) && + strstr(value, "#{") == NULL && + style_parse_colour(&sy, &grid_default_cell, value) != 0) { + xasprintf(cause, "invalid colour: %s", value); + return (-1); + } return (0); } diff --git a/prompt.c b/prompt.c index 54cbeb13b..57e267374 100644 --- a/prompt.c +++ b/prompt.c @@ -106,8 +106,9 @@ prompt_flags_to_string(int flags) void prompt_set_options(struct prompt_create_data *pd, struct session *s) { - struct options *oo; - u_int n; + struct options *oo; + struct grid_cell gc; + u_int n; if (s != NULL) oo = s->options; @@ -120,7 +121,8 @@ prompt_set_options(struct prompt_create_data *pd, struct session *s) screen_set_cursor_style(n, &pd->cstyle, &pd->cmode); n = options_get_number(oo, "prompt-command-cursor-style"); screen_set_cursor_style(n, &pd->command_cstyle, &pd->command_cmode); - pd->ccolour = options_get_number(oo, "prompt-cursor-colour"); + style_apply(&gc, oo, "prompt-cursor-colour", NULL); + pd->ccolour = gc.fg; pd->message_format = options_get_string(oo, "message-format"); pd->keys = options_get_number(oo, "status-keys"); pd->word_separators = options_get_string(oo, "word-separators"); diff --git a/screen.c b/screen.c index 7afaefec0..cea934fad 100644 --- a/screen.c +++ b/screen.c @@ -177,10 +177,11 @@ screen_reset_tabs(struct screen *s) void screen_set_default_cursor(struct screen *s, struct options *oo) { - int c; + struct grid_cell gc; + int c; - c = options_get_number(oo, "cursor-colour"); - s->default_ccolour = c; + style_apply(&gc, oo, "cursor-colour", NULL); + s->default_ccolour = gc.fg; c = options_get_number(oo, "cursor-style"); s->default_mode = 0; diff --git a/style.c b/style.c index 796600253..60ac4dd6e 100644 --- a/style.c +++ b/style.c @@ -434,6 +434,29 @@ style_apply(struct grid_cell *gc, struct options *oo, const char *name, style_add(gc, oo, name, ft); } +/* Parse a single colour into a style */ +int +style_parse_colour(struct style *sy, const struct grid_cell *base, + const char *s) +{ + int c; + + style_set(sy, base); + + if (*s == '\0') { + sy->gc.fg = -1; + return (0); + } + + if ((c = colour_fromstring(s)) == -1) + return (-1); + if (c == 8) + sy->gc.fg = base->fg; + else + sy->gc.fg = c; + return (0); +} + /* Initialize style from cell. */ void style_set(struct style *sy, const struct grid_cell *gc) diff --git a/tmux.h b/tmux.h index 07d0922dc..bbf25b9c8 100644 --- a/tmux.h +++ b/tmux.h @@ -2307,6 +2307,7 @@ enum options_table_type { #define OPTIONS_TABLE_IS_ARRAY 0x1 #define OPTIONS_TABLE_IS_HOOK 0x2 #define OPTIONS_TABLE_IS_STYLE 0x4 +#define OPTIONS_TABLE_IS_COLOUR 0x8 struct options_table_entry { const char *name; @@ -3896,6 +3897,8 @@ int popup_modify(struct client *, const char *, const char *, /* style.c */ int style_parse(struct style *,const struct grid_cell *, const char *); +int style_parse_colour(struct style *, + const struct grid_cell *, const char *); const char *style_tostring(struct style *); struct style *style_add(struct grid_cell *, struct options *, const char *, struct format_tree *); diff --git a/window-clock.c b/window-clock.c index 6a89df4b3..cf7040009 100644 --- a/window-clock.c +++ b/window-clock.c @@ -222,19 +222,24 @@ static void window_clock_draw_screen(struct window_mode_entry *wme) { struct window_pane *wp = wme->wp; + struct window *w = wp->window; struct window_clock_mode_data *data = wme->data; struct screen_write_ctx ctx; int colour, style; struct screen *s = &data->screen; struct grid_cell gc; + struct format_tree *ft; char tim[64], *ptr; const char *timeformat; time_t t; struct tm *tm; u_int i, j, x, y, idx; - colour = options_get_number(wp->window->options, "clock-mode-colour"); - style = options_get_number(wp->window->options, "clock-mode-style"); + ft = format_create_defaults(NULL, NULL, NULL, NULL, wp); + style_apply(&gc, w->options, "clock-mode-colour", ft); + format_free(ft); + colour = gc.fg; + style = options_get_number(w->options, "clock-mode-style"); screen_write_start(&ctx, s); diff --git a/window-customize.c b/window-customize.c index 559593873..9796cbf0b 100644 --- a/window-customize.c +++ b/window-customize.c @@ -769,6 +769,15 @@ window_customize_draw_option(struct window_customize_modedata *data, "EXAMPLE")) goto out; } + if (oe != NULL && (oe->flags & OPTIONS_TABLE_IS_COLOUR)) { + if (!screen_write_text(ctx, cx, sx, sy - (s->cy - cy), 1, + &grid_default_cell, "This is a colour option: ")) + goto out; + style_apply(&gc, item->oo, name, ft); + if (!screen_write_text(ctx, cx, sx, sy - (s->cy - cy), 0, &gc, + "EXAMPLE")) + goto out; + } if (oe != NULL && (oe->flags & OPTIONS_TABLE_IS_STYLE)) { if (!screen_write_text(ctx, cx, sx, sy - (s->cy - cy), 1, &grid_default_cell, "This is a style option: "))