Separate key flags and modifiers, log key flags, make the "xterm" flag

more explicit and fix M- keys with a leading escape.
This commit is contained in:
nicm 2020-05-16 16:35:13 +00:00
parent e2a26740b9
commit 292b335ca5
11 changed files with 63 additions and 46 deletions

View File

@ -73,7 +73,7 @@ cmd_list_keys_get_width(const char *tablename, key_code only)
bd = key_bindings_next(table, bd);
continue;
}
width = utf8_cstrwidth(key_string_lookup_key(bd->key));
width = utf8_cstrwidth(key_string_lookup_key(bd->key, 0));
if (width > keywidth)
keywidth = width;
@ -106,7 +106,7 @@ cmd_list_keys_print_notes(struct cmdq_item *item, struct args *args,
continue;
}
found = 1;
key = key_string_lookup_key(bd->key);
key = key_string_lookup_key(bd->key, 0);
if (bd->note == NULL || *bd->note == '\0')
note = cmd_list_print(bd->cmdlist, 1);
@ -135,7 +135,7 @@ cmd_list_keys_get_prefix(struct args *args, key_code *prefix)
*prefix = options_get_number(global_s_options, "prefix");
if (!args_has(args, 'P')) {
if (*prefix != KEYC_NONE)
xasprintf(&s, "%s ", key_string_lookup_key(*prefix));
xasprintf(&s, "%s ", key_string_lookup_key(*prefix, 0));
else
s = xstrdup("");
} else
@ -221,7 +221,7 @@ cmd_list_keys_exec(struct cmd *self, struct cmdq_item *item)
bd = key_bindings_next(table, bd);
continue;
}
key = args_escape(key_string_lookup_key(bd->key));
key = args_escape(key_string_lookup_key(bd->key, 0));
if (bd->flags & KEY_BINDING_REPEAT)
repeat = 1;
@ -255,7 +255,7 @@ cmd_list_keys_exec(struct cmd *self, struct cmdq_item *item)
continue;
}
found = 1;
key = args_escape(key_string_lookup_key(bd->key));
key = args_escape(key_string_lookup_key(bd->key, 0));
if (!repeat)
r = "";

View File

