Add an option menu-selected-style to configure the currently selected

menu item, from Alexis Hildebrandt.
pull/3666/head
nicm 2023-08-15 07:01:47 +00:00
parent 57837bbf67
commit b770a429c6
9 changed files with 73 additions and 49 deletions

View File

@ -39,11 +39,11 @@ const struct cmd_entry cmd_display_menu_entry = {
.name = "display-menu", .name = "display-menu",
.alias = "menu", .alias = "menu",
.args = { "b:c:C:t:s:S:OT:x:y:", 1, -1, cmd_display_menu_args_parse }, .args = { "b:c:C:H:s:S:Ot:T:x:y:", 1, -1, cmd_display_menu_args_parse },
.usage = "[-O] [-b border-lines] [-c target-client] " .usage = "[-O] [-b border-lines] [-c target-client] "
"[-C starting-choice] [-s style] [-S border-style] " "[-C starting-choice] [-H selected-style] [-s style] "
CMD_TARGET_PANE_USAGE "[-T title] [-x position] [-y position] " "[-S border-style] " CMD_TARGET_PANE_USAGE "[-T title] "
"name key command ...", "[-x position] [-y position] name key command ...",
.target = { 't', CMD_FIND_PANE, 0 }, .target = { 't', CMD_FIND_PANE, 0 },
@ -293,6 +293,7 @@ cmd_display_menu_exec(struct cmd *self, struct cmdq_item *item)
const char *key, *name, *value; const char *key, *name, *value;
const char *style = args_get(args, 's'); const char *style = args_get(args, 's');
const char *border_style = args_get(args, 'S'); const char *border_style = args_get(args, 'S');
const char *selected_style = args_get(args, 'H');
enum box_lines lines = BOX_LINES_DEFAULT; enum box_lines lines = BOX_LINES_DEFAULT;
char *title, *cause; char *title, *cause;
int flags = 0, starting_choice = 0; int flags = 0, starting_choice = 0;
@ -376,7 +377,7 @@ cmd_display_menu_exec(struct cmd *self, struct cmdq_item *item)
if (!event->m.valid) if (!event->m.valid)
flags |= MENU_NOMOUSE; flags |= MENU_NOMOUSE;
if (menu_display(menu, flags, starting_choice, item, px, py, tc, lines, if (menu_display(menu, flags, starting_choice, item, px, py, tc, lines,
style, border_style, target, NULL, NULL) != 0) style, selected_style, border_style, target, NULL, NULL) != 0)
return (CMD_RETURN_NORMAL); return (CMD_RETURN_NORMAL);
return (CMD_RETURN_WAIT); return (CMD_RETURN_WAIT);
} }

62
menu.c
View File

