xref: /minix/external/bsd/tmux/dist/cmd-list-keys.c (revision e3b78ef1)
1 /* $Id: cmd-list-keys.c,v 1.1.1.2 2011/08/17 18:40:04 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 <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 	*flags = '\0';
58 
59 	SPLAY_FOREACH(bd, key_bindings, &key_bindings) {
60 		key = key_string_lookup_key(bd->key & ~KEYC_PREFIX);
61 		if (key == NULL)
62 			continue;
63 
64 		keywidth = strlen(key);
65 		if (!(bd->key & KEYC_PREFIX)) {
66 			if (bd->can_repeat)
67 				keywidth += 4;
68 			else
69 				keywidth += 3;
70 		} else if (bd->can_repeat)
71 			keywidth += 3;
72 		if (keywidth > width)
73 			width = keywidth;
74 	}
75 
76 	SPLAY_FOREACH(bd, key_bindings, &key_bindings) {
77 		key = key_string_lookup_key(bd->key & ~KEYC_PREFIX);
78 		if (key == NULL)
79 			continue;
80 
81 		if (!(bd->key & KEYC_PREFIX)) {
82 			if (bd->can_repeat)
83 				xsnprintf(flags, sizeof flags, "-rn ");
84 			else
85 				xsnprintf(flags, sizeof flags, "-n ");
86 		} else if (bd->can_repeat)
87 			xsnprintf(flags, sizeof flags, "-r ");
88 
89 		used = xsnprintf(tmp, sizeof tmp, "%s%*s ",
90 		    flags, (int) (width - strlen(flags)), key);
91 		if (used >= sizeof tmp)
92 			continue;
93 
94 		cmd_list_print(bd->cmdlist, tmp + used, (sizeof tmp) - used);
95 		ctx->print(ctx, "bind-key %s", tmp);
96 	}
97 
98 	return (0);
99 }
100 
101 int
102 cmd_list_keys_table(struct cmd *self, struct cmd_ctx *ctx)
103 {
104 	struct args			*args = self->args;
105 	const char			*tablename;
106 	const struct mode_key_table	*mtab;
107 	struct mode_key_binding		*mbind;
108 	const char			*key, *cmdstr, *mode;
109 	int			 	 width, keywidth, any_mode;
110 
111 	tablename = args_get(args, 't');
112 	if ((mtab = mode_key_findtable(tablename)) == NULL) {
113 		ctx->error(ctx, "unknown key table: %s", tablename);
114 		return (-1);
115 	}
116 
117 	width = 0;
118 	any_mode = 0;
119 	SPLAY_FOREACH(mbind, mode_key_tree, mtab->tree) {
120 		key = key_string_lookup_key(mbind->key);
121 		if (key == NULL)
122 			continue;
123 
124 		if (mbind->mode != 0)
125 			any_mode = 1;
126 
127 		keywidth = strlen(key);
128 		if (keywidth > width)
129 			width = keywidth;
130 	}
131 
132 	SPLAY_FOREACH(mbind, mode_key_tree, mtab->tree) {
133 		key = key_string_lookup_key(mbind->key);
134 		if (key == NULL)
135 			continue;
136 
137 		mode = "";
138 		if (mbind->mode != 0)
139 			mode = "c";
140 		cmdstr = mode_key_tostring(mtab->cmdstr, mbind->cmd);
141 		if (cmdstr != NULL) {
142 			ctx->print(ctx, "bind-key -%st %s%s %*s %s",
143 			    mode, any_mode && *mode == '\0' ? " " : "",
144 			    mtab->name, (int) width, key, cmdstr);
145 		}
146 	}
147 
148 	return (0);
149 }
150