@ -547,7 +547,7 @@ cmdq_add_message(struct cmdq_item *item)
if (c != NULL) {
name = c->name;
if (c->session != NULL && state->event.key != KEYC_NONE) {
key = key_string_lookup_key(state->event.key);
key = key_string_lookup_key(state->event.key, 0);
server_add_message("%s key %s: %s", name, key, tmp);
} else
server_add_message("%s command: %s", name, tmp);

View File

@ -71,15 +71,13 @@ cmd_send_keys_inject_key(struct cmdq_item *item, struct cmdq_item *after,
wme = TAILQ_FIRST(&wp->modes);
if (wme == NULL || wme->mode->key_table == NULL) {
if (options_get_number(wp->window->options, "xterm-keys"))
key |= KEYC_XTERM;
if (window_pane_key(wp, tc, s, wl, key, NULL) != 0)
return (NULL);
return (item);
}
table = key_bindings_get_table(wme->mode->key_table(wme), 1);
bd = key_bindings_get(table, key & ~KEYC_XTERM);
bd = key_bindings_get(table, key & ~KEYC_MASK_FLAGS);
if (bd != NULL) {
table->references++;
after = key_bindings_dispatch(bd, after, tc, NULL, target);

View File

@ -190,7 +190,7 @@ key_bindings_add(const char *name, key_code key, const char *note, int repeat,
table = key_bindings_get_table(name, 1);
bd = key_bindings_get(table, key & ~KEYC_XTERM);
bd = key_bindings_get(table, key & ~KEYC_MASK_FLAGS);
if (bd != NULL) {
RB_REMOVE(key_bindings, &table->key_bindings, bd);
key_bindings_free(bd);
@ -217,7 +217,7 @@ key_bindings_remove(const char *name, key_code key)
if (table == NULL)
return;
bd = key_bindings_get(table, key & ~KEYC_XTERM);
bd = key_bindings_get(table, key & ~KEYC_MASK_FLAGS);
if (bd == NULL)
return;

View File

@ -143,7 +143,7 @@ key_string_get_modifiers(const char **string)
break;
case 'M':
case 'm':
modifiers |= KEYC_ESCAPE;
modifiers |= KEYC_META;
break;
case 'S':
case 's':
@ -212,7 +212,7 @@ key_string_lookup_string(const char *string)
return (KEYC_UNKNOWN);
if (utf8_combine(&ud, &wc) != UTF8_DONE)
return (KEYC_UNKNOWN);
return (wc | modifiers);
return (wc|modifiers);
}
/* Otherwise look the key up in the table. */
@ -236,14 +236,15 @@ key_string_lookup_string(const char *string)
modifiers &= ~KEYC_CTRL;
}
return (key | modifiers);
return (key|modifiers);
}
/* Convert a key code into string format, with prefix if necessary. */
const char *
key_string_lookup_key(key_code key)
key_string_lookup_key(key_code key, int with_flags)
{
static char out[32];
key_code saved = key;
static char out[64];
char tmp[8];
const char *s;
u_int i;
@ -255,25 +256,27 @@ key_string_lookup_key(key_code key)
/* Literal keys are themselves. */
if (key & KEYC_LITERAL) {
snprintf(out, sizeof out, "%c", (int)(key & 0xff));
return (out);
goto out;
}
/* Display C-@ as C-Space. */
if ((key & KEYC_MASK_KEY) == 0)
key = ' ' | KEYC_CTRL | (key & KEYC_MASK_MOD);
if ((key & (KEYC_MASK_KEY|KEYC_MASK_MODIFIERS)) == 0)
key = ' '|KEYC_CTRL;
/* Fill in the modifiers. */
if (key & KEYC_CTRL)
strlcat(out, "C-", sizeof out);
if (key & KEYC_ESCAPE)
if (key & KEYC_META)
strlcat(out, "M-", sizeof out);
if (key & KEYC_SHIFT)
strlcat(out, "S-", sizeof out);
key &= KEYC_MASK_KEY;
/* Handle no key. */
if (key == KEYC_NONE)
return ("None");
if (key == KEYC_NONE) {
s = "None";
goto append;
}
/* Handle special keys. */
if (key == KEYC_UNKNOWN) {
@ -331,7 +334,7 @@ key_string_lookup_key(key_code key)
if (key >= KEYC_USER && key < KEYC_USER + KEYC_NUSER) {
snprintf(tmp, sizeof tmp, "User%u", (u_int)(key - KEYC_USER));
strlcat(out, tmp, sizeof out);
return (out);
goto out;
}
/* Try the key against the string table. */
@ -341,7 +344,7 @@ key_string_lookup_key(key_code key)
}
if (i != nitems(key_string_table)) {
strlcat(out, key_string_table[i].string, sizeof out);
return (out);
goto out;
}
/* Is this a UTF-8 key? */
@ -350,14 +353,14 @@ key_string_lookup_key(key_code key)
off = strlen(out);
memcpy(out + off, ud.data, ud.size);
out[off + ud.size] = '\0';
return (out);
goto out;
}
}
/* Invalid keys are errors. */
if (key > 255) {
snprintf(out, sizeof out, "Invalid#%llx", key);
return (out);
goto out;
}
/* Check for standard or control key. */
@ -375,9 +378,25 @@ key_string_lookup_key(key_code key)
xsnprintf(tmp, sizeof tmp, "\\%llo", key);
strlcat(out, tmp, sizeof out);
return (out);
goto out;
append:
strlcat(out, s, sizeof out);
out:
if (with_flags && (saved & KEYC_MASK_FLAGS) != 0) {
strlcat(out, "[", sizeof out);
if (saved & KEYC_LITERAL)
strlcat(out, "L", sizeof out);
if (saved & KEYC_KEYPAD)
strlcat(out, "K", sizeof out);
if (saved & KEYC_CURSOR)
strlcat(out, "C", sizeof out);
if (saved & KEYC_IMPLIED_META)
strlcat(out, "I", sizeof out);
if (saved & KEYC_BUILD_MODIFIERS)
strlcat(out, "B", sizeof out);
strlcat(out, "]", sizeof out);
}
return (out);
}

