1 /* vi:set ts=8 sts=4 sw=4 noet:
2  *
3  * VIM - Vi IMproved	by Bram Moolenaar
4  *
5  * Lua interface by Luis Carvalho
6  *
7  * Do ":help uganda"  in Vim to read copying and usage conditions.
8  * Do ":help credits" in Vim to see a list of people who contributed.
9  * See README.txt for an overview of the Vim source code.
10  */
11 
12 #include "vim.h"
13 #include "version.h"
14 
15 #include <lua.h>
16 #include <lualib.h>
17 #include <lauxlib.h>
18 
19 // Only do the following when the feature is enabled.  Needed for "make
20 // depend".
21 #if defined(FEAT_LUA) || defined(PROTO)
22 
23 #define LUAVIM_CHUNKNAME "vim chunk"
24 #define LUAVIM_NAME "vim"
25 #define LUAVIM_EVALNAME "luaeval"
26 #define LUAVIM_EVALHEADER "local _A=select(1,...) return "
27 
28 #ifdef LUA_RELEASE
29 # define LUAVIM_VERSION LUA_RELEASE
30 #else
31 # define LUAVIM_VERSION LUA_VERSION
32 #endif
33 
34 typedef buf_T *luaV_Buffer;
35 typedef win_T *luaV_Window;
36 typedef dict_T *luaV_Dict;
37 typedef list_T *luaV_List;
38 typedef blob_T *luaV_Blob;
39 typedef struct {
40     char_u	*name;	// funcref
41     dict_T	*self;	// selfdict
42 } luaV_Funcref;
43 typedef int (*msgfunc_T)(char *);
44 
45 typedef struct {
46     int lua_funcref;    // ref to a lua func
47     int lua_tableref;   // ref to a lua table if metatable else LUA_NOREF. used
48 			// for __call
49     lua_State *L;
50 } luaV_CFuncState;
51 
52 static const char LUAVIM_DICT[] = "dict";
53 static const char LUAVIM_LIST[] = "list";
54 static const char LUAVIM_BLOB[] = "blob";
55 static const char LUAVIM_FUNCREF[] = "funcref";
56 static const char LUAVIM_BUFFER[] = "buffer";
57 static const char LUAVIM_WINDOW[] = "window";
58 static const char LUAVIM_FREE[] = "luaV_free";
59 static const char LUAVIM_LUAEVAL[] = "luaV_luaeval";
60 static const char LUAVIM_SETREF[] = "luaV_setref";
61 
62 static const char LUA___CALL[] = "__call";
63 
64 // most functions are closures with a cache table as first upvalue;
65 // get/setudata manage references to vim userdata in cache table through
66 // object pointers (light userdata)
67 #define luaV_getudata(L, v) \
68     lua_pushlightuserdata((L), (void *) (v)); \
69     lua_rawget((L), lua_upvalueindex(1))
70 #define luaV_setudata(L, v) \
71     lua_pushlightuserdata((L), (void *) (v)); \
72     lua_pushvalue((L), -2); \
73     lua_rawset((L), lua_upvalueindex(1))
74 #define luaV_getfield(L, s) \
75     lua_pushlightuserdata((L), (void *)(s)); \
76     lua_rawget((L), LUA_REGISTRYINDEX)
77 #define luaV_checksandbox(L) \
78     if (sandbox) luaL_error((L), "not allowed in sandbox")
79 #define luaV_msg(L) luaV_msgfunc((L), (msgfunc_T) msg)
80 #define luaV_emsg(L) luaV_msgfunc((L), (msgfunc_T) emsg)
81 #define luaV_checktypval(L, a, v, msg) \
82     do { \
83 	if (luaV_totypval(L, a, v) == FAIL) \
84 	    luaL_error(L, msg ": cannot convert value"); \
85     } while (0)
86 
87 static luaV_List *luaV_pushlist(lua_State *L, list_T *lis);
88 static luaV_Dict *luaV_pushdict(lua_State *L, dict_T *dic);
89 static luaV_Blob *luaV_pushblob(lua_State *L, blob_T *blo);
90 static luaV_Funcref *luaV_pushfuncref(lua_State *L, char_u *name);
91 static int luaV_call_lua_func(int argcount, typval_T *argvars, typval_T *rettv, void *state);
92 static void luaV_call_lua_func_free(void *state);
93 
94 #if LUA_VERSION_NUM <= 501
95 #define luaV_openlib(L, l, n) luaL_openlib(L, NULL, l, n)
96 #define luaL_typeerror luaL_typerror
97 #else
98 #define luaV_openlib luaL_setfuncs
99 #endif
100 
101 #ifdef DYNAMIC_LUA
102 
103 #ifndef MSWIN
104 # include <dlfcn.h>
105 # define HANDLE void*
106 # define load_dll(n) dlopen((n), RTLD_LAZY|RTLD_GLOBAL)
107 # define symbol_from_dll dlsym
108 # define close_dll dlclose
109 # define load_dll_error dlerror
110 #else
111 # define load_dll vimLoadLib
112 # define symbol_from_dll GetProcAddress
113 # define close_dll FreeLibrary
114 # define load_dll_error GetWin32Error
115 #endif
116 
117 // lauxlib
118 #if LUA_VERSION_NUM <= 501
119 #define luaL_register dll_luaL_register
120 #define luaL_prepbuffer dll_luaL_prepbuffer
121 #define luaL_openlib dll_luaL_openlib
122 #define luaL_typerror dll_luaL_typerror
123 #define luaL_loadfile dll_luaL_loadfile
124 #define luaL_loadbuffer dll_luaL_loadbuffer
125 #else
126 #define luaL_prepbuffsize dll_luaL_prepbuffsize
127 #define luaL_setfuncs dll_luaL_setfuncs
128 #define luaL_loadfilex dll_luaL_loadfilex
129 #define luaL_loadbufferx dll_luaL_loadbufferx
130 #define luaL_argerror dll_luaL_argerror
131 #endif
132 #if LUA_VERSION_NUM >= 504
133 #define luaL_typeerror dll_luaL_typeerror
134 #endif
135 #define luaL_checkany dll_luaL_checkany
136 #define luaL_checklstring dll_luaL_checklstring
137 #define luaL_checkinteger dll_luaL_checkinteger
138 #define luaL_optinteger dll_luaL_optinteger
139 #define luaL_checktype dll_luaL_checktype
140 #define luaL_error dll_luaL_error
141 #define luaL_newstate dll_luaL_newstate
142 #define luaL_buffinit dll_luaL_buffinit
143 #define luaL_addlstring dll_luaL_addlstring
144 #define luaL_pushresult dll_luaL_pushresult
145 #define luaL_loadstring dll_luaL_loadstring
146 #define luaL_ref dll_luaL_ref
147 #define luaL_unref dll_luaL_unref
148 // lua
149 #if LUA_VERSION_NUM <= 501
150 #define lua_tonumber dll_lua_tonumber
151 #define lua_tointeger dll_lua_tointeger
152 #define lua_call dll_lua_call
153 #define lua_pcall dll_lua_pcall
154 #else
155 #define lua_tonumberx dll_lua_tonumberx
156 #define lua_tointegerx dll_lua_tointegerx
157 #define lua_callk dll_lua_callk
158 #define lua_pcallk dll_lua_pcallk
159 #define lua_getglobal dll_lua_getglobal
160 #define lua_setglobal dll_lua_setglobal
161 #endif
162 #if LUA_VERSION_NUM <= 502
163 #define lua_replace dll_lua_replace
164 #define lua_remove dll_lua_remove
165 #endif
166 #if LUA_VERSION_NUM >= 503
167 #define lua_rotate dll_lua_rotate
168 #define lua_copy dll_lua_copy
169 #endif
170 #define lua_typename dll_lua_typename
171 #define lua_close dll_lua_close
172 #define lua_gettop dll_lua_gettop
173 #define lua_settop dll_lua_settop
174 #define lua_pushvalue dll_lua_pushvalue
175 #define lua_isnumber dll_lua_isnumber
176 #define lua_isstring dll_lua_isstring
177 #define lua_type dll_lua_type
178 #define lua_rawequal dll_lua_rawequal
179 #define lua_toboolean dll_lua_toboolean
180 #define lua_tolstring dll_lua_tolstring
181 #define lua_touserdata dll_lua_touserdata
182 #define lua_pushnil dll_lua_pushnil
183 #define lua_pushnumber dll_lua_pushnumber
184 #define lua_pushinteger dll_lua_pushinteger
185 #define lua_pushlstring dll_lua_pushlstring
186 #define lua_pushstring dll_lua_pushstring
187 #define lua_pushfstring dll_lua_pushfstring
188 #define lua_pushcclosure dll_lua_pushcclosure
189 #define lua_pushboolean dll_lua_pushboolean
190 #define lua_pushlightuserdata dll_lua_pushlightuserdata
191 #define lua_getfield dll_lua_getfield
192 #define lua_rawget dll_lua_rawget
193 #define lua_rawgeti dll_lua_rawgeti
194 #define lua_createtable dll_lua_createtable
195 #define lua_settable dll_lua_settable
196 #if LUA_VERSION_NUM >= 504
197  #define lua_newuserdatauv dll_lua_newuserdatauv
198 #else
199  #define lua_newuserdata dll_lua_newuserdata
200 #endif
201 #define lua_getmetatable dll_lua_getmetatable
202 #define lua_setfield dll_lua_setfield
203 #define lua_rawset dll_lua_rawset
204 #define lua_rawseti dll_lua_rawseti
205 #define lua_setmetatable dll_lua_setmetatable
206 #define lua_next dll_lua_next
207 // libs
208 #define luaopen_base dll_luaopen_base
209 #define luaopen_table dll_luaopen_table
210 #define luaopen_string dll_luaopen_string
211 #define luaopen_math dll_luaopen_math
212 #define luaopen_io dll_luaopen_io
213 #define luaopen_os dll_luaopen_os
214 #define luaopen_package dll_luaopen_package
215 #define luaopen_debug dll_luaopen_debug
216 #define luaL_openlibs dll_luaL_openlibs
217 
218 // lauxlib
219 #if LUA_VERSION_NUM <= 501
220 void (*dll_luaL_register) (lua_State *L, const char *libname, const luaL_Reg *l);
221 char *(*dll_luaL_prepbuffer) (luaL_Buffer *B);
222 void (*dll_luaL_openlib) (lua_State *L, const char *libname, const luaL_Reg *l, int nup);
223 int (*dll_luaL_typerror) (lua_State *L, int narg, const char *tname);
224 int (*dll_luaL_loadfile) (lua_State *L, const char *filename);
225 int (*dll_luaL_loadbuffer) (lua_State *L, const char *buff, size_t sz, const char *name);
226 #else
227 char *(*dll_luaL_prepbuffsize) (luaL_Buffer *B, size_t sz);
228 void (*dll_luaL_setfuncs) (lua_State *L, const luaL_Reg *l, int nup);
229 int (*dll_luaL_loadfilex) (lua_State *L, const char *filename, const char *mode);
230 int (*dll_luaL_loadbufferx) (lua_State *L, const char *buff, size_t sz, const char *name, const char *mode);
231 int (*dll_luaL_argerror) (lua_State *L, int numarg, const char *extramsg);
232 #endif
233 #if LUA_VERSION_NUM >= 504
234 int (*dll_luaL_typeerror) (lua_State *L, int narg, const char *tname);
235 #endif
236 void (*dll_luaL_checkany) (lua_State *L, int narg);
237 const char *(*dll_luaL_checklstring) (lua_State *L, int numArg, size_t *l);
238 lua_Integer (*dll_luaL_checkinteger) (lua_State *L, int numArg);
239 lua_Integer (*dll_luaL_optinteger) (lua_State *L, int nArg, lua_Integer def);
240 void (*dll_luaL_checktype) (lua_State *L, int narg, int t);
241 int (*dll_luaL_error) (lua_State *L, const char *fmt, ...);
242 lua_State *(*dll_luaL_newstate) (void);
243 void (*dll_luaL_buffinit) (lua_State *L, luaL_Buffer *B);
244 void (*dll_luaL_addlstring) (luaL_Buffer *B, const char *s, size_t l);
245 void (*dll_luaL_pushresult) (luaL_Buffer *B);
246 int (*dll_luaL_loadstring) (lua_State *L, const char *s);
247 int (*dll_luaL_ref) (lua_State *L, int idx);
248 #if LUA_VERSION_NUM <= 502
249 void (*dll_luaL_unref) (lua_State *L, int idx, int n);
250 #else
251 void (*dll_luaL_unref) (lua_State *L, int idx, lua_Integer n);
252 #endif
253 // lua
254 #if LUA_VERSION_NUM <= 501
255 lua_Number (*dll_lua_tonumber) (lua_State *L, int idx);
256 lua_Integer (*dll_lua_tointeger) (lua_State *L, int idx);
257 void (*dll_lua_call) (lua_State *L, int nargs, int nresults);
258 int (*dll_lua_pcall) (lua_State *L, int nargs, int nresults, int errfunc);
259 #else
260 lua_Number (*dll_lua_tonumberx) (lua_State *L, int idx, int *isnum);
261 lua_Integer (*dll_lua_tointegerx) (lua_State *L, int idx, int *isnum);
262 void (*dll_lua_callk) (lua_State *L, int nargs, int nresults, int ctx,
263 	lua_CFunction k);
264 int (*dll_lua_pcallk) (lua_State *L, int nargs, int nresults, int errfunc,
265 	int ctx, lua_CFunction k);
266 void (*dll_lua_getglobal) (lua_State *L, const char *var);
267 void (*dll_lua_setglobal) (lua_State *L, const char *var);
268 #endif
269 #if LUA_VERSION_NUM <= 502
270 void (*dll_lua_replace) (lua_State *L, int idx);
271 void (*dll_lua_remove) (lua_State *L, int idx);
272 #endif
273 #if LUA_VERSION_NUM >= 503
274 void  (*dll_lua_rotate) (lua_State *L, int idx, int n);
275 void (*dll_lua_copy) (lua_State *L, int fromidx, int toidx);
276 #endif
277 const char *(*dll_lua_typename) (lua_State *L, int tp);
278 void       (*dll_lua_close) (lua_State *L);
279 int (*dll_lua_gettop) (lua_State *L);
280 void (*dll_lua_settop) (lua_State *L, int idx);
281 void (*dll_lua_pushvalue) (lua_State *L, int idx);
282 int (*dll_lua_isnumber) (lua_State *L, int idx);
283 int (*dll_lua_isstring) (lua_State *L, int idx);
284 int (*dll_lua_type) (lua_State *L, int idx);
285 int (*dll_lua_rawequal) (lua_State *L, int idx1, int idx2);
286 int (*dll_lua_toboolean) (lua_State *L, int idx);
287 const char *(*dll_lua_tolstring) (lua_State *L, int idx, size_t *len);
288 void *(*dll_lua_touserdata) (lua_State *L, int idx);
289 void (*dll_lua_pushnil) (lua_State *L);
290 void (*dll_lua_pushnumber) (lua_State *L, lua_Number n);
291 void (*dll_lua_pushinteger) (lua_State *L, lua_Integer n);
292 void (*dll_lua_pushlstring) (lua_State *L, const char *s, size_t l);
293 void (*dll_lua_pushstring) (lua_State *L, const char *s);
294 const char *(*dll_lua_pushfstring) (lua_State *L, const char *fmt, ...);
295 void (*dll_lua_pushcclosure) (lua_State *L, lua_CFunction fn, int n);
296 void (*dll_lua_pushboolean) (lua_State *L, int b);
297 void (*dll_lua_pushlightuserdata) (lua_State *L, void *p);
298 void (*dll_lua_getfield) (lua_State *L, int idx, const char *k);
299 #if LUA_VERSION_NUM <= 502
300 void (*dll_lua_rawget) (lua_State *L, int idx);
301 void (*dll_lua_rawgeti) (lua_State *L, int idx, int n);
302 #else
303 int (*dll_lua_rawget) (lua_State *L, int idx);
304 int (*dll_lua_rawgeti) (lua_State *L, int idx, lua_Integer n);
305 #endif
306 void (*dll_lua_createtable) (lua_State *L, int narr, int nrec);
307 void (*dll_lua_settable) (lua_State *L, int idx);
308 #if LUA_VERSION_NUM >= 504
309 void *(*dll_lua_newuserdatauv) (lua_State *L, size_t sz, int nuvalue);
310 #else
311 void *(*dll_lua_newuserdata) (lua_State *L, size_t sz);
312 #endif
313 int (*dll_lua_getmetatable) (lua_State *L, int objindex);
314 void (*dll_lua_setfield) (lua_State *L, int idx, const char *k);
315 void (*dll_lua_rawset) (lua_State *L, int idx);
316 #if LUA_VERSION_NUM <= 502
317 void (*dll_lua_rawseti) (lua_State *L, int idx, int n);
318 #else
319 void (*dll_lua_rawseti) (lua_State *L, int idx, lua_Integer n);
320 #endif
321 int (*dll_lua_setmetatable) (lua_State *L, int objindex);
322 int (*dll_lua_next) (lua_State *L, int idx);
323 // libs
324 int (*dll_luaopen_base) (lua_State *L);
325 int (*dll_luaopen_table) (lua_State *L);
326 int (*dll_luaopen_string) (lua_State *L);
327 int (*dll_luaopen_math) (lua_State *L);
328 int (*dll_luaopen_io) (lua_State *L);
329 int (*dll_luaopen_os) (lua_State *L);
330 int (*dll_luaopen_package) (lua_State *L);
331 int (*dll_luaopen_debug) (lua_State *L);
332 void (*dll_luaL_openlibs) (lua_State *L);
333 
334 typedef void **luaV_function;
335 typedef struct {
336     const char *name;
337     luaV_function func;
338 } luaV_Reg;
339 
340 static const luaV_Reg luaV_dll[] = {
341     // lauxlib
342 #if LUA_VERSION_NUM <= 501
343     {"luaL_register", (luaV_function) &dll_luaL_register},
344     {"luaL_prepbuffer", (luaV_function) &dll_luaL_prepbuffer},
345     {"luaL_openlib", (luaV_function) &dll_luaL_openlib},
346     {"luaL_typerror", (luaV_function) &dll_luaL_typerror},
347     {"luaL_loadfile", (luaV_function) &dll_luaL_loadfile},
348     {"luaL_loadbuffer", (luaV_function) &dll_luaL_loadbuffer},
349 #else
350     {"luaL_prepbuffsize", (luaV_function) &dll_luaL_prepbuffsize},
351     {"luaL_setfuncs", (luaV_function) &dll_luaL_setfuncs},
352     {"luaL_loadfilex", (luaV_function) &dll_luaL_loadfilex},
353     {"luaL_loadbufferx", (luaV_function) &dll_luaL_loadbufferx},
354     {"luaL_argerror", (luaV_function) &dll_luaL_argerror},
355 #endif
356 #if LUA_VERSION_NUM >= 504
357     {"luaL_typeerror", (luaV_function) &dll_luaL_typeerror},
358 #endif
359     {"luaL_checkany", (luaV_function) &dll_luaL_checkany},
360     {"luaL_checklstring", (luaV_function) &dll_luaL_checklstring},
361     {"luaL_checkinteger", (luaV_function) &dll_luaL_checkinteger},
362     {"luaL_optinteger", (luaV_function) &dll_luaL_optinteger},
363     {"luaL_checktype", (luaV_function) &dll_luaL_checktype},
364     {"luaL_error", (luaV_function) &dll_luaL_error},
365     {"luaL_newstate", (luaV_function) &dll_luaL_newstate},
366     {"luaL_buffinit", (luaV_function) &dll_luaL_buffinit},
367     {"luaL_addlstring", (luaV_function) &dll_luaL_addlstring},
368     {"luaL_pushresult", (luaV_function) &dll_luaL_pushresult},
369     {"luaL_loadstring", (luaV_function) &dll_luaL_loadstring},
370     {"luaL_ref", (luaV_function) &dll_luaL_ref},
371     {"luaL_unref", (luaV_function) &dll_luaL_unref},
372     // lua
373 #if LUA_VERSION_NUM <= 501
374     {"lua_tonumber", (luaV_function) &dll_lua_tonumber},
375     {"lua_tointeger", (luaV_function) &dll_lua_tointeger},
376     {"lua_call", (luaV_function) &dll_lua_call},
377     {"lua_pcall", (luaV_function) &dll_lua_pcall},
378 #else
379     {"lua_tonumberx", (luaV_function) &dll_lua_tonumberx},
380     {"lua_tointegerx", (luaV_function) &dll_lua_tointegerx},
381     {"lua_callk", (luaV_function) &dll_lua_callk},
382     {"lua_pcallk", (luaV_function) &dll_lua_pcallk},
383     {"lua_getglobal", (luaV_function) &dll_lua_getglobal},
384     {"lua_setglobal", (luaV_function) &dll_lua_setglobal},
385 #endif
386 #if LUA_VERSION_NUM <= 502
387     {"lua_replace", (luaV_function) &dll_lua_replace},
388     {"lua_remove", (luaV_function) &dll_lua_remove},
389 #endif
390 #if LUA_VERSION_NUM >= 503
391     {"lua_rotate", (luaV_function) &dll_lua_rotate},
392     {"lua_copy", (luaV_function) &dll_lua_copy},
393 #endif
394     {"lua_typename", (luaV_function) &dll_lua_typename},
395     {"lua_close", (luaV_function) &dll_lua_close},
396     {"lua_gettop", (luaV_function) &dll_lua_gettop},
397     {"lua_settop", (luaV_function) &dll_lua_settop},
398     {"lua_pushvalue", (luaV_function) &dll_lua_pushvalue},
399     {"lua_isnumber", (luaV_function) &dll_lua_isnumber},
400     {"lua_isstring", (luaV_function) &dll_lua_isstring},
401     {"lua_type", (luaV_function) &dll_lua_type},
402     {"lua_rawequal", (luaV_function) &dll_lua_rawequal},
403     {"lua_toboolean", (luaV_function) &dll_lua_toboolean},
404     {"lua_tolstring", (luaV_function) &dll_lua_tolstring},
405     {"lua_touserdata", (luaV_function) &dll_lua_touserdata},
406     {"lua_pushnil", (luaV_function) &dll_lua_pushnil},
407     {"lua_pushnumber", (luaV_function) &dll_lua_pushnumber},
408     {"lua_pushinteger", (luaV_function) &dll_lua_pushinteger},
409     {"lua_pushlstring", (luaV_function) &dll_lua_pushlstring},
410     {"lua_pushstring", (luaV_function) &dll_lua_pushstring},
411     {"lua_pushfstring", (luaV_function) &dll_lua_pushfstring},
412     {"lua_pushcclosure", (luaV_function) &dll_lua_pushcclosure},
413     {"lua_pushboolean", (luaV_function) &dll_lua_pushboolean},
414     {"lua_pushlightuserdata", (luaV_function) &dll_lua_pushlightuserdata},
415     {"lua_getfield", (luaV_function) &dll_lua_getfield},
416     {"lua_rawget", (luaV_function) &dll_lua_rawget},
417     {"lua_rawgeti", (luaV_function) &dll_lua_rawgeti},
418     {"lua_createtable", (luaV_function) &dll_lua_createtable},
419     {"lua_settable", (luaV_function) &dll_lua_settable},
420 #if LUA_VERSION_NUM >= 504
421     {"lua_newuserdatauv", (luaV_function) &dll_lua_newuserdatauv},
422 #else
423     {"lua_newuserdata", (luaV_function) &dll_lua_newuserdata},
424 #endif
425     {"lua_getmetatable", (luaV_function) &dll_lua_getmetatable},
426     {"lua_setfield", (luaV_function) &dll_lua_setfield},
427     {"lua_rawset", (luaV_function) &dll_lua_rawset},
428     {"lua_rawseti", (luaV_function) &dll_lua_rawseti},
429     {"lua_setmetatable", (luaV_function) &dll_lua_setmetatable},
430     {"lua_next", (luaV_function) &dll_lua_next},
431     // libs
432     {"luaopen_base", (luaV_function) &dll_luaopen_base},
433     {"luaopen_table", (luaV_function) &dll_luaopen_table},
434     {"luaopen_string", (luaV_function) &dll_luaopen_string},
435     {"luaopen_math", (luaV_function) &dll_luaopen_math},
436     {"luaopen_io", (luaV_function) &dll_luaopen_io},
437     {"luaopen_os", (luaV_function) &dll_luaopen_os},
438     {"luaopen_package", (luaV_function) &dll_luaopen_package},
439     {"luaopen_debug", (luaV_function) &dll_luaopen_debug},
440     {"luaL_openlibs", (luaV_function) &dll_luaL_openlibs},
441     {NULL, NULL}
442 };
443 
444 static HANDLE hinstLua = NULL;
445 
446     static int
lua_link_init(char * libname,int verbose)447 lua_link_init(char *libname, int verbose)
448 {
449     const luaV_Reg *reg;
450     if (hinstLua) return OK;
451     hinstLua = load_dll(libname);
452     if (!hinstLua)
453     {
454 	if (verbose)
455 	    semsg(_(e_loadlib), libname, load_dll_error());
456 	return FAIL;
457     }
458     for (reg = luaV_dll; reg->func; reg++)
459     {
460 	if ((*reg->func = symbol_from_dll(hinstLua, reg->name)) == NULL)
461 	{
462 	    close_dll(hinstLua);
463 	    hinstLua = 0;
464 	    if (verbose)
465 		semsg(_(e_loadfunc), reg->name);
466 	    return FAIL;
467 	}
468     }
469     return OK;
470 }
471 #endif // DYNAMIC_LUA
472 
473 #if defined(DYNAMIC_LUA) || defined(PROTO)
474     int
lua_enabled(int verbose)475 lua_enabled(int verbose)
476 {
477     return lua_link_init((char *)p_luadll, verbose) == OK;
478 }
479 #endif
480 
481 #if LUA_VERSION_NUM > 501 && LUA_VERSION_NUM < 504
482     static int
luaL_typeerror(lua_State * L,int narg,const char * tname)483 luaL_typeerror(lua_State *L, int narg, const char *tname)
484 {
485     const char *msg = lua_pushfstring(L, "%s expected, got %s",
486 	    tname, luaL_typename(L, narg));
487     return luaL_argerror(L, narg, msg);
488 }
489 #endif
490 
491 
492 // =======   Internal   =======
493 
494     static void
luaV_newmetatable(lua_State * L,const char * tname)495 luaV_newmetatable(lua_State *L, const char *tname)
496 {
497     lua_newtable(L);
498     lua_pushlightuserdata(L, (void *) tname);
499     lua_pushvalue(L, -2);
500     lua_rawset(L, LUA_REGISTRYINDEX);
501 }
502 
503     static void *
luaV_toudata(lua_State * L,int ud,const char * tname)504 luaV_toudata(lua_State *L, int ud, const char *tname)
505 {
506     void *p = lua_touserdata(L, ud);
507 
508     if (p != NULL) // value is userdata?
509     {
510 	if (lua_getmetatable(L, ud)) // does it have a metatable?
511 	{
512 	    luaV_getfield(L, tname); // get metatable
513 	    if (lua_rawequal(L, -1, -2)) // MTs match?
514 	    {
515 		lua_pop(L, 2); // MTs
516 		return p;
517 	    }
518 	}
519     }
520     return NULL;
521 }
522 
523     static void *
luaV_checkcache(lua_State * L,void * p)524 luaV_checkcache(lua_State *L, void *p)
525 {
526     luaV_getudata(L, p);
527     if (lua_isnil(L, -1)) luaL_error(L, "invalid object");
528     lua_pop(L, 1);
529     return p;
530 }
531 
532 #define luaV_unbox(L,luatyp,ud) (*((luatyp *) lua_touserdata((L),(ud))))
533 
534 #define luaV_checkvalid(L,luatyp,ud) \
535     luaV_checkcache((L), (void *) luaV_unbox((L),luatyp,(ud)))
536 
537     static void *
luaV_checkudata(lua_State * L,int ud,const char * tname)538 luaV_checkudata(lua_State *L, int ud, const char *tname)
539 {
540     void *p = luaV_toudata(L, ud, tname);
541     if (p == NULL) luaL_typeerror(L, ud, tname);
542     return p;
543 }
544 
545     static void
luaV_pushtypval(lua_State * L,typval_T * tv)546 luaV_pushtypval(lua_State *L, typval_T *tv)
547 {
548     if (tv == NULL)
549     {
550 	lua_pushnil(L);
551 	return;
552     }
553     switch (tv->v_type)
554     {
555 	case VAR_STRING:
556 	    lua_pushstring(L, tv->vval.v_string == NULL
557 					    ? "" : (char *)tv->vval.v_string);
558 	    break;
559 	case VAR_NUMBER:
560 	    lua_pushinteger(L, (int) tv->vval.v_number);
561 	    break;
562 #ifdef FEAT_FLOAT
563 	case VAR_FLOAT:
564 	    lua_pushnumber(L, (lua_Number) tv->vval.v_float);
565 	    break;
566 #endif
567 	case VAR_LIST:
568 	    luaV_pushlist(L, tv->vval.v_list);
569 	    break;
570 	case VAR_DICT:
571 	    luaV_pushdict(L, tv->vval.v_dict);
572 	    break;
573 	case VAR_BOOL:
574 	case VAR_SPECIAL:
575 	    if (tv->vval.v_number <= VVAL_TRUE)
576 		lua_pushinteger(L, (int) tv->vval.v_number);
577 	    else
578 		lua_pushnil(L);
579 	    break;
580 	case VAR_FUNC:
581 	    luaV_pushfuncref(L, tv->vval.v_string);
582 	    break;
583 	case VAR_PARTIAL:
584 	    // TODO: handle partial arguments
585 	    luaV_pushfuncref(L, partial_name(tv->vval.v_partial));
586 	    break;
587 
588 	case VAR_BLOB:
589 	    luaV_pushblob(L, tv->vval.v_blob);
590 	    break;
591 	default:
592 	    lua_pushnil(L);
593     }
594 }
595 
596 /*
597  * Converts lua value at 'pos' to typval 'tv'.
598  * Returns OK or FAIL.
599  */
600     static int
luaV_totypval(lua_State * L,int pos,typval_T * tv)601 luaV_totypval(lua_State *L, int pos, typval_T *tv)
602 {
603     int status = OK;
604 
605     tv->v_lock = 0;
606 
607     switch (lua_type(L, pos))
608     {
609 	case LUA_TBOOLEAN:
610 	    tv->v_type = VAR_BOOL;
611 	    tv->vval.v_number = (varnumber_T) lua_toboolean(L, pos);
612 	    break;
613 	case LUA_TNIL:
614 	    tv->v_type = VAR_SPECIAL;
615 	    tv->vval.v_number = VVAL_NULL;
616 	    break;
617 	case LUA_TSTRING:
618 	    tv->v_type = VAR_STRING;
619 	    tv->vval.v_string = vim_strsave((char_u *) lua_tostring(L, pos));
620 	    break;
621 	case LUA_TNUMBER:
622 #ifdef FEAT_FLOAT
623 	{
624 	    const lua_Number n = lua_tonumber(L, pos);
625 
626 	    if (n > (lua_Number)INT64_MAX || n < (lua_Number)INT64_MIN
627 		    || ((lua_Number)((varnumber_T)n)) != n)
628 	    {
629 		tv->v_type = VAR_FLOAT;
630 		tv->vval.v_float = (float_T)n;
631 	    }
632 	    else
633 	    {
634 		tv->v_type = VAR_NUMBER;
635 		tv->vval.v_number = (varnumber_T)n;
636 	    }
637 	}
638 #else
639 	    tv->v_type = VAR_NUMBER;
640 	    tv->vval.v_number = (varnumber_T) lua_tointeger(L, pos);
641 #endif
642 	    break;
643 	case LUA_TFUNCTION:
644 	{
645 	    char_u *name;
646 	    luaV_CFuncState *state;
647 
648 	    lua_pushvalue(L, pos);
649 	    state = ALLOC_CLEAR_ONE(luaV_CFuncState);
650 	    state->lua_funcref = luaL_ref(L, LUA_REGISTRYINDEX);
651 	    state->L = L;
652 	    state->lua_tableref = LUA_NOREF;
653 	    name = register_cfunc(&luaV_call_lua_func,
654 					      &luaV_call_lua_func_free, state);
655 	    tv->v_type = VAR_FUNC;
656 	    tv->vval.v_string = vim_strsave(name);
657 	    break;
658 	}
659 	case LUA_TTABLE:
660 	{
661 	    int lua_tableref;
662 
663 	    lua_pushvalue(L, pos);
664 	    lua_tableref = luaL_ref(L, LUA_REGISTRYINDEX);
665 	    if (lua_getmetatable(L, pos)) {
666 		lua_getfield(L, -1, LUA___CALL);
667 		if (lua_isfunction(L, -1)) {
668 		    char_u *name;
669 		    int lua_funcref = luaL_ref(L, LUA_REGISTRYINDEX);
670 		    luaV_CFuncState *state = ALLOC_CLEAR_ONE(luaV_CFuncState);
671 
672 		    state->lua_funcref = lua_funcref;
673 		    state->L = L;
674 		    state->lua_tableref = lua_tableref;
675 		    name = register_cfunc(&luaV_call_lua_func,
676 					      &luaV_call_lua_func_free, state);
677 		    tv->v_type = VAR_FUNC;
678 		    tv->vval.v_string = vim_strsave(name);
679 		    break;
680 		}
681 	    }
682 	    tv->v_type = VAR_NUMBER;
683 	    tv->vval.v_number = 0;
684 	    status = FAIL;
685 	    break;
686 	}
687 	case LUA_TUSERDATA:
688 	{
689 	    void *p = lua_touserdata(L, pos);
690 
691 	    if (lua_getmetatable(L, pos)) // has metatable?
692 	    {
693 		// check list
694 		luaV_getfield(L, LUAVIM_LIST);
695 		if (lua_rawequal(L, -1, -2))
696 		{
697 		    tv->v_type = VAR_LIST;
698 		    tv->vval.v_list = *((luaV_List *) p);
699 		    ++tv->vval.v_list->lv_refcount;
700 		    lua_pop(L, 2); // MTs
701 		    break;
702 		}
703 		// check dict
704 		luaV_getfield(L, LUAVIM_DICT);
705 		if (lua_rawequal(L, -1, -3))
706 		{
707 		    tv->v_type = VAR_DICT;
708 		    tv->vval.v_dict = *((luaV_Dict *) p);
709 		    ++tv->vval.v_dict->dv_refcount;
710 		    lua_pop(L, 3); // MTs
711 		    break;
712 		}
713 		// check blob
714 		luaV_getfield(L, LUAVIM_BLOB);
715 		if (lua_rawequal(L, -1, -4))
716 		{
717 		    tv->v_type = VAR_BLOB;
718 		    tv->vval.v_blob = *((luaV_Blob *) p);
719 		    ++tv->vval.v_blob->bv_refcount;
720 		    lua_pop(L, 4); // MTs
721 		    break;
722 		}
723 		// check funcref
724 		luaV_getfield(L, LUAVIM_FUNCREF);
725 		if (lua_rawequal(L, -1, -5))
726 		{
727 		    luaV_Funcref *f = (luaV_Funcref *) p;
728 
729 		    func_ref(f->name);
730 		    tv->v_type = VAR_FUNC;
731 		    tv->vval.v_string = vim_strsave(f->name);
732 		    lua_pop(L, 5); // MTs
733 		    break;
734 		}
735 		lua_pop(L, 4); // MTs
736 	    }
737 	}
738 	// FALLTHROUGH
739 	default:
740 	    tv->v_type = VAR_NUMBER;
741 	    tv->vval.v_number = 0;
742 	    status = FAIL;
743     }
744     return status;
745 }
746 
747 /*
748  * similar to luaL_addlstring, but replaces \0 with \n if toline and
749  * \n with \0 otherwise
750  */
751     static void
luaV_addlstring(luaL_Buffer * b,const char * s,size_t l,int toline)752 luaV_addlstring(luaL_Buffer *b, const char *s, size_t l, int toline)
753 {
754     while (l--)
755     {
756 	if (*s == '\0' && toline)
757 	    luaL_addchar(b, '\n');
758 	else if (*s == '\n' && !toline)
759 	    luaL_addchar(b, '\0');
760 	else
761 	    luaL_addchar(b, *s);
762 	s++;
763     }
764 }
765 
766     static void
luaV_pushline(lua_State * L,buf_T * buf,linenr_T n)767 luaV_pushline(lua_State *L, buf_T *buf, linenr_T n)
768 {
769     const char *s = (const char *) ml_get_buf(buf, n, FALSE);
770     luaL_Buffer b;
771     luaL_buffinit(L, &b);
772     luaV_addlstring(&b, s, strlen(s), 0);
773     luaL_pushresult(&b);
774 }
775 
776     static char_u *
luaV_toline(lua_State * L,int pos)777 luaV_toline(lua_State *L, int pos)
778 {
779     size_t l;
780     const char *s = lua_tolstring(L, pos, &l);
781 
782     luaL_Buffer b;
783     luaL_buffinit(L, &b);
784     luaV_addlstring(&b, s, l, 1);
785     luaL_pushresult(&b);
786     return (char_u *) lua_tostring(L, -1);
787 }
788 
789 /*
790  * pops a string s from the top of the stack and calls mf(t) for pieces t of
791  * s separated by newlines
792  */
793     static void
luaV_msgfunc(lua_State * L,msgfunc_T mf)794 luaV_msgfunc(lua_State *L, msgfunc_T mf)
795 {
796     luaL_Buffer b;
797     size_t l;
798     const char *p, *s = lua_tolstring(L, -1, &l);
799     luaL_buffinit(L, &b);
800     luaV_addlstring(&b, s, l, 0);
801     luaL_pushresult(&b);
802     // break string
803     p = s = lua_tolstring(L, -1, &l);
804     while (l--)
805     {
806 	if (*p++ == '\0') // break?
807 	{
808 	    mf((char *)s);
809 	    s = p;
810 	}
811     }
812     mf((char *)s);
813     lua_pop(L, 2); // original and modified strings
814 }
815 
816 #define luaV_newtype(typ,tname,luatyp,luatname) \
817 	static luatyp * \
818     luaV_new##tname(lua_State *L, typ *obj) \
819     { \
820 	luatyp *o = (luatyp *) lua_newuserdata(L, sizeof(luatyp)); \
821 	*o = obj; \
822 	luaV_setudata(L, obj); /* cache[obj] = udata */ \
823 	luaV_getfield(L, luatname); \
824 	lua_setmetatable(L, -2); \
825 	return o; \
826     }
827 
828 #define luaV_pushtype(typ,tname,luatyp) \
829 	static luatyp * \
830     luaV_push##tname(lua_State *L, typ *obj) \
831     { \
832 	luatyp *o = NULL; \
833 	if (obj == NULL) \
834 	    lua_pushnil(L); \
835 	else { \
836 	    luaV_getudata(L, obj); \
837 	    if (lua_isnil(L, -1)) /* not interned? */ \
838 	    { \
839 		lua_pop(L, 1); \
840 		o = luaV_new##tname(L, obj); \
841 	    } \
842 	    else \
843 		o = (luatyp *) lua_touserdata(L, -1); \
844 	} \
845 	return o; \
846     }
847 
848 #define luaV_type_tostring(tname,luatname) \
849 	static int \
850     luaV_##tname##_tostring(lua_State *L) \
851     { \
852 	lua_pushfstring(L, "%s: %p", luatname, lua_touserdata(L, 1)); \
853 	return 1; \
854     }
855 
856 // =======   List type   =======
857 
858     static luaV_List *
luaV_newlist(lua_State * L,list_T * lis)859 luaV_newlist(lua_State *L, list_T *lis)
860 {
861     luaV_List *l = (luaV_List *) lua_newuserdata(L, sizeof(luaV_List));
862     *l = lis;
863     lis->lv_refcount++; // reference in Lua
864     luaV_setudata(L, lis); // cache[lis] = udata
865     luaV_getfield(L, LUAVIM_LIST);
866     lua_setmetatable(L, -2);
867     return l;
868 }
869 
luaV_pushtype(list_T,list,luaV_List)870 luaV_pushtype(list_T, list, luaV_List)
871 luaV_type_tostring(list, LUAVIM_LIST)
872 
873     static int
874 luaV_list_len(lua_State *L)
875 {
876     list_T *l = luaV_unbox(L, luaV_List, 1);
877     lua_pushinteger(L, (int) list_len(l));
878     return 1;
879 }
880 
881     static int
luaV_list_iter(lua_State * L)882 luaV_list_iter(lua_State *L)
883 {
884     listitem_T *li = (listitem_T *) lua_touserdata(L, lua_upvalueindex(2));
885     if (li == NULL) return 0;
886     luaV_pushtypval(L, &li->li_tv);
887     lua_pushlightuserdata(L, (void *) li->li_next);
888     lua_replace(L, lua_upvalueindex(2));
889     return 1;
890 }
891 
892     static int
luaV_list_call(lua_State * L)893 luaV_list_call(lua_State *L)
894 {
895     list_T *l = luaV_unbox(L, luaV_List, 1);
896     lua_pushvalue(L, lua_upvalueindex(1)); // pass cache table along
897     lua_pushlightuserdata(L, (void *) l->lv_first);
898     lua_pushcclosure(L, luaV_list_iter, 2);
899     return 1;
900 }
901 
902     static int
luaV_list_index(lua_State * L)903 luaV_list_index(lua_State *L)
904 {
905     list_T *l = luaV_unbox(L, luaV_List, 1);
906     if (lua_isnumber(L, 2)) // list item?
907     {
908 	long n = (long) luaL_checkinteger(L, 2);
909 	listitem_T *li;
910 
911 	// Lua array index starts with 1 while Vim uses 0, subtract 1 to
912 	// normalize.
913 	n -= 1;
914 	li = list_find(l, n);
915 	if (li == NULL)
916 	    lua_pushnil(L);
917 	else
918 	    luaV_pushtypval(L, &li->li_tv);
919     }
920     else if (lua_isstring(L, 2)) // method?
921     {
922 	const char *s = lua_tostring(L, 2);
923 	if (strncmp(s, "add", 3) == 0
924 		|| strncmp(s, "insert", 6) == 0)
925 	{
926 	    lua_getmetatable(L, 1);
927 	    lua_getfield(L, -1, s);
928 	}
929 	else
930 	    lua_pushnil(L);
931     }
932     else
933 	lua_pushnil(L);
934     return 1;
935 }
936 
937     static int
luaV_list_newindex(lua_State * L)938 luaV_list_newindex(lua_State *L)
939 {
940     list_T *l = luaV_unbox(L, luaV_List, 1);
941     long n = (long) luaL_checkinteger(L, 2);
942     listitem_T *li;
943 
944     // Lua array index starts with 1 while Vim uses 0, subtract 1 to normalize.
945     n -= 1;
946 
947     if (l->lv_lock)
948 	luaL_error(L, "list is locked");
949     li = list_find(l, n);
950     if (li == NULL)
951     {
952         if (!lua_isnil(L, 3))
953         {
954 	   typval_T v;
955 	   luaV_checktypval(L, 3, &v, "inserting list item");
956 	   if (list_insert_tv(l, &v, li) == FAIL)
957 	        luaL_error(L, "failed to add item to list");
958 	   clear_tv(&v);
959         }
960     }
961     else
962     {
963         if (lua_isnil(L, 3)) // remove?
964         {
965 	    vimlist_remove(l, li, li);
966 	    listitem_free(l, li);
967         }
968         else
969         {
970 	    typval_T v;
971 	    luaV_checktypval(L, 3, &v, "setting list item");
972 	    clear_tv(&li->li_tv);
973 	    li->li_tv = v;
974         }
975     }
976     return 0;
977 }
978 
979     static int
luaV_list_add(lua_State * L)980 luaV_list_add(lua_State *L)
981 {
982     luaV_List *lis = luaV_checkudata(L, 1, LUAVIM_LIST);
983     list_T *l = (list_T *) luaV_checkcache(L, (void *) *lis);
984     typval_T v;
985     if (l->lv_lock)
986 	luaL_error(L, "list is locked");
987     lua_settop(L, 2);
988     luaV_checktypval(L, 2, &v, "adding list item");
989     if (list_append_tv(l, &v) == FAIL)
990 	luaL_error(L, "failed to add item to list");
991     clear_tv(&v);
992     lua_settop(L, 1);
993     return 1;
994 }
995 
996     static int
luaV_list_insert(lua_State * L)997 luaV_list_insert(lua_State *L)
998 {
999     luaV_List *lis = luaV_checkudata(L, 1, LUAVIM_LIST);
1000     list_T *l = (list_T *) luaV_checkcache(L, (void *) *lis);
1001     long pos = (long) luaL_optinteger(L, 3, 0);
1002     listitem_T *li = NULL;
1003     typval_T v;
1004     if (l->lv_lock)
1005 	luaL_error(L, "list is locked");
1006     if (pos < l->lv_len)
1007     {
1008 	li = list_find(l, pos);
1009 	if (li == NULL)
1010 	    luaL_error(L, "invalid position");
1011     }
1012     lua_settop(L, 2);
1013     luaV_checktypval(L, 2, &v, "inserting list item");
1014     if (list_insert_tv(l, &v, li) == FAIL)
1015 	luaL_error(L, "failed to add item to list");
1016     clear_tv(&v);
1017     lua_settop(L, 1);
1018     return 1;
1019 }
1020 
1021 static const luaL_Reg luaV_List_mt[] = {
1022     {"__tostring", luaV_list_tostring},
1023     {"__len", luaV_list_len},
1024     {"__call", luaV_list_call},
1025     {"__index", luaV_list_index},
1026     {"__newindex", luaV_list_newindex},
1027     {"add", luaV_list_add},
1028     {"insert", luaV_list_insert},
1029     {NULL, NULL}
1030 };
1031 
1032 
1033 // =======   Dict type   =======
1034 
1035     static luaV_Dict *
luaV_newdict(lua_State * L,dict_T * dic)1036 luaV_newdict(lua_State *L, dict_T *dic)
1037 {
1038     luaV_Dict *d = (luaV_Dict *) lua_newuserdata(L, sizeof(luaV_Dict));
1039     *d = dic;
1040     dic->dv_refcount++; // reference in Lua
1041     luaV_setudata(L, dic); // cache[dic] = udata
1042     luaV_getfield(L, LUAVIM_DICT);
1043     lua_setmetatable(L, -2);
1044     return d;
1045 }
1046 
luaV_pushtype(dict_T,dict,luaV_Dict)1047 luaV_pushtype(dict_T, dict, luaV_Dict)
1048 luaV_type_tostring(dict, LUAVIM_DICT)
1049 
1050     static int
1051 luaV_dict_len(lua_State *L)
1052 {
1053     dict_T *d = luaV_unbox(L, luaV_Dict, 1);
1054     lua_pushinteger(L, (int) dict_len(d));
1055     return 1;
1056 }
1057 
1058     static int
luaV_dict_iter(lua_State * L UNUSED)1059 luaV_dict_iter(lua_State *L UNUSED)
1060 {
1061 #ifdef FEAT_EVAL
1062     hashitem_T *hi = (hashitem_T *) lua_touserdata(L, lua_upvalueindex(2));
1063     int n = lua_tointeger(L, lua_upvalueindex(3));
1064     dictitem_T *di;
1065     if (n <= 0) return 0;
1066     while (HASHITEM_EMPTY(hi)) hi++;
1067     di = dict_lookup(hi);
1068     lua_pushstring(L, (char *) hi->hi_key);
1069     luaV_pushtypval(L, &di->di_tv);
1070     lua_pushlightuserdata(L, (void *) (hi + 1));
1071     lua_replace(L, lua_upvalueindex(2));
1072     lua_pushinteger(L, n - 1);
1073     lua_replace(L, lua_upvalueindex(3));
1074     return 2;
1075 #else
1076     return 0;
1077 #endif
1078 }
1079 
1080     static int
luaV_dict_call(lua_State * L)1081 luaV_dict_call(lua_State *L)
1082 {
1083     dict_T *d = luaV_unbox(L, luaV_Dict, 1);
1084     hashtab_T *ht = &d->dv_hashtab;
1085     lua_pushvalue(L, lua_upvalueindex(1)); // pass cache table along
1086     lua_pushlightuserdata(L, (void *) ht->ht_array);
1087     lua_pushinteger(L, ht->ht_used); // # remaining items
1088     lua_pushcclosure(L, luaV_dict_iter, 3);
1089     return 1;
1090 }
1091 
1092     static int
luaV_dict_index(lua_State * L)1093 luaV_dict_index(lua_State *L)
1094 {
1095     dict_T *d = luaV_unbox(L, luaV_Dict, 1);
1096     char_u *key = (char_u *) luaL_checkstring(L, 2);
1097     dictitem_T *di = dict_find(d, key, -1);
1098 
1099     if (di == NULL)
1100 	lua_pushnil(L);
1101     else
1102     {
1103 	luaV_pushtypval(L, &di->di_tv);
1104 	if (di->di_tv.v_type == VAR_FUNC) // funcref?
1105 	{
1106 	    luaV_Funcref *f = (luaV_Funcref *) lua_touserdata(L, -1);
1107 	    f->self = d; // keep "self" reference
1108 	    d->dv_refcount++;
1109 	}
1110     }
1111     return 1;
1112 }
1113 
1114     static int
luaV_dict_newindex(lua_State * L)1115 luaV_dict_newindex(lua_State *L)
1116 {
1117     dict_T *d = luaV_unbox(L, luaV_Dict, 1);
1118     char_u *key = (char_u *) luaL_checkstring(L, 2);
1119     dictitem_T *di;
1120     typval_T tv;
1121 
1122     if (d->dv_lock)
1123 	luaL_error(L, "dict is locked");
1124     if (key == NULL)
1125 	return 0;
1126     if (*key == NUL)
1127 	luaL_error(L, "empty key");
1128     if (!lua_isnil(L, 3)) // read value?
1129     {
1130 	luaV_checktypval(L, 3, &tv, "setting dict item");
1131 	if (d->dv_scope == VAR_DEF_SCOPE && tv.v_type == VAR_FUNC)
1132 	{
1133 	    clear_tv(&tv);
1134 	    luaL_error(L, "cannot assign funcref to builtin scope");
1135 	}
1136     }
1137     di = dict_find(d, key, -1);
1138     if (di == NULL) // non-existing key?
1139     {
1140 	if (lua_isnil(L, 3))
1141 	    return 0;
1142 	di = dictitem_alloc(key);
1143 	if (di == NULL)
1144 	{
1145 	    clear_tv(&tv);
1146 	    return 0;
1147 	}
1148 	if (dict_add(d, di) == FAIL)
1149 	{
1150 	    vim_free(di);
1151 	    clear_tv(&tv);
1152 	    return 0;
1153 	}
1154     }
1155     else
1156 	clear_tv(&di->di_tv);
1157     if (lua_isnil(L, 3)) // remove?
1158     {
1159 	hashitem_T *hi = hash_find(&d->dv_hashtab, di->di_key);
1160 	hash_remove(&d->dv_hashtab, hi);
1161 	dictitem_free(di);
1162     }
1163     else
1164 	di->di_tv = tv;
1165     return 0;
1166 }
1167 
1168 static const luaL_Reg luaV_Dict_mt[] = {
1169     {"__tostring", luaV_dict_tostring},
1170     {"__len", luaV_dict_len},
1171     {"__call", luaV_dict_call},
1172     {"__index", luaV_dict_index},
1173     {"__newindex", luaV_dict_newindex},
1174     {NULL, NULL}
1175 };
1176 
1177 
1178 // =======   Blob type   =======
1179 
1180     static luaV_Blob *
luaV_newblob(lua_State * L,blob_T * blo)1181 luaV_newblob(lua_State *L, blob_T *blo)
1182 {
1183     luaV_Blob *b = (luaV_Blob *) lua_newuserdata(L, sizeof(luaV_Blob));
1184     *b = blo;
1185     blo->bv_refcount++; // reference in Lua
1186     luaV_setudata(L, blo); // cache[blo] = udata
1187     luaV_getfield(L, LUAVIM_BLOB);
1188     lua_setmetatable(L, -2);
1189     return b;
1190 }
1191 
luaV_pushtype(blob_T,blob,luaV_Blob)1192 luaV_pushtype(blob_T, blob, luaV_Blob)
1193 luaV_type_tostring(blob, LUAVIM_BLOB)
1194 
1195     static int
1196 luaV_blob_gc(lua_State *L)
1197 {
1198     blob_T *b = luaV_unbox(L, luaV_Blob, 1);
1199     blob_unref(b);
1200     return 0;
1201 }
1202 
1203     static int
luaV_blob_len(lua_State * L)1204 luaV_blob_len(lua_State *L)
1205 {
1206     blob_T *b = luaV_unbox(L, luaV_Blob, 1);
1207     lua_pushinteger(L, (int) blob_len(b));
1208     return 1;
1209 }
1210 
1211     static int
luaV_blob_index(lua_State * L)1212 luaV_blob_index(lua_State *L)
1213 {
1214     blob_T *b = luaV_unbox(L, luaV_Blob, 1);
1215     if (lua_isnumber(L, 2))
1216     {
1217 	int idx = luaL_checkinteger(L, 2);
1218 	if (idx < blob_len(b))
1219 	    lua_pushnumber(L, (lua_Number) blob_get(b, idx));
1220 	else
1221 	    lua_pushnil(L);
1222     }
1223     else if (lua_isstring(L, 2))
1224     {
1225 	const char *s = lua_tostring(L, 2);
1226 	if (strncmp(s, "add", 3) == 0)
1227 	{
1228 	    lua_getmetatable(L, 1);
1229 	    lua_getfield(L, -1, s);
1230 	}
1231 	else
1232 	    lua_pushnil(L);
1233     }
1234     else
1235 	lua_pushnil(L);
1236     return 1;
1237 }
1238 
1239     static int
luaV_blob_newindex(lua_State * L)1240 luaV_blob_newindex(lua_State *L)
1241 {
1242     blob_T *b = luaV_unbox(L, luaV_Blob, 1);
1243     if (b->bv_lock)
1244 	luaL_error(L, "blob is locked");
1245     if (lua_isnumber(L, 2))
1246     {
1247 	long len = blob_len(b);
1248 	int idx = luaL_checkinteger(L, 2);
1249 	int val = luaL_checkinteger(L, 3);
1250 	if (idx < len || (idx == len && ga_grow(&b->bv_ga, 1) == OK))
1251 	{
1252 	    blob_set(b, idx, (char_u) val);
1253 	    if (idx == len)
1254 		++b->bv_ga.ga_len;
1255 	}
1256 	else
1257 	    luaL_error(L, "index out of range");
1258     }
1259     return 0;
1260 }
1261 
1262     static int
luaV_blob_add(lua_State * L)1263 luaV_blob_add(lua_State *L)
1264 {
1265     luaV_Blob *blo = luaV_checkudata(L, 1, LUAVIM_BLOB);
1266     blob_T *b = (blob_T *) luaV_checkcache(L, (void *) *blo);
1267     if (b->bv_lock)
1268 	luaL_error(L, "blob is locked");
1269     lua_settop(L, 2);
1270     if (!lua_isstring(L, 2))
1271 	luaL_error(L, "string expected, got %s", luaL_typename(L, 2));
1272     else
1273     {
1274 	size_t i, l = 0;
1275 	const char *s = lua_tolstring(L, 2, &l);
1276 
1277 	if (ga_grow(&b->bv_ga, (int)l) == OK)
1278 	    for (i = 0; i < l; ++i)
1279 		ga_append(&b->bv_ga, s[i]);
1280     }
1281     lua_settop(L, 1);
1282     return 1;
1283 }
1284 
1285 static const luaL_Reg luaV_Blob_mt[] = {
1286     {"__tostring", luaV_blob_tostring},
1287     {"__gc", luaV_blob_gc},
1288     {"__len", luaV_blob_len},
1289     {"__index", luaV_blob_index},
1290     {"__newindex", luaV_blob_newindex},
1291     {"add", luaV_blob_add},
1292     {NULL, NULL}
1293 };
1294 
1295 
1296 // =======   Funcref type   =======
1297 
1298     static luaV_Funcref *
luaV_newfuncref(lua_State * L,char_u * name)1299 luaV_newfuncref(lua_State *L, char_u *name)
1300 {
1301     luaV_Funcref *f = (luaV_Funcref *)lua_newuserdata(L, sizeof(luaV_Funcref));
1302 
1303     if (name != NULL)
1304     {
1305 	func_ref(name);
1306 	f->name = vim_strsave(name);
1307     }
1308     f->self = NULL;
1309     luaV_getfield(L, LUAVIM_FUNCREF);
1310     lua_setmetatable(L, -2);
1311     return f;
1312 }
1313 
1314     static luaV_Funcref *
luaV_pushfuncref(lua_State * L,char_u * name)1315 luaV_pushfuncref(lua_State *L, char_u *name)
1316 {
1317     return luaV_newfuncref(L, name);
1318 }
1319 
1320 
luaV_type_tostring(funcref,LUAVIM_FUNCREF)1321 luaV_type_tostring(funcref, LUAVIM_FUNCREF)
1322 
1323     static int
1324 luaV_funcref_gc(lua_State *L)
1325 {
1326     luaV_Funcref *f = (luaV_Funcref *) lua_touserdata(L, 1);
1327 
1328     func_unref(f->name);
1329     vim_free(f->name);
1330     // NOTE: Don't call "dict_unref(f->self)", because the dict of "f->self"
1331     // will be (or has been already) freed by Vim's garbage collection.
1332     return 0;
1333 }
1334 
1335 // equivalent to string(funcref)
1336     static int
luaV_funcref_len(lua_State * L)1337 luaV_funcref_len(lua_State *L)
1338 {
1339     luaV_Funcref *f = (luaV_Funcref *) lua_touserdata(L, 1);
1340 
1341     lua_pushstring(L, (const char *) f->name);
1342     return 1;
1343 }
1344 
1345     static int
luaV_funcref_call(lua_State * L)1346 luaV_funcref_call(lua_State *L)
1347 {
1348     luaV_Funcref *f = (luaV_Funcref *) lua_touserdata(L, 1);
1349     int i, n = lua_gettop(L) - 1; // #args
1350     int status = FAIL;
1351     typval_T args;
1352     typval_T rettv;
1353 
1354     args.v_type = VAR_LIST;
1355     args.vval.v_list = list_alloc();
1356     rettv.v_type = VAR_UNKNOWN; // as in clear_tv
1357     if (args.vval.v_list != NULL)
1358     {
1359 	typval_T v;
1360 
1361 	for (i = 0; i < n; i++)
1362 	{
1363 	    luaV_checktypval(L, i + 2, &v, "calling funcref");
1364 	    list_append_tv(args.vval.v_list, &v);
1365 	    clear_tv(&v);
1366 	}
1367 	status = func_call(f->name, &args, NULL, f->self, &rettv);
1368 	if (status == OK)
1369 	    luaV_pushtypval(L, &rettv);
1370 	clear_tv(&args);
1371 	clear_tv(&rettv);
1372     }
1373     if (status != OK)
1374 	luaL_error(L, "cannot call funcref");
1375     return 1;
1376 }
1377 
1378 static const luaL_Reg luaV_Funcref_mt[] = {
1379     {"__tostring", luaV_funcref_tostring},
1380     {"__gc", luaV_funcref_gc},
1381     {"__len", luaV_funcref_len},
1382     {"__call", luaV_funcref_call},
1383     {NULL, NULL}
1384 };
1385 
1386 
1387 // =======   Buffer type   =======
1388 
luaV_newtype(buf_T,buffer,luaV_Buffer,LUAVIM_BUFFER)1389 luaV_newtype(buf_T, buffer, luaV_Buffer, LUAVIM_BUFFER)
1390 luaV_pushtype(buf_T, buffer, luaV_Buffer)
1391 luaV_type_tostring(buffer, LUAVIM_BUFFER)
1392 
1393     static int
1394 luaV_buffer_len(lua_State *L)
1395 {
1396     buf_T *b = (buf_T *) luaV_checkvalid(L, luaV_Buffer, 1);
1397     lua_pushinteger(L, b->b_ml.ml_line_count);
1398     return 1;
1399 }
1400 
1401     static int
luaV_buffer_call(lua_State * L)1402 luaV_buffer_call(lua_State *L)
1403 {
1404     buf_T *b = (buf_T *) luaV_checkvalid(L, luaV_Buffer, 1);
1405     lua_settop(L, 1);
1406     set_curbuf(b, DOBUF_SPLIT);
1407     return 1;
1408 }
1409 
1410     static int
luaV_buffer_index(lua_State * L)1411 luaV_buffer_index(lua_State *L)
1412 {
1413     buf_T *b = (buf_T *) luaV_checkvalid(L, luaV_Buffer, 1);
1414     linenr_T n = (linenr_T) lua_tointeger(L, 2);
1415     if (n > 0 && n <= b->b_ml.ml_line_count)
1416 	luaV_pushline(L, b, n);
1417     else if (lua_isstring(L, 2))
1418     {
1419 	const char *s = lua_tostring(L, 2);
1420 	if (strncmp(s, "name", 4) == 0)
1421 	    lua_pushstring(L, (b->b_sfname == NULL)
1422 					? "" : (char *) b->b_sfname);
1423 	else if (strncmp(s, "fname", 5) == 0)
1424 	    lua_pushstring(L, (b->b_ffname == NULL)
1425 					? "" : (char *) b->b_ffname);
1426 	else if (strncmp(s, "number", 6) == 0)
1427 	    lua_pushinteger(L, b->b_fnum);
1428 	// methods
1429 	else if (strncmp(s,   "insert", 6) == 0
1430 		|| strncmp(s, "next", 4) == 0
1431 		|| strncmp(s, "previous", 8) == 0
1432 		|| strncmp(s, "isvalid", 7) == 0)
1433 	{
1434 	    lua_getmetatable(L, 1);
1435 	    lua_getfield(L, -1, s);
1436 	}
1437 	else
1438 	    lua_pushnil(L);
1439     }
1440     else
1441 	lua_pushnil(L);
1442     return 1;
1443 }
1444 
1445     static int
luaV_buffer_newindex(lua_State * L)1446 luaV_buffer_newindex(lua_State *L)
1447 {
1448     buf_T *b = (buf_T *) luaV_checkvalid(L, luaV_Buffer, 1);
1449     linenr_T n = (linenr_T) luaL_checkinteger(L, 2);
1450 #ifdef HAVE_SANDBOX
1451     luaV_checksandbox(L);
1452 #endif
1453     if (n < 1 || n > b->b_ml.ml_line_count)
1454 	luaL_error(L, "invalid line number");
1455     if (lua_isnil(L, 3)) // delete line
1456     {
1457 	buf_T *buf = curbuf;
1458 	curbuf = b;
1459 	if (u_savedel(n, 1L) == FAIL)
1460 	{
1461 	    curbuf = buf;
1462 	    luaL_error(L, "cannot save undo information");
1463 	}
1464 	else if (ml_delete(n) == FAIL)
1465 	{
1466 	    curbuf = buf;
1467 	    luaL_error(L, "cannot delete line");
1468 	}
1469 	else
1470 	{
1471 	    deleted_lines_mark(n, 1L);
1472 	    if (b == curwin->w_buffer) // fix cursor in current window?
1473 	    {
1474 		if (curwin->w_cursor.lnum >= n)
1475 		{
1476 		    if (curwin->w_cursor.lnum > n)
1477 		    {
1478 			curwin->w_cursor.lnum -= 1;
1479 			check_cursor_col();
1480 		    }
1481 		    else
1482 			check_cursor();
1483 		    changed_cline_bef_curs();
1484 		}
1485 		invalidate_botline();
1486 	    }
1487 	}
1488 	curbuf = buf;
1489     }
1490     else if (lua_isstring(L, 3)) // update line
1491     {
1492 	buf_T *buf = curbuf;
1493 	curbuf = b;
1494 	if (u_savesub(n) == FAIL)
1495 	{
1496 	    curbuf = buf;
1497 	    luaL_error(L, "cannot save undo information");
1498 	}
1499 	else if (ml_replace(n, luaV_toline(L, 3), TRUE) == FAIL)
1500 	{
1501 	    curbuf = buf;
1502 	    luaL_error(L, "cannot replace line");
1503 	}
1504 	else changed_bytes(n, 0);
1505 	curbuf = buf;
1506 	if (b == curwin->w_buffer)
1507 	    check_cursor_col();
1508     }
1509     else
1510 	luaL_error(L, "wrong argument to change line");
1511     return 0;
1512 }
1513 
1514     static int
luaV_buffer_insert(lua_State * L)1515 luaV_buffer_insert(lua_State *L)
1516 {
1517     luaV_Buffer *lb = luaV_checkudata(L, 1, LUAVIM_BUFFER);
1518     buf_T *b = (buf_T *) luaV_checkcache(L, (void *) *lb);
1519     linenr_T last = b->b_ml.ml_line_count;
1520     linenr_T n = (linenr_T) luaL_optinteger(L, 3, last);
1521     buf_T *buf;
1522     luaL_checktype(L, 2, LUA_TSTRING);
1523 #ifdef HAVE_SANDBOX
1524     luaV_checksandbox(L);
1525 #endif
1526     // fix insertion line
1527     if (n < 0) n = 0;
1528     if (n > last) n = last;
1529     // insert
1530     buf = curbuf;
1531     curbuf = b;
1532     if (u_save(n, n + 1) == FAIL)
1533     {
1534 	curbuf = buf;
1535 	luaL_error(L, "cannot save undo information");
1536     }
1537     else if (ml_append(n, luaV_toline(L, 2), 0, FALSE) == FAIL)
1538     {
1539 	curbuf = buf;
1540 	luaL_error(L, "cannot insert line");
1541     }
1542     else
1543 	appended_lines_mark(n, 1L);
1544     curbuf = buf;
1545     update_screen(VALID);
1546     return 0;
1547 }
1548 
1549     static int
luaV_buffer_next(lua_State * L)1550 luaV_buffer_next(lua_State *L)
1551 {
1552     luaV_Buffer *b = luaV_checkudata(L, 1, LUAVIM_BUFFER);
1553     buf_T *buf = (buf_T *) luaV_checkcache(L, (void *) *b);
1554     luaV_pushbuffer(L, buf->b_next);
1555     return 1;
1556 }
1557 
1558     static int
luaV_buffer_previous(lua_State * L)1559 luaV_buffer_previous(lua_State *L)
1560 {
1561     luaV_Buffer *b = luaV_checkudata(L, 1, LUAVIM_BUFFER);
1562     buf_T *buf = (buf_T *) luaV_checkcache(L, (void *) *b);
1563     luaV_pushbuffer(L, buf->b_prev);
1564     return 1;
1565 }
1566 
1567     static int
luaV_buffer_isvalid(lua_State * L)1568 luaV_buffer_isvalid(lua_State *L)
1569 {
1570     luaV_Buffer *b = luaV_checkudata(L, 1, LUAVIM_BUFFER);
1571     luaV_getudata(L, *b);
1572     lua_pushboolean(L, !lua_isnil(L, -1));
1573     return 1;
1574 }
1575 
1576 static const luaL_Reg luaV_Buffer_mt[] = {
1577     {"__tostring", luaV_buffer_tostring},
1578     {"__len", luaV_buffer_len},
1579     {"__call", luaV_buffer_call},
1580     {"__index", luaV_buffer_index},
1581     {"__newindex", luaV_buffer_newindex},
1582     {"insert", luaV_buffer_insert},
1583     {"next", luaV_buffer_next},
1584     {"previous", luaV_buffer_previous},
1585     {"isvalid", luaV_buffer_isvalid},
1586     {NULL, NULL}
1587 };
1588 
1589 
1590 // =======   Window type   =======
1591 
luaV_newtype(win_T,window,luaV_Window,LUAVIM_WINDOW)1592 luaV_newtype(win_T, window, luaV_Window, LUAVIM_WINDOW)
1593 luaV_pushtype(win_T, window, luaV_Window)
1594 luaV_type_tostring(window, LUAVIM_WINDOW)
1595 
1596     static int
1597 luaV_window_call(lua_State *L)
1598 {
1599     win_T *w = (win_T *) luaV_checkvalid(L, luaV_Window, 1);
1600     lua_settop(L, 1);
1601     win_goto(w);
1602     return 1;
1603 }
1604 
1605     static int
luaV_window_index(lua_State * L)1606 luaV_window_index(lua_State *L)
1607 {
1608     win_T *w = (win_T *) luaV_checkvalid(L, luaV_Window, 1);
1609     const char *s = luaL_checkstring(L, 2);
1610     if (strncmp(s, "buffer", 6) == 0)
1611 	luaV_pushbuffer(L, w->w_buffer);
1612     else if (strncmp(s, "line", 4) == 0)
1613 	lua_pushinteger(L, w->w_cursor.lnum);
1614     else if (strncmp(s, "col", 3) == 0)
1615 	lua_pushinteger(L, w->w_cursor.col + 1);
1616     else if (strncmp(s, "width", 5) == 0)
1617 	lua_pushinteger(L, w->w_width);
1618     else if (strncmp(s, "height", 6) == 0)
1619 	lua_pushinteger(L, w->w_height);
1620     // methods
1621     else if (strncmp(s,   "next", 4) == 0
1622 	    || strncmp(s, "previous", 8) == 0
1623 	    || strncmp(s, "isvalid", 7) == 0)
1624     {
1625 	lua_getmetatable(L, 1);
1626 	lua_getfield(L, -1, s);
1627     }
1628     else
1629 	lua_pushnil(L);
1630     return 1;
1631 }
1632 
1633     static int
luaV_window_newindex(lua_State * L)1634 luaV_window_newindex(lua_State *L)
1635 {
1636     win_T *w = (win_T *) luaV_checkvalid(L, luaV_Window, 1);
1637     const char *s = luaL_checkstring(L, 2);
1638     int v = luaL_checkinteger(L, 3);
1639     if (strncmp(s, "line", 4) == 0)
1640     {
1641 #ifdef HAVE_SANDBOX
1642 	luaV_checksandbox(L);
1643 #endif
1644 	if (v < 1 || v > w->w_buffer->b_ml.ml_line_count)
1645 	    luaL_error(L, "line out of range");
1646 	w->w_cursor.lnum = v;
1647 	update_screen(VALID);
1648     }
1649     else if (strncmp(s, "col", 3) == 0)
1650     {
1651 #ifdef HAVE_SANDBOX
1652 	luaV_checksandbox(L);
1653 #endif
1654 	w->w_cursor.col = v - 1;
1655 	w->w_set_curswant = TRUE;
1656 	update_screen(VALID);
1657     }
1658     else if (strncmp(s, "width", 5) == 0)
1659     {
1660 	win_T *win = curwin;
1661 #ifdef FEAT_GUI
1662 	need_mouse_correct = TRUE;
1663 #endif
1664 	curwin = w;
1665 	win_setwidth(v);
1666 	curwin = win;
1667     }
1668     else if (strncmp(s, "height", 6) == 0)
1669     {
1670 	win_T *win = curwin;
1671 #ifdef FEAT_GUI
1672 	need_mouse_correct = TRUE;
1673 #endif
1674 	curwin = w;
1675 	win_setheight(v);
1676 	curwin = win;
1677     }
1678     else
1679 	luaL_error(L, "invalid window property: `%s'", s);
1680     return 0;
1681 }
1682 
1683     static int
luaV_window_next(lua_State * L)1684 luaV_window_next(lua_State *L)
1685 {
1686     luaV_Window *w = luaV_checkudata(L, 1, LUAVIM_WINDOW);
1687     win_T *win = (win_T *) luaV_checkcache(L, (void *) *w);
1688     luaV_pushwindow(L, win->w_next);
1689     return 1;
1690 }
1691 
1692     static int
luaV_window_previous(lua_State * L)1693 luaV_window_previous(lua_State *L)
1694 {
1695     luaV_Window *w = luaV_checkudata(L, 1, LUAVIM_WINDOW);
1696     win_T *win = (win_T *) luaV_checkcache(L, (void *) *w);
1697     luaV_pushwindow(L, win->w_prev);
1698     return 1;
1699 }
1700 
1701     static int
luaV_window_isvalid(lua_State * L)1702 luaV_window_isvalid(lua_State *L)
1703 {
1704     luaV_Window *w = luaV_checkudata(L, 1, LUAVIM_WINDOW);
1705     luaV_getudata(L, *w);
1706     lua_pushboolean(L, !lua_isnil(L, -1));
1707     return 1;
1708 }
1709 
1710 static const luaL_Reg luaV_Window_mt[] = {
1711     {"__tostring", luaV_window_tostring},
1712     {"__call", luaV_window_call},
1713     {"__index", luaV_window_index},
1714     {"__newindex", luaV_window_newindex},
1715     {"next", luaV_window_next},
1716     {"previous", luaV_window_previous},
1717     {"isvalid", luaV_window_isvalid},
1718     {NULL, NULL}
1719 };
1720 
1721 
1722 // =======   Vim module   =======
1723 
1724     static int
luaV_print(lua_State * L)1725 luaV_print(lua_State *L)
1726 {
1727     int		i, n = lua_gettop(L); // nargs
1728     const char	*s;
1729     size_t	l;
1730     garray_T	msg_ga;
1731 
1732     ga_init2(&msg_ga, 1, 128);
1733     lua_getglobal(L, "tostring");
1734     for (i = 1; i <= n; i++)
1735     {
1736 	lua_pushvalue(L, -1); // tostring
1737 	lua_pushvalue(L, i); // arg
1738 	lua_call(L, 1, 1);
1739 	s = lua_tolstring(L, -1, &l);
1740 	if (s == NULL)
1741 	    return luaL_error(L, "cannot convert to string");
1742 	if (i > 1)
1743 	    ga_append(&msg_ga, ' '); // use space instead of tab
1744 	ga_concat_len(&msg_ga, (char_u *)s, l);
1745 	lua_pop(L, 1);
1746     }
1747     // Replace any "\n" with "\0"
1748     for (i = 0; i < msg_ga.ga_len; i++)
1749 	if (((char *)msg_ga.ga_data)[i] == '\n')
1750 	    ((char *)msg_ga.ga_data)[i] = '\0';
1751     lua_pushlstring(L, msg_ga.ga_data, msg_ga.ga_len);
1752     if (!got_int)
1753 	luaV_msg(L);
1754 
1755     ga_clear(&msg_ga);
1756     return 0;
1757 }
1758 
1759     static int
luaV_debug(lua_State * L)1760 luaV_debug(lua_State *L)
1761 {
1762     lua_settop(L, 0);
1763     lua_getglobal(L, "vim");
1764     lua_getfield(L, -1, "eval");
1765     lua_remove(L, -2); // vim.eval at position 1
1766     for (;;)
1767     {
1768 	const char *input;
1769 	size_t l;
1770 	lua_pushvalue(L, 1); // vim.eval
1771 	lua_pushliteral(L, "input('lua_debug> ')");
1772 	lua_call(L, 1, 1); // return string
1773 	input = lua_tolstring(L, -1, &l);
1774 	if (l == 0 || strcmp(input, "cont") == 0)
1775 	    return 0;
1776 	msg_putchar('\n'); // avoid outputting on input line
1777 	if (luaL_loadbuffer(L, input, l, "=(debug command)")
1778 		|| lua_pcall(L, 0, 0, 0))
1779 	    luaV_emsg(L);
1780 	lua_settop(L, 1); // remove eventual returns, but keep vim.eval
1781     }
1782 }
1783 
1784     static dict_T *
luaV_get_var_scope(lua_State * L)1785 luaV_get_var_scope(lua_State *L)
1786 {
1787     const char	*scope = luaL_checkstring(L, 1);
1788     dict_T	*dict = NULL;
1789 
1790     if (STRICMP((char *)scope, "g") == 0)
1791 	dict = get_globvar_dict();
1792     else if (STRICMP((char *)scope, "v") == 0)
1793 	dict = get_vimvar_dict();
1794     else if (STRICMP((char *)scope, "b") == 0)
1795 	dict = curbuf->b_vars;
1796     else if (STRICMP((char *)scope, "w") == 0)
1797 	dict = curwin->w_vars;
1798     else if (STRICMP((char *)scope, "t") == 0)
1799 	dict = curtab->tp_vars;
1800     else
1801     {
1802 	luaL_error(L, "invalid scope %s", scope);
1803 	return NULL;
1804     }
1805 
1806     return dict;
1807 }
1808 
1809     static int
luaV_setvar(lua_State * L)1810 luaV_setvar(lua_State *L)
1811 {
1812     dict_T	*dict;
1813     dictitem_T	*di;
1814     size_t	len;
1815     char	*name;
1816     int		del;
1817     char	*error = NULL;
1818 
1819     name = (char *)luaL_checklstring(L, 3, &len);
1820     del = (lua_gettop(L) < 4) || lua_isnil(L, 4);
1821 
1822     dict = luaV_get_var_scope(L);
1823     if (dict == NULL)
1824 	return 0;
1825 
1826     di = dict_find(dict, (char_u *)name, (int)len);
1827     if (di != NULL)
1828     {
1829 	if (di->di_flags & DI_FLAGS_RO)
1830 	    error = "variable is read-only";
1831 	else if (di->di_flags & DI_FLAGS_LOCK)
1832 	    error = "variable is locked";
1833 	else if (del && di->di_flags & DI_FLAGS_FIX)
1834 	    error = "variable is fixed";
1835 	if (error != NULL)
1836 	    return luaL_error(L, error);
1837     }
1838     else if (dict->dv_lock)
1839 	return luaL_error(L, "Dictionary is locked");
1840 
1841     if (del)
1842     {
1843 	// Delete the key
1844 	if (di == NULL)
1845 	    // Doesn't exist, nothing to do
1846 	    return 0;
1847 	else
1848 	    // Delete the entry
1849 	    dictitem_remove(dict, di);
1850     }
1851     else
1852     {
1853 	// Update the key
1854 	typval_T	tv;
1855 
1856 	// Convert the lua value to a Vim script type in the temporary variable
1857 	lua_pushvalue(L, 4);
1858 	if (luaV_totypval(L, -1, &tv) == FAIL)
1859 	    return luaL_error(L, "Couldn't convert lua value");
1860 
1861 	if (di == NULL)
1862 	{
1863 	    // Need to create an entry
1864 	    di = dictitem_alloc((char_u *)name);
1865 	    if (di == NULL)
1866 	    {
1867 		clear_tv(&tv);
1868 		return 0;
1869 	    }
1870 	    // Update the value
1871 	    copy_tv(&tv, &di->di_tv);
1872 	    if (dict_add(dict, di) == FAIL)
1873 	    {
1874 		dictitem_free(di);
1875 		clear_tv(&tv);
1876 		return luaL_error(L, "Couldn't add to dictionary");
1877 	    }
1878 	}
1879 	else
1880 	{
1881 	    // Clear the old value
1882 	    clear_tv(&di->di_tv);
1883 	    // Update the value
1884 	    copy_tv(&tv, &di->di_tv);
1885 	}
1886 
1887 	// Clear the temporary variable
1888 	clear_tv(&tv);
1889     }
1890 
1891     return 0;
1892 }
1893 
1894     static int
luaV_getvar(lua_State * L)1895 luaV_getvar(lua_State *L)
1896 {
1897     dict_T	*dict = luaV_get_var_scope(L);
1898     size_t	len;
1899     const char	*name = luaL_checklstring(L, 3, &len);
1900     dictitem_T	*di = dict_find(dict, (char_u *)name, (int)len);
1901 
1902     if (di == NULL)
1903 	return 0;  // nil
1904 
1905     luaV_pushtypval(L, &di->di_tv);
1906     return 1;
1907 }
1908 
1909     static int
luaV_command(lua_State * L)1910 luaV_command(lua_State *L)
1911 {
1912     char_u  *s = vim_strsave((char_u *)luaL_checkstring(L, 1));
1913 
1914     execute_cmds_from_string(s);
1915     vim_free(s);
1916     update_screen(VALID);
1917     return 0;
1918 }
1919 
1920     static int
luaV_eval(lua_State * L)1921 luaV_eval(lua_State *L)
1922 {
1923     typval_T *tv = eval_expr((char_u *) luaL_checkstring(L, 1), NULL);
1924 
1925     if (tv == NULL) luaL_error(L, "invalid expression");
1926     luaV_pushtypval(L, tv);
1927     free_tv(tv);
1928     return 1;
1929 }
1930 
1931     static int
luaV_beep(lua_State * L UNUSED)1932 luaV_beep(lua_State *L UNUSED)
1933 {
1934     vim_beep(BO_LANG);
1935     return 0;
1936 }
1937 
1938     static int
luaV_line(lua_State * L)1939 luaV_line(lua_State *L)
1940 {
1941     luaV_pushline(L, curbuf, curwin->w_cursor.lnum);
1942     return 1;
1943 }
1944 
1945     static int
luaV_list(lua_State * L)1946 luaV_list(lua_State *L)
1947 {
1948     list_T *l;
1949     int initarg = !lua_isnoneornil(L, 1);
1950 
1951     if (initarg && lua_type(L, 1) != LUA_TTABLE)
1952 	luaL_error(L, "table expected, got %s", luaL_typename(L, 1));
1953     l = list_alloc();
1954     if (l == NULL)
1955 	lua_pushnil(L);
1956     else
1957     {
1958 	luaV_newlist(L, l);
1959 	if (initarg) // traverse table to init list
1960 	{
1961 	    int notnil, i = 0;
1962 	    typval_T v;
1963 	    do
1964 	    {
1965 		lua_rawgeti(L, 1, ++i);
1966 		notnil = !lua_isnil(L, -1);
1967 		if (notnil)
1968 		{
1969 		    luaV_checktypval(L, -1, &v, "vim.list");
1970 		    list_append_tv(l, &v);
1971 		    clear_tv(&v);
1972 		}
1973 		lua_pop(L, 1); // value
1974 	    } while (notnil);
1975 	}
1976     }
1977     return 1;
1978 }
1979 
1980     static int
luaV_dict(lua_State * L)1981 luaV_dict(lua_State *L)
1982 {
1983     dict_T *d;
1984     int initarg = !lua_isnoneornil(L, 1);
1985 
1986     if (initarg && lua_type(L, 1) != LUA_TTABLE)
1987 	luaL_error(L, "table expected, got %s", luaL_typename(L, 1));
1988     d = dict_alloc();
1989     if (d == NULL)
1990 	lua_pushnil(L);
1991     else
1992     {
1993 	luaV_newdict(L, d);
1994 	if (initarg) // traverse table to init dict
1995 	{
1996 	    lua_pushnil(L);
1997 	    while (lua_next(L, 1))
1998 	    {
1999 		char_u *key;
2000 		dictitem_T *di;
2001 		typval_T v;
2002 
2003 		lua_pushvalue(L, -2); // dup key in case it's a number
2004 		key = (char_u *) lua_tostring(L, -1);
2005 		if (key == NULL)
2006 		{
2007 		    lua_pushnil(L);
2008 		    return 1;
2009 		}
2010 		if (*key == NUL)
2011 		    luaL_error(L, "table has empty key");
2012 		luaV_checktypval(L, -2, &v, "vim.dict"); // value
2013 		di = dictitem_alloc(key);
2014 		if (di == NULL || dict_add(d, di) == FAIL)
2015 		{
2016 		    vim_free(di);
2017 		    lua_pushnil(L);
2018 		    return 1;
2019 		}
2020 		di->di_tv = v;
2021 		lua_pop(L, 2); // key copy and value
2022 	    }
2023 	}
2024     }
2025     return 1;
2026 }
2027 
2028     static int
luaV_blob(lua_State * L)2029 luaV_blob(lua_State *L)
2030 {
2031     blob_T *b;
2032     int initarg = !lua_isnoneornil(L, 1);
2033 
2034     if (initarg && !lua_isstring(L, 1))
2035 	luaL_error(L, "string expected, got %s", luaL_typename(L, 1));
2036     b = blob_alloc();
2037     if (b == NULL)
2038 	lua_pushnil(L);
2039     else
2040     {
2041 	luaV_newblob(L, b);
2042 	if (initarg)
2043 	{
2044 	    size_t i, l = 0;
2045 	    const char *s = lua_tolstring(L, 1, &l);
2046 
2047 	    if (ga_grow(&b->bv_ga, (int)l) == OK)
2048 		for (i = 0; i < l; ++i)
2049 		    ga_append(&b->bv_ga, s[i]);
2050 	}
2051     }
2052     return 1;
2053 }
2054 
2055     static int
luaV_funcref(lua_State * L)2056 luaV_funcref(lua_State *L)
2057 {
2058     const char *name = luaL_checkstring(L, 1);
2059     // note: not checking if function exists (needs function_exists)
2060     if (name == NULL || *name == NUL || VIM_ISDIGIT(*name))
2061 	luaL_error(L, "invalid function name: %s", name);
2062     luaV_newfuncref(L, (char_u *) name);
2063     return 1;
2064 }
2065 
2066     static int
luaV_buffer(lua_State * L)2067 luaV_buffer(lua_State *L)
2068 {
2069     buf_T *buf;
2070     if (lua_isstring(L, 1)) // get by number or name?
2071     {
2072 	if (lua_isnumber(L, 1)) // by number?
2073 	{
2074 	    int n = lua_tointeger(L, 1);
2075 	    FOR_ALL_BUFFERS(buf)
2076 		if (buf->b_fnum == n) break;
2077 	}
2078 	else // by name
2079 	{
2080 	    size_t l;
2081 	    const char *s = lua_tolstring(L, 1, &l);
2082 	    FOR_ALL_BUFFERS(buf)
2083 	    {
2084 		if (buf->b_ffname == NULL || buf->b_sfname == NULL)
2085 		{
2086 		    if (l == 0) break;
2087 		}
2088 		else if (strncmp(s, (char *)buf->b_ffname, l) == 0
2089 			|| strncmp(s, (char *)buf->b_sfname, l) == 0)
2090 		    break;
2091 	    }
2092 	}
2093     }
2094     else
2095 	buf = (lua_toboolean(L, 1)) ? firstbuf : curbuf; // first buffer?
2096     luaV_pushbuffer(L, buf);
2097     return 1;
2098 }
2099 
2100     static int
luaV_window(lua_State * L)2101 luaV_window(lua_State *L)
2102 {
2103     win_T *win;
2104     if (lua_isnumber(L, 1)) // get by number?
2105     {
2106 	int n = lua_tointeger(L, 1);
2107 	for (win = firstwin; win != NULL; win = win->w_next, n--)
2108 	    if (n == 1) break;
2109     }
2110     else
2111 	win = (lua_toboolean(L, 1)) ? firstwin : curwin; // first window?
2112     luaV_pushwindow(L, win);
2113     return 1;
2114 }
2115 
2116     static int
luaV_open(lua_State * L)2117 luaV_open(lua_State *L)
2118 {
2119     char_u *s = NULL;
2120 #ifdef HAVE_SANDBOX
2121     luaV_checksandbox(L);
2122 #endif
2123     if (lua_isstring(L, 1)) s = (char_u *) lua_tostring(L, 1);
2124     luaV_pushbuffer(L, buflist_new(s, NULL, 1L, BLN_LISTED));
2125     return 1;
2126 }
2127 
2128     static int
luaV_type(lua_State * L)2129 luaV_type(lua_State *L)
2130 {
2131     luaL_checkany(L, 1);
2132     if (lua_type(L, 1) == LUA_TUSERDATA) // check vim udata?
2133     {
2134 	lua_settop(L, 1);
2135 	if (lua_getmetatable(L, 1))
2136 	{
2137 	    luaV_getfield(L, LUAVIM_LIST);
2138 	    if (lua_rawequal(L, -1, 2))
2139 	    {
2140 		lua_pushstring(L, "list");
2141 		return 1;
2142 	    }
2143 	    luaV_getfield(L, LUAVIM_DICT);
2144 	    if (lua_rawequal(L, -1, 2))
2145 	    {
2146 		lua_pushstring(L, "dict");
2147 		return 1;
2148 	    }
2149 	    luaV_getfield(L, LUAVIM_BLOB);
2150 	    if (lua_rawequal(L, -1, 2))
2151 	    {
2152 		lua_pushstring(L, "blob");
2153 		return 1;
2154 	    }
2155 	    luaV_getfield(L, LUAVIM_FUNCREF);
2156 	    if (lua_rawequal(L, -1, 2))
2157 	    {
2158 		lua_pushstring(L, "funcref");
2159 		return 1;
2160 	    }
2161 	    luaV_getfield(L, LUAVIM_BUFFER);
2162 	    if (lua_rawequal(L, -1, 2))
2163 	    {
2164 		lua_pushstring(L, "buffer");
2165 		return 1;
2166 	    }
2167 	    luaV_getfield(L, LUAVIM_WINDOW);
2168 	    if (lua_rawequal(L, -1, 2))
2169 	    {
2170 		lua_pushstring(L, "window");
2171 		return 1;
2172 	    }
2173 	}
2174     }
2175     lua_pushstring(L, luaL_typename(L, 1)); // fallback
2176     return 1;
2177 }
2178 
2179     static int
luaV_call(lua_State * L)2180 luaV_call(lua_State *L)
2181 {
2182     int		argc = lua_gettop(L) - 1;
2183     size_t	funcname_len;
2184     char_u	*funcname;
2185     char	*error = NULL;
2186     typval_T	rettv;
2187     typval_T	argv[MAX_FUNC_ARGS + 1];
2188     int		i = 0;
2189 
2190     if (argc > MAX_FUNC_ARGS)
2191 	return luaL_error(L, "Function called with too many arguments");
2192 
2193     funcname = (char_u *)luaL_checklstring(L, 1, &funcname_len);
2194 
2195     for (; i < argc; i++)
2196     {
2197 	if (luaV_totypval(L, i + 2, &argv[i]) == FAIL)
2198 	{
2199 	    error = "lua: cannot convert value";
2200 	    goto free_vim_args;
2201 	}
2202     }
2203 
2204     argv[argc].v_type = VAR_UNKNOWN;
2205 
2206     if (call_vim_function(funcname, argc, argv, &rettv) == FAIL)
2207     {
2208 	error = "lua: call_vim_function failed";
2209 	goto free_vim_args;
2210     }
2211 
2212     luaV_pushtypval(L, &rettv);
2213     clear_tv(&rettv);
2214 
2215 free_vim_args:
2216     while (i > 0)
2217 	clear_tv(&argv[--i]);
2218 
2219     if (error == NULL)
2220 	return 1;
2221     else
2222 	return luaL_error(L, error);
2223 }
2224 
2225 /*
2226  * Return the Vim version as a Lua table
2227  */
2228     static int
luaV_version(lua_State * L)2229 luaV_version(lua_State *L)
2230 {
2231     lua_newtable(L);
2232     lua_pushstring(L, "major");
2233     lua_pushinteger(L, VIM_VERSION_MAJOR);
2234     lua_settable(L, -3);
2235     lua_pushstring(L, "minor");
2236     lua_pushinteger(L, VIM_VERSION_MINOR);
2237     lua_settable(L, -3);
2238     lua_pushstring(L, "patch");
2239     lua_pushinteger(L, highest_patch());
2240     lua_settable(L, -3);
2241     return 1;
2242 }
2243 
2244 static const luaL_Reg luaV_module[] = {
2245     {"command", luaV_command},
2246     {"eval", luaV_eval},
2247     {"beep", luaV_beep},
2248     {"line", luaV_line},
2249     {"list", luaV_list},
2250     {"dict", luaV_dict},
2251     {"blob", luaV_blob},
2252     {"funcref", luaV_funcref},
2253     {"buffer", luaV_buffer},
2254     {"window", luaV_window},
2255     {"open", luaV_open},
2256     {"type", luaV_type},
2257     {"call", luaV_call},
2258     {"_getvar", luaV_getvar},
2259     {"_setvar", luaV_setvar},
2260     {"version", luaV_version},
2261     {"lua_version", NULL},
2262     {NULL, NULL}
2263 };
2264 
2265 /*
2266  * for freeing list, dict, buffer and window objects; lightuserdata as arg
2267  */
2268     static int
luaV_free(lua_State * L)2269 luaV_free(lua_State *L)
2270 {
2271     lua_pushnil(L);
2272     luaV_setudata(L, lua_touserdata(L, 1));
2273     return 0;
2274 }
2275 
2276     static int
luaV_luaeval(lua_State * L)2277 luaV_luaeval(lua_State *L)
2278 {
2279     luaL_Buffer b;
2280     size_t l;
2281     const char *str = lua_tolstring(L, 1, &l);
2282     typval_T *arg = (typval_T *) lua_touserdata(L, 2);
2283     typval_T *rettv = (typval_T *) lua_touserdata(L, 3);
2284     luaL_buffinit(L, &b);
2285     luaL_addlstring(&b, LUAVIM_EVALHEADER, sizeof(LUAVIM_EVALHEADER) - 1);
2286     luaL_addlstring(&b, str, l);
2287     luaL_pushresult(&b);
2288     str = lua_tolstring(L, -1, &l);
2289     if (luaL_loadbuffer(L, str, l, LUAVIM_EVALNAME)) // compile error?
2290     {
2291 	luaV_emsg(L);
2292 	return 0;
2293     }
2294     luaV_pushtypval(L, arg);
2295     if (lua_pcall(L, 1, 1, 0)) // running error?
2296     {
2297 	luaV_emsg(L);
2298 	return 0;
2299     }
2300     if (luaV_totypval(L, -1, rettv) == FAIL)
2301 	emsg("luaeval: cannot convert value");
2302     return 0;
2303 }
2304 
2305     static int
luaV_setref(lua_State * L)2306 luaV_setref(lua_State *L)
2307 {
2308     int copyID = lua_tointeger(L, 1);
2309     int abort = FALSE;
2310 
2311     luaV_getfield(L, LUAVIM_LIST);
2312     luaV_getfield(L, LUAVIM_DICT);
2313     luaV_getfield(L, LUAVIM_FUNCREF);
2314     lua_pushnil(L);
2315     // traverse cache table
2316     while (!abort && lua_next(L, lua_upvalueindex(1)) != 0)
2317     {
2318 	lua_getmetatable(L, -1);
2319 	if (lua_rawequal(L, -1, 2)) // list?
2320 	{
2321 	    list_T *l = (list_T *)lua_touserdata(L, 5); // key
2322 
2323 	    abort = set_ref_in_list(l, copyID);
2324 	}
2325 	else if (lua_rawequal(L, -1, 3)) // dict?
2326 	{
2327 	    dict_T *d = (dict_T *)lua_touserdata(L, 5); // key
2328 
2329 	    abort = set_ref_in_dict(d, copyID);
2330 	}
2331 	else if (lua_rawequal(L, -1, 4)) // funcref?
2332 	{
2333 	    luaV_Funcref *f = (luaV_Funcref *)lua_touserdata(L, 5); // key
2334 
2335 	    abort = set_ref_in_dict(f->self, copyID);
2336 	}
2337 	lua_pop(L, 2); // metatable and value
2338     }
2339     lua_pushinteger(L, abort);
2340     return 1;
2341 }
2342 
2343     static int
luaV_pushversion(lua_State * L)2344 luaV_pushversion(lua_State *L)
2345 {
2346     int major = 0;
2347     int minor = 0;
2348     int patch = 0;
2349     char s[16];
2350 
2351     sscanf(LUAVIM_VERSION, "Lua %d.%d.%d", &major, &minor, &patch);
2352     vim_snprintf(s, sizeof(s), "%d.%d.%d", major, minor, patch);
2353     lua_pushstring(L, s);
2354     return 0;
2355 }
2356 
2357 #define LUA_VIM_FN_CODE \
2358     "vim.fn = setmetatable({}, {\n"\
2359     "  __index = function (t, key)\n"\
2360     "    local function _fn(...)\n"\
2361     "      return vim.call(key, ...)\n"\
2362     "    end\n"\
2363     "    t[key] = _fn\n"\
2364     "    return _fn\n"\
2365     "  end\n"\
2366     " })"
2367 
2368 #define LUA_VIM_UPDATE_PACKAGE_PATHS \
2369     "local last_vim_paths = {}\n"\
2370     "vim._update_package_paths = function ()\n"\
2371     "  local cur_vim_paths = {}\n"\
2372     "  local function split(s, delimiter)\n"\
2373     "    result = {}\n"\
2374     "    for match in (s..delimiter):gmatch(\"(.-)\"..delimiter) do\n"\
2375     "      table.insert(result, match)\n"\
2376     "    end\n"\
2377     "    return result\n"\
2378     "  end\n"\
2379     "  local rtps = split(vim.eval('&runtimepath'), ',')\n"\
2380     "  local sep = package.config:sub(1, 1)\n"\
2381     "  for _, key in ipairs({'path', 'cpath'}) do\n"\
2382     "    local orig_str = package[key] .. ';'\n"\
2383     "    local pathtrails_ordered = {}\n"\
2384     "    -- Note: ignores trailing item without trailing `;`. Not using something\n"\
2385     "    -- simpler in order to preserve empty items (stand for default path).\n"\
2386     "    local orig = {}\n"\
2387     "    for s in orig_str:gmatch('[^;]*;') do\n"\
2388     "      s = s:sub(1, -2)  -- Strip trailing semicolon\n"\
2389     "      orig[#orig + 1] = s\n"\
2390     "    end\n"\
2391     "    if key == 'path' then\n"\
2392     "      -- /?.lua and /?/init.lua\n"\
2393     "      pathtrails_ordered = {sep .. '?.lua', sep .. '?' .. sep .. 'init.lua'}\n"\
2394     "    else\n"\
2395     "      local pathtrails = {}\n"\
2396     "      for _, s in ipairs(orig) do\n"\
2397     "        -- Find out path patterns. pathtrail should contain something like\n"\
2398     "        -- /?.so, \?.dll. This allows not to bother determining what correct\n"\
2399     "        -- suffixes are.\n"\
2400     "        local pathtrail = s:match('[/\\\\][^/\\\\]*%?.*$')\n"\
2401     "        if pathtrail and not pathtrails[pathtrail] then\n"\
2402     "          pathtrails[pathtrail] = true\n"\
2403     "          pathtrails_ordered[#pathtrails_ordered + 1] = pathtrail\n"\
2404     "        end\n"\
2405     "      end\n"\
2406     "    end\n"\
2407     "    local new = {}\n"\
2408     "    for _, rtp in ipairs(rtps) do\n"\
2409     "      if not rtp:match(';') then\n"\
2410     "        for _, pathtrail in pairs(pathtrails_ordered) do\n"\
2411     "          local new_path = rtp .. sep .. 'lua' .. pathtrail\n"\
2412     "          -- Always keep paths from &runtimepath at the start:\n"\
2413     "          -- append them here disregarding orig possibly containing one of them.\n"\
2414     "          new[#new + 1] = new_path\n"\
2415     "          cur_vim_paths[new_path] = true\n"\
2416     "        end\n"\
2417     "      end\n"\
2418     "    end\n"\
2419     "    for _, orig_path in ipairs(orig) do\n"\
2420     "      -- Handle removing obsolete paths originating from &runtimepath: such\n"\
2421     "      -- paths either belong to cur_nvim_paths and were already added above or\n"\
2422     "      -- to last_nvim_paths and should not be added at all if corresponding\n"\
2423     "      -- entry was removed from &runtimepath list.\n"\
2424     "      if not (cur_vim_paths[orig_path] or last_vim_paths[orig_path]) then\n"\
2425     "        new[#new + 1] = orig_path\n"\
2426     "      end\n"\
2427     "    end\n"\
2428     "    package[key] = table.concat(new, ';')\n"\
2429     "  end\n"\
2430     "  last_vim_paths = cur_vim_paths\n"\
2431     "end"
2432 
2433 #define LUA_VIM_SETUP_VARIABLE_DICTS \
2434     "do\n"\
2435     "  local function make_dict_accessor(scope)\n"\
2436     "    local mt = {}\n"\
2437     "    function mt:__newindex(k, v)\n"\
2438     "      return vim._setvar(scope, 0, k, v)\n"\
2439     "    end\n"\
2440     "    function mt:__index(k)\n"\
2441     "      return vim._getvar(scope, 0, k)\n"\
2442     "    end\n"\
2443     "    return setmetatable({}, mt)\n"\
2444     "  end\n"\
2445     "  vim.g = make_dict_accessor('g')\n"\
2446     "  vim.v = make_dict_accessor('v')\n"\
2447     "  vim.b = make_dict_accessor('b')\n"\
2448     "  vim.w = make_dict_accessor('w')\n"\
2449     "  vim.t = make_dict_accessor('t')\n"\
2450     "end"
2451 
2452     static int
luaopen_vim(lua_State * L)2453 luaopen_vim(lua_State *L)
2454 {
2455     // set cache table
2456     lua_newtable(L);
2457     lua_newtable(L);
2458     lua_pushstring(L, "v");
2459     lua_setfield(L, -2, "__mode");
2460     lua_setmetatable(L, -2); // cache is weak-valued
2461     // print
2462     lua_pushcfunction(L, luaV_print);
2463     lua_setglobal(L, "print");
2464     // debug.debug
2465     lua_getglobal(L, "debug");
2466     lua_pushcfunction(L, luaV_debug);
2467     lua_setfield(L, -2, "debug");
2468     lua_pop(L, 1);
2469     // free
2470     lua_pushlightuserdata(L, (void *) LUAVIM_FREE);
2471     lua_pushvalue(L, 1); // cache table
2472     lua_pushcclosure(L, luaV_free, 1);
2473     lua_rawset(L, LUA_REGISTRYINDEX);
2474     // luaeval
2475     lua_pushlightuserdata(L, (void *) LUAVIM_LUAEVAL);
2476     lua_pushvalue(L, 1); // cache table
2477     lua_pushcclosure(L, luaV_luaeval, 1);
2478     lua_rawset(L, LUA_REGISTRYINDEX);
2479     // setref
2480     lua_pushlightuserdata(L, (void *) LUAVIM_SETREF);
2481     lua_pushvalue(L, 1); // cache table
2482     lua_pushcclosure(L, luaV_setref, 1);
2483     lua_rawset(L, LUA_REGISTRYINDEX);
2484     // register
2485     luaV_newmetatable(L, LUAVIM_LIST);
2486     lua_pushvalue(L, 1);
2487     luaV_openlib(L, luaV_List_mt, 1);
2488     luaV_newmetatable(L, LUAVIM_DICT);
2489     lua_pushvalue(L, 1);
2490     luaV_openlib(L, luaV_Dict_mt, 1);
2491     luaV_newmetatable(L, LUAVIM_BLOB);
2492     lua_pushvalue(L, 1);
2493     luaV_openlib(L, luaV_Blob_mt, 1);
2494     luaV_newmetatable(L, LUAVIM_FUNCREF);
2495     lua_pushvalue(L, 1);
2496     luaV_openlib(L, luaV_Funcref_mt, 1);
2497     luaV_newmetatable(L, LUAVIM_BUFFER);
2498     lua_pushvalue(L, 1); // cache table
2499     luaV_openlib(L, luaV_Buffer_mt, 1);
2500     luaV_newmetatable(L, LUAVIM_WINDOW);
2501     lua_pushvalue(L, 1); // cache table
2502     luaV_openlib(L, luaV_Window_mt, 1);
2503     lua_newtable(L); // vim table
2504     lua_pushvalue(L, 1); // cache table
2505     luaV_openlib(L, luaV_module, 1);
2506     luaV_pushversion(L);
2507     lua_setfield(L, -2, "lua_version");
2508     lua_setglobal(L, LUAVIM_NAME);
2509     // custom code
2510     (void)luaL_dostring(L, LUA_VIM_FN_CODE);
2511     (void)luaL_dostring(L, LUA_VIM_UPDATE_PACKAGE_PATHS);
2512     (void)luaL_dostring(L, LUA_VIM_SETUP_VARIABLE_DICTS);
2513 
2514     lua_getglobal(L, "vim");
2515     lua_getfield(L, -1, "_update_package_paths");
2516 
2517     if (lua_pcall(L, 0, 0, 0))
2518 	luaV_emsg(L);
2519 
2520     return 0;
2521 }
2522 
2523     static lua_State *
luaV_newstate(void)2524 luaV_newstate(void)
2525 {
2526     lua_State *L = luaL_newstate();
2527     luaL_openlibs(L); // core libs
2528     lua_pushcfunction(L, luaopen_vim); // vim
2529     lua_call(L, 0, 0);
2530     return L;
2531 }
2532 
2533     static void
luaV_setrange(lua_State * L,int line1,int line2)2534 luaV_setrange(lua_State *L, int line1, int line2)
2535 {
2536     lua_getglobal(L, LUAVIM_NAME);
2537     lua_pushinteger(L, line1);
2538     lua_setfield(L, -2, "firstline");
2539     lua_pushinteger(L, line2);
2540     lua_setfield(L, -2, "lastline");
2541     lua_pop(L, 1); // vim table
2542 }
2543 
2544 
2545 // =======   Interface   =======
2546 
2547 static lua_State *L = NULL;
2548 
2549     static int
lua_isopen(void)2550 lua_isopen(void)
2551 {
2552     return L != NULL;
2553 }
2554 
2555     static int
lua_init(void)2556 lua_init(void)
2557 {
2558     if (!lua_isopen())
2559     {
2560 #ifdef DYNAMIC_LUA
2561 	if (!lua_enabled(TRUE))
2562 	{
2563 	    emsg(_("Lua library cannot be loaded."));
2564 	    return FAIL;
2565 	}
2566 #endif
2567 	L = luaV_newstate();
2568     }
2569     return OK;
2570 }
2571 
2572     void
lua_end(void)2573 lua_end(void)
2574 {
2575     if (lua_isopen())
2576     {
2577 	lua_close(L);
2578 	L = NULL;
2579     }
2580 }
2581 
2582 /*
2583  * ex commands
2584  */
2585     void
ex_lua(exarg_T * eap)2586 ex_lua(exarg_T *eap)
2587 {
2588     char *script = (char *)script_get(eap, eap->arg);
2589 
2590     if (!eap->skip && lua_init() == OK)
2591     {
2592 	char *s = script != NULL ? script : (char *)eap->arg;
2593 
2594 	luaV_setrange(L, eap->line1, eap->line2);
2595 	if (luaL_loadbuffer(L, s, strlen(s), LUAVIM_CHUNKNAME)
2596 		|| lua_pcall(L, 0, 0, 0))
2597 	    luaV_emsg(L);
2598     }
2599     if (script != NULL)
2600 	vim_free(script);
2601 }
2602 
2603     void
ex_luado(exarg_T * eap)2604 ex_luado(exarg_T *eap)
2605 {
2606     linenr_T l;
2607     const char *s = (const char *) eap->arg;
2608     luaL_Buffer b;
2609     size_t len;
2610     buf_T *was_curbuf = curbuf;
2611 
2612     if (lua_init() == FAIL) return;
2613     if (u_save(eap->line1 - 1, eap->line2 + 1) == FAIL)
2614     {
2615 	emsg(_("cannot save undo information"));
2616 	return;
2617     }
2618     luaV_setrange(L, eap->line1, eap->line2);
2619     luaL_buffinit(L, &b);
2620     luaL_addlstring(&b, "return function(line, linenr) ", 30); // header
2621     luaL_addlstring(&b, s, strlen(s));
2622     luaL_addlstring(&b, " end", 4); // footer
2623     luaL_pushresult(&b);
2624     s = lua_tolstring(L, -1, &len);
2625     if (luaL_loadbuffer(L, s, len, LUAVIM_CHUNKNAME))
2626     {
2627 	luaV_emsg(L);
2628 	lua_pop(L, 1); // function body
2629 	return;
2630     }
2631     lua_call(L, 0, 1);
2632     lua_replace(L, -2); // function -> body
2633     for (l = eap->line1; l <= eap->line2; l++)
2634     {
2635 	// Check the line number, the command may have deleted lines.
2636 	if (l > curbuf->b_ml.ml_line_count)
2637 	    break;
2638 
2639 	lua_pushvalue(L, -1); // function
2640 	luaV_pushline(L, curbuf, l); // current line as arg
2641 	lua_pushinteger(L, l); // current line number as arg
2642 	if (lua_pcall(L, 2, 1, 0))
2643 	{
2644 	    luaV_emsg(L);
2645 	    break;
2646 	}
2647 	// Catch the command switching to another buffer.
2648 	if (curbuf != was_curbuf)
2649 	    break;
2650 	if (lua_isstring(L, -1)) // update line?
2651 	{
2652 #ifdef HAVE_SANDBOX
2653 	    luaV_checksandbox(L);
2654 #endif
2655 	    ml_replace(l, luaV_toline(L, -1), TRUE);
2656 	    changed_bytes(l, 0);
2657 	    lua_pop(L, 1); // result from luaV_toline
2658 	}
2659 	lua_pop(L, 1); // line
2660     }
2661     lua_pop(L, 1); // function
2662     check_cursor();
2663     update_screen(NOT_VALID);
2664 }
2665 
2666     void
ex_luafile(exarg_T * eap)2667 ex_luafile(exarg_T *eap)
2668 {
2669     if (lua_init() == FAIL)
2670 	return;
2671     if (!eap->skip)
2672     {
2673 	luaV_setrange(L, eap->line1, eap->line2);
2674 	if (luaL_loadfile(L, (char *) eap->arg) || lua_pcall(L, 0, 0, 0))
2675 	    luaV_emsg(L);
2676     }
2677 }
2678 
2679 #define luaV_freetype(typ,tname) \
2680 	void \
2681     lua_##tname##_free(typ *o) \
2682     { \
2683 	if (!lua_isopen()) return; \
2684 	luaV_getfield(L, LUAVIM_FREE); \
2685 	lua_pushlightuserdata(L, (void *) o); \
2686 	lua_call(L, 1, 0); \
2687     }
2688 
luaV_freetype(buf_T,buffer)2689 luaV_freetype(buf_T, buffer)
2690 luaV_freetype(win_T, window)
2691 
2692     void
2693 do_luaeval(char_u *str, typval_T *arg, typval_T *rettv)
2694 {
2695     lua_init();
2696     luaV_getfield(L, LUAVIM_LUAEVAL);
2697     lua_pushstring(L, (char *) str);
2698     lua_pushlightuserdata(L, (void *) arg);
2699     lua_pushlightuserdata(L, (void *) rettv);
2700     lua_call(L, 3, 0);
2701 }
2702 
2703     int
set_ref_in_lua(int copyID)2704 set_ref_in_lua(int copyID)
2705 {
2706     int aborted = 0;
2707 
2708     if (lua_isopen())
2709     {
2710 	luaV_getfield(L, LUAVIM_SETREF);
2711 	// call the function with 1 arg, getting 1 result back
2712 	lua_pushinteger(L, copyID);
2713 	lua_call(L, 1, 1);
2714 	// get the result
2715 	aborted = lua_tointeger(L, -1);
2716 	// pop result off the stack
2717 	lua_pop(L, 1);
2718     }
2719     return aborted;
2720 }
2721 
2722     void
update_package_paths_in_lua()2723 update_package_paths_in_lua()
2724 {
2725     if (lua_isopen())
2726     {
2727 	lua_getglobal(L, "vim");
2728 	lua_getfield(L, -1, "_update_package_paths");
2729 
2730 	if (lua_pcall(L, 0, 0, 0))
2731 	    luaV_emsg(L);
2732     }
2733 }
2734 
2735 /*
2736  * Native C function callback
2737  */
2738     static int
luaV_call_lua_func(int argcount,typval_T * argvars,typval_T * rettv,void * state)2739 luaV_call_lua_func(
2740 	int	 argcount,
2741 	typval_T *argvars,
2742 	typval_T *rettv,
2743 	void	 *state)
2744 {
2745     int i;
2746     int luaargcount = argcount;
2747     luaV_CFuncState *funcstate = (luaV_CFuncState*)state;
2748     lua_rawgeti(funcstate->L, LUA_REGISTRYINDEX, funcstate->lua_funcref);
2749 
2750     if (funcstate->lua_tableref != LUA_NOREF)
2751     {
2752 	// First arg for metatable __call method is a table
2753 	luaargcount += 1;
2754 	lua_rawgeti(funcstate->L, LUA_REGISTRYINDEX, funcstate->lua_tableref);
2755     }
2756 
2757     for (i = 0; i < argcount; ++i)
2758 	luaV_pushtypval(funcstate->L, &argvars[i]);
2759 
2760     if (lua_pcall(funcstate->L, luaargcount, 1, 0))
2761     {
2762 	luaV_emsg(funcstate->L);
2763 	return FCERR_OTHER;
2764     }
2765 
2766     luaV_checktypval(funcstate->L, -1, rettv, "get return value");
2767     return FCERR_NONE;
2768 }
2769 
2770 /*
2771  * Free up any lua references held by the func state.
2772  */
2773     static void
luaV_call_lua_func_free(void * state)2774 luaV_call_lua_func_free(void *state)
2775 {
2776     luaV_CFuncState *funcstate = (luaV_CFuncState*)state;
2777     luaL_unref(L, LUA_REGISTRYINDEX, funcstate->lua_funcref);
2778     funcstate->L = NULL;
2779     if (funcstate->lua_tableref != LUA_NOREF)
2780 	luaL_unref(L, LUA_REGISTRYINDEX, funcstate->lua_tableref);
2781     VIM_CLEAR(funcstate);
2782 }
2783 
2784 #endif
2785