1 /* $Id: cmd-unbind-key.c,v 1.1.1.1 2011/03/10 09:15:38 jmmv 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 * Unbind key from command. 25 */ 26 27 int cmd_unbind_key_parse(struct cmd *, int, char **, char **); 28 int cmd_unbind_key_exec(struct cmd *, struct cmd_ctx *); 29 void cmd_unbind_key_free(struct cmd *); 30 31 int cmd_unbind_key_table(struct cmd *, struct cmd_ctx *); 32 33 struct cmd_unbind_key_data { 34 int key; 35 36 int flag_all; 37 int command_key; 38 char *tablename; 39 }; 40 41 const struct cmd_entry cmd_unbind_key_entry = { 42 "unbind-key", "unbind", 43 "[-acn] [-t key-table] key", 44 0, "", 45 NULL, 46 cmd_unbind_key_parse, 47 cmd_unbind_key_exec, 48 cmd_unbind_key_free, 49 NULL 50 }; 51 52 int 53 cmd_unbind_key_parse(struct cmd *self, int argc, char **argv, char **cause) 54 { 55 struct cmd_unbind_key_data *data; 56 int opt, no_prefix = 0; 57 58 self->data = data = xmalloc(sizeof *data); 59 data->flag_all = 0; 60 data->command_key = 0; 61 data->tablename = NULL; 62 63 while ((opt = getopt(argc, argv, "acnt:")) != -1) { 64 switch (opt) { 65 case 'a': 66 data->flag_all = 1; 67 break; 68 case 'c': 69 data->command_key = 1; 70 break; 71 case 'n': 72 no_prefix = 1; 73 break; 74 case 't': 75 if (data->tablename == NULL) 76 data->tablename = xstrdup(optarg); 77 break; 78 default: 79 goto usage; 80 } 81 } 82 argc -= optind; 83 argv += optind; 84 if (data->flag_all && (argc != 0 || data->tablename)) 85 goto usage; 86 if (!data->flag_all && argc != 1) 87 goto usage; 88 89 if (!data->flag_all) { 90 data->key = key_string_lookup_string(argv[0]); 91 if (data->key == KEYC_NONE) { 92 xasprintf(cause, "unknown key: %s", argv[0]); 93 goto error; 94 } 95 if (!no_prefix) 96 data->key |= KEYC_PREFIX; 97 } 98 99 return (0); 100 101 usage: 102 xasprintf(cause, "usage: %s %s", self->entry->name, self->entry->usage); 103 104 error: 105 xfree(data); 106 return (-1); 107 } 108 109 int 110 cmd_unbind_key_exec(struct cmd *self, unused struct cmd_ctx *ctx) 111 { 112 struct cmd_unbind_key_data *data = self->data; 113 struct key_binding *bd; 114 115 if (data == NULL) 116 return (0); 117 if (data->flag_all) { 118 while (!SPLAY_EMPTY(&key_bindings)) { 119 bd = SPLAY_ROOT(&key_bindings); 120 SPLAY_REMOVE(key_bindings, &key_bindings, bd); 121 cmd_list_free(bd->cmdlist); 122 xfree(bd); 123 } 124 } else { 125 if (data->tablename != NULL) 126 return (cmd_unbind_key_table(self, ctx)); 127 128 key_bindings_remove(data->key); 129 } 130 131 return (0); 132 } 133 134 int 135 cmd_unbind_key_table(struct cmd *self, struct cmd_ctx *ctx) 136 { 137 struct cmd_unbind_key_data *data = self->data; 138 const struct mode_key_table *mtab; 139 struct mode_key_binding *mbind, mtmp; 140 141 if ((mtab = mode_key_findtable(data->tablename)) == NULL) { 142 ctx->error(ctx, "unknown key table: %s", data->tablename); 143 return (-1); 144 } 145 146 mtmp.key = data->key & ~KEYC_PREFIX; 147 mtmp.mode = data->command_key ? 1 : 0; 148 if ((mbind = SPLAY_FIND(mode_key_tree, mtab->tree, &mtmp)) != NULL) { 149 SPLAY_REMOVE(mode_key_tree, mtab->tree, mbind); 150 xfree(mbind); 151 } 152 return (0); 153 } 154 155 void 156 cmd_unbind_key_free(struct cmd *self) 157 { 158 struct cmd_unbind_key_data *data = self->data; 159 160 if (data->tablename != NULL) 161 xfree(data->tablename); 162 xfree(data); 163 } 164