1// This is an open source non-commercial project. Dear PVS-Studio, please check
2// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
3
4#include <lua.h>
5#include <lualib.h>
6#include <lauxlib.h>
7
8#include "nvim/misc1.h"
9#include "nvim/getchar.h"
10#include "nvim/garray.h"
11#include "nvim/func_attr.h"
12#include "nvim/api/private/defs.h"
13#include "nvim/api/private/helpers.h"
14#include "nvim/api/vim.h"
15#include "nvim/vim.h"
16#include "nvim/ex_getln.h"
17#include "nvim/ex_cmds2.h"
18#include "nvim/message.h"
19#include "nvim/memline.h"
20#include "nvim/buffer_defs.h"
21#include "nvim/macros.h"
22#include "nvim/screen.h"
23#include "nvim/cursor.h"
24#include "nvim/undo.h"
25#include "nvim/ascii.h"
26#include "nvim/change.h"
27
28#ifdef WIN32
29#include "nvim/os/os.h"
30#endif
31
32#include "nvim/lua/executor.h"
33#include "nvim/lua/converter.h"
34
35#include "luv/luv.h"
36
37static int in_fast_callback = 0;
38
39typedef struct {
40 Error err;
41 String lua_err_str;
42} LuaError;
43
44#ifdef INCLUDE_GENERATED_DECLARATIONS
45# include "lua/vim_module.generated.h"
46# include "lua/executor.c.generated.h"
47#endif
48
49/// Name of the run code for use in messages
50#define NLUA_EVAL_NAME "<VimL compiled string>"
51
52/// Convert lua error into a Vim error message
53///
54/// @param lstate Lua interpreter state.
55/// @param[in] msg Message base, must contain one `%s`.
56static void nlua_error(lua_State *const lstate, const char *const msg)
57 FUNC_ATTR_NONNULL_ALL
58{
59 size_t len;
60 const char *const str = lua_tolstring(lstate, -1, &len);
61
62 msg_ext_set_kind("lua_error");
63 emsgf_multiline(msg, (int)len, str);
64
65 lua_pop(lstate, 1);
66}
67
68/// Compare two strings, ignoring case
69///
70/// Expects two values on the stack: compared strings. Returns one of the
71/// following numbers: 0, -1 or 1.
72///
73/// Does no error handling: never call it with non-string or with some arguments
74/// omitted.
75static int nlua_stricmp(lua_State *const lstate) FUNC_ATTR_NONNULL_ALL
76{
77 size_t s1_len;
78 size_t s2_len;
79 const char *s1 = luaL_checklstring(lstate, 1, &s1_len);
80 const char *s2 = luaL_checklstring(lstate, 2, &s2_len);
81 char *nul1;
82 char *nul2;
83 int ret = 0;
84 assert(s1[s1_len] == NUL);
85 assert(s2[s2_len] == NUL);
86 do {
87 nul1 = memchr(s1, NUL, s1_len);
88 nul2 = memchr(s2, NUL, s2_len);
89 ret = STRICMP(s1, s2);
90 if (ret == 0) {
91 // Compare "a\0" greater then "a".
92 if ((nul1 == NULL) != (nul2 == NULL)) {
93 ret = ((nul1 != NULL) - (nul2 != NULL));
94 break;
95 }
96 if (nul1 != NULL) {
97 assert(nul2 != NULL);
98 // Can't shift both strings by the same amount of bytes: lowercase
99 // letter may have different byte-length than uppercase.
100 s1_len -= (size_t)(nul1 - s1) + 1;
101 s2_len -= (size_t)(nul2 - s2) + 1;
102 s1 = nul1 + 1;
103 s2 = nul2 + 1;
104 } else {
105 break;
106 }
107 } else {
108 break;
109 }
110 } while (true);
111 lua_pop(lstate, 2);
112 lua_pushnumber(lstate, (lua_Number)((ret > 0) - (ret < 0)));
113 return 1;
114}
115
116/// convert byte index to UTF-32 and UTF-16 indicies
117///
118/// Expects a string and an optional index. If no index is supplied, the length
119/// of the string is returned.
120///
121/// Returns two values: the UTF-32 and UTF-16 indicies.
122static int nlua_str_utfindex(lua_State *const lstate) FUNC_ATTR_NONNULL_ALL
123{
124 size_t s1_len;
125 const char *s1 = luaL_checklstring(lstate, 1, &s1_len);
126 intptr_t idx;
127 if (lua_gettop(lstate) >= 2) {
128 idx = luaL_checkinteger(lstate, 2);
129 if (idx < 0 || idx > (intptr_t)s1_len) {
130 return luaL_error(lstate, "index out of range");
131 }
132 } else {
133 idx = (intptr_t)s1_len;
134 }
135
136 size_t codepoints = 0, codeunits = 0;
137 mb_utflen((const char_u *)s1, (size_t)idx, &codepoints, &codeunits);
138
139 lua_pushinteger(lstate, (long)codepoints);
140 lua_pushinteger(lstate, (long)codeunits);
141
142 return 2;
143}
144
145/// convert UTF-32 or UTF-16 indicies to byte index.
146///
147/// Expects up to three args: string, index and use_utf16.
148/// If use_utf16 is not supplied it defaults to false (use UTF-32)
149///
150/// Returns the byte index.
151static int nlua_str_byteindex(lua_State *const lstate) FUNC_ATTR_NONNULL_ALL
152{
153 size_t s1_len;
154 const char *s1 = luaL_checklstring(lstate, 1, &s1_len);
155 intptr_t idx = luaL_checkinteger(lstate, 2);
156 if (idx < 0) {
157 return luaL_error(lstate, "index out of range");
158 }
159 bool use_utf16 = false;
160 if (lua_gettop(lstate) >= 3) {
161 use_utf16 = lua_toboolean(lstate, 3);
162 }
163
164 ssize_t byteidx = mb_utf_index_to_bytes((const char_u *)s1, s1_len,
165 (size_t)idx, use_utf16);
166 if (byteidx == -1) {
167 return luaL_error(lstate, "index out of range");
168 }
169
170 lua_pushinteger(lstate, (long)byteidx);
171
172 return 1;
173}
174
175static void nlua_luv_error_event(void **argv)
176{
177 char *error = (char *)argv[0];
178 msg_ext_set_kind("lua_error");
179 emsgf_multiline("Error executing luv callback:\n%s", error);
180 xfree(error);
181}
182
183static int nlua_luv_cfpcall(lua_State *lstate, int nargs, int nresult,
184 int flags)
185 FUNC_ATTR_NONNULL_ALL
186{
187 int retval;
188
189 // luv callbacks might be executed at any os_breakcheck/line_breakcheck
190 // call, so using the API directly here is not safe.
191 in_fast_callback++;
192
193 int top = lua_gettop(lstate);
194 int status = lua_pcall(lstate, nargs, nresult, 0);
195 if (status) {
196 if (status == LUA_ERRMEM && !(flags & LUVF_CALLBACK_NOEXIT)) {
197 // consider out of memory errors unrecoverable, just like xmalloc()
198 mch_errmsg(e_outofmem);
199 mch_errmsg("\n");
200 preserve_exit();
201 }
202 const char *error = lua_tostring(lstate, -1);
203
204 multiqueue_put(main_loop.events, nlua_luv_error_event,
205 1, xstrdup(error));
206 lua_pop(lstate, 1); // error mesage
207 retval = -status;
208 } else { // LUA_OK
209 if (nresult == LUA_MULTRET) {
210 nresult = lua_gettop(lstate) - top + nargs + 1;
211 }
212 retval = nresult;
213 }
214
215 in_fast_callback--;
216 return retval;
217}
218
219static void nlua_schedule_event(void **argv)
220{
221 LuaRef cb = (LuaRef)(ptrdiff_t)argv[0];
222 lua_State *const lstate = nlua_enter();
223 nlua_pushref(lstate, cb);
224 nlua_unref(lstate, cb);
225 if (lua_pcall(lstate, 0, 0, 0)) {
226 nlua_error(lstate, _("Error executing vim.schedule lua callback: %.*s"));
227 }
228}
229
230/// Schedule Lua callback on main loop's event queue
231///
232/// @param lstate Lua interpreter state.
233static int nlua_schedule(lua_State *const lstate)
234 FUNC_ATTR_NONNULL_ALL
235{
236 if (lua_type(lstate, 1) != LUA_TFUNCTION) {
237 lua_pushliteral(lstate, "vim.schedule: expected function");
238 return lua_error(lstate);
239 }
240
241 LuaRef cb = nlua_ref(lstate, 1);
242
243 multiqueue_put(main_loop.events, nlua_schedule_event,
244 1, (void *)(ptrdiff_t)cb);
245 return 0;
246}
247
248/// Initialize lua interpreter state
249///
250/// Called by lua interpreter itself to initialize state.
251static int nlua_state_init(lua_State *const lstate) FUNC_ATTR_NONNULL_ALL
252{
253 // print
254 lua_pushcfunction(lstate, &nlua_print);
255 lua_setglobal(lstate, "print");
256
257 // debug.debug
258 lua_getglobal(lstate, "debug");
259 lua_pushcfunction(lstate, &nlua_debug);
260 lua_setfield(lstate, -2, "debug");
261 lua_pop(lstate, 1);
262
263#ifdef WIN32
264 // os.getenv
265 lua_getglobal(lstate, "os");
266 lua_pushcfunction(lstate, &nlua_getenv);
267 lua_setfield(lstate, -2, "getenv");
268 lua_pop(lstate, 1);
269#endif
270
271 // vim
272 const char *code = (char *)&vim_module[0];
273 if (luaL_loadbuffer(lstate, code, strlen(code), "@vim.lua")
274 || lua_pcall(lstate, 0, LUA_MULTRET, 0)) {
275 nlua_error(lstate, _("E5106: Error while creating vim module: %.*s"));
276 return 1;
277 }
278 // vim.api
279 nlua_add_api_functions(lstate);
280 // vim.types, vim.type_idx, vim.val_idx
281 nlua_init_types(lstate);
282 // stricmp
283 lua_pushcfunction(lstate, &nlua_stricmp);
284 lua_setfield(lstate, -2, "stricmp");
285 // str_utfindex
286 lua_pushcfunction(lstate, &nlua_str_utfindex);
287 lua_setfield(lstate, -2, "str_utfindex");
288 // str_byteindex
289 lua_pushcfunction(lstate, &nlua_str_byteindex);
290 lua_setfield(lstate, -2, "str_byteindex");
291 // schedule
292 lua_pushcfunction(lstate, &nlua_schedule);
293 lua_setfield(lstate, -2, "schedule");
294 // in_fast_event
295 lua_pushcfunction(lstate, &nlua_in_fast_event);
296 lua_setfield(lstate, -2, "in_fast_event");
297
298 // vim.loop
299 luv_set_loop(lstate, &main_loop.uv);
300 luv_set_callback(lstate, nlua_luv_cfpcall);
301 luaopen_luv(lstate);
302 lua_pushvalue(lstate, -1);
303 lua_setfield(lstate, -3, "loop");
304
305 // package.loaded.luv = vim.loop
306 // otherwise luv will be reinitialized when require'luv'
307 lua_getglobal(lstate, "package");
308 lua_getfield(lstate, -1, "loaded");
309 lua_pushvalue(lstate, -3);
310 lua_setfield(lstate, -2, "luv");
311 lua_pop(lstate, 3);
312
313 lua_setglobal(lstate, "vim");
314 return 0;
315}
316
317/// Initialize lua interpreter
318///
319/// Crashes Nvim if initialization fails. Should be called once per lua
320/// interpreter instance.
321///
322/// @return New lua interpreter instance.
323static lua_State *nlua_init(void)
324 FUNC_ATTR_NONNULL_RET FUNC_ATTR_WARN_UNUSED_RESULT
325{
326 lua_State *lstate = luaL_newstate();
327 if (lstate == NULL) {
328 EMSG(_("E970: Failed to initialize lua interpreter"));
329 preserve_exit();
330 }
331 luaL_openlibs(lstate);
332 nlua_state_init(lstate);
333 return lstate;
334}
335
336/// Enter lua interpreter
337///
338/// Calls nlua_init() if needed. Is responsible for pre-lua call initalization
339/// like updating `package.[c]path` with directories derived from &runtimepath.
340///
341/// @return Interpreter instance to use. Will either be initialized now or
342/// taken from previous initialization.
343static lua_State *nlua_enter(void)
344 FUNC_ATTR_NONNULL_RET FUNC_ATTR_WARN_UNUSED_RESULT
345{
346 static lua_State *global_lstate = NULL;
347 if (global_lstate == NULL) {
348 global_lstate = nlua_init();
349 }
350 lua_State *const lstate = global_lstate;
351 // Last used p_rtp value. Must not be dereferenced because value pointed to
352 // may already be freed. Used to check whether &runtimepath option value
353 // changed.
354 static const void *last_p_rtp = NULL;
355 if (last_p_rtp != (const void *)p_rtp) {
356 // stack: (empty)
357 lua_getglobal(lstate, "vim");
358 // stack: vim
359 lua_getfield(lstate, -1, "_update_package_paths");
360 // stack: vim, vim._update_package_paths
361 if (lua_pcall(lstate, 0, 0, 0)) {
362 // stack: vim, error
363 nlua_error(lstate, _("E5117: Error while updating package paths: %.*s"));
364 // stack: vim
365 }
366 // stack: vim
367 lua_pop(lstate, 1);
368 // stack: (empty)
369 last_p_rtp = (const void *)p_rtp;
370 }
371 return lstate;
372}
373
374/// Execute lua string
375///
376/// @param[in] str String to execute.
377/// @param[out] ret_tv Location where result will be saved.
378///
379/// @return Result of the execution.
380void executor_exec_lua(const String str, typval_T *const ret_tv)
381 FUNC_ATTR_NONNULL_ALL
382{
383 lua_State *const lstate = nlua_enter();
384
385 if (luaL_loadbuffer(lstate, str.data, str.size, NLUA_EVAL_NAME)) {
386 nlua_error(lstate, _("E5104: Error while creating lua chunk: %.*s"));
387 return;
388 }
389 if (lua_pcall(lstate, 0, 1, 0)) {
390 nlua_error(lstate, _("E5105: Error while calling lua chunk: %.*s"));
391 return;
392 }
393
394 nlua_pop_typval(lstate, ret_tv);
395}
396
397static void nlua_print_event(void **argv)
398{
399 char *str = argv[0];
400 const size_t len = (size_t)(intptr_t)argv[1]-1; // exclude final NUL
401
402 for (size_t i = 0; i < len;) {
403 const size_t start = i;
404 while (i < len) {
405 switch (str[i]) {
406 case NUL: {
407 str[i] = NL;
408 i++;
409 continue;
410 }
411 case NL: {
412 // TODO(bfredl): use proper multiline msg? Probably should implement
413 // print() in lua in terms of nvim_message(), when it is available.
414 str[i] = NUL;
415 i++;
416 break;
417 }
418 default: {
419 i++;
420 continue;
421 }
422 }
423 break;
424 }
425 msg((char_u *)str + start);
426 }
427 if (len && str[len - 1] == NUL) { // Last was newline
428 msg((char_u *)"");
429 }
430 xfree(str);
431}
432
433/// Print as a Vim message
434///
435/// @param lstate Lua interpreter state.
436static int nlua_print(lua_State *const lstate)
437 FUNC_ATTR_NONNULL_ALL
438{
439#define PRINT_ERROR(msg) \
440 do { \
441 errmsg = msg; \
442 errmsg_len = sizeof(msg) - 1; \
443 goto nlua_print_error; \
444 } while (0)
445 const int nargs = lua_gettop(lstate);
446 lua_getglobal(lstate, "tostring");
447 const char *errmsg = NULL;
448 size_t errmsg_len = 0;
449 garray_T msg_ga;
450 ga_init(&msg_ga, 1, 80);
451 int curargidx = 1;
452 for (; curargidx <= nargs; curargidx++) {
453 lua_pushvalue(lstate, -1); // tostring
454 lua_pushvalue(lstate, curargidx); // arg
455 if (lua_pcall(lstate, 1, 1, 0)) {
456 errmsg = lua_tolstring(lstate, -1, &errmsg_len);
457 goto nlua_print_error;
458 }
459 size_t len;
460 const char *const s = lua_tolstring(lstate, -1, &len);
461 if (s == NULL) {
462 PRINT_ERROR(
463 "<Unknown error: lua_tolstring returned NULL for tostring result>");
464 }
465 ga_concat_len(&msg_ga, s, len);
466 if (curargidx < nargs) {
467 ga_append(&msg_ga, ' ');
468 }
469 lua_pop(lstate, 1);
470 }
471#undef PRINT_ERROR
472 ga_append(&msg_ga, NUL);
473
474 if (in_fast_callback) {
475 multiqueue_put(main_loop.events, nlua_print_event,
476 2, msg_ga.ga_data, msg_ga.ga_len);
477 } else {
478 nlua_print_event((void *[]){ msg_ga.ga_data,
479 (void *)(intptr_t)msg_ga.ga_len });
480 }
481 return 0;
482
483nlua_print_error:
484 ga_clear(&msg_ga);
485 const char *fmt = _("E5114: Error while converting print argument #%i: %.*s");
486 size_t len = (size_t)vim_snprintf((char *)IObuff, IOSIZE, fmt, curargidx,
487 (int)errmsg_len, errmsg);
488 lua_pushlstring(lstate, (char *)IObuff, len);
489 return lua_error(lstate);
490}
491
492/// debug.debug: interaction with user while debugging.
493///
494/// @param lstate Lua interpreter state.
495int nlua_debug(lua_State *lstate)
496 FUNC_ATTR_NONNULL_ALL
497{
498 const typval_T input_args[] = {
499 {
500 .v_lock = VAR_FIXED,
501 .v_type = VAR_STRING,
502 .vval.v_string = (char_u *)"lua_debug> ",
503 },
504 {
505 .v_type = VAR_UNKNOWN,
506 },
507 };
508 for (;;) {
509 lua_settop(lstate, 0);
510 typval_T input;
511 get_user_input(input_args, &input, false);
512 msg_putchar('\n'); // Avoid outputting on input line.
513 if (input.v_type != VAR_STRING
514 || input.vval.v_string == NULL
515 || *input.vval.v_string == NUL
516 || STRCMP(input.vval.v_string, "cont") == 0) {
517 tv_clear(&input);
518 return 0;
519 }
520 if (luaL_loadbuffer(lstate, (const char *)input.vval.v_string,
521 STRLEN(input.vval.v_string), "=(debug command)")) {
522 nlua_error(lstate, _("E5115: Error while loading debug string: %.*s"));
523 } else if (lua_pcall(lstate, 0, 0, 0)) {
524 nlua_error(lstate, _("E5116: Error while calling debug string: %.*s"));
525 }
526 tv_clear(&input);
527 }
528 return 0;
529}
530
531int nlua_in_fast_event(lua_State *lstate)
532{
533 lua_pushboolean(lstate, in_fast_callback > 0);
534 return 1;
535}
536
537#ifdef WIN32
538/// os.getenv: override os.getenv to maintain coherency. #9681
539///
540/// uv_os_setenv uses SetEnvironmentVariableW which does not update _environ.
541///
542/// @param lstate Lua interpreter state.
543static int nlua_getenv(lua_State *lstate)
544{
545 lua_pushstring(lstate, os_getenv(luaL_checkstring(lstate, 1)));
546 return 1;
547}
548#endif
549
550/// add the value to the registry
551LuaRef nlua_ref(lua_State *lstate, int index)
552{
553 lua_pushvalue(lstate, index);
554 return luaL_ref(lstate, LUA_REGISTRYINDEX);
555}
556
557/// remove the value from the registry
558void nlua_unref(lua_State *lstate, LuaRef ref)
559{
560 if (ref > 0) {
561 luaL_unref(lstate, LUA_REGISTRYINDEX, ref);
562 }
563}
564
565void executor_free_luaref(LuaRef ref)
566{
567 lua_State *const lstate = nlua_enter();
568 nlua_unref(lstate, ref);
569}
570
571/// push a value referenced in the regirstry
572void nlua_pushref(lua_State *lstate, LuaRef ref)
573{
574 lua_rawgeti(lstate, LUA_REGISTRYINDEX, ref);
575}
576
577/// Evaluate lua string
578///
579/// Used for luaeval().
580///
581/// @param[in] str String to execute.
582/// @param[in] arg Second argument to `luaeval()`.
583/// @param[out] ret_tv Location where result will be saved.
584///
585/// @return Result of the execution.
586void executor_eval_lua(const String str, typval_T *const arg,
587 typval_T *const ret_tv)
588 FUNC_ATTR_NONNULL_ALL
589{
590 lua_State *const lstate = nlua_enter();
591
592 garray_T str_ga;
593 ga_init(&str_ga, 1, 80);
594#define EVALHEADER "local _A=select(1,...) return ("
595 const size_t lcmd_len = sizeof(EVALHEADER) - 1 + str.size + 1;
596 char *lcmd;
597 if (lcmd_len < IOSIZE) {
598 lcmd = (char *)IObuff;
599 } else {
600 lcmd = xmalloc(lcmd_len);
601 }
602 memcpy(lcmd, EVALHEADER, sizeof(EVALHEADER) - 1);
603 memcpy(lcmd + sizeof(EVALHEADER) - 1, str.data, str.size);
604 lcmd[lcmd_len - 1] = ')';
605#undef EVALHEADER
606 if (luaL_loadbuffer(lstate, lcmd, lcmd_len, NLUA_EVAL_NAME)) {
607 nlua_error(lstate,
608 _("E5107: Error while creating lua chunk for luaeval(): %.*s"));
609 if (lcmd != (char *)IObuff) {
610 xfree(lcmd);
611 }
612 return;
613 }
614 if (lcmd != (char *)IObuff) {
615 xfree(lcmd);
616 }
617
618 if (arg->v_type == VAR_UNKNOWN) {
619 lua_pushnil(lstate);
620 } else {
621 nlua_push_typval(lstate, arg);
622 }
623 if (lua_pcall(lstate, 1, 1, 0)) {
624 nlua_error(lstate,
625 _("E5108: Error while calling lua chunk for luaeval(): %.*s"));
626 return;
627 }
628
629 nlua_pop_typval(lstate, ret_tv);
630}
631
632/// Execute lua string
633///
634/// Used for nvim_execute_lua().
635///
636/// @param[in] str String to execute.
637/// @param[in] args array of ... args
638/// @param[out] err Location where error will be saved.
639///
640/// @return Return value of the execution.
641Object executor_exec_lua_api(const String str, const Array args, Error *err)
642{
643 lua_State *const lstate = nlua_enter();
644
645 if (luaL_loadbuffer(lstate, str.data, str.size, "<nvim>")) {
646 size_t len;
647 const char *errstr = lua_tolstring(lstate, -1, &len);
648 api_set_error(err, kErrorTypeValidation,
649 "Error loading lua: %.*s", (int)len, errstr);
650 return NIL;
651 }
652
653 for (size_t i = 0; i < args.size; i++) {
654 nlua_push_Object(lstate, args.items[i], false);
655 }
656
657 if (lua_pcall(lstate, (int)args.size, 1, 0)) {
658 size_t len;
659 const char *errstr = lua_tolstring(lstate, -1, &len);
660 api_set_error(err, kErrorTypeException,
661 "Error executing lua: %.*s", (int)len, errstr);
662 return NIL;
663 }
664
665 return nlua_pop_Object(lstate, false, err);
666}
667
668Object executor_exec_lua_cb(LuaRef ref, const char *name, Array args,
669 bool retval)
670{
671 lua_State *const lstate = nlua_enter();
672 nlua_pushref(lstate, ref);
673 lua_pushstring(lstate, name);
674 for (size_t i = 0; i < args.size; i++) {
675 nlua_push_Object(lstate, args.items[i], false);
676 }
677
678 if (lua_pcall(lstate, (int)args.size+1, retval ? 1 : 0, 0)) {
679 // TODO(bfredl): callbacks:s might not always be msg-safe, for instance
680 // lua callbacks for redraw events. Later on let the caller deal with the
681 // error instead.
682 nlua_error(lstate, _("Error executing lua callback: %.*s"));
683 return NIL;
684 }
685 Error err = ERROR_INIT;
686
687 if (retval) {
688 return nlua_pop_Object(lstate, false, &err);
689 } else {
690 return NIL;
691 }
692}
693
694/// check if the current execution context is safe for calling deferred API
695/// methods. Luv callbacks are unsafe as they are called inside the uv loop.
696bool nlua_is_deferred_safe(lua_State *lstate)
697{
698 return in_fast_callback == 0;
699}
700
701/// Run lua string
702///
703/// Used for :lua.
704///
705/// @param eap VimL command being run.
706void ex_lua(exarg_T *const eap)
707 FUNC_ATTR_NONNULL_ALL
708{
709 size_t len;
710 char *const code = script_get(eap, &len);
711 if (eap->skip) {
712 xfree(code);
713 return;
714 }
715 typval_T tv = { .v_type = VAR_UNKNOWN };
716 executor_exec_lua((String) { .data = code, .size = len }, &tv);
717 tv_clear(&tv);
718 xfree(code);
719}
720
721/// Run lua string for each line in range
722///
723/// Used for :luado.
724///
725/// @param eap VimL command being run.
726void ex_luado(exarg_T *const eap)
727 FUNC_ATTR_NONNULL_ALL
728{
729 if (u_save(eap->line1 - 1, eap->line2 + 1) == FAIL) {
730 EMSG(_("cannot save undo information"));
731 return;
732 }
733 const char *const cmd = (const char *)eap->arg;
734 const size_t cmd_len = strlen(cmd);
735
736 lua_State *const lstate = nlua_enter();
737
738#define DOSTART "return function(line, linenr) "
739#define DOEND " end"
740 const size_t lcmd_len = (cmd_len
741 + (sizeof(DOSTART) - 1)
742 + (sizeof(DOEND) - 1));
743 char *lcmd;
744 if (lcmd_len < IOSIZE) {
745 lcmd = (char *)IObuff;
746 } else {
747 lcmd = xmalloc(lcmd_len + 1);
748 }
749 memcpy(lcmd, DOSTART, sizeof(DOSTART) - 1);
750 memcpy(lcmd + sizeof(DOSTART) - 1, cmd, cmd_len);
751 memcpy(lcmd + sizeof(DOSTART) - 1 + cmd_len, DOEND, sizeof(DOEND) - 1);
752#undef DOSTART
753#undef DOEND
754
755 if (luaL_loadbuffer(lstate, lcmd, lcmd_len, NLUA_EVAL_NAME)) {
756 nlua_error(lstate, _("E5109: Error while creating lua chunk: %.*s"));
757 if (lcmd_len >= IOSIZE) {
758 xfree(lcmd);
759 }
760 return;
761 }
762 if (lcmd_len >= IOSIZE) {
763 xfree(lcmd);
764 }
765 if (lua_pcall(lstate, 0, 1, 0)) {
766 nlua_error(lstate, _("E5110: Error while creating lua function: %.*s"));
767 return;
768 }
769 for (linenr_T l = eap->line1; l <= eap->line2; l++) {
770 if (l > curbuf->b_ml.ml_line_count) {
771 break;
772 }
773 lua_pushvalue(lstate, -1);
774 lua_pushstring(lstate, (const char *)ml_get_buf(curbuf, l, false));
775 lua_pushnumber(lstate, (lua_Number)l);
776 if (lua_pcall(lstate, 2, 1, 0)) {
777 nlua_error(lstate, _("E5111: Error while calling lua function: %.*s"));
778 break;
779 }
780 if (lua_isstring(lstate, -1)) {
781 size_t new_line_len;
782 const char *const new_line = lua_tolstring(lstate, -1, &new_line_len);
783 char *const new_line_transformed = xmemdupz(new_line, new_line_len);
784 for (size_t i = 0; i < new_line_len; i++) {
785 if (new_line_transformed[i] == NUL) {
786 new_line_transformed[i] = '\n';
787 }
788 }
789 ml_replace(l, (char_u *)new_line_transformed, false);
790 changed_bytes(l, 0);
791 }
792 lua_pop(lstate, 1);
793 }
794 lua_pop(lstate, 1);
795 check_cursor();
796 update_screen(NOT_VALID);
797}
798
799/// Run lua file
800///
801/// Used for :luafile.
802///
803/// @param eap VimL command being run.
804void ex_luafile(exarg_T *const eap)
805 FUNC_ATTR_NONNULL_ALL
806{
807 lua_State *const lstate = nlua_enter();
808
809 if (luaL_loadfile(lstate, (const char *)eap->arg)) {
810 nlua_error(lstate, _("E5112: Error while creating lua chunk: %.*s"));
811 return;
812 }
813
814 if (lua_pcall(lstate, 0, 0, 0)) {
815 nlua_error(lstate, _("E5113: Error while calling lua chunk: %.*s"));
816 return;
817 }
818}
819