diff --git a/cmd-bind-key.c b/cmd-bind-key.c index 1867e814..b13409cb 100644 --- a/cmd-bind-key.c +++ b/cmd-bind-key.c @@ -62,7 +62,7 @@ cmd_bind_key_exec(struct cmd *self, struct cmd_q *cmdq) } key = key_string_lookup_string(args->argv[0]); - if (key == KEYC_NONE) { + if (key == KEYC_NONE || key == KEYC_UNKNOWN) { cmdq_error(cmdq, "unknown key: %s", args->argv[0]); return (CMD_RETURN_ERROR); } diff --git a/cmd-send-keys.c b/cmd-send-keys.c index 73a308ae..1461baa9 100644 --- a/cmd-send-keys.c +++ b/cmd-send-keys.c @@ -52,8 +52,8 @@ cmd_send_keys_exec(struct cmd *self, struct cmd_q *cmdq) struct mouse_event *m = &cmdq->item->mouse; struct window_pane *wp; struct session *s; - const u_char *str; - int i; + int i, literal; + const u_char *keystr; key_code key; if (args_has(args, 'M')) { @@ -82,14 +82,17 @@ cmd_send_keys_exec(struct cmd *self, struct cmd_q *cmdq) input_reset(wp); for (i = 0; i < args->argc; i++) { - str = args->argv[i]; - - if (!args_has(args, 'l') && - (key = key_string_lookup_string(str)) != KEYC_NONE) { - window_pane_key(wp, NULL, s, key, NULL); - } else { - for (; *str != '\0'; str++) - window_pane_key(wp, NULL, s, *str, NULL); + literal = args_has(args, 'l'); + if (!literal) { + key = key_string_lookup_string(args->argv[i]); + if (key != KEYC_NONE && key != KEYC_UNKNOWN) + window_pane_key(wp, NULL, s, key, NULL); + else + literal = 1; + } + if (literal) { + for (keystr = args->argv[i]; *keystr != '\0'; keystr++) + window_pane_key(wp, NULL, s, *keystr, NULL); } } diff --git a/cmd-set-option.c b/cmd-set-option.c index 7de91aa2..e2a4768c 100644 --- a/cmd-set-option.c +++ b/cmd-set-option.c @@ -396,7 +396,8 @@ cmd_set_option_key(__unused struct cmd *self, struct cmd_q *cmdq, { key_code key; - if ((key = key_string_lookup_string(value)) == KEYC_NONE) { + key = key_string_lookup_string(value); + if (key == KEYC_UNKNOWN) { cmdq_error(cmdq, "bad key: %s", value); return (NULL); } diff --git a/cmd-unbind-key.c b/cmd-unbind-key.c index cec538c0..66a4525e 100644 --- a/cmd-unbind-key.c +++ b/cmd-unbind-key.c @@ -51,7 +51,7 @@ cmd_unbind_key_exec(struct cmd *self, struct cmd_q *cmdq) return (CMD_RETURN_ERROR); } key = key_string_lookup_string(args->argv[0]); - if (key == KEYC_NONE) { + if (key == KEYC_NONE || key == KEYC_UNKNOWN) { cmdq_error(cmdq, "unknown key: %s", args->argv[0]); return (CMD_RETURN_ERROR); } @@ -60,13 +60,13 @@ cmd_unbind_key_exec(struct cmd *self, struct cmd_q *cmdq) cmdq_error(cmdq, "key given with -a"); return (CMD_RETURN_ERROR); } - key = KEYC_NONE; + key = KEYC_UNKNOWN; } if (args_has(args, 't')) return (cmd_unbind_key_mode_table(self, cmdq, key)); - if (key == KEYC_NONE) { + if (key == KEYC_UNKNOWN) { tablename = args_get(args, 'T'); if (tablename == NULL) { key_bindings_remove_table("root"); @@ -109,7 +109,7 @@ cmd_unbind_key_mode_table(struct cmd *self, struct cmd_q *cmdq, key_code key) return (CMD_RETURN_ERROR); } - if (key == KEYC_NONE) { + if (key == KEYC_UNKNOWN) { while (!RB_EMPTY(mtab->tree)) { mbind = RB_ROOT(mtab->tree); RB_REMOVE(mode_key_tree, mtab->tree, mbind); diff --git a/input-keys.c b/input-keys.c index 2915cb45..3bc1f812 100644 --- a/input-keys.c +++ b/input-keys.c @@ -161,14 +161,14 @@ input_key(struct window_pane *wp, key_code key, struct mouse_event *m) * if necessary. If it is a UTF-8 key, split it and send it. */ justkey = (key & ~KEYC_ESCAPE); - if (key != KEYC_NONE && justkey <= 0x7f) { + if (justkey <= 0x7f) { if (key & KEYC_ESCAPE) bufferevent_write(wp->event, "\033", 1); ud.data[0] = justkey; bufferevent_write(wp->event, &ud.data[0], 1); return; } - if (key != KEYC_NONE && justkey > 0x7f && justkey < KEYC_BASE) { + if (justkey > 0x7f && justkey < KEYC_BASE) { if (utf8_split(justkey, &ud) != UTF8_DONE) return; if (key & KEYC_ESCAPE) diff --git a/key-string.c b/key-string.c index 9a44892d..1ff3ca30 100644 --- a/key-string.c +++ b/key-string.c @@ -22,8 +22,8 @@ #include "tmux.h" -key_code key_string_search_table(const char *); -key_code key_string_get_modifiers(const char **); +static key_code key_string_search_table(const char *); +static key_code key_string_get_modifiers(const char **); const struct { const char *string; @@ -98,7 +98,7 @@ const struct { }; /* Find key string in table. */ -key_code +static key_code key_string_search_table(const char *string) { u_int i; @@ -107,11 +107,11 @@ key_string_search_table(const char *string) if (strcasecmp(string, key_string_table[i].string) == 0) return (key_string_table[i].key); } - return (KEYC_NONE); + return (KEYC_UNKNOWN); } /* Find modifiers. */ -key_code +static key_code key_string_get_modifiers(const char **string) { key_code modifiers; @@ -150,10 +150,14 @@ key_string_lookup_string(const char *string) u_int i; enum utf8_state more; + /* Is this no key? */ + if (strcasecmp(string, "None") == 0) + return (KEYC_NONE); + /* Is this a hexadecimal value? */ if (string[0] == '0' && string[1] == 'x') { if (sscanf(string + 2, "%hx%n", &u, &size) != 1 || size > 4) - return (KEYC_NONE); + return (KEYC_UNKNOWN); return (u); } @@ -165,30 +169,30 @@ key_string_lookup_string(const char *string) } modifiers |= key_string_get_modifiers(&string); if (string[0] == '\0') - return (KEYC_NONE); + return (KEYC_UNKNOWN); /* Is this a standard ASCII key? */ if (string[1] == '\0' && (u_char)string[0] <= 127) { key = (u_char)string[0]; if (key < 32 || key == 127) - return (KEYC_NONE); + return (KEYC_UNKNOWN); } else { /* Try as a UTF-8 key. */ if ((more = utf8_open(&ud, (u_char)*string)) == UTF8_MORE) { if (strlen(string) != ud.size) - return (KEYC_NONE); + return (KEYC_UNKNOWN); for (i = 1; i < ud.size; i++) more = utf8_append(&ud, (u_char)string[i]); if (more != UTF8_DONE) - return (KEYC_NONE); + return (KEYC_UNKNOWN); key = utf8_combine(&ud); return (key | modifiers); } /* Otherwise look the key up in the table. */ key = key_string_search_table(string); - if (key == KEYC_NONE) - return (KEYC_NONE); + if (key == KEYC_UNKNOWN) + return (KEYC_UNKNOWN); } /* Convert the standard control keys. */ @@ -202,7 +206,7 @@ key_string_lookup_string(const char *string) else if (key == 63) key = KEYC_BSPACE; else - return (KEYC_NONE); + return (KEYC_UNKNOWN); modifiers &= ~KEYC_CTRL; } @@ -222,9 +226,13 @@ key_string_lookup_key(key_code key) /* Handle no key. */ if (key == KEYC_NONE) - return (""); + return ("None"); + + /* Handle special keys. */ + if (key == KEYC_UNKNOWN) + return ("Unknown"); if (key == KEYC_MOUSE) - return (""); + return ("Mouse"); /* * Special case: display C-@ as C-Space. Could do this below in @@ -265,7 +273,7 @@ key_string_lookup_key(key_code key) /* Invalid keys are errors. */ if (key == 127 || key > 255) { - snprintf(out, sizeof out, "", key); + snprintf(out, sizeof out, "Invalid#%llx", key); return (out); } diff --git a/server-client.c b/server-client.c index 8b6be5d9..ed0eefdd 100644 --- a/server-client.c +++ b/server-client.c @@ -309,7 +309,7 @@ server_client_check_mouse(struct client *c) log_debug("down at %u,%u", x, y); } if (type == NOTYPE) - return (KEYC_NONE); + return (KEYC_UNKNOWN); /* Always save the session. */ m->s = s->id; @@ -319,7 +319,7 @@ server_client_check_mouse(struct client *c) if (m->statusat != -1 && y == (u_int)m->statusat) { w = status_get_window_at(c, x); if (w == NULL) - return (KEYC_NONE); + return (KEYC_UNKNOWN); m->w = w->id; where = STATUS; } else @@ -352,7 +352,7 @@ server_client_check_mouse(struct client *c) } } if (where == NOWHERE) - return (KEYC_NONE); + return (KEYC_UNKNOWN); m->wp = wp->id; m->w = wp->window->id; } else @@ -371,7 +371,7 @@ server_client_check_mouse(struct client *c) } /* Convert to a key binding. */ - key = KEYC_NONE; + key = KEYC_UNKNOWN; switch (type) { case NOTYPE: break; @@ -483,8 +483,8 @@ server_client_check_mouse(struct client *c) } break; } - if (key == KEYC_NONE) - return (KEYC_NONE); + if (key == KEYC_UNKNOWN) + return (KEYC_UNKNOWN); /* Apply modifiers if any. */ if (b & MOUSE_MASK_META) @@ -572,7 +572,7 @@ server_client_handle_key(struct client *c, key_code key) if (c->flags & CLIENT_READONLY) return; key = server_client_check_mouse(c); - if (key == KEYC_NONE) + if (key == KEYC_UNKNOWN) return; m->valid = 1; diff --git a/tmux.1 b/tmux.1 index 115050a6..b02237f1 100644 --- a/tmux.1 +++ b/tmux.1 @@ -2664,8 +2664,19 @@ See the section for details. .It Ic prefix Ar key Set the key accepted as a prefix key. +In addition to the standard keys described under +.Sx KEY BINDINGS , +.Ic prefix +can be set to the special key +.Ql None +to set no prefix. .It Ic prefix2 Ar key Set a secondary key accepted as a prefix key. +Like +.Ic prefix , +.Ic prefix2 +can be set to +.Ql None . .It Xo Ic renumber-windows .Op Ic on | off .Xc diff --git a/tmux.h b/tmux.h index 60d16fe3..d5e5d822 100644 --- a/tmux.h +++ b/tmux.h @@ -85,6 +85,7 @@ struct tmuxproc; /* Special key codes. */ #define KEYC_NONE 0xffff00000000ULL +#define KEYC_UNKNOWN 0xfffe00000000ULL #define KEYC_BASE 0x100000000000ULL /* Key modifier bits. */ diff --git a/tty-keys.c b/tty-keys.c index b5e36f8e..86839a17 100644 --- a/tty-keys.c +++ b/tty-keys.c @@ -344,7 +344,7 @@ tty_keys_add1(struct tty_key **tkp, const char *s, key_code key) if (tk == NULL) { tk = *tkp = xcalloc(1, sizeof *tk); tk->ch = *s; - tk->key = KEYC_NONE; + tk->key = KEYC_UNKNOWN; } /* Find the next entry. */ @@ -444,7 +444,7 @@ tty_keys_find1(struct tty_key *tk, const char *buf, size_t len, size_t *size) (*size)++; /* At the end of the string, return the current node. */ - if (len == 0 || (tk->next == NULL && tk->key != KEYC_NONE)) + if (len == 0 || (tk->next == NULL && tk->key != KEYC_UNKNOWN)) return (tk); /* Move into the next tree for the following character. */ @@ -534,7 +534,7 @@ first_key: if (tk->next != NULL) goto partial_key; key = tk->key; - if (key != KEYC_NONE) + if (key != KEYC_UNKNOWN) key |= KEYC_ESCAPE; goto complete_key; } @@ -620,7 +620,7 @@ complete_key: } /* Fire the key. */ - if (key != KEYC_NONE) + if (key != KEYC_UNKNOWN) server_client_handle_key(tty->client, key); return (1);