1 /* $OpenBSD: cmd-list-keys.c,v 1.25 2014/10/20 23:27:14 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 <string.h> 22 23 #include "tmux.h" 24 25 /* 26 * List key bindings. 27 */ 28 29 enum cmd_retval cmd_list_keys_exec(struct cmd *, struct cmd_q *); 30 31 enum cmd_retval cmd_list_keys_table(struct cmd *, struct cmd_q *); 32 enum cmd_retval cmd_list_keys_commands(struct cmd *, struct cmd_q *); 33 34 const struct cmd_entry cmd_list_keys_entry = { 35 "list-keys", "lsk", 36 "t:", 0, 0, 37 "[-t key-table]", 38 0, 39 cmd_list_keys_exec 40 }; 41 42 const struct cmd_entry cmd_list_commands_entry = { 43 "list-commands", "lscm", 44 "", 0, 0, 45 "", 46 0, 47 cmd_list_keys_exec 48 }; 49 50 enum cmd_retval 51 cmd_list_keys_exec(struct cmd *self, struct cmd_q *cmdq) 52 { 53 struct args *args = self->args; 54 struct key_binding *bd; 55 const char *key; 56 char tmp[BUFSIZ], flags[8]; 57 size_t used; 58 int width, keywidth; 59 60 if (self->entry == &cmd_list_commands_entry) 61 return (cmd_list_keys_commands(self, cmdq)); 62 63 if (args_has(args, 't')) 64 return (cmd_list_keys_table(self, cmdq)); 65 66 width = 0; 67 68 RB_FOREACH(bd, key_bindings, &key_bindings) { 69 key = key_string_lookup_key(bd->key & ~KEYC_PREFIX); 70 if (key == NULL) 71 continue; 72 73 keywidth = strlen(key); 74 if (!(bd->key & KEYC_PREFIX)) { 75 if (bd->can_repeat) 76 keywidth += 4; 77 else 78 keywidth += 3; 79 } else if (bd->can_repeat) 80 keywidth += 3; 81 if (keywidth > width) 82 width = keywidth; 83 } 84 85 RB_FOREACH(bd, key_bindings, &key_bindings) { 86 key = key_string_lookup_key(bd->key & ~KEYC_PREFIX); 87 if (key == NULL) 88 continue; 89 90 *flags = '\0'; 91 if (!(bd->key & KEYC_PREFIX)) { 92 if (bd->can_repeat) 93 xsnprintf(flags, sizeof flags, "-rn "); 94 else 95 xsnprintf(flags, sizeof flags, "-n "); 96 } else if (bd->can_repeat) 97 xsnprintf(flags, sizeof flags, "-r "); 98 99 used = xsnprintf(tmp, sizeof tmp, "%s%*s ", 100 flags, (int) (width - strlen(flags)), key); 101 if (used >= sizeof tmp) 102 continue; 103 104 cmd_list_print(bd->cmdlist, tmp + used, (sizeof tmp) - used); 105 cmdq_print(cmdq, "bind-key %s", tmp); 106 } 107 108 return (CMD_RETURN_NORMAL); 109 } 110 111 enum cmd_retval 112 cmd_list_keys_table(struct cmd *self, struct cmd_q *cmdq) 113 { 114 struct args *args = self->args; 115 const char *tablename; 116 const struct mode_key_table *mtab; 117 struct mode_key_binding *mbind; 118 const char *key, *cmdstr, *mode; 119 int width, keywidth, any_mode; 120 121 tablename = args_get(args, 't'); 122 if ((mtab = mode_key_findtable(tablename)) == NULL) { 123 cmdq_error(cmdq, "unknown key table: %s", tablename); 124 return (CMD_RETURN_ERROR); 125 } 126 127 width = 0; 128 any_mode = 0; 129 RB_FOREACH(mbind, mode_key_tree, mtab->tree) { 130 key = key_string_lookup_key(mbind->key); 131 if (key == NULL) 132 continue; 133 134 if (mbind->mode != 0) 135 any_mode = 1; 136 137 keywidth = strlen(key); 138 if (keywidth > width) 139 width = keywidth; 140 } 141 142 RB_FOREACH(mbind, mode_key_tree, mtab->tree) { 143 key = key_string_lookup_key(mbind->key); 144 if (key == NULL) 145 continue; 146 147 mode = ""; 148 if (mbind->mode != 0) 149 mode = "c"; 150 cmdstr = mode_key_tostring(mtab->cmdstr, mbind->cmd); 151 if (cmdstr != NULL) { 152 cmdq_print(cmdq, "bind-key -%st %s%s %*s %s%s%s%s", 153 mode, any_mode && *mode == '\0' ? " " : "", 154 mtab->name, (int) width, key, cmdstr, 155 mbind->arg != NULL ? " \"" : "", 156 mbind->arg != NULL ? mbind->arg : "", 157 mbind->arg != NULL ? "\"": ""); 158 } 159 } 160 161 return (CMD_RETURN_NORMAL); 162 } 163 164 enum cmd_retval 165 cmd_list_keys_commands(unused struct cmd *self, struct cmd_q *cmdq) 166 { 167 const struct cmd_entry **entryp; 168 const struct cmd_entry *entry; 169 170 for (entryp = cmd_table; *entryp != NULL; entryp++) { 171 entry = *entryp; 172 if (entry->alias == NULL) { 173 cmdq_print(cmdq, "%s %s", entry->name, entry->usage); 174 continue; 175 } 176 cmdq_print(cmdq, "%s (%s) %s", entry->name, entry->alias, 177 entry->usage); 178 } 179 180 return (CMD_RETURN_NORMAL); 181 } 182