File data/vim/doc/app/vifm-lua.txt changed (mode: 100644) (index 95039099b..123626d34) |
... |
... |
Possible fields of {key}: |
570 |
570 |
Unsupported values are ignored. |
Unsupported values are ignored. |
571 |
571 |
- "isselector" (boolean) (default: false) |
- "isselector" (boolean) (default: false) |
572 |
572 |
Whether this handler defines a selector rather than a regular key. |
Whether this handler defines a selector rather than a regular key. |
|
573 |
|
- "followedby" (string) (default: "none") |
|
574 |
|
"none", "selector" (e.g., "j" in "dj") or "keyarg" (e.g., "q" in "'q"). |
573 |
575 |
- "handler" (function) |
- "handler" (function) |
574 |
576 |
Handler which accepts {info} and returns a table for selector handlers. |
Handler which accepts {info} and returns a table for selector handlers. |
575 |
577 |
See below. |
See below. |
|
... |
... |
Fields of {info} argument for {key}.handler: |
582 |
584 |
Count preceding the key or nil if none. |
Count preceding the key or nil if none. |
583 |
585 |
- "register" (string) |
- "register" (string) |
584 |
586 |
Register name or nil if none was specified. |
Register name or nil if none was specified. |
|
587 |
|
- "indexes" (table) (present if key is followed by selector) |
|
588 |
|
Table of indexes returned by selector key. |
|
589 |
|
- "keyarg" (string) (present if key is followed by keyarg) |
|
590 |
|
Key argument (e.g., "x" in "mx" sequence). |
585 |
591 |
|
|
586 |
592 |
Fields of table returned by {key}.handler for selectors: |
Fields of table returned by {key}.handler for selectors: |
587 |
593 |
- "indexes" (table) |
- "indexes" (table) |
File src/lua/vifm_keys.c changed (mode: 100644) (index 1c59fc4cb..8aacb1f09) |
... |
... |
VLUA_DECLARE_SAFE(keys_add); |
42 |
42 |
|
|
43 |
43 |
static void parse_modes(vlua_t *vlua, char modes[MODES_COUNT]); |
static void parse_modes(vlua_t *vlua, char modes[MODES_COUNT]); |
44 |
44 |
static void lua_key_handler(key_info_t key_info, keys_info_t *keys_info); |
static void lua_key_handler(key_info_t key_info, keys_info_t *keys_info); |
45 |
|
static void build_handler_args(lua_State *lua, key_info_t key_info); |
|
|
45 |
|
static void build_handler_args(lua_State *lua, key_info_t key_info, |
|
46 |
|
const keys_info_t *keys_info); |
46 |
47 |
static int extract_indexes(lua_State *lua, keys_info_t *keys_info); |
static int extract_indexes(lua_State *lua, keys_info_t *keys_info); |
47 |
48 |
static int deduplicate_ints(int array[], int count); |
static int deduplicate_ints(int array[], int count); |
48 |
49 |
static int int_sorter(const void *first, const void *second); |
static int int_sorter(const void *first, const void *second); |
|
... |
... |
VLUA_API(keys_add)(lua_State *lua) |
94 |
95 |
is_selector = lua_toboolean(lua, -1); |
is_selector = lua_toboolean(lua, -1); |
95 |
96 |
} |
} |
96 |
97 |
|
|
|
98 |
|
FollowedBy followed_by = FOLLOWED_BY_NONE; |
|
99 |
|
if(check_opt_field(lua, 1, "followedby", LUA_TSTRING)) |
|
100 |
|
{ |
|
101 |
|
const char *value = lua_tostring(lua, -1); |
|
102 |
|
if(strcmp(value, "none") == 0) |
|
103 |
|
{ |
|
104 |
|
followed_by = FOLLOWED_BY_NONE; |
|
105 |
|
} |
|
106 |
|
else if(strcmp(value, "selector") == 0) |
|
107 |
|
{ |
|
108 |
|
followed_by = FOLLOWED_BY_SELECTOR; |
|
109 |
|
} |
|
110 |
|
else if(strcmp(value, "keyarg") == 0) |
|
111 |
|
{ |
|
112 |
|
followed_by = FOLLOWED_BY_MULTIKEY; |
|
113 |
|
} |
|
114 |
|
else |
|
115 |
|
{ |
|
116 |
|
return luaL_error(lua, "Unrecognized value for `followedby`: %s", value); |
|
117 |
|
} |
|
118 |
|
} |
|
119 |
|
|
97 |
120 |
char modes[MODES_COUNT] = { }; |
char modes[MODES_COUNT] = { }; |
98 |
121 |
check_field(lua, 1, "modes", LUA_TTABLE); |
check_field(lua, 1, "modes", LUA_TTABLE); |
99 |
122 |
parse_modes(vlua, modes); |
parse_modes(vlua, modes); |
|
... |
... |
VLUA_API(keys_add)(lua_State *lua) |
108 |
131 |
key_conf_t key = { |
key_conf_t key = { |
109 |
132 |
.data.handler = &lua_key_handler, |
.data.handler = &lua_key_handler, |
110 |
133 |
.descr = descr, |
.descr = descr, |
|
134 |
|
.followed = followed_by, |
111 |
135 |
}; |
}; |
112 |
136 |
|
|
113 |
137 |
key.user_data = state_store_pointer(vlua, handler); |
key.user_data = state_store_pointer(vlua, handler); |
|
... |
... |
lua_key_handler(key_info_t key_info, keys_info_t *keys_info) |
185 |
209 |
int is_selector = lua_toboolean(lua, -1); |
int is_selector = lua_toboolean(lua, -1); |
186 |
210 |
lua_getfield(lua, -2, "handler"); |
lua_getfield(lua, -2, "handler"); |
187 |
211 |
|
|
188 |
|
build_handler_args(lua, key_info); |
|
|
212 |
|
build_handler_args(lua, key_info, keys_info); |
|
213 |
|
|
|
214 |
|
/* After we've built handler arguments, this list isn't needed anymore. */ |
|
215 |
|
free(keys_info->indexes); |
|
216 |
|
keys_info->indexes = NULL; |
|
217 |
|
keys_info->count = 0; |
189 |
218 |
|
|
190 |
219 |
curr_stats.save_msg = 0; |
curr_stats.save_msg = 0; |
191 |
220 |
|
|
|
... |
... |
lua_key_handler(key_info_t key_info, keys_info_t *keys_info) |
219 |
248 |
|
|
220 |
249 |
/* Builds table passed to key handler, leaves it at the top of the stack. */ |
/* Builds table passed to key handler, leaves it at the top of the stack. */ |
221 |
250 |
static void |
static void |
222 |
|
build_handler_args(lua_State *lua, key_info_t key_info) |
|
|
251 |
|
build_handler_args(lua_State *lua, key_info_t key_info, |
|
252 |
|
const keys_info_t *keys_info) |
223 |
253 |
{ |
{ |
224 |
254 |
lua_newtable(lua); |
lua_newtable(lua); |
225 |
255 |
|
|
|
... |
... |
build_handler_args(lua_State *lua, key_info_t key_info) |
243 |
273 |
lua_pushstring(lua, reg_name); |
lua_pushstring(lua, reg_name); |
244 |
274 |
} |
} |
245 |
275 |
lua_setfield(lua, -2, "register"); |
lua_setfield(lua, -2, "register"); |
|
276 |
|
|
|
277 |
|
if(keys_info->selector) |
|
278 |
|
{ |
|
279 |
|
int i; |
|
280 |
|
lua_newtable(lua); |
|
281 |
|
for(i = 0; i < keys_info->count; ++i) |
|
282 |
|
{ |
|
283 |
|
lua_pushinteger(lua, keys_info->indexes[i] + 1); |
|
284 |
|
lua_seti(lua, -2, i + 1); |
|
285 |
|
} |
|
286 |
|
lua_setfield(lua, -2, "indexes"); |
|
287 |
|
} |
|
288 |
|
|
|
289 |
|
if(key_info.multi != L'\0') |
|
290 |
|
{ |
|
291 |
|
lua_pushfstring(lua, "%U", key_info.multi); |
|
292 |
|
lua_setfield(lua, -2, "keyarg"); |
|
293 |
|
} |
246 |
294 |
} |
} |
247 |
295 |
|
|
248 |
296 |
/* Extracts selected indexes from "indexes" field of the table at the top of |
/* Extracts selected indexes from "indexes" field of the table at the top of |
File tests/lua/api_keys.c changed (mode: 100644) (index f52219d2f..c3380443a) |
... |
... |
SETUP() |
35 |
35 |
view_setup(&lwin); |
view_setup(&lwin); |
36 |
36 |
strcpy(lwin.curr_dir, "/lwin"); |
strcpy(lwin.curr_dir, "/lwin"); |
37 |
37 |
lwin.list_rows = 2; |
lwin.list_rows = 2; |
38 |
|
lwin.list_pos = 1; |
|
|
38 |
|
lwin.list_pos = 0; |
39 |
39 |
lwin.dir_entry = dynarray_cextend(NULL, |
lwin.dir_entry = dynarray_cextend(NULL, |
40 |
40 |
lwin.list_rows*sizeof(*lwin.dir_entry)); |
lwin.list_rows*sizeof(*lwin.dir_entry)); |
41 |
41 |
lwin.dir_entry[0].name = strdup("file0"); |
lwin.dir_entry[0].name = strdup("file0"); |
|
... |
... |
TEST(keys_add_errors) |
86 |
86 |
assert_true(ends_with(ui_sb_last(), |
assert_true(ends_with(ui_sb_last(), |
87 |
87 |
": Shortcut can't be empty or longer than 15")); |
": Shortcut can't be empty or longer than 15")); |
88 |
88 |
|
|
|
89 |
|
assert_failure(vlua_run_string(vlua, "vifm.keys.add {" |
|
90 |
|
" shortcut = 'X'," |
|
91 |
|
" modes = { 'cmdline', 'normal' }," |
|
92 |
|
" handler = handler," |
|
93 |
|
" followedby = 'something'," |
|
94 |
|
"}")); |
|
95 |
|
assert_true(ends_with(ui_sb_last(), |
|
96 |
|
": Unrecognized value for `followedby`: something")); |
|
97 |
|
|
89 |
98 |
assert_failure(vlua_run_string(vlua, "vifm.keys.add {" |
assert_failure(vlua_run_string(vlua, "vifm.keys.add {" |
90 |
99 |
" shortcut = 'X'," |
" shortcut = 'X'," |
91 |
100 |
" isselector = 10," |
" isselector = 10," |
|
... |
... |
TEST(keys_add) |
232 |
241 |
" shortcut = 'X'," |
" shortcut = 'X'," |
233 |
242 |
" modes = { 'cmdline', 'normal' }," |
" modes = { 'cmdline', 'normal' }," |
234 |
243 |
" description = 'print a message'," |
" description = 'print a message'," |
|
244 |
|
" followedby = 'none'," |
235 |
245 |
" handler = handler," |
" handler = handler," |
236 |
246 |
"})")); |
"})")); |
237 |
247 |
assert_string_equal("true", ui_sb_last()); |
assert_string_equal("true", ui_sb_last()); |
|
... |
... |
TEST(keys_add_modes) |
307 |
317 |
assert_false(vle_keys_user_exists(L"X", MORE_MODE)); |
assert_false(vle_keys_user_exists(L"X", MORE_MODE)); |
308 |
318 |
} |
} |
309 |
319 |
|
|
|
320 |
|
TEST(keys_followed_by_selector) |
|
321 |
|
{ |
|
322 |
|
ui_sb_msg(""); |
|
323 |
|
|
|
324 |
|
assert_success(vlua_run_string(vlua, "function handler(info)" |
|
325 |
|
" print(#info.indexes," |
|
326 |
|
" info.indexes[1]," |
|
327 |
|
" info.indexes[2])" |
|
328 |
|
"end")); |
|
329 |
|
assert_string_equal("", ui_sb_last()); |
|
330 |
|
|
|
331 |
|
assert_success(vlua_run_string(vlua, "print(vifm.keys.add {" |
|
332 |
|
" shortcut = 'X'," |
|
333 |
|
" modes = { 'normal' }," |
|
334 |
|
" followedby = 'selector'," |
|
335 |
|
" handler = handler," |
|
336 |
|
"})")); |
|
337 |
|
assert_string_equal("true", ui_sb_last()); |
|
338 |
|
|
|
339 |
|
(void)vle_keys_exec_timed_out(L"Xj"); |
|
340 |
|
assert_int_equal(1, curr_stats.save_msg); |
|
341 |
|
assert_string_equal("2\t1\t2", ui_sb_last()); |
|
342 |
|
} |
|
343 |
|
|
|
344 |
|
TEST(keys_followed_by_multikey) |
|
345 |
|
{ |
|
346 |
|
ui_sb_msg(""); |
|
347 |
|
|
|
348 |
|
assert_success(vlua_run_string(vlua, "function handler(info)" |
|
349 |
|
" print(info.keyarg)" |
|
350 |
|
"end")); |
|
351 |
|
assert_string_equal("", ui_sb_last()); |
|
352 |
|
|
|
353 |
|
assert_success(vlua_run_string(vlua, "print(vifm.keys.add {" |
|
354 |
|
" shortcut = 'X'," |
|
355 |
|
" modes = { 'normal' }," |
|
356 |
|
" followedby = 'keyarg'," |
|
357 |
|
" handler = handler," |
|
358 |
|
"})")); |
|
359 |
|
assert_string_equal("true", ui_sb_last()); |
|
360 |
|
|
|
361 |
|
(void)vle_keys_exec_timed_out(L"Xj"); |
|
362 |
|
assert_int_equal(1, curr_stats.save_msg); |
|
363 |
|
assert_string_equal("j", ui_sb_last()); |
|
364 |
|
} |
|
365 |
|
|
310 |
366 |
/* vim: set tabstop=2 softtabstop=2 shiftwidth=2 noexpandtab cinoptions-=(0 : */ |
/* vim: set tabstop=2 softtabstop=2 shiftwidth=2 noexpandtab cinoptions-=(0 : */ |
311 |
367 |
/* vim: set cinoptions+=t0 : */ |
/* vim: set cinoptions+=t0 : */ |