summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicholas Marriott <nicm@cvs.openbsd.org>2023-08-08 08:08:48 +0000
committerNicholas Marriott <nicm@cvs.openbsd.org>2023-08-08 08:08:48 +0000
commit594d665fcf720506f149d95fe093013f61f3b653 (patch)
treecef799cdd5a955c0c8b9cb6d7ffac33507752b03
parent9bd89ae3f2d99f469450f150bda70872426b48dc (diff)
Add options and flags for menu styles similar to those existing for
popups, from Alexis Hildebrandt. GitHub issue 3650.
-rw-r--r--usr.bin/tmux/cmd-display-menu.c41
-rw-r--r--usr.bin/tmux/menu.c53
-rw-r--r--usr.bin/tmux/mode-tree.c6
-rw-r--r--usr.bin/tmux/options-table.c29
-rw-r--r--usr.bin/tmux/popup.c6
-rw-r--r--usr.bin/tmux/screen-write.c9
-rw-r--r--usr.bin/tmux/status.c12
-rw-r--r--usr.bin/tmux/tmux.173
-rw-r--r--usr.bin/tmux/tmux.h12
9 files changed, 181 insertions, 60 deletions
diff --git a/usr.bin/tmux/cmd-display-menu.c b/usr.bin/tmux/cmd-display-menu.c
index 712524c9a55..d616d0c4314 100644
--- a/usr.bin/tmux/cmd-display-menu.c
+++ b/usr.bin/tmux/cmd-display-menu.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: cmd-display-menu.c,v 1.40 2023/08/07 10:52:00 nicm Exp $ */
+/* $OpenBSD: cmd-display-menu.c,v 1.41 2023/08/08 08:08:47 nicm Exp $ */
/*
* Copyright (c) 2019 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -39,10 +39,11 @@ const struct cmd_entry cmd_display_menu_entry = {
.name = "display-menu",
.alias = "menu",
- .args = { "c:t:S:OT:x:y:", 1, -1, cmd_display_menu_args_parse },
- .usage = "[-O] [-c target-client] [-S starting-choice] "
- CMD_TARGET_PANE_USAGE " [-T title] [-x position] "
- "[-y position] name key command ...",
+ .args = { "b:c:C:t:s:S:OT:x:y:", 1, -1, cmd_display_menu_args_parse },
+ .usage = "[-O] [-b border-lines] [-c target-client] "
+ "[-C starting-choice] [-s style] [-S border-style] "
+ CMD_TARGET_PANE_USAGE "[-T title] [-x position] [-y position] "
+ "name key command ...",
.target = { 't', CMD_FIND_PANE, 0 },
@@ -289,19 +290,25 @@ cmd_display_menu_exec(struct cmd *self, struct cmdq_item *item)
struct client *tc = cmdq_get_target_client(item);
struct menu *menu = NULL;
struct menu_item menu_item;
- const char *key, *name;
+ const char *key, *name, *value;
+ const char *style = args_get(args, 's');
+ const char *border_style = args_get(args, 'S');
+ enum box_lines lines = BOX_LINES_DEFAULT;
char *title, *cause;
int flags = 0, starting_choice = 0;
u_int px, py, i, count = args_count(args);
+ struct options *o = target->s->curw->window->options;
+ struct options_entry *oe;
+
if (tc->overlay_draw != NULL)
return (CMD_RETURN_NORMAL);
- if (args_has(args, 'S')) {
- if (strcmp(args_get(args, 'S'), "-") == 0)
+ if (args_has(args, 'C')) {
+ if (strcmp(args_get(args, 'C'), "-") == 0)
starting_choice = -1;
else {
- starting_choice = args_strtonum(args, 'S', 0, UINT_MAX,
+ starting_choice = args_strtonum(args, 'C', 0, UINT_MAX,
&cause);
if (cause != NULL) {
cmdq_error(item, "starting choice %s", cause);
@@ -352,12 +359,24 @@ cmd_display_menu_exec(struct cmd *self, struct cmdq_item *item)
return (CMD_RETURN_NORMAL);
}
+ value = args_get(args, 'b');
+ if (value != NULL) {
+ oe = options_get(o, "menu-border-lines");
+ lines = options_find_choice(options_table_entry(oe), value,
+ &cause);
+ if (lines == -1) {
+ cmdq_error(item, "menu-border-lines %s", cause);
+ free(cause);
+ return (CMD_RETURN_ERROR);
+ }
+ }
+
if (args_has(args, 'O'))
flags |= MENU_STAYOPEN;
if (!event->m.valid)
flags |= MENU_NOMOUSE;
- if (menu_display(menu, flags, starting_choice, item, px, py, tc, target,
- NULL, NULL) != 0)
+ if (menu_display(menu, flags, starting_choice, item, px, py, tc, lines,
+ style, border_style, target, NULL, NULL) != 0)
return (CMD_RETURN_NORMAL);
return (CMD_RETURN_WAIT);
}
diff --git a/usr.bin/tmux/menu.c b/usr.bin/tmux/menu.c
index 4c72a49edde..4b0622020e7 100644
--- a/usr.bin/tmux/menu.c
+++ b/usr.bin/tmux/menu.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: menu.c,v 1.50 2023/08/08 07:41:04 nicm Exp $ */
+/* $OpenBSD: menu.c,v 1.51 2023/08/08 08:08:47 nicm Exp $ */
/*
* Copyright (c) 2019 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -27,6 +27,10 @@ struct menu_data {
struct cmdq_item *item;
int flags;
+ struct grid_cell style;
+ struct grid_cell border_style;
+ enum box_lines border_lines;
+
struct cmd_find_state fs;
struct screen s;
@@ -199,12 +203,17 @@ menu_draw_cb(struct client *c, void *data,
u_int i, px = md->px, py = md->py;
struct grid_cell gc;
- style_apply(&gc, c->session->curw->window->options, "mode-style", NULL);
-
screen_write_start(&ctx, s);
screen_write_clearscreen(&ctx, 8);
- screen_write_menu(&ctx, menu, md->choice, BOX_LINES_DEFAULT,
- &grid_default_cell, &grid_default_cell, &gc);
+
+ if (md->border_lines != BOX_LINES_NONE) {
+ screen_write_box(&ctx, menu->width + 4, menu->count + 2,
+ 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,
+ &md->style, &md->border_style, &gc);
screen_write_stop(&ctx);
for (i = 0; i < screen_size_y(&md->s); i++) {
@@ -432,11 +441,14 @@ chosen:
struct menu_data *
menu_prepare(struct menu *menu, int flags, int starting_choice,
struct cmdq_item *item, u_int px, u_int py, struct client *c,
+ enum box_lines lines, const char *style, const char *border_style,
struct cmd_find_state *fs, menu_choice_cb cb, void *data)
{
struct menu_data *md;
int choice;
const char *name;
+ struct style sytmp;
+ struct options *o = c->session->curw->window->options;
if (c->tty.sx < menu->width + 4 || c->tty.sy < menu->count + 2)
return (NULL);
@@ -445,9 +457,35 @@ menu_prepare(struct menu *menu, int flags, int starting_choice,
if (py + menu->count + 2 > c->tty.sy)
py = c->tty.sy - menu->count - 2;
+ if (lines == BOX_LINES_DEFAULT)
+ lines = options_get_number(o, "menu-border-lines");
+
md = xcalloc(1, sizeof *md);
md->item = item;
md->flags = flags;
+ md->border_lines = lines;
+
+ memcpy(&md->style, &grid_default_cell, sizeof md->style);
+ style_apply(&md->style, o, "menu-style", NULL);
+ if (style != NULL) {
+ style_set(&sytmp, &grid_default_cell);
+ 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)
cmd_find_copy_state(&md->fs, fs);
@@ -501,12 +539,13 @@ menu_prepare(struct menu *menu, int flags, int starting_choice,
int
menu_display(struct menu *menu, int flags, int starting_choice,
struct cmdq_item *item, u_int px, u_int py, struct client *c,
+ enum box_lines lines, const char *style, const char *border_style,
struct cmd_find_state *fs, menu_choice_cb cb, void *data)
{
struct menu_data *md;
- md = menu_prepare(menu, flags, starting_choice, item, px, py, c, fs, cb,
- data);
+ md = menu_prepare(menu, flags, starting_choice, item, px, py, c, lines,
+ style, border_style, fs, cb, data);
if (md == NULL)
return (-1);
server_client_set_overlay(c, 0, NULL, menu_mode_cb, menu_draw_cb,
diff --git a/usr.bin/tmux/mode-tree.c b/usr.bin/tmux/mode-tree.c
index b90980f9f7a..08a5c294f5f 100644
--- a/usr.bin/tmux/mode-tree.c
+++ b/usr.bin/tmux/mode-tree.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mode-tree.c,v 1.63 2023/01/20 21:36:00 nicm Exp $ */
+/* $OpenBSD: mode-tree.c,v 1.64 2023/08/08 08:08:47 nicm Exp $ */
/*
* Copyright (c) 2017 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -962,8 +962,8 @@ mode_tree_display_menu(struct mode_tree_data *mtd, struct client *c, u_int x,
x -= (menu->width + 4) / 2;
else
x = 0;
- if (menu_display(menu, 0, 0, NULL, x, y, c, NULL,
- mode_tree_menu_callback, mtm) != 0)
+ if (menu_display(menu, 0, 0, NULL, x, y, c, BOX_LINES_DEFAULT, NULL,
+ NULL, NULL, mode_tree_menu_callback, mtm) != 0)
menu_free(menu);
}
diff --git a/usr.bin/tmux/options-table.c b/usr.bin/tmux/options-table.c
index d7757f7f691..211257f218a 100644
--- a/usr.bin/tmux/options-table.c
+++ b/usr.bin/tmux/options-table.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: options-table.c,v 1.165 2022/09/09 11:02:23 nicm Exp $ */
+/* $OpenBSD: options-table.c,v 1.166 2023/08/08 08:08:47 nicm Exp $ */
/*
* Copyright (c) 2011 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -327,6 +327,33 @@ const struct options_table_entry options_table[] = {
"Empty does not write a history file."
},
+ { .name = "menu-style",
+ .type = OPTIONS_TABLE_STRING,
+ .scope = OPTIONS_TABLE_WINDOW,
+ .flags = OPTIONS_TABLE_IS_STYLE,
+ .default_str = "default",
+ .separator = ",",
+ .text = "Default style of menu."
+ },
+
+ { .name = "menu-border-style",
+ .type = OPTIONS_TABLE_STRING,
+ .scope = OPTIONS_TABLE_WINDOW,
+ .default_str = "default",
+ .flags = OPTIONS_TABLE_IS_STYLE,
+ .separator = ",",
+ .text = "Default style of menu borders."
+ },
+
+ { .name = "menu-border-lines",
+ .type = OPTIONS_TABLE_CHOICE,
+ .scope = OPTIONS_TABLE_WINDOW,
+ .choices = options_table_popup_border_lines_list,
+ .default_num = BOX_LINES_SINGLE,
+ .text = "Type of characters used to draw menu border lines. Some of "
+ "these are only supported on terminals with UTF-8 support."
+ },
+
{ .name = "message-limit",
.type = OPTIONS_TABLE_NUMBER,
.scope = OPTIONS_TABLE_SERVER,
diff --git a/usr.bin/tmux/popup.c b/usr.bin/tmux/popup.c
index b172f40267b..35adb1b3ccb 100644
--- a/usr.bin/tmux/popup.c
+++ b/usr.bin/tmux/popup.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: popup.c,v 1.50 2023/06/21 06:28:18 nicm Exp $ */
+/* $OpenBSD: popup.c,v 1.51 2023/08/08 08:08:47 nicm Exp $ */
/*
* Copyright (c) 2020 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -575,8 +575,8 @@ menu:
x = m->x - (pd->menu->width + 4) / 2;
else
x = 0;
- pd->md = menu_prepare(pd->menu, 0, 0, NULL, x, m->y, c, NULL,
- popup_menu_done, pd);
+ pd->md = menu_prepare(pd->menu, 0, 0, NULL, x, m->y, c,
+ BOX_LINES_DEFAULT, NULL, NULL, NULL, popup_menu_done, pd);
c->flags |= CLIENT_REDRAWOVERLAY;
out:
diff --git a/usr.bin/tmux/screen-write.c b/usr.bin/tmux/screen-write.c
index 9f57565a88c..8d98e0e9967 100644
--- a/usr.bin/tmux/screen-write.c
+++ b/usr.bin/tmux/screen-write.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: screen-write.c,v 1.216 2023/08/08 07:41:04 nicm Exp $ */
+/* $OpenBSD: screen-write.c,v 1.217 2023/08/08 08:08:47 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -713,15 +713,16 @@ screen_write_menu(struct screen_write_ctx *ctx, struct menu *menu, int choice,
name = menu->items[i].name;
if (name == NULL) {
screen_write_cursormove(ctx, cx, cy + 1 + i, 0);
- screen_write_hline(ctx, width + 4, 1, 1, lines, gc);
+ screen_write_hline(ctx, width + 4, 1, 1, lines,
+ border_gc);
continue;
}
if (choice >= 0 && i == (u_int)choice && *name != '-')
gc = choice_gc;
- screen_write_cursormove(ctx, cx + 2, cy + 1 + i, 0);
- for (j = 0; j < width; j++)
+ screen_write_cursormove(ctx, cx + 1, cy + 1 + i, 0);
+ for (j = 0; j < width + 2; j++)
screen_write_putc(ctx, gc, ' ');
screen_write_cursormove(ctx, cx + 2, cy + 1 + i, 0);
diff --git a/usr.bin/tmux/status.c b/usr.bin/tmux/status.c
index d562ea4dd9d..ce8c9f70506 100644
--- a/usr.bin/tmux/status.c
+++ b/usr.bin/tmux/status.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: status.c,v 1.238 2023/04/17 18:22:24 nicm Exp $ */
+/* $OpenBSD: status.c,v 1.239 2023/08/08 08:08:47 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -1764,8 +1764,9 @@ status_prompt_complete_list_menu(struct client *c, char **list, u_int size,
else
offset = 0;
- if (menu_display(menu, MENU_NOMOUSE|MENU_TAB, 0, NULL, offset,
- py, c, NULL, status_prompt_menu_callback, spm) != 0) {
+ if (menu_display(menu, MENU_NOMOUSE|MENU_TAB, 0, NULL, offset, py, c,
+ BOX_LINES_DEFAULT, NULL, NULL, NULL, status_prompt_menu_callback,
+ spm) != 0) {
menu_free(menu);
free(spm);
return (0);
@@ -1857,8 +1858,9 @@ status_prompt_complete_window_menu(struct client *c, struct session *s,
else
offset = 0;
- if (menu_display(menu, MENU_NOMOUSE|MENU_TAB, 0, NULL, offset,
- py, c, NULL, status_prompt_menu_callback, spm) != 0) {
+ if (menu_display(menu, MENU_NOMOUSE|MENU_TAB, 0, NULL, offset, py, c,
+ BOX_LINES_DEFAULT, NULL, NULL, NULL, status_prompt_menu_callback,
+ spm) != 0) {
menu_free(menu);
free(spm);
return (NULL);
diff --git a/usr.bin/tmux/tmux.1 b/usr.bin/tmux/tmux.1
index cf0f9fdb167..35c6a1187aa 100644
--- a/usr.bin/tmux/tmux.1
+++ b/usr.bin/tmux/tmux.1
@@ -1,4 +1,4 @@
-.\" $OpenBSD: tmux.1,v 1.924 2023/07/11 16:09:09 nicm Exp $
+.\" $OpenBSD: tmux.1,v 1.925 2023/08/08 08:08:47 nicm Exp $
.\"
.\" Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
.\"
@@ -14,7 +14,7 @@
.\" IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
.\" OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
-.Dd $Mdocdate: July 11 2023 $
+.Dd $Mdocdate: August 8 2023 $
.Dt TMUX 1
.Os
.Sh NAME
@@ -4073,6 +4073,26 @@ The default is to run
.Xr lock 1
with
.Fl np .
+.It Ic menu-style Ar style
+Set the menu style.
+See the
+.Sx STYLES
+section on how to specify
+.Ar style .
+Attributes are ignored.
+.It Ic menu-border-style Ar style
+Set the menu border style.
+See the
+.Sx STYLES
+section on how to specify
+.Ar style .
+Attributes are ignored.
+.It Ic menu-border-lines Ar type
+Set the type of characters used for drawing menu borders.
+See
+.Ic popup-border-lines
+for possible values for
+.Ar type .
.It Ic message-command-style Ar style
Set status line message command style.
This is used for the command prompt with
@@ -4540,20 +4560,18 @@ Attributes are ignored.
.Pp
.It Ic popup-style Ar style
Set the popup style.
-For how to specify
-.Ar style ,
-see the
+See the
.Sx STYLES
-section.
+section on how to specify
+.Ar style .
Attributes are ignored.
.Pp
.It Ic popup-border-style Ar style
Set the popup border style.
-For how to specify
-.Ar style ,
-see the
+See the
.Sx STYLES
-section.
+section on how to specify
+.Ar style .
Attributes are ignored.
.Pp
.It Ic popup-border-lines Ar type
@@ -6028,9 +6046,12 @@ the default is
.Tg menu
.It Xo Ic display-menu
.Op Fl O
+.Op Fl b Ar border-lines
.Op Fl c Ar target-client
+.Op Fl s Ar style
+.Op Fl S Ar border-style
.Op Fl t Ar target-pane
-.Op Fl S Ar starting-choice
+.Op Fl C Ar starting-choice
.Op Fl T Ar title
.Op Fl x Ar position
.Op Fl y Ar position
@@ -6057,10 +6078,24 @@ may not be chosen.
The name may be empty for a separator line, in which case both the key and
command should be omitted.
.Pp
+.Fl b
+sets the type of characters used for drawing menu borders.
+See
+.Ic popup-border-lines
+for possible values for
+.Ar border-lines .
+.Pp
+.Fl s
+sets the style for the menu and
+.Fl S
+sets the style for the menu border (see
+.Sx STYLES ) .
+.Pp
.Fl T
is a format for the menu title (see
.Sx FORMATS ) .
-.Fl S
+.Pp
+.Fl C
sets the menu item selected by default, if the menu is not bound to a mouse key
binding.
.Pp
@@ -6175,8 +6210,8 @@ forwards any input read from stdin to the empty pane given by
.Op Fl d Ar start-directory
.Op Fl e Ar environment
.Op Fl h Ar height
-.Op Fl s Ar style
-.Op Fl S Ar border-style
+.Op Fl s Ar border-style
+.Op Fl S Ar style
.Op Fl t Ar target-pane
.Op Fl T Ar title
.Op Fl w Ar width
@@ -6219,7 +6254,7 @@ If omitted, half of the terminal size is used.
does not surround the popup by a border.
.Pp
.Fl b
-sets the type of border line for the popup.
+sets the type of characters used for drawing popup borders.
When
.Fl B
is specified, the
@@ -6233,12 +6268,8 @@ for possible values for
.Fl s
sets the style for the popup and
.Fl S
-sets the style for the popup border.
-For how to specify
-.Ar style ,
-see the
-.Sx STYLES
-section.
+sets the style for the popup border (see
+.Sx STYLES ) .
.Pp
.Fl e
takes the form
diff --git a/usr.bin/tmux/tmux.h b/usr.bin/tmux/tmux.h
index 1b994db77e2..b2616b63692 100644
--- a/usr.bin/tmux/tmux.h
+++ b/usr.bin/tmux/tmux.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: tmux.h,v 1.1202 2023/08/08 07:41:04 nicm Exp $ */
+/* $OpenBSD: tmux.h,v 1.1203 2023/08/08 08:08:47 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -3306,11 +3306,13 @@ void menu_add_item(struct menu *, const struct menu_item *,
struct cmd_find_state *);
void menu_free(struct menu *);
struct menu_data *menu_prepare(struct menu *, int, int, struct cmdq_item *,
- u_int, u_int, struct client *, struct cmd_find_state *,
- menu_choice_cb, void *);
+ u_int, u_int, struct client *, enum box_lines, const char *,
+ const char *, struct cmd_find_state *, menu_choice_cb,
+ void *);
int menu_display(struct menu *, int, int, struct cmdq_item *,
- u_int, u_int, struct client *, struct cmd_find_state *,
- menu_choice_cb, void *);
+ u_int, u_int, struct client *, enum box_lines, const char *,
+ const char *, struct cmd_find_state *, menu_choice_cb,
+ void *);
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,
struct overlay_ranges *);