cmd-bind-key.c revision 1.4
1/* $OpenBSD: cmd-bind-key.c,v 1.4 2009/07/26 12:58:44 nicm Exp $ */ 2 3/* 4 * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> 5 * 6 * Permission to use, copy, modify, and distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER 15 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING 16 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19#include <sys/types.h> 20 21#include "tmux.h" 22 23/* 24 * Bind a key to a command, this recurses through cmd_*. 25 */ 26 27int cmd_bind_key_parse(struct cmd *, int, char **, char **); 28int cmd_bind_key_exec(struct cmd *, struct cmd_ctx *); 29void cmd_bind_key_free(struct cmd *); 30size_t cmd_bind_key_print(struct cmd *, char *, size_t); 31 32struct cmd_bind_key_data { 33 int key; 34 int can_repeat; 35 struct cmd_list *cmdlist; 36}; 37 38const struct cmd_entry cmd_bind_key_entry = { 39 "bind-key", "bind", 40 "[-nr] key command [arguments]", 41 0, 0, 42 NULL, 43 cmd_bind_key_parse, 44 cmd_bind_key_exec, 45 cmd_bind_key_free, 46 cmd_bind_key_print 47}; 48 49int 50cmd_bind_key_parse(struct cmd *self, int argc, char **argv, char **cause) 51{ 52 struct cmd_bind_key_data *data; 53 int opt, no_prefix = 0; 54 55 self->data = data = xmalloc(sizeof *data); 56 data->can_repeat = 0; 57 data->cmdlist = NULL; 58 59 while ((opt = getopt(argc, argv, "nr")) != -1) { 60 switch (opt) { 61 case 'n': 62 no_prefix = 1; 63 break; 64 case 'r': 65 data->can_repeat = 1; 66 break; 67 default: 68 goto usage; 69 } 70 } 71 argc -= optind; 72 argv += optind; 73 if (argc < 1) 74 goto usage; 75 76 if ((data->key = key_string_lookup_string(argv[0])) == KEYC_NONE) { 77 xasprintf(cause, "unknown key: %s", argv[0]); 78 goto error; 79 } 80 if (!no_prefix) 81 data->key |= KEYC_PREFIX; 82 83 argc--; 84 argv++; 85 if ((data->cmdlist = cmd_list_parse(argc, argv, cause)) == NULL) 86 goto error; 87 88 return (0); 89 90usage: 91 xasprintf(cause, "usage: %s %s", self->entry->name, self->entry->usage); 92 93error: 94 self->entry->free(self); 95 return (-1); 96} 97 98int 99cmd_bind_key_exec(struct cmd *self, unused struct cmd_ctx *ctx) 100{ 101 struct cmd_bind_key_data *data = self->data; 102 103 if (data == NULL) 104 return (0); 105 106 key_bindings_add(data->key, data->can_repeat, data->cmdlist); 107 data->cmdlist = NULL; /* avoid free */ 108 109 return (0); 110} 111 112void 113cmd_bind_key_free(struct cmd *self) 114{ 115 struct cmd_bind_key_data *data = self->data; 116 117 if (data->cmdlist != NULL) 118 cmd_list_free(data->cmdlist); 119 xfree(data); 120} 121 122size_t 123cmd_bind_key_print(struct cmd *self, char *buf, size_t len) 124{ 125 struct cmd_bind_key_data *data = self->data; 126 size_t off = 0; 127 const char *skey; 128 129 off += xsnprintf(buf, len, "%s", self->entry->name); 130 if (data == NULL) 131 return (off); 132 if (off < len) { 133 skey = key_string_lookup_key(data->key); 134 off += xsnprintf(buf + off, len - off, " %s ", skey); 135 } 136 if (off < len) 137 off += cmd_list_print(data->cmdlist, buf + off, len - off); 138 return (off); 139} 140