xref: /openbsd/usr.bin/tmux/cmd-list-keys.c (revision 891d7ab6)
1 /* $OpenBSD: cmd-list-keys.c,v 1.14 2011/07/04 00:31:57 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 int	cmd_list_keys_exec(struct cmd *, struct cmd_ctx *);
30 
31 int	cmd_list_keys_table(struct cmd *, struct cmd_ctx *);
32 
33 const struct cmd_entry cmd_list_keys_entry = {
34 	"list-keys", "lsk",
35 	"t:", 0, 0,
36 	"[-t key-table]",
37 	0,
38 	NULL,
39 	NULL,
40 	cmd_list_keys_exec
41 };
42 
43 int
44 cmd_list_keys_exec(struct cmd *self, struct cmd_ctx *ctx)
45 {
46 	struct args		*args = self->args;
47 	struct key_binding	*bd;
48 	const char		*key;
49 	char			 tmp[BUFSIZ], flags[8];
50 	size_t			 used;
51 	int			 width, keywidth;
52 
53 	if (args_has(args, 't'))
54 		return (cmd_list_keys_table(self, ctx));
55 
56 	width = 0;
57 	SPLAY_FOREACH(bd, key_bindings, &key_bindings) {
58 		key = key_string_lookup_key(bd->key & ~KEYC_PREFIX);
59 		if (key == NULL)
60 			continue;
61 
62 		keywidth = strlen(key);
63 		if (!(bd->key & KEYC_PREFIX)) {
64 			if (bd->can_repeat)
65 				keywidth += 4;
66 			else
67 				keywidth += 3;
68 		} else if (bd->can_repeat)
69 			keywidth += 3;
70 		if (keywidth > width)
71 			width = keywidth;
72 	}
73 
74 	SPLAY_FOREACH(bd, key_bindings, &key_bindings) {
75 		key = key_string_lookup_key(bd->key & ~KEYC_PREFIX);
76 		if (key == NULL)
77 			continue;
78 
79 		if (!(bd->key & KEYC_PREFIX)) {
80 			if (bd->can_repeat)
81 				xsnprintf(flags, sizeof flags, "-rn ");
82 			else
83 				xsnprintf(flags, sizeof flags, "-n ");
84 		} else if (bd->can_repeat)
85 			xsnprintf(flags, sizeof flags, "-r ");
86 
87 		used = xsnprintf(tmp, sizeof tmp, "%s%*s ",
88 		    flags, (int) (width - strlen(flags)), key);
89 		if (used >= sizeof tmp)
90 			continue;
91 
92 		cmd_list_print(bd->cmdlist, tmp + used, (sizeof tmp) - used);
93 		ctx->print(ctx, "bind-key %s", tmp);
94 	}
95 
96 	return (0);
97 }
98 
99 int
100 cmd_list_keys_table(struct cmd *self, struct cmd_ctx *ctx)
101 {
102 	struct args			*args = self->args;
103 	const char			*tablename;
104 	const struct mode_key_table	*mtab;
105 	struct mode_key_binding		*mbind;
106 	const char			*key, *cmdstr, *mode;
107 	int			 	 width, keywidth, any_mode;
108 
109 	tablename = args_get(args, 't');
110 	if ((mtab = mode_key_findtable(tablename)) == NULL) {
111 		ctx->error(ctx, "unknown key table: %s", tablename);
112 		return (-1);
113 	}
114 
115 	width = 0;
116 	any_mode = 0;
117 	SPLAY_FOREACH(mbind, mode_key_tree, mtab->tree) {
118 		key = key_string_lookup_key(mbind->key);
119 		if (key == NULL)
120 			continue;
121 
122 		if (mbind->mode != 0)
123 			any_mode = 1;
124 
125 		keywidth = strlen(key);
126 		if (keywidth > width)
127 			width = keywidth;
128 	}
129 
130 	SPLAY_FOREACH(mbind, mode_key_tree, mtab->tree) {
131 		key = key_string_lookup_key(mbind->key);
132 		if (key == NULL)
133 			continue;
134 
135 		mode = "";
136 		if (mbind->mode != 0)
137 			mode = "c";
138 		cmdstr = mode_key_tostring(mtab->cmdstr, mbind->cmd);
139 		if (cmdstr != NULL) {
140 			ctx->print(ctx, "bind-key -%st %s%s %*s %s",
141 			    mode, any_mode && *mode == '\0' ? " " : "",
142 			    mtab->name, (int) width, key, cmdstr);
143 		}
144 	}
145 
146 	return (0);
147 }
148