cmd-list-keys.c revision 1.1.1.5 1 /* $OpenBSD$ */
2
3 /*
4 * Copyright (c) 2007 Nicholas Marriott <nicm (at) 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:T:", 0, 0,
37 "[-t mode-table] [-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_table *table;
55 struct key_binding *bd;
56 const char *key, *tablename, *r;
57 char tmp[BUFSIZ];
58 size_t used;
59 int repeat, width, tablewidth, keywidth;
60
61 if (self->entry == &cmd_list_commands_entry)
62 return (cmd_list_keys_commands(self, cmdq));
63
64 if (args_has(args, 't'))
65 return (cmd_list_keys_table(self, cmdq));
66
67 tablename = args_get(args, 'T');
68 if (tablename != NULL && key_bindings_get_table(tablename, 0) == NULL) {
69 cmdq_error(cmdq, "table %s doesn't exist", tablename);
70 return (CMD_RETURN_ERROR);
71 }
72
73 repeat = 0;
74 tablewidth = keywidth = 0;
75 RB_FOREACH(table, key_tables, &key_tables) {
76 if (tablename != NULL && strcmp(table->name, tablename) != 0)
77 continue;
78 RB_FOREACH(bd, key_bindings, &table->key_bindings) {
79 key = key_string_lookup_key(bd->key);
80 if (key == NULL)
81 continue;
82
83 if (bd->can_repeat)
84 repeat = 1;
85
86 width = strlen(table->name);
87 if (width > tablewidth)
88 tablewidth =width;
89 width = strlen(key);
90 if (width > keywidth)
91 keywidth = width;
92 }
93 }
94
95 RB_FOREACH(table, key_tables, &key_tables) {
96 if (tablename != NULL && strcmp(table->name, tablename) != 0)
97 continue;
98 RB_FOREACH(bd, key_bindings, &table->key_bindings) {
99 key = key_string_lookup_key(bd->key);
100 if (key == NULL)
101 continue;
102
103 if (!repeat)
104 r = "";
105 else if (bd->can_repeat)
106 r = "-r ";
107 else
108 r = " ";
109 used = xsnprintf(tmp, sizeof tmp, "%s-T %-*s %-*s ", r,
110 (int)tablewidth, table->name, (int)keywidth, key);
111 if (used < sizeof tmp) {
112 cmd_list_print(bd->cmdlist, tmp + used,
113 (sizeof tmp) - used);
114 }
115
116 cmdq_print(cmdq, "bind-key %s", tmp);
117 }
118 }
119
120 return (CMD_RETURN_NORMAL);
121 }
122
123 enum cmd_retval
124 cmd_list_keys_table(struct cmd *self, struct cmd_q *cmdq)
125 {
126 struct args *args = self->args;
127 const char *tablename;
128 const struct mode_key_table *mtab;
129 struct mode_key_binding *mbind;
130 const char *key, *cmdstr, *mode;
131 int width, keywidth, any_mode;
132
133 tablename = args_get(args, 't');
134 if ((mtab = mode_key_findtable(tablename)) == NULL) {
135 cmdq_error(cmdq, "unknown key table: %s", tablename);
136 return (CMD_RETURN_ERROR);
137 }
138
139 width = 0;
140 any_mode = 0;
141 RB_FOREACH(mbind, mode_key_tree, mtab->tree) {
142 key = key_string_lookup_key(mbind->key);
143 if (key == NULL)
144 continue;
145
146 if (mbind->mode != 0)
147 any_mode = 1;
148
149 keywidth = strlen(key);
150 if (keywidth > width)
151 width = keywidth;
152 }
153
154 RB_FOREACH(mbind, mode_key_tree, mtab->tree) {
155 key = key_string_lookup_key(mbind->key);
156 if (key == NULL)
157 continue;
158
159 mode = "";
160 if (mbind->mode != 0)
161 mode = "c";
162 cmdstr = mode_key_tostring(mtab->cmdstr, mbind->cmd);
163 if (cmdstr != NULL) {
164 cmdq_print(cmdq, "bind-key -%st %s%s %*s %s%s%s%s",
165 mode, any_mode && *mode == '\0' ? " " : "",
166 mtab->name, (int) width, key, cmdstr,
167 mbind->arg != NULL ? " \"" : "",
168 mbind->arg != NULL ? mbind->arg : "",
169 mbind->arg != NULL ? "\"": "");
170 }
171 }
172
173 return (CMD_RETURN_NORMAL);
174 }
175
176 enum cmd_retval
177 cmd_list_keys_commands(unused struct cmd *self, struct cmd_q *cmdq)
178 {
179 const struct cmd_entry **entryp;
180 const struct cmd_entry *entry;
181
182 for (entryp = cmd_table; *entryp != NULL; entryp++) {
183 entry = *entryp;
184 if (entry->alias == NULL) {
185 cmdq_print(cmdq, "%s %s", entry->name, entry->usage);
186 continue;
187 }
188 cmdq_print(cmdq, "%s (%s) %s", entry->name, entry->alias,
189 entry->usage);
190 }
191
192 return (CMD_RETURN_NORMAL);
193 }
194