summaryrefslogtreecommitdiffstats
path: root/mode-tree.c
diff options
context:
space:
mode:
authornicm <nicm>2021-04-12 06:50:25 +0000
committernicm <nicm>2021-04-12 06:50:25 +0000
commitcd208c9d72df79a34024df6b8eb8f984613de8ef (patch)
tree334af8c27c6b06e00dbf1a61ab769594c1bd58ba /mode-tree.c
parent73cbe46f8d871b70310735276f34d9c207412587 (diff)
Permit shortcut keys in buffer, client, tree modes to be configured with
a format; the default remains the line number. GitHub issue 2636.
Diffstat (limited to 'mode-tree.c')
-rw-r--r--mode-tree.c68
1 files changed, 48 insertions, 20 deletions
diff --git a/mode-tree.c b/mode-tree.c
index a47c0c06..c0f85026 100644
--- a/mode-tree.c
+++ b/mode-tree.c
@@ -46,6 +46,7 @@ struct mode_tree_data {
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 @@ struct mode_tree_item {
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 @@ mode_tree_free_item(struct mode_tree_item *mti)
free((void *)mti->name);
free((void *)mti->text);
+ free((void *)mti->keystr);
free(mti);
}
@@ -193,6 +199,26 @@ mode_tree_build_lines(struct mode_tree_data *mtd,
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 @@ 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,
- 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 @@ mode_tree_start(struct window_pane *wp, struct args *args,
mtd->searchcb = searchcb;
mtd->menucb = menucb;
mtd->heightcb = heightcb;
+ mtd->keycb = keycb;
TAILQ_INIT(&mtd->children);
@@ -596,10 +623,10 @@ mode_tree_draw(struct mode_tree_data *mtd)
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 @@ mode_tree_draw(struct mode_tree_data *mtd)
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 @@ mode_tree_draw(struct mode_tree_data *mtd)
}
}
free(text);
+ free(key);
if (mti->tagged) {
gc.attr ^= GRID_ATTR_BRIGHT;
@@ -951,7 +981,6 @@ mode_tree_key(struct mode_tree_data *mtd, struct client *c, key_code *key,
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 @@ mode_tree_key(struct mode_tree_data *mtd, struct client *c, key_code *key,
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) {