=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/tmux/mode-tree.c,v retrieving revision 1.51 retrieving revision 1.52 diff -u -r1.51 -r1.52 --- src/usr.bin/tmux/mode-tree.c 2020/07/27 08:03:10 1.51 +++ src/usr.bin/tmux/mode-tree.c 2021/04/12 06:50:25 1.52 @@ -1,4 +1,4 @@ -/* $OpenBSD: mode-tree.c,v 1.51 2020/07/27 08:03:10 nicm Exp $ */ +/* $OpenBSD: mode-tree.c,v 1.52 2021/04/12 06:50:25 nicm Exp $ */ /* * Copyright (c) 2017 Nicholas Marriott @@ -46,6 +46,7 @@ mode_tree_search_cb searchcb; mode_tree_menu_cb menucb; mode_tree_height_cb heightcb; + mode_tree_key_cb keycb; struct mode_tree_list children; struct mode_tree_list saved; @@ -74,6 +75,10 @@ void *itemdata; u_int line; + key_code key; + const char *keystr; + size_t keylen; + uint64_t tag; const char *name; const char *text; @@ -135,6 +140,7 @@ free((void *)mti->name); free((void *)mti->text); + free((void *)mti->keystr); free(mti); } @@ -193,6 +199,26 @@ flat = 0; if (mti->expanded) mode_tree_build_lines(mtd, &mti->children, depth + 1); + + if (mtd->keycb != NULL) { + mti->key = mtd->keycb(mtd->modedata, mti->itemdata, + mti->line); + if (mti->key == KEYC_UNKNOWN) + mti->key = KEYC_NONE; + } else if (mti->line < 10) + mti->key = '0' + mti->line; + else if (mti->line < 36) + mti->key = KEYC_META|('a' + mti->line - 10); + else + mti->key = KEYC_NONE; + if (mti->key != KEYC_NONE) { + mti->keystr = xstrdup(key_string_lookup_key(mti->key, + 0)); + mti->keylen = strlen(mti->keystr); + } else { + mti->keystr = NULL; + mti->keylen = 0; + } } TAILQ_FOREACH(mti, mtl, entry) { for (i = 0; i < mtd->line_size; i++) { @@ -363,7 +389,7 @@ 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, - mode_tree_height_cb heightcb, void *modedata, + mode_tree_height_cb heightcb, mode_tree_key_cb keycb, void *modedata, const struct menu_item *menu, const char **sort_list, u_int sort_size, struct screen **s) { @@ -402,6 +428,7 @@ mtd->searchcb = searchcb; mtd->menucb = menucb; mtd->heightcb = heightcb; + mtd->keycb = keycb; TAILQ_INIT(&mtd->children); @@ -596,10 +623,10 @@ struct screen_write_ctx ctx; struct grid_cell gc0, gc; u_int w, h, i, j, sy, box_x, box_y, width; - char *text, *start, key[7]; + char *text, *start, *key; const char *tag, *symbol; size_t size, n; - int keylen; + int keylen, pad; if (mtd->line_size == 0) return; @@ -614,28 +641,30 @@ screen_write_start(&ctx, s); screen_write_clearscreen(&ctx, 8); - if (mtd->line_size > 10) - keylen = 6; - else - keylen = 4; + keylen = 0; + for (i = 0; i < mtd->line_size; i++) { + mti = mtd->line_list[i].item; + if (mti->key == KEYC_NONE) + continue; + if ((int)mti->keylen + 3 > keylen) + keylen = mti->keylen + 3; + } for (i = 0; i < mtd->line_size; i++) { if (i < mtd->offset) continue; if (i > mtd->offset + h - 1) break; - line = &mtd->line_list[i]; mti = line->item; screen_write_cursormove(&ctx, 0, i - mtd->offset, 0); - if (i < 10) - snprintf(key, sizeof key, "(%c) ", '0' + i); - else if (i < 36) - snprintf(key, sizeof key, "(M-%c)", 'a' + (i - 10)); + pad = keylen - 2 - mti->keylen; + if (mti->key != KEYC_NONE) + xasprintf(&key, "(%s)%*s", mti->keystr, pad, ""); else - *key = '\0'; + key = xstrdup(""); if (line->flat) symbol = ""; @@ -698,6 +727,7 @@ } } free(text); + free(key); if (mti->tagged) { gc.attr ^= GRID_ATTR_BRIGHT; @@ -951,7 +981,6 @@ struct mode_tree_item *current, *parent, *mti; u_int i, x, y; int choice; - key_code tmp; if (KEYC_IS_MOUSE(*key) && m != NULL) { if (cmd_mouse_at(mtd->wp, m, &x, &y, 0) != 0) { @@ -993,12 +1022,11 @@ current = line->item; choice = -1; - if (*key >= '0' && *key <= '9') - choice = (*key) - '0'; - else if (((*key) & KEYC_MASK_MODIFIERS) == KEYC_META) { - tmp = (*key) & KEYC_MASK_KEY; - if (tmp >= 'a' && tmp <= 'z') - choice = 10 + (tmp - 'a'); + for (i = 0; i < mtd->line_size; i++) { + if (*key == mtd->line_list[i].item->key) { + choice = i; + break; + } } if (choice != -1) { if ((u_int)choice > mtd->line_size - 1) {