Add a flag to display-menu to select the manu item chosen first, GitHub
authornicm <nicm@openbsd.org>
Fri, 20 Jan 2023 21:36:00 +0000 (21:36 +0000)
committernicm <nicm@openbsd.org>
Fri, 20 Jan 2023 21:36:00 +0000 (21:36 +0000)
issue 3442.

usr.bin/tmux/cmd-display-menu.c
usr.bin/tmux/menu.c
usr.bin/tmux/mode-tree.c
usr.bin/tmux/popup.c
usr.bin/tmux/status.c
usr.bin/tmux/tmux.1
usr.bin/tmux/tmux.h

index 7df9297..dc7bc21 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: cmd-display-menu.c,v 1.37 2021/10/25 09:38:36 nicm Exp $ */
+/* $OpenBSD: cmd-display-menu.c,v 1.38 2023/01/20 21:36:00 nicm Exp $ */
 
 /*
  * Copyright (c) 2019 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -39,9 +39,10 @@ const struct cmd_entry cmd_display_menu_entry = {
        .name = "display-menu",
        .alias = "menu",
 
-       .args = { "c:t:OT:x:y:", 1, -1, cmd_display_menu_args_parse },
-       .usage = "[-O] [-c target-client] " CMD_TARGET_PANE_USAGE " [-T title] "
-                "[-x position] [-y position] name key command ...",
+       .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 ...",
 
        .target = { 't', CMD_FIND_PANE, 0 },
 
@@ -288,13 +289,27 @@ cmd_display_menu_exec(struct cmd *self, struct cmdq_item *item)
        struct menu             *menu = NULL;
        struct menu_item         menu_item;
        const char              *key, *name;
-       char                    *title;
-       int                      flags = 0;
+       char                    *title, *cause;
+       int                      flags = 0, starting_choice = 0;
        u_int                    px, py, i, count = args_count(args);
 
        if (tc->overlay_draw != NULL)
                return (CMD_RETURN_NORMAL);
 
+       if (args_has(args, 'S')) {
+               if (strcmp(args_get(args, 'S'), "-") == 0)
+                       starting_choice = -1;
+               else {
+                       starting_choice = args_strtonum(args, 'S', 0, UINT_MAX,
+                           &cause);
+                       if (cause != NULL) {
+                               cmdq_error(item, "starting choice %s", cause);
+                               free(cause);
+                               return (CMD_RETURN_ERROR);
+                       }
+               }
+       }
+
        if (args_has(args, 'T'))
                title = format_single_from_target(item, args_get(args, 'T'));
        else
@@ -341,8 +356,8 @@ cmd_display_menu_exec(struct cmd *self, struct cmdq_item *item)
                flags |= MENU_STAYOPEN;
        if (!event->m.valid)
                flags |= MENU_NOMOUSE;
-       if (menu_display(menu, flags, item, px, py, tc, target, NULL,
-           NULL) != 0)
+       if (menu_display(menu, flags, starting_choice, item, px, py, tc, target,
+           NULL, NULL) != 0)
                return (CMD_RETURN_NORMAL);
        return (CMD_RETURN_WAIT);
 }
index 6db916f..5238703 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: menu.c,v 1.47 2022/08/04 12:06:09 nicm Exp $ */
+/* $OpenBSD: menu.c,v 1.48 2023/01/20 21:36:00 nicm Exp $ */
 
 /*
  * Copyright (c) 2019 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -427,12 +427,12 @@ chosen:
 }
 
 struct menu_data *
-menu_prepare(struct menu *menu, int flags, struct cmdq_item *item, u_int px,
-    u_int py, struct client *c, struct cmd_find_state *fs, menu_choice_cb cb,
-    void *data)
+menu_prepare(struct menu *menu, int flags, int starting_choice,
+    struct cmdq_item *item, u_int px, u_int py, struct client *c,
+    struct cmd_find_state *fs, menu_choice_cb cb, void *data)
 {
        struct menu_data        *md;
-       u_int                    i;
+       int                      choice;
        const char              *name;
 
        if (c->tty.sx < menu->width + 4 || c->tty.sy < menu->count + 2)
@@ -457,18 +457,38 @@ menu_prepare(struct menu *menu, int flags, struct cmdq_item *item, u_int px,
        md->py = py;
 
        md->menu = menu;
+       md->choice = -1;
+
        if (md->flags & MENU_NOMOUSE) {
-               for (i = 0; i < menu->count; i++) {
-                       name = menu->items[i].name;
-                       if (name != NULL && *name != '-')
-                               break;
+               if (starting_choice >= (int)menu->count) {
+                       starting_choice = menu->count - 1;
+                       choice = starting_choice + 1;
+                       for (;;) {
+                               name = menu->items[choice - 1].name;
+                               if (name != NULL && *name != '-') {
+                                       md->choice = choice - 1;
+                                       break;
+                               }
+                               if (--choice == 0)
+                                       choice = menu->count;
+                               if (choice == starting_choice + 1)
+                                       break;
+                       }
+               } else if (starting_choice >= 0) {
+                       choice = starting_choice;
+                       for (;;) {
+                               name = menu->items[choice].name;
+                               if (name != NULL && *name != '-') {
+                                       md->choice = choice;
+                                       break;
+                               }
+                               if (++choice == (int)menu->count)
+                                       choice = 0;
+                               if (choice == starting_choice)
+                                       break;
+                       }
                }
-               if (i != menu->count)
-                       md->choice = i;
-               else
-                       md->choice = -1;
-       } else
-               md->choice = -1;
+       }
 
        md->cb = cb;
        md->data = data;
@@ -476,13 +496,14 @@ menu_prepare(struct menu *menu, int flags, struct cmdq_item *item, u_int px,
 }
 
 int
-menu_display(struct menu *menu, int flags, struct cmdq_item *item, u_int px,
-    u_int py, struct client *c, struct cmd_find_state *fs, menu_choice_cb cb,
-    void *data)
+menu_display(struct menu *menu, int flags, int starting_choice,
+    struct cmdq_item *item, u_int px, u_int py, struct client *c,
+    struct cmd_find_state *fs, menu_choice_cb cb, void *data)
 {
        struct menu_data        *md;
 
-       md = menu_prepare(menu, flags, item, px, py, c, fs, cb, data);
+       md = menu_prepare(menu, flags, starting_choice, item, px, py, c, fs, cb,
+           data);
        if (md == NULL)
                return (-1);
        server_client_set_overlay(c, 0, NULL, menu_mode_cb, menu_draw_cb,
index 960bccd..b90980f 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: mode-tree.c,v 1.62 2022/02/01 18:12:20 nicm Exp $ */
+/* $OpenBSD: mode-tree.c,v 1.63 2023/01/20 21:36:00 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, NULL, x, y, c, NULL, mode_tree_menu_callback,
-           mtm) != 0)
+       if (menu_display(menu, 0, 0, NULL, x, y, c, NULL,
+           mode_tree_menu_callback, mtm) != 0)
                menu_free(menu);
 }
 
index e5136be..e69ae5e 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: popup.c,v 1.46 2022/02/22 11:01:57 nicm Exp $ */
+/* $OpenBSD: popup.c,v 1.47 2023/01/20 21:36:00 nicm Exp $ */
 
 /*
  * Copyright (c) 2020 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -574,7 +574,7 @@ menu:
                x = m->x - (pd->menu->width + 4) / 2;
        else
                x = 0;
-       pd->md = menu_prepare(pd->menu, 0, NULL, x, m->y, c, NULL,
+       pd->md = menu_prepare(pd->menu, 0, 0, NULL, x, m->y, c, NULL,
            popup_menu_done, pd);
        c->flags |= CLIENT_REDRAWOVERLAY;
 
index ab079bb..609d683 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: status.c,v 1.236 2022/09/10 17:01:33 nicm Exp $ */
+/* $OpenBSD: status.c,v 1.237 2023/01/20 21:36:00 nicm Exp $ */
 
 /*
  * Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -1766,7 +1766,7 @@ status_prompt_complete_list_menu(struct client *c, char **list, u_int size,
        else
                offset = 0;
 
-       if (menu_display(menu, MENU_NOMOUSE|MENU_TAB, NULL, offset,
+       if (menu_display(menu, MENU_NOMOUSE|MENU_TAB, 0, NULL, offset,
            py, c, NULL, status_prompt_menu_callback, spm) != 0) {
                menu_free(menu);
                free(spm);
@@ -1859,7 +1859,7 @@ status_prompt_complete_window_menu(struct client *c, struct session *s,
        else
                offset = 0;
 
-       if (menu_display(menu, MENU_NOMOUSE|MENU_TAB, NULL, offset,
+       if (menu_display(menu, MENU_NOMOUSE|MENU_TAB, 0, NULL, offset,
            py, c, NULL, status_prompt_menu_callback, spm) != 0) {
                menu_free(menu);
                free(spm);
index 6e51f1f..a46e3f6 100644 (file)
@@ -1,4 +1,4 @@
-.\" $OpenBSD: tmux.1,v 1.911 2023/01/08 21:00:01 nicm Exp $
+.\" $OpenBSD: tmux.1,v 1.912 2023/01/20 21:36:00 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: January 8 2023 $
+.Dd $Mdocdate: January 20 2023 $
 .Dt TMUX 1
 .Os
 .Sh NAME
@@ -5815,6 +5815,7 @@ until it is dismissed.
 .Op Fl O
 .Op Fl c Ar target-client
 .Op Fl t Ar target-pane
+.Op Fl S Ar starting-choice
 .Op Fl T Ar title
 .Op Fl x Ar position
 .Op Fl y Ar position
@@ -5844,6 +5845,9 @@ command should be omitted.
 .Fl T
 is a format for the menu title (see
 .Sx FORMATS ) .
+.Fl S
+sets the menu item selected by default, if the menu is not bound to a mouse key
+binding.
 .Pp
 .Fl x
 and
index b36df4a..ad2e792 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: tmux.h,v 1.1192 2023/01/16 11:26:14 nicm Exp $ */
+/* $OpenBSD: tmux.h,v 1.1193 2023/01/20 21:36:00 nicm Exp $ */
 
 /*
  * Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -3292,11 +3292,11 @@ void             menu_add_item(struct menu *, const struct menu_item *,
                    struct cmdq_item *, struct client *,
                    struct cmd_find_state *);
 void            menu_free(struct menu *);
-struct menu_data *menu_prepare(struct menu *, int, struct cmdq_item *, u_int,
-                   u_int, struct client *, struct cmd_find_state *,
+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 *);
-int             menu_display(struct menu *, int, struct cmdq_item *, u_int,
-                   u_int, struct client *, struct cmd_find_state *,
+int             menu_display(struct menu *, int, int, struct cmdq_item *,
+                   u_int, u_int, struct client *, 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,