xref: /minix/external/bsd/tmux/dist/cmd-list-keys.c (revision 0a6a1f1d)
1 /* Id */
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 enum cmd_retval	 cmd_list_keys_table(struct cmd *, struct cmd_q *);
31 
32 const struct cmd_entry cmd_list_keys_entry = {
33 	"list-keys", "lsk",
34 	"t:", 0, 0,
35 	"[-t key-table]",
36 	0,
37 	NULL,
38 	cmd_list_keys_exec
39 };
40 
41 enum cmd_retval
cmd_list_keys_exec(struct cmd * self,struct cmd_q * cmdq)42 cmd_list_keys_exec(struct cmd *self, struct cmd_q *cmdq)
43 {
44 	struct args		*args = self->args;
45 	struct key_binding	*bd;
46 	const char		*key;
47 	char			 tmp[BUFSIZ], flags[8];
48 	size_t			 used;
49 	int			 width, keywidth;
50 
51 	if (args_has(args, 't'))
52 		return (cmd_list_keys_table(self, cmdq));
53 
54 	width = 0;
55 
56 	RB_FOREACH(bd, key_bindings, &key_bindings) {
57 		key = key_string_lookup_key(bd->key & ~KEYC_PREFIX);
58 		if (key == NULL)
59 			continue;
60 
61 		keywidth = strlen(key);
62 		if (!(bd->key & KEYC_PREFIX)) {
63 			if (bd->can_repeat)
64 				keywidth += 4;
65 			else
66 				keywidth += 3;
67 		} else if (bd->can_repeat)
68 			keywidth += 3;
69 		if (keywidth > width)
70 			width = keywidth;
71 	}
72 
73 	RB_FOREACH(bd, key_bindings, &key_bindings) {
74 		key = key_string_lookup_key(bd->key & ~KEYC_PREFIX);
75 		if (key == NULL)
76 			continue;
77 
78 		*flags = '\0';
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 		cmdq_print(cmdq, "bind-key %s", tmp);
94 	}
95 
96 	return (CMD_RETURN_NORMAL);
97 }
98 
99 enum cmd_retval
cmd_list_keys_table(struct cmd * self,struct cmd_q * cmdq)100 cmd_list_keys_table(struct cmd *self, struct cmd_q *cmdq)
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 		cmdq_error(cmdq, "unknown key table: %s", tablename);
112 		return (CMD_RETURN_ERROR);
113 	}
114 
115 	width = 0;
116 	any_mode = 0;
117 	RB_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 	RB_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 			cmdq_print(cmdq, "bind-key -%st %s%s %*s %s%s%s%s",
141 			    mode, any_mode && *mode == '\0' ? " " : "",
142 			    mtab->name, (int) width, key, cmdstr,
143 			    mbind->arg != NULL ? " \"" : "",
144 			    mbind->arg != NULL ? mbind->arg : "",
145 			    mbind->arg != NULL ? "\"": "");
146 		}
147 	}
148 
149 	return (CMD_RETURN_NORMAL);
150 }
151