diff options
author | Nicholas Marriott <nicm@cvs.openbsd.org> | 2019-05-28 07:18:43 +0000 |
---|---|---|
committer | Nicholas Marriott <nicm@cvs.openbsd.org> | 2019-05-28 07:18:43 +0000 |
commit | e24280f07a09b142cec6c35affbda616b270073a (patch) | |
tree | 838c2d531cbd21934216d31bc62675be0d06e8c3 | |
parent | da4818b66eb44a1b7d0f1f5b2171d8e61b0d068d (diff) |
Change display-menu from taking a single string to a set of arguments,
which is much easier to work with. Based on a diff from Avi Halachmi.
-rw-r--r-- | usr.bin/tmux/cmd-display-menu.c | 51 | ||||
-rw-r--r-- | usr.bin/tmux/format.c | 53 | ||||
-rw-r--r-- | usr.bin/tmux/key-bindings.c | 51 | ||||
-rw-r--r-- | usr.bin/tmux/menu.c | 118 | ||||
-rw-r--r-- | usr.bin/tmux/mode-tree.c | 30 | ||||
-rw-r--r-- | usr.bin/tmux/tmux.1 | 37 | ||||
-rw-r--r-- | usr.bin/tmux/tmux.h | 22 | ||||
-rw-r--r-- | usr.bin/tmux/window-buffer.c | 31 | ||||
-rw-r--r-- | usr.bin/tmux/window-client.c | 25 | ||||
-rw-r--r-- | usr.bin/tmux/window-tree.c | 31 |
10 files changed, 215 insertions, 234 deletions
diff --git a/usr.bin/tmux/cmd-display-menu.c b/usr.bin/tmux/cmd-display-menu.c index 08d22add102..6e021c77551 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.3 2019/05/26 17:34:45 nicm Exp $ */ +/* $OpenBSD: cmd-display-menu.c,v 1.4 2019/05/28 07:18:42 nicm Exp $ */ /* * Copyright (c) 2019 Nicholas Marriott <nicholas.marriott@gmail.com> @@ -34,9 +34,9 @@ const struct cmd_entry cmd_display_menu_entry = { .name = "display-menu", .alias = "menu", - .args = { "c:FM:t:T:x:y:", 0, 0 }, - .usage = "[-F] [-c target-client] [-M menu] " CMD_TARGET_PANE_USAGE " " - "[-T title] [-x position] [-y position]", + .args = { "c:t:T:x:y:", 1, -1 }, + .usage = "[-c target-client] " CMD_TARGET_PANE_USAGE " [-T title] " + "[-x position] [-y position] name key command ...", .target = { 't', CMD_FIND_PANE, 0 }, @@ -55,10 +55,11 @@ cmd_display_menu_exec(struct cmd *self, struct cmdq_item *item) struct cmd_find_state *fs = &item->target; struct menu *menu = NULL; struct style_range *sr; - const char *string, *xp, *yp; - int at, flags; + struct menu_item menu_item; + const char *xp, *yp, *key; + char *title, *name; + int at, flags, i; u_int px, py, ox, oy, sx, sy; - char *title; if ((c = cmd_find_client(item, args_get(args, 'c'), 0)) == NULL) return (CMD_RETURN_ERROR); @@ -66,23 +67,37 @@ cmd_display_menu_exec(struct cmd *self, struct cmdq_item *item) return (CMD_RETURN_NORMAL); at = status_at_line(c); - string = args_get(args, 'M'); - if (string == NULL) { - cmdq_error(item, "no menu specified"); - return (CMD_RETURN_ERROR); - } - if (args_has(args, 'F')) - string = format_single(NULL, string, c, s, wl, wp); - else - string = xstrdup(string); if (args_has(args, 'T')) title = format_single(NULL, args_get(args, 'T'), c, s, wl, wp); else title = xstrdup(""); - menu = menu_create(string, item, c, fs, title); + + menu = menu_create(title); + + for (i = 0; i != args->argc; /* nothing */) { + name = args->argv[i++]; + if (*name == '\0') { + menu_add_item(menu, NULL, item, c, fs); + continue; + } + + if (args->argc - i < 2) { + cmdq_error(item, "not enough arguments"); + free(title); + menu_free(menu); + return (CMD_RETURN_ERROR); + } + key = args->argv[i++]; + + menu_item.name = name; + menu_item.key = key_string_lookup_string(key); + menu_item.command = args->argv[i++]; + + menu_add_item(menu, &menu_item, item, c, fs); + } free(title); if (menu == NULL) { - cmdq_error(item, "invalid menu %s", string); + cmdq_error(item, "invalid menu arguments"); return (CMD_RETURN_ERROR); } if (menu->count == 0) { diff --git a/usr.bin/tmux/format.c b/usr.bin/tmux/format.c index d6c6868f2d7..d788766c6f0 100644 --- a/usr.bin/tmux/format.c +++ b/usr.bin/tmux/format.c @@ -1,4 +1,4 @@ -/* $OpenBSD: format.c,v 1.199 2019/05/27 15:29:46 nicm Exp $ */ +/* $OpenBSD: format.c,v 1.200 2019/05/28 07:18:42 nicm Exp $ */ /* * Copyright (c) 2011 Nicholas Marriott <nicholas.marriott@gmail.com> @@ -54,52 +54,6 @@ static void format_defaults_session(struct format_tree *, static void format_defaults_client(struct format_tree *, struct client *); static void format_defaults_winlink(struct format_tree *, struct winlink *); -/* Default menus. */ -#define DEFAULT_CLIENT_MENU \ - "Detach,d,detach-client|" \ - "Detach & Kill,X,detach-client -P|" \ - "Detach Others,o,detach-client -a|" \ - "|" \ - "Lock,l,lock-client" -#define DEFAULT_SESSION_MENU \ - "Next,n,switch-client -n|" \ - "Previous,p,switch-client -p|" \ - "|" \ - "Renumber,N,move-window -r|" \ - "Rename,n,command-prompt -I \"#S\" \"rename-session -- '%%'\"|" \ - "|" \ - "New Session,s,new-session|" \ - "New Window,w,new-window" -#define DEFAULT_WINDOW_MENU \ - "Swap Left,l,swap-window -t:-1|" \ - "Swap Right,r,swap-window -t:+1|" \ - "#{?pane_marked_set,,#[dim]}Swap Marked,s,swap-window|" \ - "|" \ - "Kill,X,kill-window|" \ - "Respawn,R,respawn-window -k|" \ - "#{?pane_marked,Unmark,Mark},m,select-pane -m|" \ - "Rename,n,command-prompt -I \"#W\" \"rename-window -- '%%'\"|" \ - "|" \ - "New After,w,new-window -a|" \ - "New At End,W,new-window" -#define DEFAULT_PANE_MENU \ - "#{?mouse_word,Search For #[underscore]#{=/9/...:mouse_word},},C-r,copy-mode -t=; send -Xt= search-backward \"#{q:mouse_word}\"|" \ - "#{?mouse_word,Type #[underscore]#{=/9/...:mouse_word},},C-y,send-keys -l \"#{q:mouse_word}\"|" \ - "#{?mouse_word,Copy #[underscore]#{=/9/...:mouse_word},},c,set-buffer \"#{q:mouse_word}\"|" \ - "#{?mouse_line,Copy Line,},l,set-buffer \"#{q:mouse_line}\"|" \ - "|" \ - "Horizontal Split,h,split-window -h|" \ - "Vertical Split,v,split-window -v|" \ - "|" \ - "Swap Up,u,swap-pane -U|" \ - "Swap Down,d,swap-pane -D|" \ - "#{?pane_marked_set,,#[dim]}Swap Marked,s,swap-pane|" \ - "|" \ - "Kill,X,kill-pane|" \ - "Respawn,R,respawn-pane -k|" \ - "#{?pane_marked,Unmark,Mark},m,select-pane -m|" \ - "#{?window_zoomed_flag,Unzoom,Zoom},z,resize-pane -Z" - /* Entry in format job tree. */ struct format_job { struct client *client; @@ -944,11 +898,6 @@ format_create(struct client *c, struct cmdq_item *item, int tag, int flags) } } - format_add(ft, "client_menu", "%s", DEFAULT_CLIENT_MENU); - format_add(ft, "session_menu", "%s", DEFAULT_SESSION_MENU); - format_add(ft, "window_menu", "%s", DEFAULT_WINDOW_MENU); - format_add(ft, "pane_menu", "%s", DEFAULT_PANE_MENU); - if (item != NULL) format_create_add_item(ft, item); diff --git a/usr.bin/tmux/key-bindings.c b/usr.bin/tmux/key-bindings.c index de5fd64f481..d80e808ba43 100644 --- a/usr.bin/tmux/key-bindings.c +++ b/usr.bin/tmux/key-bindings.c @@ -1,4 +1,4 @@ -/* $OpenBSD: key-bindings.c,v 1.94 2019/05/27 12:16:27 nicm Exp $ */ +/* $OpenBSD: key-bindings.c,v 1.95 2019/05/28 07:18:42 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com> @@ -280,10 +280,51 @@ key_bindings_init(void) "bind -n MouseDrag1Pane if -Ft= '#{mouse_any_flag}' 'if -Ft= \"#{pane_in_mode}\" \"copy-mode -M\" \"send-keys -M\"' 'copy-mode -M'", "bind -n MouseDown3Pane if -Ft= '#{||:mouse_any_flag,pane_in_mode}' 'select-pane -t=; send-keys -M' 'select-pane -mt='", "bind -n WheelUpPane if -Ft= '#{mouse_any_flag}' 'send-keys -M' 'if -Ft= \"#{pane_in_mode}\" \"send-keys -M\" \"copy-mode -et=\"'", - "bind -n MouseDown3StatusRight display-menu -t= -xM -yS -F -M \"#{client_menu}\" -T \"#[align=centre]#{client_name}\"", - "bind -n MouseDown3StatusLeft display-menu -t= -xM -yS -F -M \"#{session_menu}\" -T \"#[align=centre]#{session_name}\"", - "bind -n MouseDown3Status display-menu -t= -xW -yS -F -M \"#{window_menu}\" -T \"#[align=centre]#{window_index}:#{window_name}\"", - "bind -n M-MouseDown3Pane display-menu -t= -xM -yM -F -M \"#{pane_menu}\" -T \"#[align=centre]#{pane_index} (#{pane_id})\"", + + "bind -n MouseDown3StatusRight display-menu -t= -xM -yS -T \"#[align=centre]#{client_name}\"" + " 'Detach' 'd' {detach-client}" + " 'Detach & Kill' 'X' {detach-client -P}" + " 'Detach Others' 'o' {detach-client -a}" + " ''" + " 'Lock' 'l' {lock-client}", + "bind -n MouseDown3StatusLeft display-menu -t= -xM -yS -T \"#[align=centre]#{session_name}\"" + " 'Next' 'n' {switch-client -n}" + " 'Previous' 'p' {switch-client -p}" + " ''" + " 'Renumber' 'N' {move-window -r}" + " 'Rename' 'n' {command-prompt -I \"#S\" \"rename-session -- '%%'\"}" + " ''" + " 'New Session' 's' {new-session}" + " 'New Window' 'w' {new-window}", + "bind -n MouseDown3Status display-menu -t= -xW -yS -T \"#[align=centre]#{window_index}:#{window_name}\"" + " 'Swap Left' 'l' {swap-window -t:-1}" + " 'Swap Right' 'r' {swap-window -t:+1}" + " '#{?pane_marked_set,,#[dim]}Swap Marked' 's' {swap-window}" + " ''" + " 'Kill' 'X' {kill-window}" + " 'Respawn' 'R' {respawn-window -k}" + " '#{?pane_marked,Unmark,Mark}' 'm' {select-pane -m}" + " 'Rename' 'n' {command-prompt -I \"#W\" \"rename-window -- '%%'\"}" + " ''" + " 'New After' 'w' {new-window -a}" + " 'New At End' 'W' {new-window}", + "bind -n M-MouseDown3Pane display-menu -t= -xM -yM -T \"#[align=centre]#{pane_index} (#{pane_id})\"" + " '#{?mouse_word,Search For #[underscore]#{=/9/...:mouse_word},}' 'C-r' {copy-mode -t=; send -Xt= search-backward \"#{q:mouse_word}\"}" + " '#{?mouse_word,Type #[underscore]#{=/9/...:mouse_word},}' 'C-y' {send-keys -l -- \"#{q:mouse_word}\"}" + " '#{?mouse_word,Copy #[underscore]#{=/9/...:mouse_word},}' 'c' {set-buffer -- \"#{q:mouse_word}\"}" + " '#{?mouse_line,Copy Line,}' 'l' {set-buffer -- \"#{q:mouse_line}\"}" + " ''" + " 'Horizontal Split' 'h' {split-window -h}" + " 'Vertical Split' 'v' {split-window -v}" + " ''" + " 'Swap Up' 'u' {swap-pane -U}" + " 'Swap Down' 'd' {swap-pane -D}" + " '#{?pane_marked_set,,#[dim]}Swap Marked' 's' {swap-pane}" + " ''" + " 'Kill' 'X' {kill-pane}" + " 'Respawn' 'R' {respawn-pane -k}" + " '#{?pane_marked,Unmark,Mark}' 'm' {select-pane -m}" + " '#{?window_zoomed_flag,Unzoom,Zoom}' 'z' {resize-pane -Z}", "bind -Tcopy-mode C-Space send -X begin-selection", "bind -Tcopy-mode C-a send -X start-of-line", diff --git a/usr.bin/tmux/menu.c b/usr.bin/tmux/menu.c index c906818e26b..cec97f8d524 100644 --- a/usr.bin/tmux/menu.c +++ b/usr.bin/tmux/menu.c @@ -1,4 +1,4 @@ -/* $OpenBSD: menu.c,v 1.7 2019/05/26 18:19:52 nicm Exp $ */ +/* $OpenBSD: menu.c,v 1.8 2019/05/28 07:18:42 nicm Exp $ */ /* * Copyright (c) 2019 Nicholas Marriott <nicholas.marriott@gmail.com> @@ -40,49 +40,63 @@ struct menu_data { void *data; }; -static void -menu_add_item(struct menu *menu, struct menu_item *item, +void +menu_add_items(struct menu *menu, const struct menu_item *items, + struct cmdq_item *qitem, struct client *c, struct cmd_find_state *fs) +{ + const struct menu_item *loop; + + for (loop = items; loop->name != NULL; loop++) + menu_add_item(menu, loop, qitem, c, fs); +} + +void +menu_add_item(struct menu *menu, const struct menu_item *item, struct cmdq_item *qitem, struct client *c, struct cmd_find_state *fs) { struct menu_item *new_item; - const char *key; - char *name; + const char *key, *cmd; + char *s, *name; u_int width; + int line; + + line = (item == NULL || item->name == NULL || *item->name == '\0'); + if (line && menu->count == 0) + return; menu->items = xreallocarray(menu->items, menu->count + 1, sizeof *menu->items); new_item = &menu->items[menu->count++]; memset(new_item, 0, sizeof *new_item); - if (item == NULL || *item->name == '\0') /* horizontal line */ + if (line) return; - if (fs != NULL) { - name = format_single(qitem, item->name, c, fs->s, fs->wl, - fs->wp); - } else - name = format_single(qitem, item->name, c, NULL, NULL, NULL); - if (*name == '\0') { /* no item if empty after format expanded */ + + if (fs != NULL) + s = format_single(qitem, item->name, c, fs->s, fs->wl, fs->wp); + else + s = format_single(qitem, item->name, c, NULL, NULL, NULL); + if (*s == '\0') { /* no item if empty after format expanded */ menu->count--; return; } - if (item->key != KEYC_UNKNOWN) { + if (item->key != KEYC_UNKNOWN && item->key != KEYC_NONE) { key = key_string_lookup_key(item->key); - xasprintf(&new_item->name, "%s#[default] #[align=right](%s)", - name, key); + xasprintf(&name, "%s#[default] #[align=right](%s)", s, key); } else - xasprintf(&new_item->name, "%s", name); - free(name); - - if (item->command != NULL) { - if (fs != NULL) { - new_item->command = format_single(qitem, item->command, - c, fs->s, fs->wl, fs->wp); - } else { - new_item->command = format_single(qitem, item->command, - c, NULL, NULL, NULL); - } + xasprintf(&name, "%s", s); + new_item->name = name; + free(s); + + cmd = item->command; + if (cmd != NULL) { + if (fs != NULL) + s = format_single(qitem, cmd, c, fs->s, fs->wl, fs->wp); + else + s = format_single(qitem, cmd, c, NULL, NULL, NULL); } else - new_item->command = NULL; + s = NULL; + new_item->command = s; new_item->key = item->key; width = format_width(new_item->name); @@ -90,56 +104,14 @@ menu_add_item(struct menu *menu, struct menu_item *item, menu->width = width; } -static void -menu_parse_item(struct menu *menu, const char *s, struct cmdq_item *qitem, - struct client *c, struct cmd_find_state *fs) -{ - char *copy, *first; - const char *second, *third; - struct menu_item item; - - first = copy = xstrdup(s); - if ((second = format_skip(first, ",")) != NULL) { - *(char *)second++ = '\0'; - if ((third = format_skip(second, ",")) != NULL) { - *(char *)third++ = '\0'; - - item.name = first; - item.command = (char *)third; - item.key = key_string_lookup_string(second); - menu_add_item(menu, &item, qitem, c, fs); - } - } - free(copy); -} - struct menu * -menu_create(const char *s, struct cmdq_item *qitem, struct client *c, - struct cmd_find_state *fs, const char *title) +menu_create(const char *title) { struct menu *menu; - char *copy, *string, *next; - - if (*s == '\0') - return (NULL); menu = xcalloc(1, sizeof *menu); menu->title = xstrdup(title); - copy = string = xstrdup(s); - do { - next = (char *)format_skip(string, "|"); - if (next != NULL) - *next++ = '\0'; - if (*string == '\0') { - if (menu->count != 0) - menu_add_item(menu, NULL, qitem, c, fs); - } else - menu_parse_item(menu, string, qitem, c, fs); - string = next; - } while (next != NULL); - free(copy); - return (menu); } @@ -149,12 +121,12 @@ menu_free(struct menu *menu) u_int i; for (i = 0; i < menu->count; i++) { - free(menu->items[i].name); - free(menu->items[i].command); + free((void *)menu->items[i].name); + free((void *)menu->items[i].command); } free(menu->items); - free(menu->title); + free((void *)menu->title); free(menu); } diff --git a/usr.bin/tmux/mode-tree.c b/usr.bin/tmux/mode-tree.c index e726164582d..27c7fa8d578 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.32 2019/05/27 06:50:04 nicm Exp $ */ +/* $OpenBSD: mode-tree.c,v 1.33 2019/05/28 07:18:42 nicm Exp $ */ /* * Copyright (c) 2017 Nicholas Marriott <nicholas.marriott@gmail.com> @@ -35,7 +35,7 @@ struct mode_tree_data { struct window_pane *wp; void *modedata; - const char *menu; + const struct menu_item *menu; const char **sort_list; u_int sort_size; @@ -100,11 +100,14 @@ struct mode_tree_menu { static void mode_tree_free_items(struct mode_tree_list *); -#define MODE_TREE_MENU \ - "Scroll Left,<,|" \ - "Scroll Right,>,|" \ - "|" \ - "Cancel,q," +static const struct menu_item mode_tree_menu_items[] = { + { "Scroll Left", '<', NULL }, + { "Scroll Right", '>', NULL }, + { "", KEYC_NONE, NULL }, + { "Cancel", 'q', NULL }, + + { NULL, KEYC_NONE, NULL } +}; static struct mode_tree_item * mode_tree_find_item(struct mode_tree_list *mtl, uint64_t tag) @@ -315,7 +318,7 @@ struct mode_tree_data * mode_tree_start(struct window_pane *wp, struct args *args, mode_tree_build_cb buildcb, mode_tree_draw_cb drawcb, mode_tree_search_cb searchcb, mode_tree_menu_cb menucb, void *modedata, - const char *menu, const char **sort_list, u_int sort_size, + const struct menu_item *menu, const char **sort_list, u_int sort_size, struct screen **s) { struct mode_tree_data *mtd; @@ -812,8 +815,8 @@ mode_tree_display_menu(struct mode_tree_data *mtd, struct client *c, u_int x, { struct mode_tree_item *mti; struct menu *menu; + const struct menu_item *items; struct mode_tree_menu *mtm; - const char *s; char *title; u_int line; @@ -824,16 +827,15 @@ mode_tree_display_menu(struct mode_tree_data *mtd, struct client *c, u_int x, mti = mtd->line_list[line].item; if (!outside) { - s = mtd->menu; + items = mtd->menu; xasprintf(&title, "#[align=centre]%s", mti->name); } else { - s = MODE_TREE_MENU; + items = mode_tree_menu_items; title = xstrdup(""); } - menu = menu_create(s, NULL, c, NULL, title); + menu = menu_create(title); + menu_add_items(menu, items, NULL, NULL, NULL); free(title); - if (menu == NULL) - return; mtm = xmalloc(sizeof *mtm); mtm->data = mtd; diff --git a/usr.bin/tmux/tmux.1 b/usr.bin/tmux/tmux.1 index e3d5d64a711..24a4e237af5 100644 --- a/usr.bin/tmux/tmux.1 +++ b/usr.bin/tmux/tmux.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: tmux.1,v 1.656 2019/05/27 16:22:32 nicm Exp $ +.\" $OpenBSD: tmux.1,v 1.657 2019/05/28 07:18:42 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: May 27 2019 $ +.Dd $Mdocdate: May 28 2019 $ .Dt TMUX 1 .Os .Sh NAME @@ -4123,7 +4123,6 @@ The following variables are available, where appropriate: .It Li "client_height" Ta "" Ta "Height of client" .It Li "client_key_table" Ta "" Ta "Current key table" .It Li "client_last_session" Ta "" Ta "Name of the client's last session" -.It Li "client_menu" Ta "" Ta "The default client menu" .It Li "client_name" Ta "" Ta "Name of client" .It Li "client_pid" Ta "" Ta "PID of client process" .It Li "client_prefix" Ta "" Ta "1 if prefix key has been pressed" @@ -4184,7 +4183,6 @@ The following variables are available, where appropriate: .It Li "pane_left" Ta "" Ta "Left of pane" .It Li "pane_marked" Ta "" Ta "1 if this is the marked pane" .It Li "pane_marked_set" Ta "" Ta "1 if a marked pane is set" -.It Li "pane_menu" Ta "" Ta "The default pane menu" .It Li "pane_mode" Ta "" Ta "Name of pane mode, if any." .It Li "pane_pid" Ta "" Ta "PID of first process in pane" .It Li "pane_pipe" Ta "" Ta "1 if pane is being piped" @@ -4215,7 +4213,6 @@ The following variables are available, where appropriate: .It Li "session_id" Ta "" Ta "Unique session ID" .It Li "session_last_attached" Ta "" Ta "Time session last attached" .It Li "session_many_attached" Ta "" Ta "1 if multiple clients attached" -.It Li "session_menu" Ta "" Ta "The default session menu" .It Li "session_name" Ta "#S" Ta "Name of session" .It Li "session_stack" Ta "" Ta "Window indexes in most recent order" .It Li "session_windows" Ta "" Ta "Number of windows in session" @@ -4235,7 +4232,6 @@ The following variables are available, where appropriate: .It Li "window_last_flag" Ta "" Ta "1 if window is the last used" .It Li "window_layout" Ta "" Ta "Window layout description, ignoring zoomed window panes" .It Li "window_linked" Ta "" Ta "1 if window is linked across sessions" -.It Li "window_menu" Ta "" Ta "The default window menu" .It Li "window_name" Ta "#W" Ta "Name of window" .It Li "window_offset_x" Ta "" Ta "X offset into window if larger than client" .It Li "window_offset_y" Ta "" Ta "Y offset into window if larger than client" @@ -4654,13 +4650,15 @@ option. This command works only from inside .Nm . .It Xo Ic display-menu -.Op Fl F .Op Fl c Ar target-client -.Op Fl M Ar menu .Op Fl t Ar target-pane .Op Fl T Ar title .Op Fl x Ar position .Op Fl y Ar position +.Ar name +.Ar key +.Ar command +.Ar ... .Xc .D1 (alias: Ic menu ) Display a menu on @@ -4668,27 +4666,16 @@ Display a menu on .Ar target-pane gives the target for any commands run from the menu. .Pp -A menu is passed to -.Fl M -as a list of menu items separated by -.Ql | . -Each menu item consists of three comma-separated parts: -.Bl -enum -width Ds -.It -The menu item name. -This is a format and may include embedded styles, see the +A menu is passed as a series of arguments: first the menu item name, +second the key shortcut (or empty for none) and third the command +to run when the menu item is chosen. +The name and command are formats, see the .Sx FORMATS and .Sx STYLES sections. -.It -The menu item shortcut key. -If this is empty the menu item has no key shortcut. -.It -The command run when the menu item is chosen. -.El -.Pp -An empty menu item is a separator line. +The name may be empty for a separator line, in which case both the key and +command should be omitted. .Pp .Fl T is a format for the menu title (see diff --git a/usr.bin/tmux/tmux.h b/usr.bin/tmux/tmux.h index 2a18becbf95..27ad03f38e8 100644 --- a/usr.bin/tmux/tmux.h +++ b/usr.bin/tmux/tmux.h @@ -1,4 +1,4 @@ -/* $OpenBSD: tmux.h,v 1.906 2019/05/26 17:34:45 nicm Exp $ */ +/* $OpenBSD: tmux.h,v 1.907 2019/05/28 07:18:42 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com> @@ -752,12 +752,12 @@ struct screen_redraw_ctx { /* Menu. */ struct menu_item { - char *name; - char *command; + const char *name; key_code key; + const char *command; }; struct menu { - char *title; + const char *title; struct menu_item *items; u_int count; u_int width; @@ -2467,8 +2467,8 @@ void mode_tree_each_tagged(struct mode_tree_data *, mode_tree_each_cb, void mode_tree_down(struct mode_tree_data *, int); struct mode_tree_data *mode_tree_start(struct window_pane *, struct args *, mode_tree_build_cb, mode_tree_draw_cb, mode_tree_search_cb, - mode_tree_menu_cb, void *, const char *, const char **, u_int, - struct screen **); + mode_tree_menu_cb, void *, const struct menu_item *, const char **, + u_int, struct screen **); void mode_tree_zoom(struct mode_tree_data *, struct args *); void mode_tree_build(struct mode_tree_data *); void mode_tree_free(struct mode_tree_data *); @@ -2600,8 +2600,14 @@ __dead void printflike(1, 2) fatal(const char *, ...); __dead void printflike(1, 2) fatalx(const char *, ...); /* menu.c */ -struct menu *menu_create(const char *, struct cmdq_item *, struct client *, - struct cmd_find_state *, const char *); +struct menu *menu_create(const char *); +void menu_add_items(struct menu *, const struct menu_item *, + struct cmdq_item *, struct client *, + struct cmd_find_state *); +void menu_add_item(struct menu *, const struct menu_item *, + struct cmdq_item *, struct client *, + struct cmd_find_state *); + void menu_free(struct menu *); int menu_display(struct menu *, int, struct cmdq_item *, u_int, u_int, struct client *, struct cmd_find_state *, diff --git a/usr.bin/tmux/window-buffer.c b/usr.bin/tmux/window-buffer.c index 63347f07b93..46e6e4f9f88 100644 --- a/usr.bin/tmux/window-buffer.c +++ b/usr.bin/tmux/window-buffer.c @@ -1,4 +1,4 @@ -/* $OpenBSD: window-buffer.c,v 1.19 2019/05/12 08:58:09 nicm Exp $ */ +/* $OpenBSD: window-buffer.c,v 1.20 2019/05/28 07:18:42 nicm Exp $ */ /* * Copyright (c) 2017 Nicholas Marriott <nicholas.marriott@gmail.com> @@ -39,18 +39,21 @@ static void window_buffer_key(struct window_mode_entry *, #define WINDOW_BUFFER_DEFAULT_FORMAT \ "#{buffer_size} bytes (#{t:buffer_created})" -#define WINDOW_BUFFER_MENU \ - "Paste,p,|" \ - "Paste Tagged,P,|" \ - "|" \ - "Tag,t,|" \ - "Tag All,C-t,|" \ - "Tag None,T,|" \ - "|" \ - "Delete,d,|" \ - "Delete Tagged,D,|" \ - "|" \ - "Cancel,q," +static const struct menu_item window_buffer_menu_items[] = { + { "Paste", 'p', NULL }, + { "Paste Tagged", 'P', NULL }, + { "", KEYC_NONE, NULL }, + { "Tag", 't', NULL }, + { "Tag All", '\024', NULL }, + { "Tag None", 'T', NULL }, + { "", KEYC_NONE, NULL }, + { "Delete", 'd', NULL }, + { "Delete Tagged", 'D', NULL }, + { "", KEYC_NONE, NULL }, + { "Cancel", 'q', NULL }, + + { NULL, KEYC_NONE, NULL } +}; const struct window_mode window_buffer_mode = { .name = "buffer-mode", @@ -315,7 +318,7 @@ window_buffer_init(struct window_mode_entry *wme, struct cmd_find_state *fs, data->data = mode_tree_start(wp, args, window_buffer_build, window_buffer_draw, window_buffer_search, window_buffer_menu, data, - WINDOW_BUFFER_MENU, window_buffer_sort_list, + window_buffer_menu_items, window_buffer_sort_list, nitems(window_buffer_sort_list), &s); mode_tree_zoom(data->data, args); diff --git a/usr.bin/tmux/window-client.c b/usr.bin/tmux/window-client.c index 6a6e109eeef..5969aaa8910 100644 --- a/usr.bin/tmux/window-client.c +++ b/usr.bin/tmux/window-client.c @@ -1,4 +1,4 @@ -/* $OpenBSD: window-client.c,v 1.22 2019/05/12 08:58:09 nicm Exp $ */ +/* $OpenBSD: window-client.c,v 1.23 2019/05/28 07:18:42 nicm Exp $ */ /* * Copyright (c) 2017 Nicholas Marriott <nicholas.marriott@gmail.com> @@ -40,15 +40,18 @@ static void window_client_key(struct window_mode_entry *, "session #{session_name} " \ "(#{client_width}x#{client_height}, #{t:client_activity})" -#define WINDOW_CLIENT_MENU \ - "Detach,d,|" \ - "Detach Tagged,D,|" \ - "|" \ - "Tag,t,|" \ - "Tag All,C-t,|" \ - "Tag None,T,|" \ - "|" \ - "Cancel,q," +static const struct menu_item window_client_menu_items[] = { + { "Detach", 'd', NULL }, + { "Detach Tagged", 'D', NULL }, + { "", KEYC_NONE, NULL }, + { "Tag", 't', NULL }, + { "Tag All", '\024', NULL }, + { "Tag None", 'T', NULL }, + { "", KEYC_NONE, NULL }, + { "Cancel", 'q', NULL }, + + { NULL, KEYC_NONE, NULL } +}; const struct window_mode window_client_mode = { .name = "client-mode", @@ -296,7 +299,7 @@ window_client_init(struct window_mode_entry *wme, data->data = mode_tree_start(wp, args, window_client_build, window_client_draw, NULL, window_client_menu, data, - WINDOW_CLIENT_MENU, window_client_sort_list, + window_client_menu_items, window_client_sort_list, nitems(window_client_sort_list), &s); mode_tree_zoom(data->data, args); diff --git a/usr.bin/tmux/window-tree.c b/usr.bin/tmux/window-tree.c index 4082a85d1cd..e4b52c7d423 100644 --- a/usr.bin/tmux/window-tree.c +++ b/usr.bin/tmux/window-tree.c @@ -1,4 +1,4 @@ -/* $OpenBSD: window-tree.c,v 1.38 2019/05/12 08:58:09 nicm Exp $ */ +/* $OpenBSD: window-tree.c,v 1.39 2019/05/28 07:18:42 nicm Exp $ */ /* * Copyright (c) 2017 Nicholas Marriott <nicholas.marriott@gmail.com> @@ -53,18 +53,21 @@ static void window_tree_key(struct window_mode_entry *, "}" \ "}" -#define WINDOW_TREE_MENU \ - "Select,Enter,|" \ - "Expand,Right,|" \ - "|" \ - "Tag,t,|" \ - "Tag All,C-t,|" \ - "Tag None,T,|" \ - "|" \ - "Kill,x,|" \ - "Kill Tagged,X,|" \ - "|" \ - "Cancel,q," +static const struct menu_item window_tree_menu_items[] = { + { "Select", 'E', NULL }, + { "Expand", 'R', NULL }, + { "", KEYC_NONE, NULL }, + { "Tag", 't', NULL }, + { "Tag All", '\024', NULL }, + { "Tag None", 'T', NULL }, + { "", KEYC_NONE, NULL }, + { "Kill", 'x', NULL }, + { "Kill Tagged", 'X', NULL }, + { "", KEYC_NONE, NULL }, + { "Cancel", 'q', NULL }, + + { NULL, KEYC_NONE, NULL } +}; const struct window_mode window_tree_mode = { .name = "tree-mode", @@ -872,7 +875,7 @@ window_tree_init(struct window_mode_entry *wme, struct cmd_find_state *fs, data->data = mode_tree_start(wp, args, window_tree_build, window_tree_draw, window_tree_search, window_tree_menu, data, - WINDOW_TREE_MENU, window_tree_sort_list, + window_tree_menu_items, window_tree_sort_list, nitems(window_tree_sort_list), &s); mode_tree_zoom(data->data, args); |