4
menu.c
View File

@ -81,7 +81,7 @@ menu_add_item(struct menu *menu, const struct menu_item *item,
return;
}
if (*s != '-' && item->key != KEYC_UNKNOWN && item->key != KEYC_NONE) {
key = key_string_lookup_key(item->key);
key = key_string_lookup_key(item->key, 0);
xasprintf(&name, "%s#[default] #[align=right](%s)", s, key);
} else
xasprintf(&name, "%s", s);
@ -226,7 +226,7 @@ menu_key_cb(struct client *c, struct key_event *event)
goto chosen;
}
}
switch (event->key) {
switch (event->key & ~KEYC_MASK_FLAGS) {
case KEYC_UP:
case 'k':
if (old == -1)

View File

@ -987,7 +987,7 @@ mode_tree_key(struct mode_tree_data *mtd, struct client *c, key_code *key,
choice = -1;
if (*key >= '0' && *key <= '9')
choice = (*key) - '0';
else if (((*key) & KEYC_MASK_MOD) == KEYC_ESCAPE) {
else if (((*key) & KEYC_MASK_MODIFIERS) == KEYC_META) {
tmp = (*key) & KEYC_MASK_KEY;
if (tmp >= 'a' && tmp <= 'z')
choice = 10 + (tmp - 'a');
@ -1111,12 +1111,12 @@ mode_tree_key(struct mode_tree_data *mtd, struct client *c, key_code *key,
mode_tree_build(mtd);
}
break;
case '-'|KEYC_ESCAPE:
case '-'|KEYC_META:
TAILQ_FOREACH(mti, &mtd->children, entry)
mti->expanded = 0;
mode_tree_build(mtd);
break;
case '+'|KEYC_ESCAPE:
case '+'|KEYC_META:
TAILQ_FOREACH(mti, &mtd->children, entry)
mti->expanded = 1;
mode_tree_build(mtd);

View File

@ -130,7 +130,7 @@ options_value_to_string(struct options_entry *o, union options_value *ov,
xasprintf(&s, "%lld", ov->number);
break;
case OPTIONS_TABLE_KEY:
s = xstrdup(key_string_lookup_key(ov->number));
s = xstrdup(key_string_lookup_key(ov->number, 0));
break;
case OPTIONS_TABLE_COLOUR:
s = xstrdup(colour_tostring(ov->number));
@ -283,7 +283,7 @@ options_default_to_string(const struct options_table_entry *oe)
xasprintf(&s, "%lld", oe->default_num);
break;
case OPTIONS_TABLE_KEY:
s = xstrdup(key_string_lookup_key(oe->default_num));
s = xstrdup(key_string_lookup_key(oe->default_num, 0));
break;
case OPTIONS_TABLE_COLOUR:
s = xstrdup(colour_tostring(oe->default_num));

View File

@ -329,7 +329,7 @@ popup_key_cb(struct client *c, struct key_event *event)
bufferevent_write(job_get_event(pd->job), buf, len);
return (0);
}
input_key(NULL, &pd->s, job_get_event(pd->job), event->key);
input_key(&pd->s, job_get_event(pd->job), event->key);
return (0);
}
@ -341,7 +341,7 @@ popup_key_cb(struct client *c, struct key_event *event)
format_defaults(ft, c, fs->s, fs->wl, fs->wp);
else
format_defaults(ft, c, NULL, NULL, NULL);
format_add(ft, "popup_key", "%s", key_string_lookup_key(event->key));
format_add(ft, "popup_key", "%s", key_string_lookup_key(event->key, 0));
if (KEYC_IS_MOUSE(event->key)) {
format_add(ft, "popup_mouse", "1");
format_add(ft, "popup_mouse_x", "%u", m->x - pd->px);

View File

@ -827,7 +827,7 @@ status_prompt_translate_key(struct client *c, key_code key, key_code *new_key)
return (1);
case 'b':
case 'B':
*new_key = 'b'|KEYC_ESCAPE;
*new_key = 'b'|KEYC_META;
return (1);
case 'd':
*new_key = '\025';
@ -836,7 +836,7 @@ status_prompt_translate_key(struct client *c, key_code key, key_code *new_key)
case 'E':
case 'w':
case 'W':
*new_key = 'f'|KEYC_ESCAPE;
*new_key = 'f'|KEYC_META;
return (1);
case 'p':
*new_key = '\031'; /* C-y */
@ -1023,7 +1023,7 @@ status_prompt_key(struct client *c, key_code key)
int keys;
if (c->prompt_flags & PROMPT_KEY) {
keystring = key_string_lookup_key(key);
keystring = key_string_lookup_key(key, 0);
c->prompt_inputcb(c, c->prompt_data, keystring, 1);
status_prompt_clear(c);
return (0);
@ -1039,7 +1039,7 @@ status_prompt_key(struct client *c, key_code key)
free(s);
return (1);
}
key &= ~KEYC_XTERM;
key &= ~KEYC_MASK_FLAGS;
keys = options_get_number(c->session->options, "status-keys");
if (keys == MODEKEY_VI) {
@ -1158,7 +1158,7 @@ process_key:
c->prompt_index = idx;
goto changed;
case 'f'|KEYC_ESCAPE:
case 'f'|KEYC_META:
case KEYC_RIGHT|KEYC_CTRL:
ws = options_get_string(oo, "word-separators");
@ -1182,7 +1182,7 @@ process_key:
c->prompt_index--;
goto changed;
case 'b'|KEYC_ESCAPE:
case 'b'|KEYC_META:
case KEYC_LEFT|KEYC_CTRL:
ws = options_get_string(oo, "word-separators");

View File

@ -460,7 +460,7 @@ window_customize_build_keys(struct window_customize_modedata *data,
bd = key_bindings_first(kt);
while (bd != NULL) {
format_add(ft, "key", "%s", key_string_lookup_key(bd->key));
format_add(ft, "key", "%s", key_string_lookup_key(bd->key, 0));
if (bd->note != NULL)
format_add(ft, "key_note", "%s", bd->note);
if (filter != NULL) {
@ -1233,7 +1233,7 @@ window_customize_set_key(struct client *c,
if (strcmp(s, "Repeat") == 0)
bd->flags ^= KEY_BINDING_REPEAT;
else if (strcmp(s, "Command") == 0) {
xasprintf(&prompt, "(%s) ", key_string_lookup_key(key));
xasprintf(&prompt, "(%s) ", key_string_lookup_key(key, 0));
value = cmd_list_print(bd->cmdlist, 0);
new_item = xcalloc(1, sizeof *new_item);
@ -1250,7 +1250,7 @@ window_customize_set_key(struct client *c,
free(prompt);
free(value);
} else if (strcmp(s, "Note") == 0) {
xasprintf(&prompt, "(%s) ", key_string_lookup_key(key));
xasprintf(&prompt, "(%s) ", key_string_lookup_key(key, 0));
new_item = xcalloc(1, sizeof *new_item);
new_item->data = data;
@ -1395,7 +1395,7 @@ window_customize_key(struct window_mode_entry *wme, struct client *c,
break;
if (item->scope == WINDOW_CUSTOMIZE_KEY) {
xasprintf(&prompt, "Unbind key %s? ",
key_string_lookup_key(item->key));
key_string_lookup_key(item->key, 0));
} else
xasprintf(&prompt, "Unset option %s? ", item->name);
data->references++;