xref: /vim-8.2.3635/src/if_lua.c (revision 61d35bd0)
1 /* vi:set ts=8 sts=4 sw=4:
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 
14 #include <lua.h>
15 #include <lualib.h>
16 #include <lauxlib.h>
17 
18 /* Only do the following when the feature is enabled.  Needed for "make
19  * depend". */
20 #if defined(FEAT_LUA) || defined(PROTO)
21 
22 #define LUAVIM_CHUNKNAME "vim chunk"
23 #define LUAVIM_NAME "vim"
24 
25 typedef buf_T *luaV_Buffer;
26 typedef win_T *luaV_Window;
27 typedef void (*msgfunc_T)(char_u *);
28 
29 static const char LUAVIM_BUFFER[] = "buffer";
30 static const char LUAVIM_WINDOW[] = "window";
31 static const char LUAVIM_FREE[] = "luaV_free";
32 
33 #define luaV_getfield(L, s) \
34     lua_pushlightuserdata((L), (void *)(s)); \
35     lua_rawget((L), LUA_REGISTRYINDEX)
36 #define luaV_checksandbox(L) \
37     if (sandbox) luaL_error((L), "not allowed in sandbox")
38 #define luaV_msg(L) luaV_msgfunc((L), (msgfunc_T) msg)
39 #define luaV_emsg(L) luaV_msgfunc((L), (msgfunc_T) emsg)
40 
41 
42 #ifdef DYNAMIC_LUA
43 
44 #ifndef WIN3264
45 # include <dlfcn.h>
46 # define HANDLE void*
47 # define load_dll(n) dlopen((n), RTLD_LAZY|RTLD_GLOBAL)
48 # define symbol_from_dll dlsym
49 # define close_dll dlclose
50 #else
51 # define load_dll vimLoadLib
52 # define symbol_from_dll GetProcAddress
53 # define close_dll FreeLibrary
54 #endif
55 
56 /* lauxlib */
57 #define luaL_register dll_luaL_register
58 #define luaL_typerror dll_luaL_typerror
59 #define luaL_checklstring dll_luaL_checklstring
60 #define luaL_checkinteger dll_luaL_checkinteger
61 #define luaL_optinteger dll_luaL_optinteger
62 #define luaL_checktype dll_luaL_checktype
63 #define luaL_error dll_luaL_error
64 #define luaL_loadfile dll_luaL_loadfile
65 #define luaL_loadbuffer dll_luaL_loadbuffer
66 #define luaL_newstate dll_luaL_newstate
67 #define luaL_buffinit dll_luaL_buffinit
68 #define luaL_prepbuffer dll_luaL_prepbuffer
69 #define luaL_addlstring dll_luaL_addlstring
70 #define luaL_pushresult dll_luaL_pushresult
71 /* lua */
72 #define lua_close dll_lua_close
73 #define lua_gettop dll_lua_gettop
74 #define lua_settop dll_lua_settop
75 #define lua_pushvalue dll_lua_pushvalue
76 #define lua_replace dll_lua_replace
77 #define lua_isnumber dll_lua_isnumber
78 #define lua_isstring dll_lua_isstring
79 #define lua_type dll_lua_type
80 #define lua_rawequal dll_lua_rawequal
81 #define lua_tonumber dll_lua_tonumber
82 #define lua_tointeger dll_lua_tointeger
83 #define lua_toboolean dll_lua_toboolean
84 #define lua_tolstring dll_lua_tolstring
85 #define lua_touserdata dll_lua_touserdata
86 #define lua_pushnil dll_lua_pushnil
87 #define lua_pushnumber dll_lua_pushnumber
88 #define lua_pushinteger dll_lua_pushinteger
89 #define lua_pushlstring dll_lua_pushlstring
90 #define lua_pushstring dll_lua_pushstring
91 #define lua_pushfstring dll_lua_pushfstring
92 #define lua_pushcclosure dll_lua_pushcclosure
93 #define lua_pushboolean dll_lua_pushboolean
94 #define lua_pushlightuserdata dll_lua_pushlightuserdata
95 #define lua_getfield dll_lua_getfield
96 #define lua_rawget dll_lua_rawget
97 #define lua_createtable dll_lua_createtable
98 #define lua_newuserdata dll_lua_newuserdata
99 #define lua_getmetatable dll_lua_getmetatable
100 #define lua_setfield dll_lua_setfield
101 #define lua_rawset dll_lua_rawset
102 #define lua_rawseti dll_lua_rawseti
103 #define lua_remove dll_lua_remove
104 #define lua_setmetatable dll_lua_setmetatable
105 #define lua_call dll_lua_call
106 #define lua_pcall dll_lua_pcall
107 /* libs */
108 #define luaopen_base dll_luaopen_base
109 #define luaopen_table dll_luaopen_table
110 #define luaopen_string dll_luaopen_string
111 #define luaopen_math dll_luaopen_math
112 #define luaopen_io dll_luaopen_io
113 #define luaopen_os dll_luaopen_os
114 #define luaopen_package dll_luaopen_package
115 #define luaopen_debug dll_luaopen_debug
116 #define luaL_openlibs dll_luaL_openlibs
117 
118 /* lauxlib */
119 void (*dll_luaL_register) (lua_State *L, const char *libname, const luaL_Reg *l);
120 int (*dll_luaL_typerror) (lua_State *L, int narg, const char *tname);
121 const char *(*dll_luaL_checklstring) (lua_State *L, int numArg, size_t *l);
122 lua_Integer (*dll_luaL_checkinteger) (lua_State *L, int numArg);
123 lua_Integer (*dll_luaL_optinteger) (lua_State *L, int nArg, lua_Integer def);
124 void (*dll_luaL_checktype) (lua_State *L, int narg, int t);
125 int (*dll_luaL_error) (lua_State *L, const char *fmt, ...);
126 int (*dll_luaL_loadfile) (lua_State *L, const char *filename);
127 int (*dll_luaL_loadbuffer) (lua_State *L, const char *buff, size_t sz, const char *name);
128 lua_State *(*dll_luaL_newstate) (void);
129 void (*dll_luaL_buffinit) (lua_State *L, luaL_Buffer *B);
130 char *(*dll_luaL_prepbuffer) (luaL_Buffer *B);
131 void (*dll_luaL_addlstring) (luaL_Buffer *B, const char *s, size_t l);
132 void (*dll_luaL_pushresult) (luaL_Buffer *B);
133 /* lua */
134 void       (*dll_lua_close) (lua_State *L);
135 int (*dll_lua_gettop) (lua_State *L);
136 void (*dll_lua_settop) (lua_State *L, int idx);
137 void (*dll_lua_pushvalue) (lua_State *L, int idx);
138 void (*dll_lua_replace) (lua_State *L, int idx);
139 int (*dll_lua_isnumber) (lua_State *L, int idx);
140 int (*dll_lua_isstring) (lua_State *L, int idx);
141 int (*dll_lua_type) (lua_State *L, int idx);
142 int (*dll_lua_rawequal) (lua_State *L, int idx1, int idx2);
143 lua_Number (*dll_lua_tonumber) (lua_State *L, int idx);
144 lua_Integer (*dll_lua_tointeger) (lua_State *L, int idx);
145 int (*dll_lua_toboolean) (lua_State *L, int idx);
146 const char *(*dll_lua_tolstring) (lua_State *L, int idx, size_t *len);
147 void *(*dll_lua_touserdata) (lua_State *L, int idx);
148 void (*dll_lua_pushnil) (lua_State *L);
149 void (*dll_lua_pushnumber) (lua_State *L, lua_Number n);
150 void (*dll_lua_pushinteger) (lua_State *L, lua_Integer n);
151 void (*dll_lua_pushlstring) (lua_State *L, const char *s, size_t l);
152 void (*dll_lua_pushstring) (lua_State *L, const char *s);
153 const char *(*dll_lua_pushfstring) (lua_State *L, const char *fmt, ...);
154 void (*dll_lua_pushcclosure) (lua_State *L, lua_CFunction fn, int n);
155 void (*dll_lua_pushboolean) (lua_State *L, int b);
156 void (*dll_lua_pushlightuserdata) (lua_State *L, void *p);
157 void (*dll_lua_getfield) (lua_State *L, int idx, const char *k);
158 void (*dll_lua_rawget) (lua_State *L, int idx);
159 void (*dll_lua_createtable) (lua_State *L, int narr, int nrec);
160 void *(*dll_lua_newuserdata) (lua_State *L, size_t sz);
161 int (*dll_lua_getmetatable) (lua_State *L, int objindex);
162 void (*dll_lua_setfield) (lua_State *L, int idx, const char *k);
163 void (*dll_lua_rawset) (lua_State *L, int idx);
164 void (*dll_lua_rawseti) (lua_State *L, int idx, int n);
165 void (*dll_lua_remove) (lua_State *L, int idx);
166 int (*dll_lua_setmetatable) (lua_State *L, int objindex);
167 void (*dll_lua_call) (lua_State *L, int nargs, int nresults);
168 int (*dll_lua_pcall) (lua_State *L, int nargs, int nresults, int errfunc);
169 /* libs */
170 int (*dll_luaopen_base) (lua_State *L);
171 int (*dll_luaopen_table) (lua_State *L);
172 int (*dll_luaopen_string) (lua_State *L);
173 int (*dll_luaopen_math) (lua_State *L);
174 int (*dll_luaopen_io) (lua_State *L);
175 int (*dll_luaopen_os) (lua_State *L);
176 int (*dll_luaopen_package) (lua_State *L);
177 int (*dll_luaopen_debug) (lua_State *L);
178 void (*dll_luaL_openlibs) (lua_State *L);
179 
180 typedef void **luaV_function;
181 typedef struct {
182     const char *name;
183     luaV_function func;
184 } luaV_Reg;
185 
186 static const luaV_Reg luaV_dll[] = {
187     /* lauxlib */
188     {"luaL_register", (luaV_function) &dll_luaL_register},
189     {"luaL_typerror", (luaV_function) &dll_luaL_typerror},
190     {"luaL_checklstring", (luaV_function) &dll_luaL_checklstring},
191     {"luaL_checkinteger", (luaV_function) &dll_luaL_checkinteger},
192     {"luaL_optinteger", (luaV_function) &dll_luaL_optinteger},
193     {"luaL_checktype", (luaV_function) &dll_luaL_checktype},
194     {"luaL_error", (luaV_function) &dll_luaL_error},
195     {"luaL_loadfile", (luaV_function) &dll_luaL_loadfile},
196     {"luaL_loadbuffer", (luaV_function) &dll_luaL_loadbuffer},
197     {"luaL_newstate", (luaV_function) &dll_luaL_newstate},
198     {"luaL_buffinit", (luaV_function) &dll_luaL_buffinit},
199     {"luaL_prepbuffer", (luaV_function) &dll_luaL_prepbuffer},
200     {"luaL_addlstring", (luaV_function) &dll_luaL_addlstring},
201     {"luaL_pushresult", (luaV_function) &dll_luaL_pushresult},
202     /* lua */
203     {"lua_close", (luaV_function) &dll_lua_close},
204     {"lua_gettop", (luaV_function) &dll_lua_gettop},
205     {"lua_settop", (luaV_function) &dll_lua_settop},
206     {"lua_pushvalue", (luaV_function) &dll_lua_pushvalue},
207     {"lua_replace", (luaV_function) &dll_lua_replace},
208     {"lua_isnumber", (luaV_function) &dll_lua_isnumber},
209     {"lua_isstring", (luaV_function) &dll_lua_isstring},
210     {"lua_type", (luaV_function) &dll_lua_type},
211     {"lua_rawequal", (luaV_function) &dll_lua_rawequal},
212     {"lua_tonumber", (luaV_function) &dll_lua_tonumber},
213     {"lua_tointeger", (luaV_function) &dll_lua_tointeger},
214     {"lua_toboolean", (luaV_function) &dll_lua_toboolean},
215     {"lua_tolstring", (luaV_function) &dll_lua_tolstring},
216     {"lua_touserdata", (luaV_function) &dll_lua_touserdata},
217     {"lua_pushnil", (luaV_function) &dll_lua_pushnil},
218     {"lua_pushnumber", (luaV_function) &dll_lua_pushnumber},
219     {"lua_pushinteger", (luaV_function) &dll_lua_pushinteger},
220     {"lua_pushlstring", (luaV_function) &dll_lua_pushlstring},
221     {"lua_pushstring", (luaV_function) &dll_lua_pushstring},
222     {"lua_pushfstring", (luaV_function) &dll_lua_pushfstring},
223     {"lua_pushcclosure", (luaV_function) &dll_lua_pushcclosure},
224     {"lua_pushboolean", (luaV_function) &dll_lua_pushboolean},
225     {"lua_pushlightuserdata", (luaV_function) &dll_lua_pushlightuserdata},
226     {"lua_getfield", (luaV_function) &dll_lua_getfield},
227     {"lua_rawget", (luaV_function) &dll_lua_rawget},
228     {"lua_createtable", (luaV_function) &dll_lua_createtable},
229     {"lua_newuserdata", (luaV_function) &dll_lua_newuserdata},
230     {"lua_getmetatable", (luaV_function) &dll_lua_getmetatable},
231     {"lua_setfield", (luaV_function) &dll_lua_setfield},
232     {"lua_rawset", (luaV_function) &dll_lua_rawset},
233     {"lua_rawseti", (luaV_function) &dll_lua_rawseti},
234     {"lua_remove", (luaV_function) &dll_lua_remove},
235     {"lua_setmetatable", (luaV_function) &dll_lua_setmetatable},
236     {"lua_call", (luaV_function) &dll_lua_call},
237     {"lua_pcall", (luaV_function) &dll_lua_pcall},
238     /* libs */
239     {"luaopen_base", (luaV_function) &dll_luaopen_base},
240     {"luaopen_table", (luaV_function) &dll_luaopen_table},
241     {"luaopen_string", (luaV_function) &dll_luaopen_string},
242     {"luaopen_math", (luaV_function) &dll_luaopen_math},
243     {"luaopen_io", (luaV_function) &dll_luaopen_io},
244     {"luaopen_os", (luaV_function) &dll_luaopen_os},
245     {"luaopen_package", (luaV_function) &dll_luaopen_package},
246     {"luaopen_debug", (luaV_function) &dll_luaopen_debug},
247     {"luaL_openlibs", (luaV_function) &dll_luaL_openlibs},
248     {NULL, NULL}
249 };
250 
251 static HANDLE hinstLua = NULL;
252 
253     static void
254 end_dynamic_lua(void)
255 {
256     if (hinstLua)
257     {
258 	close_dll(hinstLua);
259 	hinstLua = 0;
260     }
261 }
262 
263     static int
264 lua_link_init(char *libname, int verbose)
265 {
266     const luaV_Reg *reg;
267     if (hinstLua) return OK;
268     hinstLua = load_dll(libname);
269     if (!hinstLua)
270     {
271 	if (verbose)
272 	    EMSG2(_(e_loadlib), libname);
273 	return FAIL;
274     }
275     for (reg = luaV_dll; reg->func; reg++)
276     {
277 	if ((*reg->func = symbol_from_dll(hinstLua, reg->name)) == NULL)
278 	{
279 	    close_dll(hinstLua);
280 	    hinstLua = 0;
281 	    if (verbose)
282 		EMSG2(_(e_loadfunc), reg->name);
283 	    return FAIL;
284 	}
285     }
286     return OK;
287 }
288 
289     int
290 lua_enabled(int verbose)
291 {
292     return lua_link_init(DYNAMIC_LUA_DLL, verbose) == OK;
293 }
294 
295 #endif /* DYNAMIC_LUA */
296 
297 
298 /* =======   Internal   ======= */
299 
300     static void
301 luaV_newmetatable(lua_State *L, const char *tname)
302 {
303     lua_newtable(L);
304     lua_pushlightuserdata(L, (void *) tname);
305     lua_pushvalue(L, -2);
306     lua_rawset(L, LUA_REGISTRYINDEX);
307 }
308 
309     static void *
310 luaV_toudata(lua_State *L, int ud, const char *tname)
311 {
312     void *p = lua_touserdata(L, ud);
313 
314     if (p != NULL) /* value is userdata? */
315     {
316 	if (lua_getmetatable(L, ud)) /* does it have a metatable? */
317 	{
318 	    luaV_getfield(L, tname); /* get metatable */
319 	    if (lua_rawequal(L, -1, -2)) /* MTs match? */
320 	    {
321 		lua_pop(L, 2); /* MTs */
322 		return p;
323 	    }
324 	}
325     }
326     return NULL;
327 }
328 
329     static void *
330 luaV_checkudata(lua_State *L, int ud, const char *tname)
331 {
332     void *p = luaV_toudata(L, ud, tname);
333     if (p == NULL) luaL_typerror(L, ud, tname);
334     return p;
335 }
336 
337     static void
338 luaV_pushtypval(lua_State *L, typval_T *tv)
339 {
340     if (tv == NULL) luaL_error(L, "null type");
341     switch (tv->v_type)
342     {
343 	case VAR_STRING:
344 	    lua_pushstring(L, (char *) tv->vval.v_string);
345 	    break;
346 	case VAR_NUMBER:
347 	    lua_pushinteger(L, (int) tv->vval.v_number);
348 	    break;
349 #ifdef FEAT_FLOAT
350 	case VAR_FLOAT:
351 	    lua_pushnumber(L, (lua_Number) tv->vval.v_float);
352 	    break;
353 #endif
354 	case VAR_LIST: {
355 	    list_T *l = tv->vval.v_list;
356 
357 	    if (l != NULL)
358 	    {
359 		/* check cache */
360 		lua_pushlightuserdata(L, (void *) l);
361 		lua_rawget(L, LUA_ENVIRONINDEX);
362 		if (lua_isnil(L, -1)) /* not interned? */
363 		{
364 		    listitem_T *li;
365 		    int n = 0;
366 		    lua_pop(L, 1); /* nil */
367 		    lua_newtable(L);
368 		    lua_pushlightuserdata(L, (void *) l);
369 		    lua_pushvalue(L, -2);
370 		    lua_rawset(L, LUA_ENVIRONINDEX);
371 		    for (li = l->lv_first; li != NULL; li = li->li_next)
372 		    {
373 			luaV_pushtypval(L, &li->li_tv);
374 			lua_rawseti(L, -2, ++n);
375 		    }
376 		}
377 	    }
378 	    else lua_pushnil(L);
379 	    break;
380 		       }
381 	case VAR_DICT: {
382 	    dict_T *d = tv->vval.v_dict;
383 
384 	    if (d != NULL)
385 	    {
386 		/* check cache */
387 		lua_pushlightuserdata(L, (void *) d);
388 		lua_rawget(L, LUA_ENVIRONINDEX);
389 		if (lua_isnil(L, -1)) /* not interned? */
390 		{
391 		    hashtab_T *ht = &d->dv_hashtab;
392 		    hashitem_T *hi;
393 		    int n = ht->ht_used; /* remaining items */
394 		    lua_pop(L, 1); /* nil */
395 		    lua_newtable(L);
396 		    lua_pushlightuserdata(L, (void *) d);
397 		    lua_pushvalue(L, -2);
398 		    lua_rawset(L, LUA_ENVIRONINDEX);
399 		    for (hi = ht->ht_array; n > 0; hi++)
400 		    {
401 			if (!HASHITEM_EMPTY(hi))
402 			{
403 			    dictitem_T *di = dict_lookup(hi);
404 			    luaV_pushtypval(L, &di->di_tv);
405 			    lua_setfield(L, -2, (char *) hi->hi_key);
406 			    n--;
407 			}
408 		    }
409 		}
410 	    }
411 	    else lua_pushnil(L);
412 	    break;
413 	}
414 	default:
415 	    luaL_error(L, "invalid type");
416     }
417 }
418 
419 /* similar to luaL_addlstring, but replaces \0 with \n if toline and
420  * \n with \0 otherwise */
421     static void
422 luaV_addlstring(luaL_Buffer *b, const char *s, size_t l, int toline)
423 {
424     while (l--)
425     {
426 	if (*s == '\0' && toline)
427 	    luaL_addchar(b, '\n');
428 	else if (*s == '\n' && !toline)
429 	    luaL_addchar(b, '\0');
430 	else
431 	    luaL_addchar(b, *s);
432 	s++;
433     }
434 }
435 
436     static void
437 luaV_pushline(lua_State *L, buf_T *buf, linenr_T n)
438 {
439     const char *s = (const char *) ml_get_buf(buf, n, FALSE);
440     luaL_Buffer b;
441     luaL_buffinit(L, &b);
442     luaV_addlstring(&b, s, strlen(s), 0);
443     luaL_pushresult(&b);
444 }
445 
446     static char_u *
447 luaV_toline(lua_State *L, int pos)
448 {
449     size_t l;
450     const char *s = lua_tolstring(L, pos, &l);
451 
452     luaL_Buffer b;
453     luaL_buffinit(L, &b);
454     luaV_addlstring(&b, s, l, 1);
455     luaL_pushresult(&b);
456     return (char_u *) lua_tostring(L, -1);
457 }
458 
459 /* pops a string s from the top of the stack and calls mf(t) for pieces t of
460  * s separated by newlines */
461     static void
462 luaV_msgfunc(lua_State *L, msgfunc_T mf)
463 {
464     luaL_Buffer b;
465     size_t l;
466     const char *p, *s = lua_tolstring(L, -1, &l);
467     luaL_buffinit(L, &b);
468     luaV_addlstring(&b, s, l, 0);
469     luaL_pushresult(&b);
470     /* break string */
471     p = s = lua_tolstring(L, -1, &l);
472     while (l--)
473     {
474 	if (*p++ == '\0') /* break? */
475 	{
476 	    mf((char_u *) s);
477 	    s = p;
478 	}
479     }
480     mf((char_u *) s);
481     lua_pop(L, 2); /* original and modified strings */
482 }
483 
484 
485 /* =======   Buffer type   ======= */
486 
487     static luaV_Buffer *
488 luaV_newbuffer(lua_State *L, buf_T *buf)
489 {
490     luaV_Buffer *b = (luaV_Buffer *) lua_newuserdata(L, sizeof(luaV_Buffer));
491     *b = buf;
492     lua_pushlightuserdata(L, (void *) buf);
493     lua_pushvalue(L, -2);
494     lua_rawset(L, LUA_ENVIRONINDEX); /* env[buf] = udata */
495     /* to avoid GC, store as key in env */
496     lua_pushvalue(L, -1);
497     lua_pushboolean(L, 1);
498     lua_rawset(L, LUA_ENVIRONINDEX); /* env[udata] = true */
499     /* set metatable */
500     luaV_getfield(L, LUAVIM_BUFFER);
501     lua_setmetatable(L, -2);
502     return b;
503 }
504 
505     static luaV_Buffer *
506 luaV_pushbuffer (lua_State *L, buf_T *buf)
507 {
508     luaV_Buffer *b = NULL;
509     if (buf == NULL)
510 	lua_pushnil(L);
511     else {
512 	lua_pushlightuserdata(L, (void *) buf);
513 	lua_rawget(L, LUA_ENVIRONINDEX);
514 	if (lua_isnil(L, -1)) /* not interned? */
515 	{
516 	    lua_pop(L, 1);
517 	    b = luaV_newbuffer(L, buf);
518 	}
519 	else
520 	    b = (luaV_Buffer *) lua_touserdata(L, -1);
521     }
522     return b;
523 }
524 
525 /* Buffer metamethods */
526 
527     static int
528 luaV_buffer_tostring(lua_State *L)
529 {
530     lua_pushfstring(L, "%s: %p", LUAVIM_BUFFER, lua_touserdata(L, 1));
531     return 1;
532 }
533 
534     static int
535 luaV_buffer_len(lua_State *L)
536 {
537     luaV_Buffer *b = lua_touserdata(L, 1);
538     lua_pushinteger(L, (*b)->b_ml.ml_line_count);
539     return 1;
540 }
541 
542     static int
543 luaV_buffer_call(lua_State *L)
544 {
545     luaV_Buffer *b = (luaV_Buffer *) lua_touserdata(L, 1);
546     lua_settop(L, 1);
547     set_curbuf(*b, DOBUF_SPLIT);
548     return 1;
549 }
550 
551     static int
552 luaV_buffer_index(lua_State *L)
553 {
554     luaV_Buffer *b = (luaV_Buffer *) lua_touserdata(L, 1);
555     linenr_T n = (linenr_T) lua_tointeger(L, 2);
556     if (n > 0 && n <= (*b)->b_ml.ml_line_count)
557 	luaV_pushline(L, *b, n);
558     else if (lua_isstring(L, 2))
559     {
560 	const char *s = lua_tostring(L, 2);
561 	if (strncmp(s, "name", 4) == 0)
562 	    lua_pushstring(L, (char *) (*b)->b_sfname);
563 	else if (strncmp(s, "fname", 5) == 0)
564 	    lua_pushstring(L, (char *) (*b)->b_ffname);
565 	else if (strncmp(s, "number", 6) == 0)
566 	    lua_pushinteger(L, (*b)->b_fnum);
567 	/* methods */
568 	else if (strncmp(s,   "insert", 6) == 0
569 		|| strncmp(s, "next", 4) == 0
570 		|| strncmp(s, "previous", 8) == 0
571 		|| strncmp(s, "isvalid", 7) == 0)
572 	{
573 	    lua_getmetatable(L, 1);
574 	    lua_getfield(L, -1, s);
575 	}
576 	else
577 	    lua_pushnil(L);
578     }
579     else
580 	lua_pushnil(L);
581     return 1;
582 }
583 
584     static int
585 luaV_buffer_newindex(lua_State *L)
586 {
587     luaV_Buffer *b = (luaV_Buffer *) lua_touserdata(L, 1);
588     linenr_T n = (linenr_T) luaL_checkinteger(L, 2);
589 #ifdef HAVE_SANDBOX
590     luaV_checksandbox(L);
591 #endif
592     if (n < 1 || n > (*b)->b_ml.ml_line_count)
593 	luaL_error(L, "invalid line number");
594     if (lua_isnil(L, 3)) /* delete line */
595     {
596 	buf_T *buf = curbuf;
597 	curbuf = *b;
598 	if (u_savedel(n, 1L) == FAIL)
599 	{
600 	    curbuf = buf;
601 	    luaL_error(L, "cannot save undo information");
602 	}
603 	else if (ml_delete(n, FALSE) == FAIL)
604 	{
605 	    curbuf = buf;
606 	    luaL_error(L, "cannot delete line");
607 	}
608 	else {
609 	    deleted_lines_mark(n, 1L);
610 	    if (*b == curwin->w_buffer) /* fix cursor in current window? */
611 	    {
612 		if (curwin->w_cursor.lnum >= n)
613 		{
614 		    if (curwin->w_cursor.lnum > n)
615 		    {
616 			curwin->w_cursor.lnum -= 1;
617 			check_cursor_col();
618 		    }
619 		    else check_cursor();
620 		    changed_cline_bef_curs();
621 		}
622 		invalidate_botline();
623 	    }
624 	}
625 	curbuf = buf;
626     }
627     else if (lua_isstring(L, 3)) /* update line */
628     {
629 	buf_T *buf = curbuf;
630 	curbuf = *b;
631 	if (u_savesub(n) == FAIL)
632 	{
633 	    curbuf = buf;
634 	    luaL_error(L, "cannot save undo information");
635 	}
636 	else if (ml_replace(n, luaV_toline(L, 3), TRUE) == FAIL)
637 	{
638 	    curbuf = buf;
639 	    luaL_error(L, "cannot replace line");
640 	}
641 	else changed_bytes(n, 0);
642 	curbuf = buf;
643 	if (*b == curwin->w_buffer)
644 	    check_cursor_col();
645     }
646     else
647 	luaL_error(L, "wrong argument to change line");
648     return 0;
649 }
650 
651     static int
652 luaV_buffer_insert(lua_State *L)
653 {
654     luaV_Buffer *b = luaV_checkudata(L, 1, LUAVIM_BUFFER);
655     linenr_T last = (*b)->b_ml.ml_line_count;
656     linenr_T n = (linenr_T) luaL_optinteger(L, 3, last);
657     buf_T *buf;
658     luaL_checktype(L, 2, LUA_TSTRING);
659 #ifdef HAVE_SANDBOX
660     luaV_checksandbox(L);
661 #endif
662     /* fix insertion line */
663     if (n < 0) n = 0;
664     if (n > last) n = last;
665     /* insert */
666     buf = curbuf;
667     curbuf = *b;
668     if (u_save(n, n + 1) == FAIL)
669     {
670 	curbuf = buf;
671 	luaL_error(L, "cannot save undo information");
672     }
673     else if (ml_append(n, luaV_toline(L, 2), 0, FALSE) == FAIL)
674     {
675 	curbuf = buf;
676 	luaL_error(L, "cannot insert line");
677     }
678     else
679 	appended_lines_mark(n, 1L);
680     curbuf = buf;
681     update_screen(VALID);
682     return 0;
683 }
684 
685     static int
686 luaV_buffer_next(lua_State *L)
687 {
688     luaV_Buffer *b = luaV_checkudata(L, 1, LUAVIM_BUFFER);
689     luaV_pushbuffer(L, (*b)->b_next);
690     return 1;
691 }
692 
693     static int
694 luaV_buffer_previous(lua_State *L)
695 {
696     luaV_Buffer *b = luaV_checkudata(L, 1, LUAVIM_BUFFER);
697     luaV_pushbuffer(L, (*b)->b_prev);
698     return 1;
699 }
700 
701     static int
702 luaV_buffer_isvalid(lua_State *L)
703 {
704     luaV_Buffer *b = luaV_checkudata(L, 1, LUAVIM_BUFFER);
705     lua_pushlightuserdata(L, (void *) (*b));
706     lua_rawget(L, LUA_ENVIRONINDEX);
707     lua_pushboolean(L, !lua_isnil(L, -1));
708     return 1;
709 }
710 
711 static const luaL_Reg luaV_Buffer_mt[] = {
712     {"__tostring", luaV_buffer_tostring},
713     {"__len", luaV_buffer_len},
714     {"__call", luaV_buffer_call},
715     {"__index", luaV_buffer_index},
716     {"__newindex", luaV_buffer_newindex},
717     {"insert", luaV_buffer_insert},
718     {"next", luaV_buffer_next},
719     {"previous", luaV_buffer_previous},
720     {"isvalid", luaV_buffer_isvalid},
721     {NULL, NULL}
722 };
723 
724 
725 /* =======   Window type   ======= */
726 
727     static luaV_Window *
728 luaV_newwindow(lua_State *L, win_T *win)
729 {
730     luaV_Window *w = (luaV_Window *) lua_newuserdata(L, sizeof(luaV_Window));
731     *w = win;
732     lua_pushlightuserdata(L, (void *) win);
733     lua_pushvalue(L, -2);
734     lua_rawset(L, LUA_ENVIRONINDEX); /* env[win] = udata */
735     /* to avoid GC, store as key in env */
736     lua_pushvalue(L, -1);
737     lua_pushboolean(L, 1);
738     lua_rawset(L, LUA_ENVIRONINDEX); /* env[udata] = true */
739     /* set metatable */
740     luaV_getfield(L, LUAVIM_WINDOW);
741     lua_setmetatable(L, -2);
742     return w;
743 }
744 
745     static luaV_Window *
746 luaV_pushwindow(lua_State *L, win_T *win)
747 {
748     luaV_Window *w = NULL;
749     if (win == NULL)
750 	lua_pushnil(L);
751     else {
752 	lua_pushlightuserdata(L, (void *) win);
753 	lua_rawget(L, LUA_ENVIRONINDEX);
754 	if (lua_isnil(L, -1)) /* not interned? */
755 	{
756 	    lua_pop(L, 1);
757 	    w = luaV_newwindow(L, win);
758 	}
759 	else w = (luaV_Window *) lua_touserdata(L, -1);
760     }
761     return w;
762 }
763 
764 /* Window metamethods */
765 
766     static int
767 luaV_window_tostring(lua_State *L)
768 {
769     lua_pushfstring(L, "%s: %p", LUAVIM_WINDOW, lua_touserdata(L, 1));
770     return 1;
771 }
772 
773     static int
774 luaV_window_call(lua_State *L)
775 {
776     luaV_Window *w = (luaV_Window *) lua_touserdata(L, 1);
777     lua_settop(L, 1);
778     win_goto(*w);
779     return 1;
780 }
781 
782     static int
783 luaV_window_index(lua_State *L)
784 {
785     luaV_Window *w = (luaV_Window *) lua_touserdata(L, 1);
786     const char *s = luaL_checkstring(L, 2);
787     if (strncmp(s, "buffer", 6) == 0)
788 	luaV_pushbuffer(L, (*w)->w_buffer);
789     else if (strncmp(s, "line", 4) == 0)
790 	lua_pushinteger(L, (*w)->w_cursor.lnum);
791     else if (strncmp(s, "col", 3) == 0)
792 	lua_pushinteger(L, (*w)->w_cursor.col + 1);
793 #ifdef FEAT_VERTSPLIT
794     else if (strncmp(s, "width", 5) == 0)
795 	lua_pushinteger(L, W_WIDTH((*w)));
796 #endif
797     else if (strncmp(s, "height", 6) == 0)
798 	lua_pushinteger(L, (*w)->w_height);
799     /* methods */
800     else if (strncmp(s,   "next", 4) == 0
801 	    || strncmp(s, "previous", 8) == 0
802 	    || strncmp(s, "isvalid", 7) == 0)
803     {
804 	lua_getmetatable(L, 1);
805 	lua_getfield(L, -1, s);
806     }
807     else
808 	lua_pushnil(L);
809     return 1;
810 }
811 
812     static int
813 luaV_window_newindex (lua_State *L)
814 {
815     luaV_Window *w = (luaV_Window *) lua_touserdata(L, 1);
816     const char *s = luaL_checkstring(L, 2);
817     int v = luaL_checkinteger(L, 3);
818     if (strncmp(s, "line", 4) == 0)
819     {
820 #ifdef HAVE_SANDBOX
821 	luaV_checksandbox(L);
822 #endif
823 	if (v < 1 || v > (*w)->w_buffer->b_ml.ml_line_count)
824 	    luaL_error(L, "line out of range");
825 	(*w)->w_cursor.lnum = v;
826 	update_screen(VALID);
827     }
828     else if (strncmp(s, "col", 3) == 0)
829     {
830 #ifdef HAVE_SANDBOX
831 	luaV_checksandbox(L);
832 #endif
833 	(*w)->w_cursor.col = v - 1;
834 	update_screen(VALID);
835     }
836 #ifdef FEAT_VERTSPLIT
837     else if (strncmp(s, "width", 5) == 0)
838     {
839 	win_T *win = curwin;
840 #ifdef FEAT_GUI
841 	need_mouse_correct = TRUE;
842 #endif
843 	curwin = *w;
844 	win_setwidth(v);
845 	curwin = win;
846     }
847 #endif
848     else if (strncmp(s, "height", 6) == 0)
849     {
850 	win_T *win = curwin;
851 #ifdef FEAT_GUI
852 	need_mouse_correct = TRUE;
853 #endif
854 	curwin = *w;
855 	win_setheight(v);
856 	curwin = win;
857     }
858     else
859 	luaL_error(L, "invalid window property: `%s'", s);
860     return 0;
861 }
862 
863     static int
864 luaV_window_next(lua_State *L)
865 {
866     luaV_Window *w = luaV_checkudata(L, 1, LUAVIM_WINDOW);
867     luaV_pushwindow(L, (*w)->w_next);
868     return 1;
869 }
870 
871     static int
872 luaV_window_previous(lua_State *L)
873 {
874     luaV_Window *w = luaV_checkudata(L, 1, LUAVIM_WINDOW);
875     luaV_pushwindow(L, (*w)->w_prev);
876     return 1;
877 }
878 
879     static int
880 luaV_window_isvalid(lua_State *L)
881 {
882     luaV_Window *w = luaV_checkudata(L, 1, LUAVIM_WINDOW);
883     lua_pushlightuserdata(L, (void *) (*w));
884     lua_rawget(L, LUA_ENVIRONINDEX);
885     lua_pushboolean(L, !lua_isnil(L, -1));
886     return 1;
887 }
888 
889 static const luaL_Reg luaV_Window_mt[] = {
890     {"__tostring", luaV_window_tostring},
891     {"__call", luaV_window_call},
892     {"__index", luaV_window_index},
893     {"__newindex", luaV_window_newindex},
894     {"next", luaV_window_next},
895     {"previous", luaV_window_previous},
896     {"isvalid", luaV_window_isvalid},
897     {NULL, NULL}
898 };
899 
900 
901 /* =======   Vim module   ======= */
902 
903     static int
904 luaV_print(lua_State *L)
905 {
906     int i, n = lua_gettop(L); /* nargs */
907     const char *s;
908     size_t l;
909     luaL_Buffer b;
910     luaL_buffinit(L, &b);
911     lua_getglobal(L, "tostring");
912     for (i = 1; i <= n; i++)
913     {
914 	lua_pushvalue(L, -1); /* tostring */
915 	lua_pushvalue(L, i); /* arg */
916 	lua_call(L, 1, 1);
917 	s = lua_tolstring(L, -1, &l);
918 	if (s == NULL)
919 	    return luaL_error(L, "cannot convert to string");
920 	if (i > 1) luaL_addchar(&b, ' '); /* use space instead of tab */
921 	luaV_addlstring(&b, s, l, 0);
922 	lua_pop(L, 1);
923     }
924     luaL_pushresult(&b);
925     luaV_msg(L);
926     return 0;
927 }
928 
929     static int
930 luaV_debug(lua_State *L)
931 {
932     lua_settop(L, 0);
933     lua_getglobal(L, "vim");
934     lua_getfield(L, -1, "eval");
935     lua_remove(L, -2); /* vim.eval at position 1 */
936     for (;;)
937     {
938 	const char *input;
939 	size_t l;
940 	lua_pushvalue(L, 1); /* vim.eval */
941 	lua_pushliteral(L, "input('lua_debug> ')");
942 	lua_call(L, 1, 1); /* return string */
943 	input = lua_tolstring(L, -1, &l);
944 	if (l == 0 || strcmp(input, "cont") == 0)
945 	    return 0;
946 	msg_putchar('\n'); /* avoid outputting on input line */
947 	if (luaL_loadbuffer(L, input, l, "=(debug command)")
948 		|| lua_pcall(L, 0, 0, 0))
949 	    luaV_emsg(L);
950 	lua_settop(L, 1); /* remove eventual returns, but keep vim.eval */
951     }
952 }
953 
954     static int
955 luaV_command(lua_State *L)
956 {
957     do_cmdline_cmd((char_u *) luaL_checkstring(L, 1));
958     update_screen(VALID);
959     return 0;
960 }
961 
962     static int
963 luaV_eval(lua_State *L)
964 {
965     typval_T *tv = eval_expr((char_u *) luaL_checkstring(L, 1), NULL);
966     if (tv == NULL) luaL_error(L, "invalid expression");
967     luaV_pushtypval(L, tv);
968     return 1;
969 }
970 
971     static int
972 luaV_beep(lua_State *L UNUSED)
973 {
974     vim_beep();
975     return 0;
976 }
977 
978     static int
979 luaV_line(lua_State *L)
980 {
981     luaV_pushline(L, curbuf, curwin->w_cursor.lnum);
982     return 1;
983 }
984 
985     static int
986 luaV_buffer(lua_State *L)
987 {
988     buf_T *buf;
989     if (lua_isstring(L, 1)) /* get by number or name? */
990     {
991 	if (lua_isnumber(L, 1)) /* by number? */
992 	{
993 	    int n = lua_tointeger(L, 1);
994 	    for (buf = firstbuf; buf != NULL; buf = buf->b_next)
995 		if (buf->b_fnum == n) break;
996 	}
997 	else { /* by name */
998 	    size_t l;
999 	    const char *s = lua_tolstring(L, 1, &l);
1000 	    for (buf = firstbuf; buf != NULL; buf = buf->b_next)
1001 	    {
1002 		if (buf->b_ffname == NULL || buf->b_sfname == NULL)
1003 		{
1004 		    if (l == 0) break;
1005 		}
1006 		else if (strncmp(s, (char *)buf->b_ffname, l) == 0
1007 			|| strncmp(s, (char *)buf->b_sfname, l) == 0)
1008 		    break;
1009 	    }
1010 	}
1011 	if (buf == NULL) /* not found? */
1012 	    lua_pushnil(L);
1013 	else
1014 	    luaV_pushbuffer(L, buf);
1015     }
1016     else {
1017 	buf = (lua_toboolean(L, 1)) ? firstbuf : curbuf; /* first buffer? */
1018 	luaV_pushbuffer(L, buf);
1019     }
1020     return 1;
1021 }
1022 
1023     static int
1024 luaV_window(lua_State *L)
1025 {
1026     win_T *win;
1027     if (lua_isnumber(L, 1)) /* get by number? */
1028     {
1029 	int n = lua_tointeger(L, 1);
1030 	for (win = firstwin; win != NULL; win = win->w_next, n--)
1031 	    if (n == 1) break;
1032 	if (win == NULL) /* not found? */
1033 	    lua_pushnil(L);
1034 	else
1035 	    luaV_pushwindow(L, win);
1036     }
1037     else {
1038 	win = (lua_toboolean(L, 1)) ? firstwin : curwin; /* first window? */
1039 	luaV_pushwindow(L, win);
1040     }
1041     return 1;
1042 }
1043 
1044     static int
1045 luaV_open(lua_State *L)
1046 {
1047     char_u *s = NULL;
1048 #ifdef HAVE_SANDBOX
1049     luaV_checksandbox(L);
1050 #endif
1051     if (lua_isstring(L, 1)) s = (char_u *) lua_tostring(L, 1);
1052     luaV_pushbuffer(L, buflist_new(s, NULL, 1L, BLN_LISTED));
1053     return 1;
1054 }
1055 
1056     static int
1057 luaV_isbuffer(lua_State *L)
1058 {
1059     lua_pushboolean(L, luaV_toudata(L, 1, LUAVIM_BUFFER) != NULL);
1060     return 1;
1061 }
1062 
1063     static int
1064 luaV_iswindow(lua_State *L)
1065 {
1066     lua_pushboolean(L, luaV_toudata(L, 1, LUAVIM_WINDOW) != NULL);
1067     return 1;
1068 }
1069 
1070 /* for freeing buffer and window objects; lightuserdata as arg */
1071     static int
1072 luaV_free(lua_State *L)
1073 {
1074     lua_pushvalue(L, 1); /* lightudata */
1075     lua_rawget(L, LUA_ENVIRONINDEX);
1076     if (!lua_isnil(L, -1))
1077     {
1078 	lua_pushnil(L);
1079 	lua_rawset(L, LUA_ENVIRONINDEX); /* env[udata] = nil */
1080 	lua_pushnil(L);
1081 	lua_rawset(L, LUA_ENVIRONINDEX); /* env[lightudata] = nil */
1082     }
1083     return 0;
1084 }
1085 
1086 static const luaL_Reg luaV_module[] = {
1087     {"command", luaV_command},
1088     {"eval", luaV_eval},
1089     {"beep", luaV_beep},
1090     {"line", luaV_line},
1091     {"buffer", luaV_buffer},
1092     {"window", luaV_window},
1093     {"open", luaV_open},
1094     {"isbuffer", luaV_isbuffer},
1095     {"iswindow", luaV_iswindow},
1096     {NULL, NULL}
1097 };
1098 
1099     static int
1100 luaopen_vim(lua_State *L)
1101 {
1102     /* set environment */
1103     lua_newtable(L);
1104     lua_newtable(L);
1105     lua_pushliteral(L, "v");
1106     lua_setfield(L, -2, "__mode");
1107     lua_setmetatable(L, -2);
1108     lua_replace(L, LUA_ENVIRONINDEX);
1109     /* print */
1110     lua_pushcfunction(L, luaV_print);
1111     lua_setglobal(L, "print");
1112     /* debug.debug */
1113     lua_getglobal(L, "debug");
1114     lua_pushcfunction(L, luaV_debug);
1115     lua_setfield(L, -2, "debug");
1116     lua_pop(L, 1);
1117     /* free */
1118     lua_pushlightuserdata(L, (void *) LUAVIM_FREE);
1119     lua_pushcfunction(L, luaV_free);
1120     lua_rawset(L, LUA_REGISTRYINDEX);
1121     /* register */
1122     luaV_newmetatable(L, LUAVIM_BUFFER);
1123     luaL_register(L, NULL, luaV_Buffer_mt);
1124     luaV_newmetatable(L, LUAVIM_WINDOW);
1125     luaL_register(L, NULL, luaV_Window_mt);
1126     luaL_register(L, LUAVIM_NAME, luaV_module);
1127     return 0;
1128 }
1129 
1130     static lua_State *
1131 luaV_newstate(void)
1132 {
1133     lua_State *L = luaL_newstate();
1134     luaL_openlibs(L); /* core libs */
1135     lua_pushcfunction(L, luaopen_vim); /* vim */
1136     lua_call(L, 0, 0);
1137     return L;
1138 }
1139 
1140     static void
1141 luaV_setrange(lua_State *L, int line1, int line2)
1142 {
1143     lua_getglobal(L, LUAVIM_NAME);
1144     lua_pushinteger(L, line1);
1145     lua_setfield(L, -2, "firstline");
1146     lua_pushinteger(L, line2);
1147     lua_setfield(L, -2, "lastline");
1148     lua_pop(L, 1); /* vim table */
1149 }
1150 
1151 
1152 /* =======   Interface   ======= */
1153 
1154 static lua_State *L = NULL;
1155 
1156     static int
1157 lua_is_open(void)
1158 {
1159     return L != NULL;
1160 }
1161 
1162     static int
1163 lua_init(void)
1164 {
1165     if (L == NULL)
1166     {
1167 #ifdef DYNAMIC_LUA
1168 	if (!lua_enabled(TRUE))
1169 	{
1170 	    EMSG(_("Lua library cannot be loaded."));
1171 	    return FAIL;
1172 	}
1173 #endif
1174 	L = luaV_newstate();
1175     }
1176     return OK;
1177 }
1178 
1179     void
1180 lua_end(void)
1181 {
1182     if (L != NULL)
1183     {
1184 	lua_close(L);
1185 	L = NULL;
1186 #ifdef DYNAMIC_LUA
1187 	end_dynamic_lua();
1188 #endif
1189     }
1190 }
1191 
1192 /* ex commands */
1193     void
1194 ex_lua(exarg_T *eap)
1195 {
1196     char *script;
1197     if (lua_init() == FAIL) return;
1198     script = (char *) script_get(eap, eap->arg);
1199     if (!eap->skip)
1200     {
1201 	char *s = (script) ? script :  (char *) eap->arg;
1202 	luaV_setrange(L, eap->line1, eap->line2);
1203 	if (luaL_loadbuffer(L, s, strlen(s), LUAVIM_CHUNKNAME)
1204 		|| lua_pcall(L, 0, 0, 0))
1205 	    luaV_emsg(L);
1206     }
1207     if (script != NULL) vim_free(script);
1208 }
1209 
1210     void
1211 ex_luado(exarg_T *eap)
1212 {
1213     linenr_T l;
1214     const char *s = (const char *) eap->arg;
1215     luaL_Buffer b;
1216     size_t len;
1217     if (lua_init() == FAIL) return;
1218     if (u_save(eap->line1 - 1, eap->line2 + 1) == FAIL)
1219     {
1220 	EMSG(_("cannot save undo information"));
1221 	return;
1222     }
1223     luaV_setrange(L, eap->line1, eap->line2);
1224     luaL_buffinit(L, &b);
1225     luaL_addlstring(&b, "return function(line) ", 22); /* header */
1226     luaL_addlstring(&b, s, strlen(s));
1227     luaL_addlstring(&b, " end", 4); /* footer */
1228     luaL_pushresult(&b);
1229     s = lua_tolstring(L, -1, &len);
1230     if (luaL_loadbuffer(L, s, len, LUAVIM_CHUNKNAME))
1231     {
1232 	luaV_emsg(L);
1233 	lua_pop(L, 1); /* function body */
1234 	return;
1235     }
1236     lua_call(L, 0, 1);
1237     lua_replace(L, -2); /* function -> body */
1238     for (l = eap->line1; l <= eap->line2; l++)
1239     {
1240 	lua_pushvalue(L, -1); /* function */
1241 	luaV_pushline(L, curbuf, l); /* current line as arg */
1242 	if (lua_pcall(L, 1, 1, 0))
1243 	{
1244 	    luaV_emsg(L);
1245 	    break;
1246 	}
1247 	if (lua_isstring(L, -1)) /* update line? */
1248 	{
1249 #ifdef HAVE_SANDBOX
1250 	    luaV_checksandbox(L);
1251 #endif
1252 	    ml_replace(l, luaV_toline(L, -1), TRUE);
1253 	    changed_bytes(l, 0);
1254 	    lua_pop(L, 1); /* result from luaV_toline */
1255 	}
1256 	lua_pop(L, 1); /* line */
1257     }
1258     lua_pop(L, 1); /* function */
1259     check_cursor();
1260     update_screen(NOT_VALID);
1261 }
1262 
1263     void
1264 ex_luafile(exarg_T *eap)
1265 {
1266     if (lua_init() == FAIL)
1267 	return;
1268     if (!eap->skip)
1269     {
1270 	luaV_setrange(L, eap->line1, eap->line2);
1271 	if (luaL_loadfile(L, (char *) eap->arg) || lua_pcall(L, 0, 0, 0))
1272 	    luaV_emsg(L);
1273     }
1274 }
1275 
1276 /* buffer */
1277     void
1278 lua_buffer_free(buf_T *buf)
1279 {
1280     if (!lua_is_open()) return;
1281     luaV_getfield(L, LUAVIM_FREE);
1282     lua_pushlightuserdata(L, (void *) buf);
1283     lua_call(L, 1, 0);
1284 }
1285 
1286 /* window */
1287     void
1288 lua_window_free(win_T *win)
1289 {
1290     if (!lua_is_open()) return;
1291     luaV_getfield(L, LUAVIM_FREE);
1292     lua_pushlightuserdata(L, (void *) win);
1293     lua_call(L, 1, 0);
1294 }
1295 
1296 #endif
1297