diff --git a/mode-key.c b/mode-key.c index bae6650c..ea43962b 100644 --- a/mode-key.c +++ b/mode-key.c @@ -192,16 +192,16 @@ struct mode_key_tree mode_key_tree_vi_edit; /* vi choice selection keys. */ const struct mode_key_entry mode_key_vi_choice[] = { - { '0', 0, MODEKEYCHOICE_STARTNUMBERPREFIX }, - { '1', 0, MODEKEYCHOICE_STARTNUMBERPREFIX }, - { '2', 0, MODEKEYCHOICE_STARTNUMBERPREFIX }, - { '3', 0, MODEKEYCHOICE_STARTNUMBERPREFIX }, - { '4', 0, MODEKEYCHOICE_STARTNUMBERPREFIX }, - { '5', 0, MODEKEYCHOICE_STARTNUMBERPREFIX }, - { '6', 0, MODEKEYCHOICE_STARTNUMBERPREFIX }, - { '7', 0, MODEKEYCHOICE_STARTNUMBERPREFIX }, - { '8', 0, MODEKEYCHOICE_STARTNUMBERPREFIX }, - { '9', 0, MODEKEYCHOICE_STARTNUMBERPREFIX }, + { '0' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTNUMBERPREFIX }, + { '1' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTNUMBERPREFIX }, + { '2' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTNUMBERPREFIX }, + { '3' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTNUMBERPREFIX }, + { '4' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTNUMBERPREFIX }, + { '5' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTNUMBERPREFIX }, + { '6' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTNUMBERPREFIX }, + { '7' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTNUMBERPREFIX }, + { '8' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTNUMBERPREFIX }, + { '9' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTNUMBERPREFIX }, { '\002' /* C-b */, 0, MODEKEYCHOICE_PAGEUP }, { '\003' /* C-c */, 0, MODEKEYCHOICE_CANCEL }, { '\005' /* C-e */, 0, MODEKEYCHOICE_SCROLLDOWN }, @@ -330,16 +330,16 @@ struct mode_key_tree mode_key_tree_emacs_edit; /* emacs choice selection keys. */ const struct mode_key_entry mode_key_emacs_choice[] = { - { '0', 0, MODEKEYCHOICE_STARTNUMBERPREFIX }, - { '1', 0, MODEKEYCHOICE_STARTNUMBERPREFIX }, - { '2', 0, MODEKEYCHOICE_STARTNUMBERPREFIX }, - { '3', 0, MODEKEYCHOICE_STARTNUMBERPREFIX }, - { '4', 0, MODEKEYCHOICE_STARTNUMBERPREFIX }, - { '5', 0, MODEKEYCHOICE_STARTNUMBERPREFIX }, - { '6', 0, MODEKEYCHOICE_STARTNUMBERPREFIX }, - { '7', 0, MODEKEYCHOICE_STARTNUMBERPREFIX }, - { '8', 0, MODEKEYCHOICE_STARTNUMBERPREFIX }, - { '9', 0, MODEKEYCHOICE_STARTNUMBERPREFIX }, + { '0' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTNUMBERPREFIX }, + { '1' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTNUMBERPREFIX }, + { '2' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTNUMBERPREFIX }, + { '3' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTNUMBERPREFIX }, + { '4' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTNUMBERPREFIX }, + { '5' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTNUMBERPREFIX }, + { '6' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTNUMBERPREFIX }, + { '7' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTNUMBERPREFIX }, + { '8' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTNUMBERPREFIX }, + { '9' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTNUMBERPREFIX }, { '\003' /* C-c */, 0, MODEKEYCHOICE_CANCEL }, { '\016' /* C-n */, 0, MODEKEYCHOICE_DOWN }, { '\020' /* C-p */, 0, MODEKEYCHOICE_UP }, diff --git a/window-choose.c b/window-choose.c index 99c09d52..9d08376e 100644 --- a/window-choose.c +++ b/window-choose.c @@ -71,7 +71,8 @@ struct window_choose_mode_data { void (*freefn)(struct window_choose_data *); }; -int window_choose_index_key(int); +int window_choose_key_index(struct window_choose_mode_data *, u_int); +int window_choose_index_key(struct window_choose_mode_data *, int); void window_choose_prompt_input(enum window_choose_input_type, const char *, struct window_pane *, int); @@ -89,7 +90,7 @@ window_choose_add(struct window_pane *wp, struct window_choose_data *wcd) item->wcd = wcd; item->pos = ARRAY_LENGTH(&data->list) - 1; - data->width = snprintf (tmp, sizeof tmp , "%u", item->pos); + data->width = xsnprintf (tmp, sizeof tmp , "%u", item->pos); } void @@ -241,27 +242,48 @@ window_choose_key(struct window_pane *wp, unused struct session *sess, int key) items = ARRAY_LENGTH(&data->list); + if (data->input_type == WINDOW_CHOOSE_GOTO_ITEM) { + switch (mode_key_lookup(&data->mdata, key)) { + case MODEKEYCHOICE_CANCEL: + data->input_type = WINDOW_CHOOSE_NORMAL; + window_choose_redraw_screen(wp); + break; + case MODEKEYCHOICE_CHOOSE: + n = strtonum(data->input_str, 0, INT_MAX, NULL); + if (n > items - 1) { + data->input_type = WINDOW_CHOOSE_NORMAL; + window_choose_redraw_screen(wp); + break; + } + item = &ARRAY_ITEM(&data->list, n); + window_choose_fire_callback(wp, item->wcd); + window_pane_reset_mode(wp); + break; + case MODEKEYCHOICE_BACKSPACE: + input_len = strlen(data->input_str); + if (input_len > 0) + data->input_str[input_len - 1] = '\0'; + window_choose_redraw_screen(wp); + break; + default: + if (key < '0' || key > '9') + break; + window_choose_prompt_input(WINDOW_CHOOSE_GOTO_ITEM, + "Goto Item", wp, key); + break; + } + return; + } + switch (mode_key_lookup(&data->mdata, key)) { case MODEKEYCHOICE_CANCEL: window_choose_fire_callback(wp, NULL); window_pane_reset_mode(wp); break; case MODEKEYCHOICE_CHOOSE: - switch (data->input_type) { - case WINDOW_CHOOSE_NORMAL: - item = &ARRAY_ITEM(&data->list, data->selected); - window_choose_fire_callback(wp, item->wcd); - window_pane_reset_mode(wp); - break; - case WINDOW_CHOOSE_GOTO_ITEM: - n = strtonum(data->input_str, 0, INT_MAX, NULL); - if (n > items - 1) - break; - item = &ARRAY_ITEM(&data->list, n); - window_choose_fire_callback(wp, item->wcd); - window_pane_reset_mode(wp); - break; - } + item = &ARRAY_ITEM(&data->list, data->selected); + window_choose_fire_callback(wp, item->wcd); + window_pane_reset_mode(wp); break; case MODEKEYCHOICE_UP: if (items == 0) @@ -366,29 +388,21 @@ window_choose_key(struct window_pane *wp, unused struct session *sess, int key) window_choose_redraw_screen(wp); break; case MODEKEYCHOICE_STARTNUMBERPREFIX: - if (key < '0' && key > '9') + key &= KEYC_MASK_KEY; + if (key < '0' || key > '9') break; - - /* - * If there's less than ten items (0-9) then pressing a number - * will automatically select that item; otherwise, prompt for - * the item to go to. - */ - if (ARRAY_LENGTH(&data->list) - 1 <= 9) { - idx = window_choose_index_key(key); - if (idx < 0 || (u_int) idx >= ARRAY_LENGTH(&data->list)) - break; - data->selected = idx; - - item = &ARRAY_ITEM(&data->list, data->selected); - window_choose_fire_callback(wp, item->wcd); - window_pane_reset_mode(wp); - } else { - window_choose_prompt_input( - WINDOW_CHOOSE_GOTO_ITEM, "Goto item", wp, key); - } + window_choose_prompt_input(WINDOW_CHOOSE_GOTO_ITEM, + "Goto Item", wp, key); break; default: + idx = window_choose_index_key(data, key); + if (idx < 0 || (u_int) idx >= ARRAY_LENGTH(&data->list)) + break; + data->selected = idx; + + item = &ARRAY_ITEM(&data->list, data->selected); + window_choose_fire_callback(wp, item->wcd); + window_pane_reset_mode(wp); break; } } @@ -430,8 +444,8 @@ window_choose_write_line( struct screen *s = &data->screen; struct grid_cell gc; size_t last, xoff = 0; - char hdr[32]; - int utf8flag; + char hdr[32], label[32]; + int utf8flag, key; if (data->callbackfn == NULL) fatalx("called before callback assigned"); @@ -448,10 +462,14 @@ window_choose_write_line( if (item->wcd->wl != NULL && item->wcd->wl->flags & WINLINK_ALERTFLAGS) gc.attr |= GRID_ATTR_BRIGHT; - screen_write_nputs(ctx, screen_size_x(s) - 1, - &gc, utf8flag, "(%*d) %s", data->width, - item->pos, item->name); + key = window_choose_key_index(data, data->top + py); + if (key != -1) + xsnprintf (label, sizeof label, "(%c)", key); + else + xsnprintf (label, sizeof label, "(%d)", item->pos); + screen_write_nputs(ctx, screen_size_x(s) - 1, &gc, utf8flag, + "%*s %s", data->width + 2, label, item->name); } while (s->cx < screen_size_x(s)) screen_write_putc(ctx, &gc, ' '); @@ -470,13 +488,38 @@ window_choose_write_line( } int -window_choose_index_key(int key) +window_choose_key_index(struct window_choose_mode_data *data, u_int idx) { - static const char keys[] = "0123456789"; + static const char keys[] = "0123456789" + "abcdefghijklmnopqrstuvwxyz" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; const char *ptr; + int mkey; + + for (ptr = keys; *ptr != '\0'; ptr++) { + mkey = mode_key_lookup(&data->mdata, *ptr); + if (mkey != MODEKEY_NONE && mkey != MODEKEY_OTHER) + continue; + if (idx-- == 0) + return (*ptr); + } + return (-1); +} + +int +window_choose_index_key(struct window_choose_mode_data *data, int key) +{ + static const char keys[] = "0123456789" + "abcdefghijklmnopqrstuvwxyz" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + const char *ptr; + int mkey; u_int idx = 0; for (ptr = keys; *ptr != '\0'; ptr++) { + mkey = mode_key_lookup(&data->mdata, *ptr); + if (mkey != MODEKEY_NONE && mkey != MODEKEY_OTHER) + continue; if (key == *ptr) return (idx); idx++;