1 /* vifm
2  * Copyright (C) 2011 xaizek.
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
17  */
18 
19 #ifndef VIFM__ENGINE__KEYS_H__
20 #define VIFM__ENGINE__KEYS_H__
21 
22 #include <stddef.h> /* size_t wchar_t */
23 
24 enum
25 {
26 	NO_COUNT_GIVEN = -1,
27 	NO_REG_GIVEN = -1,
28 };
29 
30 enum
31 {
32 	MF_USES_REGS = 1,
33 	MF_USES_COUNT = 2,
34 	MF_USES_INPUT = 4,
35 };
36 
37 enum
38 {
39 	KEYS_UNKNOWN    = -1024,
40 	KEYS_WAIT       = -2048,
41 	KEYS_WAIT_SHORT = -4096,
42 };
43 
44 /* Flags for a user key mapping. */
45 enum
46 {
47 	KEYS_FLAG_NONE = 0,    /* No flags. */
48 	KEYS_FLAG_NOREMAP = 1, /* Ignore user mappings in RHS. */
49 	KEYS_FLAG_SILENT = 2,  /* Postpone screen update until mapping's end. */
50 	KEYS_FLAG_WAIT = 4,    /* Do not use short wait to resolve conflict against
51 	                          builtin mapping. */
52 };
53 
54 /* Checks passed in value for being among list of error codes this unit can
55  * return. */
56 #define IS_KEYS_RET_CODE(c) \
57 		({ \
58 			const int tmp = (c); \
59 			tmp == KEYS_UNKNOWN || tmp == KEYS_WAIT || tmp == KEYS_WAIT_SHORT; \
60 		})
61 
62 typedef enum
63 {
64 	FOLLOWED_BY_NONE,
65 	FOLLOWED_BY_SELECTOR,
66 	FOLLOWED_BY_MULTIKEY,
67 }
68 FollowedBy;
69 
70 /* Describes single key (command or selector) on its own. */
71 typedef struct
72 {
73 	int count; /* Repeat count, may be equal NO_COUNT_GIVEN. */
74 	int reg;   /* Number of selected register. */
75 	int multi; /* Multikey. */
76 }
77 key_info_t;
78 
79 /* Describes sequence of keys (it can consist of a single key).  This structure
80  * is shared among elements composite constructs like command+selector. */
81 typedef struct
82 {
83 	int selector;   /* Selector passed. */
84 	int count;      /* Count of selected items. */
85 	int *indexes;   /* Item indexes. */
86 	int after_wait; /* After short timeout. */
87 	int mapped;     /* Not users input. */
88 	int recursive;  /* The key is from recursive call of execute_keys_*(...). */
89 }
90 keys_info_t;
91 
92 /* Handler for builtin keys. */
93 typedef void (*vle_keys_handler)(key_info_t key_info, keys_info_t *keys_info);
94 /* Type of function invoked by vle_keys_list() and vle_keys_suggest().  rhs is
95  * provided for user-defined keys and is empty otherwise.  Description is empty
96  * for user-defined keys or when not set. */
97 typedef void (*vle_keys_list_cb)(const wchar_t lhs[], const wchar_t rhs[],
98 		const char descr[]);
99 /* User-provided suggestion callback for multikeys. */
100 typedef void (*vle_suggest_func)(vle_keys_list_cb cb);
101 /* User-provided callback for silencing UI.  Non-zero argument makes UI more
102  * silent, zero argument makes it less silent. */
103 typedef void (*vle_silence_func)(int more);
104 
105 /* Type of callback that handles all keys uncaught by shortcuts.  Should return
106  * zero on success and non-zero on error. */
107 typedef int (*default_handler)(wchar_t key);
108 
109 typedef struct
110 {
111 	union
112 	{
113 		vle_keys_handler handler; /* Handler for builtin commands. */
114 		wchar_t *cmd;             /* Mapped value for user-defined keys. */
115 	}
116 	data;
117 	FollowedBy followed;        /* What type of key should we wait for. */
118 	vle_suggest_func suggest;   /* Suggestion function (can be NULL).  Invoked for
119 	                               multikeys. */
120 	const char *descr;          /* Brief description of the key (can be NULL). */
121 	int nim;                    /* Whether additional count in the middle is
122 	                               allowed. */
123 	int skip_suggestion;        /* Do not print this among suggestions. */
124 }
125 key_conf_t;
126 
127 typedef struct
128 {
129 	const wchar_t keys[5];
130 	key_conf_t info;
131 }
132 keys_add_info_t;
133 
134 /* Initializes the unit.  Assumed that key_mode_flags is an array of at least
135  * modes_count items. */
136 void vle_keys_init(int modes_count, int *key_mode_flags,
137 		vle_silence_func silence);
138 
139 /* Frees all memory allocated by the unit and returns it to initial state. */
140 void vle_keys_reset(void);
141 
142 /* Removes just user-defined keys (leaving builtin keys intact). */
143 void vle_keys_user_clear(void);
144 
145 /* Set handler for unregistered keys.  handler can be NULL to remove it. */
146 void vle_keys_set_def_handler(int mode, default_handler handler);
147 
148 /* Process sequence of keys.  Return value:
149  *  - 0 - success
150  *  - KEYS_*
151  *  - something else from the default key handler */
152 int vle_keys_exec(const wchar_t keys[]);
153 
154 /* Same as vle_keys_exec(), but disallows map processing in RHS of maps. */
155 int vle_keys_exec_no_remap(const wchar_t keys[]);
156 
157 /* Same as vle_keys_exec(), but assumes that key wait timeout has expired. */
158 int vle_keys_exec_timed_out(const wchar_t keys[]);
159 
160 /* Same as vle_keys_exec_no_remap(), but assumes that key wait timeout has
161  * expired. */
162 int vle_keys_exec_timed_out_no_remap(const wchar_t keys[]);
163 
164 /* Registers cmds[0 .. len-1] commands for the mode.  Returns non-zero on error,
165  * otherwise zero is returned. */
166 int vle_keys_add(keys_add_info_t cmds[], size_t len, int mode);
167 
168 /* Registers cmds[0 .. len-1] selectors for the mode.  Returns non-zero on
169  * error, otherwise zero is returned. */
170 int vle_keys_add_selectors(keys_add_info_t cmds[], size_t len, int mode);
171 
172 /* Registers user key mapping.  The flags parameter accepts combinations of
173  * KEYS_FLAG_*.  Returns non-zero or error, otherwise zero is returned. */
174 int vle_keys_user_add(const wchar_t keys[], const wchar_t rhs[], int mode,
175 		int flags);
176 
177 /* Checks whether given user mapping exists.  Returns non-zero if so, otherwise
178  * zero is returned. */
179 int vle_keys_user_exists(const wchar_t keys[], int mode);
180 
181 /* Removes user mapping from the mode.  Returns non-zero if given key sequence
182  * wasn't found. */
183 int vle_keys_user_remove(const wchar_t keys[], int mode);
184 
185 /* Lists all or just user keys of the given mode with description. */
186 void vle_keys_list(int mode, vle_keys_list_cb cb, int user_only);
187 
188 /* Retrieves number of keys processed so far.  Clients are expected to use
189  * difference of returned values.  Returns the number. */
190 size_t vle_keys_counter(void);
191 
192 /* Retrieves current mapping state.  Entering a mapping at the top level (so not
193  * a nested mapping) increases state number.  Returns the state number or zero
194  * if no mapping is currently active. */
195 int vle_keys_mapping_state(void);
196 
197 /* Invokes cb for each possible keys continuation.  Intended to be used on
198  * KEYS_WAIT and KEYS_WAIT_SHORT returns.  The custom_only flag limits
199  * suggestions to those generated by invoking key_conf_t::suggest.  The
200  * fold_subkeys enables folding of multiple keys with common prefix. */
201 void vle_keys_suggest(const wchar_t keys[], vle_keys_list_cb cb,
202 		int custom_only, int fold_subkeys);
203 
204 #endif /* VIFM__ENGINE__KEYS_H__ */
205 
206 /* vim: set tabstop=2 softtabstop=2 shiftwidth=2 noexpandtab cinoptions-=(0: */
207 /* vim: set cinoptions+=t0 filetype=c : */
208