int cmd_unbind_key_exec(struct cmd *self, unused struct cmd_ctx *ctx) { struct args *args = self->args; struct key_binding *bd; int key; if (args_has(args, 'a')) { while (!SPLAY_EMPTY(&key_bindings)) { bd = SPLAY_ROOT(&key_bindings); SPLAY_REMOVE(key_bindings, &key_bindings, bd); cmd_list_free(bd->cmdlist); xfree(bd); } return (0); } key = key_string_lookup_string(args->argv[0]); if (key == KEYC_NONE) { ctx->error(ctx, "unknown key: %s", args->argv[0]); return (-1); } if (args_has(args, 't')) return (cmd_unbind_key_table(self, ctx, key)); if (!args_has(args, 'n')) key |= KEYC_PREFIX; key_bindings_remove(key); return (0); }
/* Set a keys option. */ struct options_entry * cmd_set_option_keys(struct cmd *self, struct cmd_ctx *ctx, const struct options_table_entry *oe, struct options *oo) { struct cmd_target_data *data = self->data; struct keylist *keylist; char *copy, *ptr, *s; int key; keylist = xmalloc(sizeof *keylist); ARRAY_INIT(keylist); ptr = copy = xstrdup(data->arg2); while ((s = strsep(&ptr, ",")) != NULL) { if ((key = key_string_lookup_string(s)) == KEYC_NONE) { ctx->error(ctx, "unknown key: %s", s); xfree(copy); xfree(keylist); return (NULL); } ARRAY_ADD(keylist, key); } xfree(copy); return (options_set_data(oo, oe->name, keylist, xfree)); }
enum cmd_retval cmd_bind_key_exec(struct cmd *self, struct cmd_q *cmdq) { struct args *args = self->args; char *cause; struct cmd_list *cmdlist; int key; key = key_string_lookup_string(args->argv[0]); if (key == KEYC_NONE) { cmdq_error(cmdq, "unknown key: %s", args->argv[0]); return (CMD_RETURN_ERROR); } if (args_has(args, 't')) return (cmd_bind_key_table(self, cmdq, key)); cmdlist = cmd_list_parse(args->argc - 1, args->argv + 1, NULL, 0, &cause); if (cmdlist == NULL) { cmdq_error(cmdq, "%s", cause); free(cause); return (CMD_RETURN_ERROR); } if (!args_has(args, 'n')) key |= KEYC_PREFIX; key_bindings_add(key, args_has(args, 'r'), cmdlist); return (CMD_RETURN_NORMAL); }
int cmd_send_keys_exec(struct cmd *self, struct cmd_ctx *ctx) { struct args *args = self->args; struct window_pane *wp; struct session *s; const char *str; int i, key; if (cmd_find_pane(ctx, args_get(args, 't'), &s, &wp) == NULL) return (-1); for (i = 0; i < args->argc; i++) { str = args->argv[i]; if ((key = key_string_lookup_string(str)) != KEYC_NONE) { window_pane_key(wp, s, key); } else { for (; *str != '\0'; str++) window_pane_key(wp, s, *str); } } return (0); }
void cmd_set_option_keys(struct cmd_ctx *ctx, struct options *oo, const struct set_option_entry *entry, char *value) { struct options_entry *o; struct keylist *keylist; char *copyvalue, *ptr, *str; int key; if (value == NULL) { ctx->error(ctx, "empty value"); return; } keylist = xmalloc(sizeof *keylist); ARRAY_INIT(keylist); ptr = copyvalue = xstrdup(value); while ((str = strsep(&ptr, ",")) != NULL) { if ((key = key_string_lookup_string(str)) == KEYC_NONE) { xfree(keylist); ctx->error(ctx, "unknown key: %s", str); xfree(copyvalue); return; } ARRAY_ADD(keylist, key); } xfree(copyvalue); o = options_set_data(oo, entry->name, keylist, xfree); ctx->info(ctx, "set option: %s -> %s", o->name, cmd_set_option_print(entry, o)); }
int cmd_bind_key_exec(struct cmd *self, struct cmd_ctx *ctx) { struct args *args = self->args; char *cause; struct cmd_list *cmdlist; int key; key = key_string_lookup_string(args->argv[0]); if (key == KEYC_NONE) { ctx->error(ctx, "unknown key: %s", args->argv[0]); return (-1); } if (args_has(args, 't')) return (cmd_bind_key_table(self, ctx, key)); cmdlist = cmd_list_parse(args->argc - 1, args->argv + 1, &cause); if (cmdlist == NULL) { ctx->error(ctx, "%s", cause); xfree(cause); return (-1); } if (!args_has(args, 'n')) key |= KEYC_PREFIX; key_bindings_add(key, args_has(args, 'r'), cmdlist); return (0); }
int cmd_unbind_key_exec(struct cmd *self, unused struct cmd_ctx *ctx) { struct args *args = self->args; struct key_binding *bd; int key; if (!args_has(args, 'a')) { key = key_string_lookup_string(args->argv[0]); if (key == KEYC_NONE) { ctx->error(ctx, "unknown key: %s", args->argv[0]); return (-1); } } else key = KEYC_NONE; if (args_has(args, 't')) return (cmd_unbind_key_table(self, ctx, key)); if (key == KEYC_NONE) { while (!RB_EMPTY(&key_bindings)) { bd = RB_ROOT(&key_bindings); key_bindings_remove(bd->key); } return (0); } if (!args_has(args, 'n')) key |= KEYC_PREFIX; key_bindings_remove(key); return (0); }
int cmd_unbind_key_parse(struct cmd *self, int argc, char **argv, char **cause) { struct cmd_unbind_key_data *data; int opt, no_prefix = 0; self->data = data = xmalloc(sizeof *data); data->flag_all = 0; data->command_key = 0; data->tablename = NULL; while ((opt = getopt(argc, argv, "acnt:")) != -1) { switch (opt) { case 'a': data->flag_all = 1; break; case 'c': data->command_key = 1; break; case 'n': no_prefix = 1; break; case 't': if (data->tablename == NULL) data->tablename = xstrdup(optarg); break; default: goto usage; } } argc -= optind; argv += optind; if (data->flag_all && (argc != 0 || data->tablename)) goto usage; if (!data->flag_all && argc != 1) goto usage; if (!data->flag_all) { data->key = key_string_lookup_string(argv[0]); if (data->key == KEYC_NONE) { xasprintf(cause, "unknown key: %s", argv[0]); goto error; } if (!no_prefix) data->key |= KEYC_PREFIX; } return (0); usage: xasprintf(cause, "usage: %s %s", self->entry->name, self->entry->usage); error: xfree(data); return (-1); }
enum cmd_retval cmd_unbind_key_exec(struct cmd *self, struct cmd_q *cmdq) { struct args *args = self->args; key_code key; const char *tablename; if (!args_has(args, 'a')) { if (args->argc != 1) { cmdq_error(cmdq, "missing key"); return (CMD_RETURN_ERROR); } key = key_string_lookup_string(args->argv[0]); if (key == KEYC_NONE || key == KEYC_UNKNOWN) { cmdq_error(cmdq, "unknown key: %s", args->argv[0]); return (CMD_RETURN_ERROR); } } else { if (args->argc != 0) { cmdq_error(cmdq, "key given with -a"); return (CMD_RETURN_ERROR); } key = KEYC_UNKNOWN; } if (args_has(args, 't')) return (cmd_unbind_key_mode_table(self, cmdq, key)); if (key == KEYC_UNKNOWN) { tablename = args_get(args, 'T'); if (tablename == NULL) { key_bindings_remove_table("root"); key_bindings_remove_table("prefix"); return (CMD_RETURN_NORMAL); } if (key_bindings_get_table(tablename, 0) == NULL) { cmdq_error(cmdq, "table %s doesn't exist", tablename); return (CMD_RETURN_ERROR); } key_bindings_remove_table(tablename); return (CMD_RETURN_NORMAL); } if (args_has(args, 'T')) { tablename = args_get(args, 'T'); if (key_bindings_get_table(tablename, 0) == NULL) { cmdq_error(cmdq, "table %s doesn't exist", tablename); return (CMD_RETURN_ERROR); } } else if (args_has(args, 'n')) tablename = "root"; else tablename = "prefix"; key_bindings_remove(tablename, key); return (CMD_RETURN_NORMAL); }
int key_string_lookup_string(const char *string) { int key; const u_char *ptr; if (string[0] == '\0') return (KEYC_NONE); if (string[1] == '\0') return (string[0]); ptr = NULL; if ((string[0] == 'C' || string[0] == 'c') && string[1] == '-') ptr = string + 2; else if (string[0] == '^') ptr = string + 1; if (ptr != NULL) { if (ptr[0] == '\0') return (KEYC_NONE); if (ptr[1] == '\0') { if (ptr[0] == 32) return (0); if (ptr[0] == 63) return (KEYC_BSPACE); if (ptr[0] >= 64 && ptr[0] <= 95) return (ptr[0] - 64); if (ptr[0] >= 97 && ptr[0] <= 122) return (ptr[0] - 96); return (KEYC_NONE); } key = key_string_search_table(ptr); if (key != KEYC_NONE) return (key | KEYC_CTRL); return (KEYC_NONE); } if ((string[0] == 'M' || string[0] == 'm') && string[1] == '-') { ptr = string + 2; if (ptr[0] == '\0') return (KEYC_NONE); if (ptr[1] == '\0') { if (ptr[0] < 32 || ptr[0] > 127) return (KEYC_NONE); return (ptr[0] | KEYC_ESCAPE); } key = key_string_lookup_string(ptr); if (key != KEYC_NONE) return (key | KEYC_ESCAPE); return (KEYC_NONE); } return (key_string_search_table(string)); }
enum cmd_retval cmd_send_keys_exec(struct cmd *self, struct cmd_q *cmdq) { struct args *args = self->args; struct window_pane *wp; struct session *s; struct input_ctx *ictx; const u_char *str; int i, key; if (cmd_find_pane(cmdq, args_get(args, 't'), &s, &wp) == NULL) return (CMD_RETURN_ERROR); if (self->entry == &cmd_send_prefix_entry) { if (args_has(args, '2')) key = options_get_number(&s->options, "prefix2"); else key = options_get_number(&s->options, "prefix"); window_pane_key(wp, s, key); return (CMD_RETURN_NORMAL); } if (args_has(args, 'R')) { ictx = &wp->ictx; memcpy(&ictx->cell, &grid_default_cell, sizeof ictx->cell); memcpy(&ictx->old_cell, &ictx->cell, sizeof ictx->old_cell); ictx->old_cx = 0; ictx->old_cy = 0; if (wp->mode == NULL) screen_write_start(&ictx->ctx, wp, &wp->base); else screen_write_start(&ictx->ctx, NULL, &wp->base); screen_write_reset(&ictx->ctx); screen_write_stop(&ictx->ctx); } 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, s, key); } else { for (; *str != '\0'; str++) window_pane_key(wp, s, *str); } } return (CMD_RETURN_NORMAL); }
/* Set a key option. */ struct options_entry * cmd_set_option_key(unused struct cmd *self, struct cmd_q *cmdq, const struct options_table_entry *oe, struct options *oo, const char *value) { int key; if ((key = key_string_lookup_string(value)) == KEYC_NONE) { cmdq_error(cmdq, "bad key: %s", value); return (NULL); } return (options_set_number(oo, oe->name, key)); }
int cmd_send_keys_parse(struct cmd *self, int argc, char **argv, char **cause) { struct cmd_send_keys_data *data; int opt, key; char *s; self->data = data = xmalloc(sizeof *data); data->target = NULL; data->nkeys = 0; data->keys = NULL; while ((opt = getopt(argc, argv, "t:")) != -1) { switch (opt) { case 't': if (data->target == NULL) data->target = xstrdup(optarg); break; default: goto usage; } } argc -= optind; argv += optind; if (argc == 0) goto usage; while (argc-- != 0) { if ((key = key_string_lookup_string(*argv)) != KEYC_NONE) { data->keys = xrealloc( data->keys, data->nkeys + 1, sizeof *data->keys); data->keys[data->nkeys++] = key; } else { for (s = *argv; *s != '\0'; s++) { data->keys = xrealloc(data->keys, data->nkeys + 1, sizeof *data->keys); data->keys[data->nkeys++] = *s; } } argv++; } return (0); usage: xasprintf(cause, "usage: %s %s", self->entry->name, self->entry->usage); self->entry->free(self); return (-1); }
enum cmd_retval cmd_send_keys_exec(struct cmd *self, struct cmd_q *cmdq) { struct args *args = self->args; struct mouse_event *m = &cmdq->item->mouse; struct window_pane *wp; struct session *s; const char *str; int i, key; if (args_has(args, 'M')) { wp = cmd_mouse_pane(m, &s, NULL); if (wp == NULL) { cmdq_error(cmdq, "no mouse target"); return (CMD_RETURN_ERROR); } window_pane_key(wp, NULL, s, m->key, m); return (CMD_RETURN_NORMAL); } if (cmd_find_pane(cmdq, args_get(args, 't'), &s, &wp) == NULL) return (CMD_RETURN_ERROR); if (self->entry == &cmd_send_prefix_entry) { if (args_has(args, '2')) key = options_get_number(&s->options, "prefix2"); else key = options_get_number(&s->options, "prefix"); window_pane_key(wp, NULL, s, key, NULL); return (CMD_RETURN_NORMAL); } if (args_has(args, 'R')) 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); } } return (CMD_RETURN_NORMAL); }
enum cmd_retval cmd_bind_key_exec(struct cmd *self, struct cmd_q *cmdq) { struct args *args = self->args; char *cause; struct cmd_list *cmdlist; key_code key; const char *tablename; if (args_has(args, 't')) { if (args->argc != 2 && args->argc != 3) { cmdq_error(cmdq, "not enough arguments"); return (CMD_RETURN_ERROR); } } else { if (args->argc < 2) { cmdq_error(cmdq, "not enough arguments"); return (CMD_RETURN_ERROR); } } key = key_string_lookup_string(args->argv[0]); if (key == KEYC_NONE || key == KEYC_UNKNOWN) { cmdq_error(cmdq, "unknown key: %s", args->argv[0]); return (CMD_RETURN_ERROR); } if (args_has(args, 't')) return (cmd_bind_key_mode_table(self, cmdq, key)); if (args_has(args, 'T')) tablename = args_get(args, 'T'); else if (args_has(args, 'n')) tablename = "root"; else tablename = "prefix"; cmdlist = cmd_list_parse(args->argc - 1, args->argv + 1, NULL, 0, &cause); if (cmdlist == NULL) { cmdq_error(cmdq, "%s", cause); free(cause); return (CMD_RETURN_ERROR); } key_bindings_add(tablename, key, args_has(args, 'r'), cmdlist); return (CMD_RETURN_NORMAL); }
enum cmd_retval cmd_unbind_key_exec(struct cmd *self, struct cmd_q *cmdq) { struct args *args = self->args; struct key_binding *bd; int key; if (!args_has(args, 'a')) { if (args->argc != 1) { cmdq_error(cmdq, "missing key"); return (CMD_RETURN_ERROR); } key = key_string_lookup_string(args->argv[0]); if (key == KEYC_NONE) { cmdq_error(cmdq, "unknown key: %s", args->argv[0]); return (CMD_RETURN_ERROR); } } else { if (args->argc != 0) { cmdq_error(cmdq, "key given with -a"); return (CMD_RETURN_ERROR); } key = KEYC_NONE; } if (args_has(args, 't')) return (cmd_unbind_key_table(self, cmdq, key)); if (key == KEYC_NONE) { while (!RB_EMPTY(&key_bindings)) { bd = RB_ROOT(&key_bindings); key_bindings_remove(bd->key); } return (CMD_RETURN_NORMAL); } if (!args_has(args, 'n')) key |= KEYC_PREFIX; key_bindings_remove(key); return (CMD_RETURN_NORMAL); }
/* Lookup a string and convert to a key value, handling C-/M-/S- prefix. */ int key_string_lookup_string(const char *string) { int key; const char *ptr; if (string[0] == '\0') return (KEYC_NONE); if (string[1] == '\0') return ((u_char) string[0]); ptr = NULL; if ((string[0] == 'C' || string[0] == 'c') && string[1] == '-') ptr = string + 2; else if (string[0] == '^') ptr = string + 1; if (ptr != NULL) { if (ptr[0] == '\0') return (KEYC_NONE); /* * Lookup as a named key. If a function key (>= KEYC_BASE), * return it with the ctrl modifier, otherwise fallthrough with * the key value from the table (eg for C-Space). If not a * named key, check for single character keys and try that. */ key = key_string_search_table(ptr); if (key != KEYC_NONE) { if (key >= KEYC_BASE) return (key | KEYC_CTRL); } else { if (ptr[1] != '\0') return (KEYC_NONE); key = (u_char) ptr[0]; } /* * Figure out if the single character in key is a valid ctrl * key. */ if (key == 32) return (0); if (key == 63) return (KEYC_BSPACE); if (key >= 64 && key <= 95) return (key - 64); if (key >= 97 && key <= 122) return (key - 96); return (KEYC_NONE); } if ((string[0] == 'M' || string[0] == 'm') && string[1] == '-') { ptr = string + 2; if (ptr[0] == '\0') return (KEYC_NONE); key = key_string_lookup_string(ptr); if (key != KEYC_NONE) { if (key >= KEYC_BASE) return (key | KEYC_ESCAPE); } else { if (ptr[1] == '\0') return (KEYC_NONE); key = (u_char) ptr[0]; } if (key >= 32 && key <= 127) return (key | KEYC_ESCAPE); return (KEYC_NONE); } if ((string[0] == 'S' || string[0] == 's') && string[1] == '-') { ptr = string + 2; if (ptr[0] == '\0') return (KEYC_NONE); key = key_string_lookup_string(ptr); if (key != KEYC_NONE) { if (key >= KEYC_BASE) return (key | KEYC_SHIFT); } else { if (ptr[1] == '\0') return (KEYC_NONE); key = (u_char) ptr[0]; } if (key >= 32 && key <= 127) return (key | KEYC_SHIFT); return (KEYC_NONE); } return (key_string_search_table(string)); }
int cmd_bind_key_parse(struct cmd *self, int argc, char **argv, char **cause) { struct cmd_bind_key_data *data; int opt, no_prefix = 0; self->data = data = xmalloc(sizeof *data); data->can_repeat = 0; data->cmdlist = NULL; data->command_key = 0; data->tablename = NULL; data->modecmd = NULL; while ((opt = getopt(argc, argv, "cnrt:")) != -1) { switch (opt) { case 'c': data->command_key = 1; break; case 'n': no_prefix = 1; break; case 'r': data->can_repeat = 1; break; case 't': if (data->tablename == NULL) data->tablename = xstrdup(optarg); break; default: goto usage; } } argc -= optind; argv += optind; if (argc < 1) goto usage; if ((data->key = key_string_lookup_string(argv[0])) == KEYC_NONE) { xasprintf(cause, "unknown key: %s", argv[0]); goto error; } if (!no_prefix) data->key |= KEYC_PREFIX; argc--; argv++; if (data->tablename != NULL) { if (argc != 1) goto usage; data->modecmd = xstrdup(argv[0]); } else { if ((data->cmdlist = cmd_list_parse(argc, argv, cause)) == NULL) goto error; } return (0); usage: xasprintf(cause, "usage: %s %s", self->entry->name, self->entry->usage); error: self->entry->free(self); return (-1); }