@ -29,6 +29,7 @@ struct menu_data {
struct grid_cell style; struct grid_cell style;
struct grid_cell border_style; struct grid_cell border_style;
struct grid_cell selected_style;
enum box_lines border_lines; enum box_lines border_lines;
struct cmd_find_state fs; struct cmd_find_state fs;
@ -201,7 +202,6 @@ menu_draw_cb(struct client *c, void *data,
struct menu *menu = md->menu; struct menu *menu = md->menu;
struct screen_write_ctx ctx; struct screen_write_ctx ctx;
u_int i, px = md->px, py = md->py; u_int i, px = md->px, py = md->py;
struct grid_cell gc;
screen_write_start(&ctx, s); screen_write_start(&ctx, s);
screen_write_clearscreen(&ctx, 8); screen_write_clearscreen(&ctx, 8);
@ -210,10 +210,9 @@ menu_draw_cb(struct client *c, void *data,
screen_write_box(&ctx, menu->width + 4, menu->count + 2, screen_write_box(&ctx, menu->width + 4, menu->count + 2,
md->border_lines, &md->border_style, menu->title); md->border_lines, &md->border_style, menu->title);
} }
style_apply(&gc, c->session->curw->window->options, "mode-style", NULL);
screen_write_menu(&ctx, menu, md->choice, md->border_lines, screen_write_menu(&ctx, menu, md->choice, md->border_lines,
&md->style, &md->border_style, &gc); &md->style, &md->border_style, &md->selected_style);
screen_write_stop(&ctx); screen_write_stop(&ctx);
for (i = 0; i < screen_size_y(&md->s); i++) { for (i = 0; i < screen_size_y(&md->s); i++) {
@ -438,16 +437,35 @@ chosen:
return (1); return (1);
} }
static void
menu_set_style(struct client *c, struct grid_cell *gc, const char *style,
const char *option)
{
struct style sytmp;
struct options *o = c->session->curw->window->options;
memcpy(gc, &grid_default_cell, sizeof *gc);
style_apply(gc, o, option, NULL);
if (style != NULL) {
style_set(&sytmp, &grid_default_cell);
if (style_parse(&sytmp, gc, style) == 0) {
gc->fg = sytmp.gc.fg;
gc->bg = sytmp.gc.bg;
}
}
gc->attr = 0;
}
struct menu_data * struct menu_data *
menu_prepare(struct menu *menu, int flags, int starting_choice, menu_prepare(struct menu *menu, int flags, int starting_choice,
struct cmdq_item *item, u_int px, u_int py, struct client *c, struct cmdq_item *item, u_int px, u_int py, struct client *c,
enum box_lines lines, const char *style, const char *border_style, enum box_lines lines, const char *style, const char *selected_style,
struct cmd_find_state *fs, menu_choice_cb cb, void *data) const char *border_style, struct cmd_find_state *fs, menu_choice_cb cb,
void *data)
{ {
struct menu_data *md; struct menu_data *md;
int choice; int choice;
const char *name; const char *name;
struct style sytmp;
struct options *o = c->session->curw->window->options; struct options *o = c->session->curw->window->options;
if (c->tty.sx < menu->width + 4 || c->tty.sy < menu->count + 2) if (c->tty.sx < menu->width + 4 || c->tty.sy < menu->count + 2)
@ -465,27 +483,10 @@ menu_prepare(struct menu *menu, int flags, int starting_choice,
md->flags = flags; md->flags = flags;
md->border_lines = lines; md->border_lines = lines;
memcpy(&md->style, &grid_default_cell, sizeof md->style); menu_set_style(c, &md->style, style, "menu-style");
style_apply(&md->style, o, "menu-style", NULL); menu_set_style(c, &md->selected_style, selected_style,
if (style != NULL) { "menu-selected-style");
style_set(&sytmp, &grid_default_cell); menu_set_style(c, &md->border_style, border_style, "menu-border-style");
if (style_parse(&sytmp, &md->style, style) == 0) {
md->style.fg = sytmp.gc.fg;
md->style.bg = sytmp.gc.bg;
}
}
md->style.attr = 0;
memcpy(&md->border_style, &grid_default_cell, sizeof md->border_style);
style_apply(&md->border_style, o, "menu-border-style", NULL);
if (border_style != NULL) {
style_set(&sytmp, &grid_default_cell);
if (style_parse(&sytmp, &md->border_style, border_style) == 0) {
md->border_style.fg = sytmp.gc.fg;
md->border_style.bg = sytmp.gc.bg;
}
}
md->border_style.attr = 0;
if (fs != NULL) if (fs != NULL)
cmd_find_copy_state(&md->fs, fs); cmd_find_copy_state(&md->fs, fs);
@ -539,13 +540,14 @@ menu_prepare(struct menu *menu, int flags, int starting_choice,
int int
menu_display(struct menu *menu, int flags, int starting_choice, menu_display(struct menu *menu, int flags, int starting_choice,
struct cmdq_item *item, u_int px, u_int py, struct client *c, struct cmdq_item *item, u_int px, u_int py, struct client *c,
enum box_lines lines, const char *style, const char *border_style, enum box_lines lines, const char *style, const char *selected_style,
struct cmd_find_state *fs, menu_choice_cb cb, void *data) const char *border_style, struct cmd_find_state *fs, menu_choice_cb cb,
void *data)
{ {
struct menu_data *md; struct menu_data *md;
md = menu_prepare(menu, flags, starting_choice, item, px, py, c, lines, md = menu_prepare(menu, flags, starting_choice, item, px, py, c, lines,
style, border_style, fs, cb, data); style, selected_style, border_style, fs, cb, data);
if (md == NULL) if (md == NULL)
return (-1); return (-1);
server_client_set_overlay(c, 0, NULL, menu_mode_cb, menu_draw_cb, server_client_set_overlay(c, 0, NULL, menu_mode_cb, menu_draw_cb,

View File

@ -963,7 +963,7 @@ mode_tree_display_menu(struct mode_tree_data *mtd, struct client *c, u_int x,
else else
x = 0; x = 0;
if (menu_display(menu, 0, 0, NULL, x, y, c, BOX_LINES_DEFAULT, NULL, if (menu_display(menu, 0, 0, NULL, x, y, c, BOX_LINES_DEFAULT, NULL,
NULL, NULL, mode_tree_menu_callback, mtm) != 0) NULL, NULL, NULL, mode_tree_menu_callback, mtm) != 0)
menu_free(menu); menu_free(menu);
} }

View File

@ -336,6 +336,15 @@ const struct options_table_entry options_table[] = {
.text = "Default style of menu." .text = "Default style of menu."
}, },
{ .name = "menu-selected-style",
.type = OPTIONS_TABLE_STRING,
.scope = OPTIONS_TABLE_WINDOW,
.flags = OPTIONS_TABLE_IS_STYLE,
.default_str = "bg=yellow,fg=black",
.separator = ",",
.text = "Default style of selected menu item."
},
{ .name = "menu-border-style", { .name = "menu-border-style",
.type = OPTIONS_TABLE_STRING, .type = OPTIONS_TABLE_STRING,
.scope = OPTIONS_TABLE_WINDOW, .scope = OPTIONS_TABLE_WINDOW,
@ -962,8 +971,8 @@ const struct options_table_entry options_table[] = {
{ .name = "mode-style", { .name = "mode-style",
.type = OPTIONS_TABLE_STRING, .type = OPTIONS_TABLE_STRING,
.scope = OPTIONS_TABLE_WINDOW, .scope = OPTIONS_TABLE_WINDOW,
.default_str = "bg=yellow,fg=black",
.flags = OPTIONS_TABLE_IS_STYLE, .flags = OPTIONS_TABLE_IS_STYLE,
.default_str = "bg=yellow,fg=black",
.separator = ",", .separator = ",",
.text = "Style of indicators and highlighting in modes." .text = "Style of indicators and highlighting in modes."
}, },

View File

@ -576,7 +576,7 @@ menu:
else else
x = 0; x = 0;
pd->md = menu_prepare(pd->menu, 0, 0, NULL, x, m->y, c, pd->md = menu_prepare(pd->menu, 0, 0, NULL, x, m->y, c,
BOX_LINES_DEFAULT, NULL, NULL, NULL, popup_menu_done, pd); BOX_LINES_DEFAULT, NULL, NULL, NULL, NULL, popup_menu_done, pd);
c->flags |= CLIENT_REDRAWOVERLAY; c->flags |= CLIENT_REDRAWOVERLAY;
out: out:

View File

@ -733,7 +733,7 @@ screen_write_menu(struct screen_write_ctx *ctx, struct menu *menu, int choice,
continue; continue;
} }
format_draw(ctx, gc, width, name, NULL, gc == choice_gc); format_draw(ctx, gc, width, name, NULL, 0);
gc = &default_gc; gc = &default_gc;
} }

View File

@ -1765,8 +1765,8 @@ status_prompt_complete_list_menu(struct client *c, char **list, u_int size,
offset = 0; offset = 0;
if (menu_display(menu, MENU_NOMOUSE|MENU_TAB, 0, NULL, offset, py, c, if (menu_display(menu, MENU_NOMOUSE|MENU_TAB, 0, NULL, offset, py, c,
BOX_LINES_DEFAULT, NULL, NULL, NULL, status_prompt_menu_callback, BOX_LINES_DEFAULT, NULL, NULL, NULL, NULL,
spm) != 0) { status_prompt_menu_callback, spm) != 0) {
menu_free(menu); menu_free(menu);
free(spm); free(spm);
return (0); return (0);
@ -1859,8 +1859,8 @@ status_prompt_complete_window_menu(struct client *c, struct session *s,
offset = 0; offset = 0;
if (menu_display(menu, MENU_NOMOUSE|MENU_TAB, 0, NULL, offset, py, c, if (menu_display(menu, MENU_NOMOUSE|MENU_TAB, 0, NULL, offset, py, c,
BOX_LINES_DEFAULT, NULL, NULL, NULL, status_prompt_menu_callback, BOX_LINES_DEFAULT, NULL, NULL, NULL, NULL,
spm) != 0) { status_prompt_menu_callback, spm) != 0) {
menu_free(menu); menu_free(menu);
free(spm); free(spm);
return (NULL); return (NULL);

16
tmux.1
View File

@ -4096,6 +4096,13 @@ See the
section on how to specify section on how to specify
.Ar style . .Ar style .
Attributes are ignored. Attributes are ignored.
.It Ic menu-selected-style Ar style
Set the selected menu item style.
See the
.Sx STYLES
section on how to specify
.Ar style .
Attributes are ignored.
.It Ic menu-border-style Ar style .It Ic menu-border-style Ar style
Set the menu border style. Set the menu border style.
See the See the
@ -4108,7 +4115,7 @@ Set the type of characters used for drawing menu borders.
See See
.Ic popup-border-lines .Ic popup-border-lines
for possible values for for possible values for
.Ar type . .Ar border-lines .
.It Ic message-command-style Ar style .It Ic message-command-style Ar style
Set status line message command style. Set status line message command style.
This is used for the command prompt with This is used for the command prompt with
@ -6064,10 +6071,11 @@ the default is
.Op Fl O .Op Fl O
.Op Fl b Ar border-lines .Op Fl b Ar border-lines
.Op Fl c Ar target-client .Op Fl c Ar target-client
.Op Fl C Ar starting-choice
.Op Fl H Ar selected-style
.Op Fl s Ar style .Op Fl s Ar style
.Op Fl S Ar border-style .Op Fl S Ar border-style
.Op Fl t Ar target-pane .Op Fl t Ar target-pane
.Op Fl C Ar starting-choice
.Op Fl T Ar title .Op Fl T Ar title
.Op Fl x Ar position .Op Fl x Ar position
.Op Fl y Ar position .Op Fl y Ar position
@ -6101,6 +6109,10 @@ See
for possible values for for possible values for
.Ar border-lines . .Ar border-lines .
.Pp .Pp
.Fl H
sets the style for the selected menu item (see
.Sx STYLES ) .
.Pp
.Fl s .Fl s
sets the style for the menu and sets the style for the menu and
.Fl S .Fl S

8
tmux.h
View File

@ -3308,12 +3308,12 @@ void menu_add_item(struct menu *, const struct menu_item *,
void menu_free(struct menu *); void menu_free(struct menu *);
struct menu_data *menu_prepare(struct menu *, int, int, struct cmdq_item *, struct menu_data *menu_prepare(struct menu *, int, int, struct cmdq_item *,
u_int, u_int, struct client *, enum box_lines, const char *, u_int, u_int, struct client *, enum box_lines, const char *,
const char *, struct cmd_find_state *, menu_choice_cb, const char *, const char *, struct cmd_find_state *,
void *); menu_choice_cb, void *);
int menu_display(struct menu *, int, int, struct cmdq_item *, int menu_display(struct menu *, int, int, struct cmdq_item *,
u_int, u_int, struct client *, enum box_lines, const char *, u_int, u_int, struct client *, enum box_lines, const char *,
const char *, struct cmd_find_state *, menu_choice_cb, const char *, const char *, struct cmd_find_state *,
void *); menu_choice_cb, void *);
struct screen *menu_mode_cb(struct client *, void *, u_int *, u_int *); struct screen *menu_mode_cb(struct client *, void *, u_int *, u_int *);
void menu_check_cb(struct client *, void *, u_int, u_int, u_int, void menu_check_cb(struct client *, void *, u_int, u_int, u_int,
struct overlay_ranges *); struct overlay_ranges *);