blob: da88aab780642cd2a550a96789c2e37fd220f83a [file] [log] [blame]
Bram Moolenaar1dced572012-04-05 16:54:08 +02001/* vi:set ts=8 sts=4 sw=4 noet:
Bram Moolenaar0ba04292010-07-14 23:23:17 +02002 *
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
Bram Moolenaare2793352011-01-17 19:53:27 +010012#include "vim.h"
13
Bram Moolenaar0ba04292010-07-14 23:23:17 +020014#include <lua.h>
15#include <lualib.h>
16#include <lauxlib.h>
Bram Moolenaar0ba04292010-07-14 23:23:17 +020017
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"
Bram Moolenaar1dced572012-04-05 16:54:08 +020024#define LUAVIM_EVALNAME "luaeval"
25#define LUAVIM_EVALHEADER "local _A=select(1,...) return "
Bram Moolenaar0ba04292010-07-14 23:23:17 +020026
27typedef buf_T *luaV_Buffer;
28typedef win_T *luaV_Window;
Bram Moolenaar1dced572012-04-05 16:54:08 +020029typedef dict_T *luaV_Dict;
30typedef list_T *luaV_List;
Bram Moolenaar0ba04292010-07-14 23:23:17 +020031typedef void (*msgfunc_T)(char_u *);
32
Bram Moolenaar1dced572012-04-05 16:54:08 +020033static const char LUAVIM_DICT[] = "dict";
34static const char LUAVIM_LIST[] = "list";
Bram Moolenaar0ba04292010-07-14 23:23:17 +020035static const char LUAVIM_BUFFER[] = "buffer";
36static const char LUAVIM_WINDOW[] = "window";
37static const char LUAVIM_FREE[] = "luaV_free";
Bram Moolenaar1dced572012-04-05 16:54:08 +020038static const char LUAVIM_LUAEVAL[] = "luaV_luaeval";
39static const char LUAVIM_SETREF[] = "luaV_setref";
Bram Moolenaar0ba04292010-07-14 23:23:17 +020040
Bram Moolenaar1dced572012-04-05 16:54:08 +020041/* most functions are closures with a cache table as first upvalue;
42 * get/setudata manage references to vim userdata in cache table through
43 * object pointers (light userdata) */
44#define luaV_getudata(L, v) \
45 lua_pushlightuserdata((L), (void *) (v)); \
46 lua_rawget((L), lua_upvalueindex(1))
47#define luaV_setudata(L, v) \
48 lua_pushlightuserdata((L), (void *) (v)); \
49 lua_pushvalue((L), -2); \
50 lua_rawset((L), lua_upvalueindex(1))
Bram Moolenaar0ba04292010-07-14 23:23:17 +020051#define luaV_getfield(L, s) \
52 lua_pushlightuserdata((L), (void *)(s)); \
53 lua_rawget((L), LUA_REGISTRYINDEX)
54#define luaV_checksandbox(L) \
55 if (sandbox) luaL_error((L), "not allowed in sandbox")
56#define luaV_msg(L) luaV_msgfunc((L), (msgfunc_T) msg)
57#define luaV_emsg(L) luaV_msgfunc((L), (msgfunc_T) emsg)
58
Bram Moolenaar1dced572012-04-05 16:54:08 +020059static luaV_List *luaV_pushlist (lua_State *L, list_T *lis);
60static luaV_Dict *luaV_pushdict (lua_State *L, dict_T *dic);
61
62#if LUA_VERSION_NUM <= 501
63#define luaV_openlib(L, l, n) luaL_openlib(L, NULL, l, n)
64#define luaL_typeerror luaL_typerror
65#else
66#define luaV_openlib luaL_setfuncs
67#endif
Bram Moolenaar0ba04292010-07-14 23:23:17 +020068
69#ifdef DYNAMIC_LUA
Bram Moolenaar2334b6d2010-07-22 21:32:16 +020070
71#ifndef WIN3264
72# include <dlfcn.h>
73# define HANDLE void*
74# define load_dll(n) dlopen((n), RTLD_LAZY|RTLD_GLOBAL)
75# define symbol_from_dll dlsym
76# define close_dll dlclose
77#else
Bram Moolenaarebbcb822010-10-23 14:02:54 +020078# define load_dll vimLoadLib
Bram Moolenaar2334b6d2010-07-22 21:32:16 +020079# define symbol_from_dll GetProcAddress
80# define close_dll FreeLibrary
81#endif
82
Bram Moolenaar0ba04292010-07-14 23:23:17 +020083/* lauxlib */
Bram Moolenaar1dced572012-04-05 16:54:08 +020084#if LUA_VERSION_NUM <= 501
Bram Moolenaar0ba04292010-07-14 23:23:17 +020085#define luaL_register dll_luaL_register
Bram Moolenaar1dced572012-04-05 16:54:08 +020086#define luaL_prepbuffer dll_luaL_prepbuffer
87#define luaL_openlib dll_luaL_openlib
Bram Moolenaar0ba04292010-07-14 23:23:17 +020088#define luaL_typerror dll_luaL_typerror
Bram Moolenaar1dced572012-04-05 16:54:08 +020089#define luaL_loadfile dll_luaL_loadfile
90#define luaL_loadbuffer dll_luaL_loadbuffer
91#else
92#define luaL_prepbuffsize dll_luaL_prepbuffsize
93#define luaL_setfuncs dll_luaL_setfuncs
94#define luaL_loadfilex dll_luaL_loadfilex
95#define luaL_loadbufferx dll_luaL_loadbufferx
96#define luaL_argerror dll_luaL_argerror
97#endif
Bram Moolenaar0ba04292010-07-14 23:23:17 +020098#define luaL_checklstring dll_luaL_checklstring
99#define luaL_checkinteger dll_luaL_checkinteger
100#define luaL_optinteger dll_luaL_optinteger
101#define luaL_checktype dll_luaL_checktype
102#define luaL_error dll_luaL_error
Bram Moolenaar0ba04292010-07-14 23:23:17 +0200103#define luaL_newstate dll_luaL_newstate
104#define luaL_buffinit dll_luaL_buffinit
Bram Moolenaar0ba04292010-07-14 23:23:17 +0200105#define luaL_addlstring dll_luaL_addlstring
106#define luaL_pushresult dll_luaL_pushresult
107/* lua */
Bram Moolenaar1dced572012-04-05 16:54:08 +0200108#if LUA_VERSION_NUM <= 501
109#define lua_tonumber dll_lua_tonumber
110#define lua_tointeger dll_lua_tointeger
111#define lua_call dll_lua_call
112#define lua_pcall dll_lua_pcall
113#else
114#define lua_tonumberx dll_lua_tonumberx
115#define lua_tointegerx dll_lua_tointegerx
116#define lua_callk dll_lua_callk
117#define lua_pcallk dll_lua_pcallk
118#define lua_getglobal dll_lua_getglobal
119#define lua_setglobal dll_lua_setglobal
120#define lua_typename dll_lua_typename
121#endif
Bram Moolenaar0ba04292010-07-14 23:23:17 +0200122#define lua_close dll_lua_close
123#define lua_gettop dll_lua_gettop
124#define lua_settop dll_lua_settop
125#define lua_pushvalue dll_lua_pushvalue
126#define lua_replace dll_lua_replace
Bram Moolenaar1dced572012-04-05 16:54:08 +0200127#define lua_remove dll_lua_remove
Bram Moolenaar0ba04292010-07-14 23:23:17 +0200128#define lua_isnumber dll_lua_isnumber
129#define lua_isstring dll_lua_isstring
130#define lua_type dll_lua_type
131#define lua_rawequal dll_lua_rawequal
Bram Moolenaar0ba04292010-07-14 23:23:17 +0200132#define lua_toboolean dll_lua_toboolean
133#define lua_tolstring dll_lua_tolstring
134#define lua_touserdata dll_lua_touserdata
135#define lua_pushnil dll_lua_pushnil
136#define lua_pushnumber dll_lua_pushnumber
137#define lua_pushinteger dll_lua_pushinteger
138#define lua_pushlstring dll_lua_pushlstring
139#define lua_pushstring dll_lua_pushstring
140#define lua_pushfstring dll_lua_pushfstring
141#define lua_pushcclosure dll_lua_pushcclosure
142#define lua_pushboolean dll_lua_pushboolean
143#define lua_pushlightuserdata dll_lua_pushlightuserdata
144#define lua_getfield dll_lua_getfield
145#define lua_rawget dll_lua_rawget
Bram Moolenaar1dced572012-04-05 16:54:08 +0200146#define lua_rawgeti dll_lua_rawgeti
Bram Moolenaar0ba04292010-07-14 23:23:17 +0200147#define lua_createtable dll_lua_createtable
148#define lua_newuserdata dll_lua_newuserdata
149#define lua_getmetatable dll_lua_getmetatable
150#define lua_setfield dll_lua_setfield
151#define lua_rawset dll_lua_rawset
152#define lua_rawseti dll_lua_rawseti
153#define lua_setmetatable dll_lua_setmetatable
Bram Moolenaar0ba04292010-07-14 23:23:17 +0200154/* libs */
155#define luaopen_base dll_luaopen_base
156#define luaopen_table dll_luaopen_table
157#define luaopen_string dll_luaopen_string
158#define luaopen_math dll_luaopen_math
Bram Moolenaar16c98f92010-07-28 22:46:08 +0200159#define luaopen_io dll_luaopen_io
Bram Moolenaar0ba04292010-07-14 23:23:17 +0200160#define luaopen_os dll_luaopen_os
161#define luaopen_package dll_luaopen_package
162#define luaopen_debug dll_luaopen_debug
Bram Moolenaar16c98f92010-07-28 22:46:08 +0200163#define luaL_openlibs dll_luaL_openlibs
Bram Moolenaar0ba04292010-07-14 23:23:17 +0200164
165/* lauxlib */
Bram Moolenaar1dced572012-04-05 16:54:08 +0200166#if LUA_VERSION_NUM <= 501
Bram Moolenaar0ba04292010-07-14 23:23:17 +0200167void (*dll_luaL_register) (lua_State *L, const char *libname, const luaL_Reg *l);
Bram Moolenaar1dced572012-04-05 16:54:08 +0200168char *(*dll_luaL_prepbuffer) (luaL_Buffer *B);
169void (*dll_luaL_openlib) (lua_State *L, const char *libname, const luaL_Reg *l, int nup);
Bram Moolenaar0ba04292010-07-14 23:23:17 +0200170int (*dll_luaL_typerror) (lua_State *L, int narg, const char *tname);
Bram Moolenaar1dced572012-04-05 16:54:08 +0200171int (*dll_luaL_loadfile) (lua_State *L, const char *filename);
172int (*dll_luaL_loadbuffer) (lua_State *L, const char *buff, size_t sz, const char *name);
173#else
174char *(*dll_luaL_prepbuffsize) (luaL_Buffer *B, size_t sz);
175void (*dll_luaL_setfuncs) (lua_State *L, const luaL_Reg *l, int nup);
176int (*dll_luaL_loadfilex) (lua_State *L, const char *filename, const char *mode);
177int (*dll_luaL_loadbufferx) (lua_State *L, const char *buff, size_t sz, const char *name, const char *mode);
178int (*dll_luaL_argerror) (lua_State *L, int numarg, const char *extramsg);
179#endif
Bram Moolenaar0ba04292010-07-14 23:23:17 +0200180const char *(*dll_luaL_checklstring) (lua_State *L, int numArg, size_t *l);
181lua_Integer (*dll_luaL_checkinteger) (lua_State *L, int numArg);
182lua_Integer (*dll_luaL_optinteger) (lua_State *L, int nArg, lua_Integer def);
183void (*dll_luaL_checktype) (lua_State *L, int narg, int t);
184int (*dll_luaL_error) (lua_State *L, const char *fmt, ...);
Bram Moolenaar0ba04292010-07-14 23:23:17 +0200185lua_State *(*dll_luaL_newstate) (void);
186void (*dll_luaL_buffinit) (lua_State *L, luaL_Buffer *B);
Bram Moolenaar0ba04292010-07-14 23:23:17 +0200187void (*dll_luaL_addlstring) (luaL_Buffer *B, const char *s, size_t l);
188void (*dll_luaL_pushresult) (luaL_Buffer *B);
189/* lua */
Bram Moolenaar1dced572012-04-05 16:54:08 +0200190#if LUA_VERSION_NUM <= 501
191lua_Number (*dll_lua_tonumber) (lua_State *L, int idx);
192lua_Integer (*dll_lua_tointeger) (lua_State *L, int idx);
193void (*dll_lua_call) (lua_State *L, int nargs, int nresults);
194int (*dll_lua_pcall) (lua_State *L, int nargs, int nresults, int errfunc);
195#else
196lua_Number (*dll_lua_tonumberx) (lua_State *L, int idx, int *isnum);
197lua_Integer (*dll_lua_tointegerx) (lua_State *L, int idx, int *isnum);
198void (*dll_lua_callk) (lua_State *L, int nargs, int nresults, int ctx,
199 lua_CFunction k);
200int (*dll_lua_pcallk) (lua_State *L, int nargs, int nresults, int errfunc,
201 int ctx, lua_CFunction k);
202void (*dll_lua_getglobal) (lua_State *L, const char *var);
203void (*dll_lua_setglobal) (lua_State *L, const char *var);
204const char *(*dll_lua_typename) (lua_State *L, int tp);
205#endif
Bram Moolenaar0ba04292010-07-14 23:23:17 +0200206void (*dll_lua_close) (lua_State *L);
207int (*dll_lua_gettop) (lua_State *L);
208void (*dll_lua_settop) (lua_State *L, int idx);
209void (*dll_lua_pushvalue) (lua_State *L, int idx);
210void (*dll_lua_replace) (lua_State *L, int idx);
Bram Moolenaar1dced572012-04-05 16:54:08 +0200211void (*dll_lua_remove) (lua_State *L, int idx);
Bram Moolenaar0ba04292010-07-14 23:23:17 +0200212int (*dll_lua_isnumber) (lua_State *L, int idx);
213int (*dll_lua_isstring) (lua_State *L, int idx);
214int (*dll_lua_type) (lua_State *L, int idx);
215int (*dll_lua_rawequal) (lua_State *L, int idx1, int idx2);
Bram Moolenaar0ba04292010-07-14 23:23:17 +0200216int (*dll_lua_toboolean) (lua_State *L, int idx);
217const char *(*dll_lua_tolstring) (lua_State *L, int idx, size_t *len);
218void *(*dll_lua_touserdata) (lua_State *L, int idx);
219void (*dll_lua_pushnil) (lua_State *L);
220void (*dll_lua_pushnumber) (lua_State *L, lua_Number n);
221void (*dll_lua_pushinteger) (lua_State *L, lua_Integer n);
222void (*dll_lua_pushlstring) (lua_State *L, const char *s, size_t l);
223void (*dll_lua_pushstring) (lua_State *L, const char *s);
224const char *(*dll_lua_pushfstring) (lua_State *L, const char *fmt, ...);
225void (*dll_lua_pushcclosure) (lua_State *L, lua_CFunction fn, int n);
226void (*dll_lua_pushboolean) (lua_State *L, int b);
227void (*dll_lua_pushlightuserdata) (lua_State *L, void *p);
228void (*dll_lua_getfield) (lua_State *L, int idx, const char *k);
229void (*dll_lua_rawget) (lua_State *L, int idx);
Bram Moolenaar1dced572012-04-05 16:54:08 +0200230void (*dll_lua_rawgeti) (lua_State *L, int idx, int n);
Bram Moolenaar0ba04292010-07-14 23:23:17 +0200231void (*dll_lua_createtable) (lua_State *L, int narr, int nrec);
232void *(*dll_lua_newuserdata) (lua_State *L, size_t sz);
233int (*dll_lua_getmetatable) (lua_State *L, int objindex);
234void (*dll_lua_setfield) (lua_State *L, int idx, const char *k);
235void (*dll_lua_rawset) (lua_State *L, int idx);
236void (*dll_lua_rawseti) (lua_State *L, int idx, int n);
237int (*dll_lua_setmetatable) (lua_State *L, int objindex);
Bram Moolenaar0ba04292010-07-14 23:23:17 +0200238/* libs */
239int (*dll_luaopen_base) (lua_State *L);
240int (*dll_luaopen_table) (lua_State *L);
241int (*dll_luaopen_string) (lua_State *L);
242int (*dll_luaopen_math) (lua_State *L);
Bram Moolenaar16c98f92010-07-28 22:46:08 +0200243int (*dll_luaopen_io) (lua_State *L);
Bram Moolenaar0ba04292010-07-14 23:23:17 +0200244int (*dll_luaopen_os) (lua_State *L);
245int (*dll_luaopen_package) (lua_State *L);
246int (*dll_luaopen_debug) (lua_State *L);
Bram Moolenaar16c98f92010-07-28 22:46:08 +0200247void (*dll_luaL_openlibs) (lua_State *L);
Bram Moolenaar0ba04292010-07-14 23:23:17 +0200248
249typedef void **luaV_function;
250typedef struct {
251 const char *name;
252 luaV_function func;
253} luaV_Reg;
254
255static const luaV_Reg luaV_dll[] = {
256 /* lauxlib */
Bram Moolenaar1dced572012-04-05 16:54:08 +0200257#if LUA_VERSION_NUM <= 501
Bram Moolenaar0ba04292010-07-14 23:23:17 +0200258 {"luaL_register", (luaV_function) &dll_luaL_register},
Bram Moolenaar1dced572012-04-05 16:54:08 +0200259 {"luaL_prepbuffer", (luaV_function) &dll_luaL_prepbuffer},
260 {"luaL_openlib", (luaV_function) &dll_luaL_openlib},
Bram Moolenaar0ba04292010-07-14 23:23:17 +0200261 {"luaL_typerror", (luaV_function) &dll_luaL_typerror},
Bram Moolenaar1dced572012-04-05 16:54:08 +0200262 {"luaL_loadfile", (luaV_function) &dll_luaL_loadfile},
263 {"luaL_loadbuffer", (luaV_function) &dll_luaL_loadbuffer},
264#else
265 {"luaL_prepbuffsize", (luaV_function) &dll_luaL_prepbuffsize},
266 {"luaL_setfuncs", (luaV_function) &dll_luaL_setfuncs},
267 {"luaL_loadfilex", (luaV_function) &dll_luaL_loadfilex},
268 {"luaL_loadbufferx", (luaV_function) &dll_luaL_loadbufferx},
269 {"luaL_argerror", (luaV_function) &dll_luaL_argerror},
270#endif
Bram Moolenaar0ba04292010-07-14 23:23:17 +0200271 {"luaL_checklstring", (luaV_function) &dll_luaL_checklstring},
272 {"luaL_checkinteger", (luaV_function) &dll_luaL_checkinteger},
273 {"luaL_optinteger", (luaV_function) &dll_luaL_optinteger},
274 {"luaL_checktype", (luaV_function) &dll_luaL_checktype},
275 {"luaL_error", (luaV_function) &dll_luaL_error},
Bram Moolenaar0ba04292010-07-14 23:23:17 +0200276 {"luaL_newstate", (luaV_function) &dll_luaL_newstate},
277 {"luaL_buffinit", (luaV_function) &dll_luaL_buffinit},
Bram Moolenaar0ba04292010-07-14 23:23:17 +0200278 {"luaL_addlstring", (luaV_function) &dll_luaL_addlstring},
279 {"luaL_pushresult", (luaV_function) &dll_luaL_pushresult},
280 /* lua */
Bram Moolenaar1dced572012-04-05 16:54:08 +0200281#if LUA_VERSION_NUM <= 501
282 {"lua_tonumber", (luaV_function) &dll_lua_tonumber},
283 {"lua_tointeger", (luaV_function) &dll_lua_tointeger},
284 {"lua_call", (luaV_function) &dll_lua_call},
285 {"lua_pcall", (luaV_function) &dll_lua_pcall},
286#else
287 {"lua_tonumberx", (luaV_function) &dll_lua_tonumberx},
288 {"lua_tointegerx", (luaV_function) &dll_lua_tointegerx},
289 {"lua_callk", (luaV_function) &dll_lua_callk},
290 {"lua_pcallk", (luaV_function) &dll_lua_pcallk},
291 {"lua_getglobal", (luaV_function) &dll_lua_getglobal},
292 {"lua_setglobal", (luaV_function) &dll_lua_setglobal},
293 {"lua_typename", (luaV_function) &dll_lua_typename},
294#endif
Bram Moolenaar0ba04292010-07-14 23:23:17 +0200295 {"lua_close", (luaV_function) &dll_lua_close},
296 {"lua_gettop", (luaV_function) &dll_lua_gettop},
297 {"lua_settop", (luaV_function) &dll_lua_settop},
298 {"lua_pushvalue", (luaV_function) &dll_lua_pushvalue},
299 {"lua_replace", (luaV_function) &dll_lua_replace},
Bram Moolenaar1dced572012-04-05 16:54:08 +0200300 {"lua_remove", (luaV_function) &dll_lua_remove},
Bram Moolenaar0ba04292010-07-14 23:23:17 +0200301 {"lua_isnumber", (luaV_function) &dll_lua_isnumber},
302 {"lua_isstring", (luaV_function) &dll_lua_isstring},
303 {"lua_type", (luaV_function) &dll_lua_type},
304 {"lua_rawequal", (luaV_function) &dll_lua_rawequal},
Bram Moolenaar0ba04292010-07-14 23:23:17 +0200305 {"lua_toboolean", (luaV_function) &dll_lua_toboolean},
306 {"lua_tolstring", (luaV_function) &dll_lua_tolstring},
307 {"lua_touserdata", (luaV_function) &dll_lua_touserdata},
308 {"lua_pushnil", (luaV_function) &dll_lua_pushnil},
309 {"lua_pushnumber", (luaV_function) &dll_lua_pushnumber},
310 {"lua_pushinteger", (luaV_function) &dll_lua_pushinteger},
311 {"lua_pushlstring", (luaV_function) &dll_lua_pushlstring},
312 {"lua_pushstring", (luaV_function) &dll_lua_pushstring},
313 {"lua_pushfstring", (luaV_function) &dll_lua_pushfstring},
314 {"lua_pushcclosure", (luaV_function) &dll_lua_pushcclosure},
315 {"lua_pushboolean", (luaV_function) &dll_lua_pushboolean},
316 {"lua_pushlightuserdata", (luaV_function) &dll_lua_pushlightuserdata},
317 {"lua_getfield", (luaV_function) &dll_lua_getfield},
318 {"lua_rawget", (luaV_function) &dll_lua_rawget},
Bram Moolenaar1dced572012-04-05 16:54:08 +0200319 {"lua_rawgeti", (luaV_function) &dll_lua_rawgeti},
Bram Moolenaar0ba04292010-07-14 23:23:17 +0200320 {"lua_createtable", (luaV_function) &dll_lua_createtable},
321 {"lua_newuserdata", (luaV_function) &dll_lua_newuserdata},
322 {"lua_getmetatable", (luaV_function) &dll_lua_getmetatable},
323 {"lua_setfield", (luaV_function) &dll_lua_setfield},
324 {"lua_rawset", (luaV_function) &dll_lua_rawset},
325 {"lua_rawseti", (luaV_function) &dll_lua_rawseti},
326 {"lua_setmetatable", (luaV_function) &dll_lua_setmetatable},
Bram Moolenaar0ba04292010-07-14 23:23:17 +0200327 /* libs */
328 {"luaopen_base", (luaV_function) &dll_luaopen_base},
329 {"luaopen_table", (luaV_function) &dll_luaopen_table},
330 {"luaopen_string", (luaV_function) &dll_luaopen_string},
331 {"luaopen_math", (luaV_function) &dll_luaopen_math},
Bram Moolenaar16c98f92010-07-28 22:46:08 +0200332 {"luaopen_io", (luaV_function) &dll_luaopen_io},
Bram Moolenaar0ba04292010-07-14 23:23:17 +0200333 {"luaopen_os", (luaV_function) &dll_luaopen_os},
334 {"luaopen_package", (luaV_function) &dll_luaopen_package},
335 {"luaopen_debug", (luaV_function) &dll_luaopen_debug},
Bram Moolenaar16c98f92010-07-28 22:46:08 +0200336 {"luaL_openlibs", (luaV_function) &dll_luaL_openlibs},
Bram Moolenaar0ba04292010-07-14 23:23:17 +0200337 {NULL, NULL}
338};
339
Bram Moolenaar2334b6d2010-07-22 21:32:16 +0200340static HANDLE hinstLua = NULL;
Bram Moolenaar0ba04292010-07-14 23:23:17 +0200341
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200342 static void
343end_dynamic_lua(void)
344{
345 if (hinstLua)
346 {
Bram Moolenaar2334b6d2010-07-22 21:32:16 +0200347 close_dll(hinstLua);
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200348 hinstLua = 0;
Bram Moolenaar0ba04292010-07-14 23:23:17 +0200349 }
350}
351
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200352 static int
353lua_link_init(char *libname, int verbose)
354{
Bram Moolenaar0ba04292010-07-14 23:23:17 +0200355 const luaV_Reg *reg;
356 if (hinstLua) return OK;
Bram Moolenaar2334b6d2010-07-22 21:32:16 +0200357 hinstLua = load_dll(libname);
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200358 if (!hinstLua)
359 {
360 if (verbose)
361 EMSG2(_(e_loadlib), libname);
362 return FAIL;
Bram Moolenaar0ba04292010-07-14 23:23:17 +0200363 }
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200364 for (reg = luaV_dll; reg->func; reg++)
365 {
Bram Moolenaar2334b6d2010-07-22 21:32:16 +0200366 if ((*reg->func = symbol_from_dll(hinstLua, reg->name)) == NULL)
367 {
368 close_dll(hinstLua);
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200369 hinstLua = 0;
370 if (verbose)
371 EMSG2(_(e_loadfunc), reg->name);
372 return FAIL;
373 }
Bram Moolenaar0ba04292010-07-14 23:23:17 +0200374 }
375 return OK;
376}
377
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200378 int
379lua_enabled(int verbose)
380{
Bram Moolenaar0ba04292010-07-14 23:23:17 +0200381 return lua_link_init(DYNAMIC_LUA_DLL, verbose) == OK;
382}
383
384#endif /* DYNAMIC_LUA */
385
Bram Moolenaar1dced572012-04-05 16:54:08 +0200386#if LUA_VERSION_NUM > 501
387 static int
388luaL_typeerror (lua_State *L, int narg, const char *tname)
389{
390 const char *msg = lua_pushfstring(L, "%s expected, got %s",
391 tname, luaL_typename(L, narg));
392 return luaL_argerror(L, narg, msg);
393}
394#endif
395
Bram Moolenaar0ba04292010-07-14 23:23:17 +0200396
397/* ======= Internal ======= */
398
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200399 static void
400luaV_newmetatable(lua_State *L, const char *tname)
401{
Bram Moolenaar0ba04292010-07-14 23:23:17 +0200402 lua_newtable(L);
403 lua_pushlightuserdata(L, (void *) tname);
404 lua_pushvalue(L, -2);
405 lua_rawset(L, LUA_REGISTRYINDEX);
406}
407
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200408 static void *
409luaV_toudata(lua_State *L, int ud, const char *tname)
410{
Bram Moolenaar0ba04292010-07-14 23:23:17 +0200411 void *p = lua_touserdata(L, ud);
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200412
413 if (p != NULL) /* value is userdata? */
414 {
415 if (lua_getmetatable(L, ud)) /* does it have a metatable? */
416 {
417 luaV_getfield(L, tname); /* get metatable */
418 if (lua_rawequal(L, -1, -2)) /* MTs match? */
419 {
420 lua_pop(L, 2); /* MTs */
421 return p;
422 }
423 }
Bram Moolenaar0ba04292010-07-14 23:23:17 +0200424 }
425 return NULL;
426}
427
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200428 static void *
Bram Moolenaar1dced572012-04-05 16:54:08 +0200429luaV_checkcache(lua_State *L, void *p)
430{
431 luaV_getudata(L, p);
432 if (lua_isnil(L, -1)) luaL_error(L, "invalid object");
433 lua_pop(L, 1);
434 return p;
435}
436
437#define luaV_unbox(L,luatyp,ud) (*((luatyp *) lua_touserdata((L),(ud))))
438
439#define luaV_checkvalid(L,luatyp,ud) \
440 luaV_checkcache((L), (void *) luaV_unbox((L),luatyp,(ud)))
441
442 static void *
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200443luaV_checkudata(lua_State *L, int ud, const char *tname)
444{
Bram Moolenaar0ba04292010-07-14 23:23:17 +0200445 void *p = luaV_toudata(L, ud, tname);
Bram Moolenaar1dced572012-04-05 16:54:08 +0200446 if (p == NULL) luaL_typeerror(L, ud, tname);
Bram Moolenaar0ba04292010-07-14 23:23:17 +0200447 return p;
448}
449
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200450 static void
451luaV_pushtypval(lua_State *L, typval_T *tv)
452{
Bram Moolenaar1dced572012-04-05 16:54:08 +0200453 if (tv == NULL)
454 {
455 lua_pushnil(L);
456 return;
457 }
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200458 switch (tv->v_type)
459 {
460 case VAR_STRING:
461 lua_pushstring(L, (char *) tv->vval.v_string);
462 break;
463 case VAR_NUMBER:
464 lua_pushinteger(L, (int) tv->vval.v_number);
465 break;
Bram Moolenaar0ba04292010-07-14 23:23:17 +0200466#ifdef FEAT_FLOAT
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200467 case VAR_FLOAT:
468 lua_pushnumber(L, (lua_Number) tv->vval.v_float);
469 break;
Bram Moolenaar0ba04292010-07-14 23:23:17 +0200470#endif
Bram Moolenaar1dced572012-04-05 16:54:08 +0200471 case VAR_LIST:
472 luaV_pushlist(L, tv->vval.v_list);
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200473 break;
Bram Moolenaar1dced572012-04-05 16:54:08 +0200474 case VAR_DICT:
475 luaV_pushdict(L, tv->vval.v_dict);
476 break;
477 default:
478 lua_pushnil(L);
479 }
480}
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200481
Bram Moolenaar1dced572012-04-05 16:54:08 +0200482/* converts lua value at 'pos' to typval 'tv' */
483 static void
484luaV_totypval (lua_State *L, int pos, typval_T *tv)
485{
486 switch(lua_type(L, pos)) {
487 case LUA_TBOOLEAN:
488 tv->v_type = VAR_NUMBER;
489 tv->vval.v_number = (varnumber_T) lua_toboolean(L, pos);
490 break;
491 case LUA_TSTRING:
492 tv->v_type = VAR_STRING;
493 tv->vval.v_string = vim_strsave((char_u *) lua_tostring(L, pos));
494 break;
495 case LUA_TNUMBER:
496#ifdef FEAT_FLOAT
497 tv->v_type = VAR_FLOAT;
498 tv->vval.v_float = (float_T) lua_tonumber(L, pos);
499#else
500 tv->v_type = VAR_NUMBER;
501 tv->vval.v_number = (varnumber_T) lua_tointeger(L, pos);
502#endif
503 break;
504 case LUA_TUSERDATA: {
505 void *p = lua_touserdata(L, pos);
506 if (lua_getmetatable(L, pos)) /* has metatable? */
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200507 {
Bram Moolenaar1dced572012-04-05 16:54:08 +0200508 /* check list */
509 luaV_getfield(L, LUAVIM_LIST);
510 if (lua_rawequal(L, -1, -2))
Bram Moolenaar2334b6d2010-07-22 21:32:16 +0200511 {
Bram Moolenaar1dced572012-04-05 16:54:08 +0200512 tv->v_type = VAR_LIST;
513 tv->vval.v_list = *((luaV_List *) p);
514 ++tv->vval.v_list->lv_refcount;
515 lua_pop(L, 2); /* MTs */
516 return;
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200517 }
Bram Moolenaar1dced572012-04-05 16:54:08 +0200518 /* check dict */
519 luaV_getfield(L, LUAVIM_DICT);
520 if (lua_rawequal(L, -1, -3))
521 {
522 tv->v_type = VAR_DICT;
523 tv->vval.v_dict = *((luaV_Dict *) p);
524 ++tv->vval.v_dict->dv_refcount;
525 lua_pop(L, 3); /* MTs */
526 return;
527 }
528 lua_pop(L, 3); /* MTs */
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200529 }
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200530 break;
531 }
532 default:
Bram Moolenaar1dced572012-04-05 16:54:08 +0200533 tv->v_type = VAR_NUMBER;
534 tv->vval.v_number = 0;
Bram Moolenaar0ba04292010-07-14 23:23:17 +0200535 }
536}
537
538/* similar to luaL_addlstring, but replaces \0 with \n if toline and
539 * \n with \0 otherwise */
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200540 static void
541luaV_addlstring(luaL_Buffer *b, const char *s, size_t l, int toline)
542{
543 while (l--)
544 {
545 if (*s == '\0' && toline)
546 luaL_addchar(b, '\n');
547 else if (*s == '\n' && !toline)
548 luaL_addchar(b, '\0');
549 else
550 luaL_addchar(b, *s);
551 s++;
Bram Moolenaar0ba04292010-07-14 23:23:17 +0200552 }
553}
554
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200555 static void
556luaV_pushline(lua_State *L, buf_T *buf, linenr_T n)
557{
Bram Moolenaar0ba04292010-07-14 23:23:17 +0200558 const char *s = (const char *) ml_get_buf(buf, n, FALSE);
559 luaL_Buffer b;
560 luaL_buffinit(L, &b);
561 luaV_addlstring(&b, s, strlen(s), 0);
562 luaL_pushresult(&b);
563}
564
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200565 static char_u *
566luaV_toline(lua_State *L, int pos)
567{
Bram Moolenaar0ba04292010-07-14 23:23:17 +0200568 size_t l;
569 const char *s = lua_tolstring(L, pos, &l);
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200570
Bram Moolenaar0ba04292010-07-14 23:23:17 +0200571 luaL_Buffer b;
572 luaL_buffinit(L, &b);
573 luaV_addlstring(&b, s, l, 1);
574 luaL_pushresult(&b);
575 return (char_u *) lua_tostring(L, -1);
576}
577
578/* pops a string s from the top of the stack and calls mf(t) for pieces t of
579 * s separated by newlines */
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200580 static void
581luaV_msgfunc(lua_State *L, msgfunc_T mf)
582{
Bram Moolenaar0ba04292010-07-14 23:23:17 +0200583 luaL_Buffer b;
584 size_t l;
585 const char *p, *s = lua_tolstring(L, -1, &l);
586 luaL_buffinit(L, &b);
587 luaV_addlstring(&b, s, l, 0);
588 luaL_pushresult(&b);
589 /* break string */
590 p = s = lua_tolstring(L, -1, &l);
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200591 while (l--)
592 {
593 if (*p++ == '\0') /* break? */
594 {
595 mf((char_u *) s);
596 s = p;
597 }
Bram Moolenaar0ba04292010-07-14 23:23:17 +0200598 }
599 mf((char_u *) s);
600 lua_pop(L, 2); /* original and modified strings */
601}
602
Bram Moolenaar1dced572012-04-05 16:54:08 +0200603#define luaV_newtype(typ,tname,luatyp,luatname) \
604 static luatyp * \
605 luaV_new##tname (lua_State *L, typ *obj) \
606 { \
607 luatyp *o = (luatyp *) lua_newuserdata(L, sizeof(luatyp)); \
608 *o = obj; \
609 luaV_setudata(L, obj); /* cache[obj] = udata */ \
610 luaV_getfield(L, luatname); \
611 lua_setmetatable(L, -2); \
612 return o; \
Bram Moolenaar0ba04292010-07-14 23:23:17 +0200613 }
Bram Moolenaar1dced572012-04-05 16:54:08 +0200614
615#define luaV_pushtype(typ,tname,luatyp) \
616 static luatyp * \
617 luaV_push##tname (lua_State *L, typ *obj) \
618 { \
619 luatyp *o = NULL; \
620 if (obj == NULL) \
621 lua_pushnil(L); \
622 else { \
623 luaV_getudata(L, obj); \
624 if (lua_isnil(L, -1)) /* not interned? */ \
625 { \
626 lua_pop(L, 1); \
627 o = luaV_new##tname(L, obj); \
628 } \
629 else \
630 o = (luatyp *) lua_touserdata(L, -1); \
631 } \
632 return o; \
633 }
634
635#define luaV_type_tostring(tname,luatname) \
636 static int \
637 luaV_##tname##_tostring (lua_State *L) \
638 { \
639 lua_pushfstring(L, "%s: %p", luatname, lua_touserdata(L, 1)); \
640 return 1; \
641 }
642
643
644/* adapted from eval.c */
645
646#define listitem_alloc() (listitem_T *)alloc(sizeof(listitem_T))
647
648 static listitem_T *
649list_find (list_T *l, long n)
650{
651 listitem_T *li;
652 if (l == NULL || n < -l->lv_len || n >= l->lv_len)
653 return NULL;
654 if (n < 0) /* search backward? */
655 for (li = l->lv_last; n < -1; li = li->li_prev)
656 n++;
657 else /* search forward */
658 for (li = l->lv_first; n > 0; li = li->li_next)
659 n--;
660 return li;
Bram Moolenaar0ba04292010-07-14 23:23:17 +0200661}
662
Bram Moolenaar1dced572012-04-05 16:54:08 +0200663 static void
664list_remove (list_T *l, listitem_T *li)
665{
666 listwatch_T *lw;
667 --l->lv_len;
668 /* fix watchers */
669 for (lw = l->lv_watch; lw != NULL; lw = lw->lw_next)
670 if (lw->lw_item == li)
671 lw->lw_item = li->li_next;
672 /* fix list pointers */
673 if (li->li_next == NULL) /* last? */
674 l->lv_last = li->li_prev;
675 else
676 li->li_next->li_prev = li->li_prev;
677 if (li->li_prev == NULL) /* first? */
678 l->lv_first = li->li_next;
679 else
680 li->li_prev->li_next = li->li_next;
681 l->lv_idx_item = NULL;
682}
683
684 static void
685list_append(list_T *l, listitem_T *item)
686{
687 if (l->lv_last == NULL) /* empty list? */
688 l->lv_first = item;
689 else
690 l->lv_last->li_next = item;
691 item->li_prev = l->lv_last;
692 item->li_next = NULL;
693 l->lv_last = item;
694 ++l->lv_len;
695}
Bram Moolenaar0ba04292010-07-14 23:23:17 +0200696
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200697 static int
Bram Moolenaar1dced572012-04-05 16:54:08 +0200698list_insert_tv(list_T *l, typval_T *tv, listitem_T *item)
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200699{
Bram Moolenaar1dced572012-04-05 16:54:08 +0200700 listitem_T *ni = listitem_alloc();
701
702 if (ni == NULL)
703 return FAIL;
704 copy_tv(tv, &ni->li_tv);
705 if (item == NULL)
706 list_append(l, ni);
707 else
708 {
709 ni->li_prev = item->li_prev;
710 ni->li_next = item;
711 if (item->li_prev == NULL)
712 {
713 l->lv_first = ni;
714 ++l->lv_idx;
715 }
716 else
717 {
718 item->li_prev->li_next = ni;
719 l->lv_idx_item = NULL;
720 }
721 item->li_prev = ni;
722 ++l->lv_len;
723 }
724 return OK;
725}
726
727/* set references */
728
729static void set_ref_in_tv (typval_T *tv, int copyID);
730
731 static void
732set_ref_in_dict(dict_T *d, int copyID)
733{
734 hashtab_T *ht = &d->dv_hashtab;
735 int n = ht->ht_used;
736 hashitem_T *hi;
737 for (hi = ht->ht_array; n > 0; ++hi)
738 if (!HASHITEM_EMPTY(hi))
739 {
740 dictitem_T *di = dict_lookup(hi);
741 set_ref_in_tv(&di->di_tv, copyID);
742 --n;
743 }
744}
745
746 static void
747set_ref_in_list(list_T *l, int copyID)
748{
749 listitem_T *li;
750 for (li = l->lv_first; li != NULL; li = li->li_next)
751 set_ref_in_tv(&li->li_tv, copyID);
752}
753
754 static void
755set_ref_in_tv(typval_T *tv, int copyID)
756{
757 if (tv->v_type == VAR_LIST)
758 {
759 list_T *l = tv->vval.v_list;
760 if (l != NULL && l->lv_copyID != copyID)
761 {
762 l->lv_copyID = copyID;
763 set_ref_in_list(l, copyID);
764 }
765 }
766 else if (tv->v_type == VAR_DICT)
767 {
768 dict_T *d = tv->vval.v_dict;
769 if (d != NULL && d->dv_copyID != copyID)
770 {
771 d->dv_copyID = copyID;
772 set_ref_in_dict(d, copyID);
773 }
774 }
775}
776
777
778/* ======= List type ======= */
779
780 static luaV_List *
781luaV_newlist (lua_State *L, list_T *lis)
782{
783 luaV_List *l = (luaV_List *) lua_newuserdata(L, sizeof(luaV_List));
784 *l = lis;
785 lis->lv_refcount++; /* reference in Lua */
786 luaV_setudata(L, lis); /* cache[lis] = udata */
787 luaV_getfield(L, LUAVIM_LIST);
788 lua_setmetatable(L, -2);
789 return l;
790}
791
792luaV_pushtype(list_T, list, luaV_List)
793luaV_type_tostring(list, LUAVIM_LIST)
794
795 static int
796luaV_list_gc (lua_State *L)
797{
798 list_unref(luaV_unbox(L, luaV_List, 1));
799 return 0;
800}
801
802 static int
803luaV_list_len (lua_State *L)
804{
805 list_T *l = luaV_unbox(L, luaV_List, 1);
806 lua_pushinteger(L, (l == NULL) ? 0 : (int) l->lv_len);
Bram Moolenaar0ba04292010-07-14 23:23:17 +0200807 return 1;
808}
809
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200810 static int
Bram Moolenaar1dced572012-04-05 16:54:08 +0200811luaV_list_iter (lua_State *L)
812{
813 listitem_T *li = (listitem_T *) lua_touserdata(L, lua_upvalueindex(2));
814 if (li == NULL) return 0;
815 luaV_pushtypval(L, &li->li_tv);
816 lua_pushlightuserdata(L, (void *) li->li_next);
817 lua_replace(L, lua_upvalueindex(2));
818 return 1;
819}
820
821 static int
822luaV_list_call (lua_State *L)
823{
824 list_T *l = luaV_unbox(L, luaV_List, 1);
825 lua_pushvalue(L, lua_upvalueindex(1)); /* pass cache table along */
826 lua_pushlightuserdata(L, (void *) l->lv_first);
827 lua_pushcclosure(L, luaV_list_iter, 2);
828 return 1;
829}
830
831 static int
832luaV_list_index (lua_State *L)
833{
834 list_T *l = luaV_unbox(L, luaV_List, 1);
835 if (lua_isnumber(L, 2)) /* list item? */
836 {
837 listitem_T *li = list_find(l, (long) luaL_checkinteger(L, 2));
838 if (li == NULL)
839 lua_pushnil(L);
840 else
841 luaV_pushtypval(L, &li->li_tv);
842 }
843 else if (lua_isstring(L, 2)) /* method? */
844 {
845 const char *s = lua_tostring(L, 2);
846 if (strncmp(s, "add", 3) == 0
847 || strncmp(s, "insert", 6) == 0
848 || strncmp(s, "extend", 6) == 0)
849 {
850 lua_getmetatable(L, 1);
851 lua_getfield(L, -1, s);
852 }
853 else
854 lua_pushnil(L);
855 }
856 else
857 lua_pushnil(L);
858 return 1;
859}
860
861 static int
862luaV_list_newindex (lua_State *L)
863{
864 list_T *l = luaV_unbox(L, luaV_List, 1);
865 long n = (long) luaL_checkinteger(L, 2);
866 listitem_T *li;
867 if (l->lv_lock)
868 luaL_error(L, "list is locked");
869 li = list_find(l, n);
870 if (li == NULL) return 0;
871 if (lua_isnil(L, 3)) /* remove? */
872 {
873 list_remove(l, li);
874 clear_tv(&li->li_tv);
875 vim_free(li);
876 }
877 else
878 {
879 typval_T v;
880 luaV_totypval(L, 3, &v);
881 clear_tv(&li->li_tv);
882 copy_tv(&v, &li->li_tv);
883 }
884 return 0;
885}
886
887 static int
888luaV_list_add (lua_State *L)
889{
890 luaV_List *lis = luaV_checkudata(L, 1, LUAVIM_LIST);
891 list_T *l = (list_T *) luaV_checkcache(L, (void *) *lis);
892 listitem_T *li;
893 if (l->lv_lock)
894 luaL_error(L, "list is locked");
895 li = listitem_alloc();
896 if (li != NULL)
897 {
898 typval_T v;
899 lua_settop(L, 2);
900 luaV_totypval(L, 2, &v);
901 copy_tv(&v, &li->li_tv);
902 list_append(l, li);
903 }
904 lua_settop(L, 1);
905 return 1;
906}
907
908 static int
909luaV_list_insert (lua_State *L)
910{
911 luaV_List *lis = luaV_checkudata(L, 1, LUAVIM_LIST);
912 list_T *l = (list_T *) luaV_checkcache(L, (void *) *lis);
913 long pos = luaL_optlong(L, 3, 0);
914 listitem_T *li = NULL;
915 typval_T v;
916 if (l->lv_lock)
917 luaL_error(L, "list is locked");
918 if (pos < l->lv_len)
919 {
920 li = list_find(l, pos);
921 if (li == NULL)
922 luaL_error(L, "invalid position");
923 }
924 lua_settop(L, 2);
925 luaV_totypval(L, 2, &v);
926 list_insert_tv(l, &v, li);
927 lua_settop(L, 1);
928 return 1;
929}
930
931static const luaL_Reg luaV_List_mt[] = {
932 {"__tostring", luaV_list_tostring},
933 {"__gc", luaV_list_gc},
934 {"__len", luaV_list_len},
935 {"__call", luaV_list_call},
936 {"__index", luaV_list_index},
937 {"__newindex", luaV_list_newindex},
938 {"add", luaV_list_add},
939 {"insert", luaV_list_insert},
940 {NULL, NULL}
941};
942
943
944/* ======= Dict type ======= */
945
946 static luaV_Dict *
947luaV_newdict (lua_State *L, dict_T *dic)
948{
949 luaV_Dict *d = (luaV_Dict *) lua_newuserdata(L, sizeof(luaV_Dict));
950 *d = dic;
951 dic->dv_refcount++; /* reference in Lua */
952 luaV_setudata(L, dic); /* cache[dic] = udata */
953 luaV_getfield(L, LUAVIM_DICT);
954 lua_setmetatable(L, -2);
955 return d;
956}
957
958luaV_pushtype(dict_T, dict, luaV_Dict)
959luaV_type_tostring(dict, LUAVIM_DICT)
960
961 static int
962luaV_dict_gc (lua_State *L)
963{
964 dict_unref(luaV_unbox(L, luaV_Dict, 1));
965 return 0;
966}
967
968 static int
969luaV_dict_len (lua_State *L)
970{
971 dict_T *d = luaV_unbox(L, luaV_Dict, 1);
972 lua_pushinteger(L, (d == NULL) ? 0 : (int) d->dv_hashtab.ht_used);
973 return 1;
974}
975
976 static int
977luaV_dict_iter (lua_State *L)
978{
979 hashitem_T *hi = (hashitem_T *) lua_touserdata(L, lua_upvalueindex(2));
980 int n = lua_tointeger(L, lua_upvalueindex(3));
981 dictitem_T *di;
982 if (n <= 0) return 0;
983 while (HASHITEM_EMPTY(hi)) hi++;
984 di = dict_lookup(hi);
985 lua_pushstring(L, (char *) hi->hi_key);
986 luaV_pushtypval(L, &di->di_tv);
987 lua_pushlightuserdata(L, (void *) (hi + 1));
988 lua_replace(L, lua_upvalueindex(2));
989 lua_pushinteger(L, n - 1);
990 lua_replace(L, lua_upvalueindex(3));
991 return 2;
992}
993
994 static int
995luaV_dict_call (lua_State *L)
996{
997 dict_T *d = luaV_unbox(L, luaV_Dict, 1);
998 hashtab_T *ht = &d->dv_hashtab;
999 lua_pushvalue(L, lua_upvalueindex(1)); /* pass cache table along */
1000 lua_pushlightuserdata(L, (void *) ht->ht_array);
1001 lua_pushinteger(L, ht->ht_used); /* # remaining items */
1002 lua_pushcclosure(L, luaV_dict_iter, 3);
1003 return 1;
1004}
1005
1006 static int
1007luaV_dict_index (lua_State *L)
1008{
1009 dict_T *d = luaV_unbox(L, luaV_Dict, 1);
1010 char_u *key = (char_u *) luaL_checkstring(L, 2);
1011 dictitem_T *di = dict_find(d, key, -1);
1012 if (di == NULL)
1013 lua_pushnil(L);
1014 else
1015 luaV_pushtypval(L, &di->di_tv);
1016 return 1;
1017}
1018
1019 static int
1020luaV_dict_newindex (lua_State *L)
1021{
1022 dict_T *d = luaV_unbox(L, luaV_Dict, 1);
1023 char_u *key = (char_u *) luaL_checkstring(L, 2);
1024 dictitem_T *di;
1025 if (d->dv_lock)
1026 luaL_error(L, "dict is locked");
1027 di = dict_find(d, key, -1);
1028 if (di == NULL) /* non-existing key? */
1029 {
1030 if (lua_isnil(L, 3)) return 0;
1031 di = dictitem_alloc(key);
1032 if (di == NULL) return 0;
1033 if (dict_add(d, di) == FAIL)
1034 {
1035 vim_free(di);
1036 return 0;
1037 }
1038 }
1039 else
1040 clear_tv(&di->di_tv);
1041 if (lua_isnil(L, 3)) /* remove? */
1042 {
1043 hashitem_T *hi = hash_find(&d->dv_hashtab, di->di_key);
1044 hash_remove(&d->dv_hashtab, hi);
1045 dictitem_free(di);
1046 }
1047 else {
1048 typval_T v;
1049 luaV_totypval(L, 3, &v);
1050 copy_tv(&v, &di->di_tv);
1051 }
1052 return 0;
1053}
1054
1055static const luaL_Reg luaV_Dict_mt[] = {
1056 {"__tostring", luaV_dict_tostring},
1057 {"__gc", luaV_dict_gc},
1058 {"__len", luaV_dict_len},
1059 {"__call", luaV_dict_call},
1060 {"__index", luaV_dict_index},
1061 {"__newindex", luaV_dict_newindex},
1062 {NULL, NULL}
1063};
1064
1065
1066/* ======= Buffer type ======= */
1067
1068luaV_newtype(buf_T, buffer, luaV_Buffer, LUAVIM_BUFFER)
1069luaV_pushtype(buf_T, buffer, luaV_Buffer)
1070luaV_type_tostring(buffer, LUAVIM_BUFFER)
1071
1072 static int
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001073luaV_buffer_len(lua_State *L)
1074{
Bram Moolenaar1dced572012-04-05 16:54:08 +02001075 buf_T *b = (buf_T *) luaV_checkvalid(L, luaV_Buffer, 1);
1076 lua_pushinteger(L, b->b_ml.ml_line_count);
Bram Moolenaar0ba04292010-07-14 23:23:17 +02001077 return 1;
1078}
1079
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001080 static int
1081luaV_buffer_call(lua_State *L)
1082{
Bram Moolenaar1dced572012-04-05 16:54:08 +02001083 buf_T *b = (buf_T *) luaV_checkvalid(L, luaV_Buffer, 1);
Bram Moolenaar0ba04292010-07-14 23:23:17 +02001084 lua_settop(L, 1);
Bram Moolenaar1dced572012-04-05 16:54:08 +02001085 set_curbuf(b, DOBUF_SPLIT);
Bram Moolenaar0ba04292010-07-14 23:23:17 +02001086 return 1;
1087}
1088
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001089 static int
1090luaV_buffer_index(lua_State *L)
1091{
Bram Moolenaar1dced572012-04-05 16:54:08 +02001092 buf_T *b = (buf_T *) luaV_checkvalid(L, luaV_Buffer, 1);
Bram Moolenaar0ba04292010-07-14 23:23:17 +02001093 linenr_T n = (linenr_T) lua_tointeger(L, 2);
Bram Moolenaar1dced572012-04-05 16:54:08 +02001094 if (n > 0 && n <= b->b_ml.ml_line_count)
1095 luaV_pushline(L, b, n);
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001096 else if (lua_isstring(L, 2))
1097 {
1098 const char *s = lua_tostring(L, 2);
1099 if (strncmp(s, "name", 4) == 0)
Bram Moolenaar1dced572012-04-05 16:54:08 +02001100 lua_pushstring(L, (char *) b->b_sfname);
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001101 else if (strncmp(s, "fname", 5) == 0)
Bram Moolenaar1dced572012-04-05 16:54:08 +02001102 lua_pushstring(L, (char *) b->b_ffname);
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001103 else if (strncmp(s, "number", 6) == 0)
Bram Moolenaar1dced572012-04-05 16:54:08 +02001104 lua_pushinteger(L, b->b_fnum);
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001105 /* methods */
1106 else if (strncmp(s, "insert", 6) == 0
1107 || strncmp(s, "next", 4) == 0
1108 || strncmp(s, "previous", 8) == 0
1109 || strncmp(s, "isvalid", 7) == 0)
1110 {
1111 lua_getmetatable(L, 1);
1112 lua_getfield(L, -1, s);
1113 }
1114 else
1115 lua_pushnil(L);
Bram Moolenaar0ba04292010-07-14 23:23:17 +02001116 }
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001117 else
1118 lua_pushnil(L);
Bram Moolenaar0ba04292010-07-14 23:23:17 +02001119 return 1;
1120}
1121
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001122 static int
1123luaV_buffer_newindex(lua_State *L)
1124{
Bram Moolenaar1dced572012-04-05 16:54:08 +02001125 buf_T *b = (buf_T *) luaV_checkvalid(L, luaV_Buffer, 1);
Bram Moolenaar0ba04292010-07-14 23:23:17 +02001126 linenr_T n = (linenr_T) luaL_checkinteger(L, 2);
1127#ifdef HAVE_SANDBOX
1128 luaV_checksandbox(L);
1129#endif
Bram Moolenaar1dced572012-04-05 16:54:08 +02001130 if (n < 1 || n > b->b_ml.ml_line_count)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001131 luaL_error(L, "invalid line number");
1132 if (lua_isnil(L, 3)) /* delete line */
1133 {
1134 buf_T *buf = curbuf;
Bram Moolenaar1dced572012-04-05 16:54:08 +02001135 curbuf = b;
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001136 if (u_savedel(n, 1L) == FAIL)
1137 {
1138 curbuf = buf;
1139 luaL_error(L, "cannot save undo information");
1140 }
1141 else if (ml_delete(n, FALSE) == FAIL)
1142 {
1143 curbuf = buf;
1144 luaL_error(L, "cannot delete line");
1145 }
1146 else {
1147 deleted_lines_mark(n, 1L);
Bram Moolenaar1dced572012-04-05 16:54:08 +02001148 if (b == curwin->w_buffer) /* fix cursor in current window? */
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001149 {
1150 if (curwin->w_cursor.lnum >= n)
1151 {
1152 if (curwin->w_cursor.lnum > n)
1153 {
1154 curwin->w_cursor.lnum -= 1;
1155 check_cursor_col();
1156 }
1157 else check_cursor();
1158 changed_cline_bef_curs();
1159 }
1160 invalidate_botline();
1161 }
1162 }
1163 curbuf = buf;
Bram Moolenaar0ba04292010-07-14 23:23:17 +02001164 }
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001165 else if (lua_isstring(L, 3)) /* update line */
1166 {
1167 buf_T *buf = curbuf;
Bram Moolenaar1dced572012-04-05 16:54:08 +02001168 curbuf = b;
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001169 if (u_savesub(n) == FAIL)
1170 {
1171 curbuf = buf;
1172 luaL_error(L, "cannot save undo information");
1173 }
1174 else if (ml_replace(n, luaV_toline(L, 3), TRUE) == FAIL)
1175 {
1176 curbuf = buf;
1177 luaL_error(L, "cannot replace line");
1178 }
1179 else changed_bytes(n, 0);
1180 curbuf = buf;
Bram Moolenaar1dced572012-04-05 16:54:08 +02001181 if (b == curwin->w_buffer)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001182 check_cursor_col();
Bram Moolenaar0ba04292010-07-14 23:23:17 +02001183 }
1184 else
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001185 luaL_error(L, "wrong argument to change line");
Bram Moolenaar0ba04292010-07-14 23:23:17 +02001186 return 0;
1187}
1188
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001189 static int
1190luaV_buffer_insert(lua_State *L)
1191{
Bram Moolenaar1dced572012-04-05 16:54:08 +02001192 luaV_Buffer *lb = luaV_checkudata(L, 1, LUAVIM_BUFFER);
1193 buf_T *b = (buf_T *) luaV_checkcache(L, (void *) *lb);
1194 linenr_T last = b->b_ml.ml_line_count;
Bram Moolenaar0ba04292010-07-14 23:23:17 +02001195 linenr_T n = (linenr_T) luaL_optinteger(L, 3, last);
1196 buf_T *buf;
1197 luaL_checktype(L, 2, LUA_TSTRING);
1198#ifdef HAVE_SANDBOX
1199 luaV_checksandbox(L);
1200#endif
1201 /* fix insertion line */
1202 if (n < 0) n = 0;
1203 if (n > last) n = last;
1204 /* insert */
1205 buf = curbuf;
Bram Moolenaar1dced572012-04-05 16:54:08 +02001206 curbuf = b;
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001207 if (u_save(n, n + 1) == FAIL)
1208 {
1209 curbuf = buf;
1210 luaL_error(L, "cannot save undo information");
Bram Moolenaar0ba04292010-07-14 23:23:17 +02001211 }
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001212 else if (ml_append(n, luaV_toline(L, 2), 0, FALSE) == FAIL)
1213 {
1214 curbuf = buf;
1215 luaL_error(L, "cannot insert line");
Bram Moolenaar0ba04292010-07-14 23:23:17 +02001216 }
1217 else
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001218 appended_lines_mark(n, 1L);
Bram Moolenaar0ba04292010-07-14 23:23:17 +02001219 curbuf = buf;
1220 update_screen(VALID);
1221 return 0;
1222}
1223
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001224 static int
1225luaV_buffer_next(lua_State *L)
1226{
Bram Moolenaar0ba04292010-07-14 23:23:17 +02001227 luaV_Buffer *b = luaV_checkudata(L, 1, LUAVIM_BUFFER);
Bram Moolenaar1dced572012-04-05 16:54:08 +02001228 buf_T *buf = (buf_T *) luaV_checkcache(L, (void *) *b);
1229 luaV_pushbuffer(L, buf->b_next);
Bram Moolenaar0ba04292010-07-14 23:23:17 +02001230 return 1;
1231}
1232
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001233 static int
1234luaV_buffer_previous(lua_State *L)
1235{
Bram Moolenaar0ba04292010-07-14 23:23:17 +02001236 luaV_Buffer *b = luaV_checkudata(L, 1, LUAVIM_BUFFER);
Bram Moolenaar1dced572012-04-05 16:54:08 +02001237 buf_T *buf = (buf_T *) luaV_checkcache(L, (void *) *b);
1238 luaV_pushbuffer(L, buf->b_prev);
Bram Moolenaar0ba04292010-07-14 23:23:17 +02001239 return 1;
1240}
1241
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001242 static int
1243luaV_buffer_isvalid(lua_State *L)
1244{
Bram Moolenaar0ba04292010-07-14 23:23:17 +02001245 luaV_Buffer *b = luaV_checkudata(L, 1, LUAVIM_BUFFER);
Bram Moolenaar1dced572012-04-05 16:54:08 +02001246 luaV_getudata(L, *b);
Bram Moolenaar0ba04292010-07-14 23:23:17 +02001247 lua_pushboolean(L, !lua_isnil(L, -1));
1248 return 1;
1249}
1250
1251static const luaL_Reg luaV_Buffer_mt[] = {
1252 {"__tostring", luaV_buffer_tostring},
1253 {"__len", luaV_buffer_len},
1254 {"__call", luaV_buffer_call},
1255 {"__index", luaV_buffer_index},
1256 {"__newindex", luaV_buffer_newindex},
1257 {"insert", luaV_buffer_insert},
1258 {"next", luaV_buffer_next},
1259 {"previous", luaV_buffer_previous},
1260 {"isvalid", luaV_buffer_isvalid},
1261 {NULL, NULL}
1262};
1263
1264
1265/* ======= Window type ======= */
1266
Bram Moolenaar1dced572012-04-05 16:54:08 +02001267luaV_newtype(win_T, window, luaV_Window, LUAVIM_WINDOW)
1268luaV_pushtype(win_T, window, luaV_Window)
1269luaV_type_tostring(window, LUAVIM_WINDOW)
Bram Moolenaar0ba04292010-07-14 23:23:17 +02001270
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001271 static int
1272luaV_window_call(lua_State *L)
1273{
Bram Moolenaar1dced572012-04-05 16:54:08 +02001274 win_T *w = (win_T *) luaV_checkvalid(L, luaV_Window, 1);
Bram Moolenaar0ba04292010-07-14 23:23:17 +02001275 lua_settop(L, 1);
Bram Moolenaar1dced572012-04-05 16:54:08 +02001276 win_goto(w);
Bram Moolenaar0ba04292010-07-14 23:23:17 +02001277 return 1;
1278}
1279
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001280 static int
1281luaV_window_index(lua_State *L)
1282{
Bram Moolenaar1dced572012-04-05 16:54:08 +02001283 win_T *w = (win_T *) luaV_checkvalid(L, luaV_Window, 1);
Bram Moolenaar0ba04292010-07-14 23:23:17 +02001284 const char *s = luaL_checkstring(L, 2);
1285 if (strncmp(s, "buffer", 6) == 0)
Bram Moolenaar1dced572012-04-05 16:54:08 +02001286 luaV_pushbuffer(L, w->w_buffer);
Bram Moolenaar0ba04292010-07-14 23:23:17 +02001287 else if (strncmp(s, "line", 4) == 0)
Bram Moolenaar1dced572012-04-05 16:54:08 +02001288 lua_pushinteger(L, w->w_cursor.lnum);
Bram Moolenaar0ba04292010-07-14 23:23:17 +02001289 else if (strncmp(s, "col", 3) == 0)
Bram Moolenaar1dced572012-04-05 16:54:08 +02001290 lua_pushinteger(L, w->w_cursor.col + 1);
Bram Moolenaar0ba04292010-07-14 23:23:17 +02001291#ifdef FEAT_VERTSPLIT
1292 else if (strncmp(s, "width", 5) == 0)
Bram Moolenaar1dced572012-04-05 16:54:08 +02001293 lua_pushinteger(L, W_WIDTH(w));
Bram Moolenaar0ba04292010-07-14 23:23:17 +02001294#endif
1295 else if (strncmp(s, "height", 6) == 0)
Bram Moolenaar1dced572012-04-05 16:54:08 +02001296 lua_pushinteger(L, w->w_height);
Bram Moolenaar0ba04292010-07-14 23:23:17 +02001297 /* methods */
1298 else if (strncmp(s, "next", 4) == 0
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001299 || strncmp(s, "previous", 8) == 0
1300 || strncmp(s, "isvalid", 7) == 0)
1301 {
1302 lua_getmetatable(L, 1);
1303 lua_getfield(L, -1, s);
Bram Moolenaar0ba04292010-07-14 23:23:17 +02001304 }
1305 else
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001306 lua_pushnil(L);
Bram Moolenaar0ba04292010-07-14 23:23:17 +02001307 return 1;
1308}
1309
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001310 static int
1311luaV_window_newindex (lua_State *L)
1312{
Bram Moolenaar1dced572012-04-05 16:54:08 +02001313 win_T *w = (win_T *) luaV_checkvalid(L, luaV_Window, 1);
Bram Moolenaar0ba04292010-07-14 23:23:17 +02001314 const char *s = luaL_checkstring(L, 2);
1315 int v = luaL_checkinteger(L, 3);
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001316 if (strncmp(s, "line", 4) == 0)
1317 {
Bram Moolenaar0ba04292010-07-14 23:23:17 +02001318#ifdef HAVE_SANDBOX
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001319 luaV_checksandbox(L);
Bram Moolenaar0ba04292010-07-14 23:23:17 +02001320#endif
Bram Moolenaar1dced572012-04-05 16:54:08 +02001321 if (v < 1 || v > w->w_buffer->b_ml.ml_line_count)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001322 luaL_error(L, "line out of range");
Bram Moolenaar1dced572012-04-05 16:54:08 +02001323 w->w_cursor.lnum = v;
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001324 update_screen(VALID);
Bram Moolenaar0ba04292010-07-14 23:23:17 +02001325 }
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001326 else if (strncmp(s, "col", 3) == 0)
1327 {
Bram Moolenaar0ba04292010-07-14 23:23:17 +02001328#ifdef HAVE_SANDBOX
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001329 luaV_checksandbox(L);
Bram Moolenaar0ba04292010-07-14 23:23:17 +02001330#endif
Bram Moolenaar1dced572012-04-05 16:54:08 +02001331 w->w_cursor.col = v - 1;
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001332 update_screen(VALID);
Bram Moolenaar0ba04292010-07-14 23:23:17 +02001333 }
1334#ifdef FEAT_VERTSPLIT
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001335 else if (strncmp(s, "width", 5) == 0)
1336 {
1337 win_T *win = curwin;
Bram Moolenaar0ba04292010-07-14 23:23:17 +02001338#ifdef FEAT_GUI
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001339 need_mouse_correct = TRUE;
Bram Moolenaar0ba04292010-07-14 23:23:17 +02001340#endif
Bram Moolenaar1dced572012-04-05 16:54:08 +02001341 curwin = w;
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001342 win_setwidth(v);
1343 curwin = win;
Bram Moolenaar0ba04292010-07-14 23:23:17 +02001344 }
1345#endif
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001346 else if (strncmp(s, "height", 6) == 0)
1347 {
1348 win_T *win = curwin;
Bram Moolenaar0ba04292010-07-14 23:23:17 +02001349#ifdef FEAT_GUI
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001350 need_mouse_correct = TRUE;
Bram Moolenaar0ba04292010-07-14 23:23:17 +02001351#endif
Bram Moolenaar1dced572012-04-05 16:54:08 +02001352 curwin = w;
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001353 win_setheight(v);
1354 curwin = win;
Bram Moolenaar0ba04292010-07-14 23:23:17 +02001355 }
1356 else
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001357 luaL_error(L, "invalid window property: `%s'", s);
Bram Moolenaar0ba04292010-07-14 23:23:17 +02001358 return 0;
1359}
1360
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001361 static int
1362luaV_window_next(lua_State *L)
1363{
Bram Moolenaar0ba04292010-07-14 23:23:17 +02001364 luaV_Window *w = luaV_checkudata(L, 1, LUAVIM_WINDOW);
Bram Moolenaar1dced572012-04-05 16:54:08 +02001365 win_T *win = (win_T *) luaV_checkcache(L, (void *) *w);
1366 luaV_pushwindow(L, win->w_next);
Bram Moolenaar0ba04292010-07-14 23:23:17 +02001367 return 1;
1368}
1369
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001370 static int
1371luaV_window_previous(lua_State *L)
1372{
Bram Moolenaar0ba04292010-07-14 23:23:17 +02001373 luaV_Window *w = luaV_checkudata(L, 1, LUAVIM_WINDOW);
Bram Moolenaar1dced572012-04-05 16:54:08 +02001374 win_T *win = (win_T *) luaV_checkcache(L, (void *) *w);
1375 luaV_pushwindow(L, win->w_prev);
Bram Moolenaar0ba04292010-07-14 23:23:17 +02001376 return 1;
1377}
1378
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001379 static int
1380luaV_window_isvalid(lua_State *L)
1381{
Bram Moolenaar0ba04292010-07-14 23:23:17 +02001382 luaV_Window *w = luaV_checkudata(L, 1, LUAVIM_WINDOW);
Bram Moolenaar1dced572012-04-05 16:54:08 +02001383 luaV_getudata(L, *w);
Bram Moolenaar0ba04292010-07-14 23:23:17 +02001384 lua_pushboolean(L, !lua_isnil(L, -1));
1385 return 1;
1386}
1387
1388static const luaL_Reg luaV_Window_mt[] = {
1389 {"__tostring", luaV_window_tostring},
1390 {"__call", luaV_window_call},
1391 {"__index", luaV_window_index},
1392 {"__newindex", luaV_window_newindex},
1393 {"next", luaV_window_next},
1394 {"previous", luaV_window_previous},
1395 {"isvalid", luaV_window_isvalid},
1396 {NULL, NULL}
1397};
1398
1399
1400/* ======= Vim module ======= */
1401
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001402 static int
1403luaV_print(lua_State *L)
1404{
Bram Moolenaar0ba04292010-07-14 23:23:17 +02001405 int i, n = lua_gettop(L); /* nargs */
1406 const char *s;
1407 size_t l;
1408 luaL_Buffer b;
1409 luaL_buffinit(L, &b);
1410 lua_getglobal(L, "tostring");
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001411 for (i = 1; i <= n; i++)
1412 {
1413 lua_pushvalue(L, -1); /* tostring */
1414 lua_pushvalue(L, i); /* arg */
1415 lua_call(L, 1, 1);
1416 s = lua_tolstring(L, -1, &l);
1417 if (s == NULL)
1418 return luaL_error(L, "cannot convert to string");
1419 if (i > 1) luaL_addchar(&b, ' '); /* use space instead of tab */
1420 luaV_addlstring(&b, s, l, 0);
1421 lua_pop(L, 1);
Bram Moolenaar0ba04292010-07-14 23:23:17 +02001422 }
1423 luaL_pushresult(&b);
1424 luaV_msg(L);
1425 return 0;
1426}
1427
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001428 static int
Bram Moolenaar38e2b062011-09-21 17:15:39 +02001429luaV_debug(lua_State *L)
1430{
1431 lua_settop(L, 0);
1432 lua_getglobal(L, "vim");
1433 lua_getfield(L, -1, "eval");
1434 lua_remove(L, -2); /* vim.eval at position 1 */
1435 for (;;)
1436 {
1437 const char *input;
1438 size_t l;
1439 lua_pushvalue(L, 1); /* vim.eval */
1440 lua_pushliteral(L, "input('lua_debug> ')");
1441 lua_call(L, 1, 1); /* return string */
1442 input = lua_tolstring(L, -1, &l);
1443 if (l == 0 || strcmp(input, "cont") == 0)
1444 return 0;
1445 msg_putchar('\n'); /* avoid outputting on input line */
1446 if (luaL_loadbuffer(L, input, l, "=(debug command)")
1447 || lua_pcall(L, 0, 0, 0))
1448 luaV_emsg(L);
1449 lua_settop(L, 1); /* remove eventual returns, but keep vim.eval */
1450 }
1451}
1452
1453 static int
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001454luaV_command(lua_State *L)
1455{
Bram Moolenaar0ba04292010-07-14 23:23:17 +02001456 do_cmdline_cmd((char_u *) luaL_checkstring(L, 1));
1457 update_screen(VALID);
1458 return 0;
1459}
1460
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001461 static int
1462luaV_eval(lua_State *L)
1463{
Bram Moolenaar0ba04292010-07-14 23:23:17 +02001464 typval_T *tv = eval_expr((char_u *) luaL_checkstring(L, 1), NULL);
1465 if (tv == NULL) luaL_error(L, "invalid expression");
1466 luaV_pushtypval(L, tv);
1467 return 1;
1468}
1469
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001470 static int
Bram Moolenaar0d2e4fc2010-07-18 12:35:47 +02001471luaV_beep(lua_State *L UNUSED)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001472{
Bram Moolenaar0ba04292010-07-14 23:23:17 +02001473 vim_beep();
1474 return 0;
1475}
1476
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001477 static int
1478luaV_line(lua_State *L)
1479{
Bram Moolenaar0ba04292010-07-14 23:23:17 +02001480 luaV_pushline(L, curbuf, curwin->w_cursor.lnum);
1481 return 1;
1482}
1483
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001484 static int
Bram Moolenaar1dced572012-04-05 16:54:08 +02001485luaV_list(lua_State *L)
1486{
1487 list_T *l = list_alloc();
1488 if (l == NULL)
1489 lua_pushnil(L);
1490 else
1491 luaV_newlist(L, l);
1492 return 1;
1493}
1494
1495 static int
1496luaV_dict(lua_State *L)
1497{
1498 dict_T *d = dict_alloc();
1499 if (d == NULL)
1500 lua_pushnil(L);
1501 else
1502 luaV_newdict(L, d);
1503 return 1;
1504}
1505
1506 static int
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001507luaV_buffer(lua_State *L)
1508{
Bram Moolenaar0ba04292010-07-14 23:23:17 +02001509 buf_T *buf;
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001510 if (lua_isstring(L, 1)) /* get by number or name? */
1511 {
1512 if (lua_isnumber(L, 1)) /* by number? */
1513 {
1514 int n = lua_tointeger(L, 1);
1515 for (buf = firstbuf; buf != NULL; buf = buf->b_next)
1516 if (buf->b_fnum == n) break;
1517 }
1518 else { /* by name */
1519 size_t l;
1520 const char *s = lua_tolstring(L, 1, &l);
1521 for (buf = firstbuf; buf != NULL; buf = buf->b_next)
1522 {
1523 if (buf->b_ffname == NULL || buf->b_sfname == NULL)
1524 {
1525 if (l == 0) break;
1526 }
Bram Moolenaar0d2e4fc2010-07-18 12:35:47 +02001527 else if (strncmp(s, (char *)buf->b_ffname, l) == 0
1528 || strncmp(s, (char *)buf->b_sfname, l) == 0)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001529 break;
1530 }
1531 }
Bram Moolenaar0ba04292010-07-14 23:23:17 +02001532 }
Bram Moolenaar1dced572012-04-05 16:54:08 +02001533 else
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001534 buf = (lua_toboolean(L, 1)) ? firstbuf : curbuf; /* first buffer? */
Bram Moolenaar1dced572012-04-05 16:54:08 +02001535 luaV_pushbuffer(L, buf);
Bram Moolenaar0ba04292010-07-14 23:23:17 +02001536 return 1;
1537}
1538
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001539 static int
1540luaV_window(lua_State *L)
1541{
Bram Moolenaar0ba04292010-07-14 23:23:17 +02001542 win_T *win;
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001543 if (lua_isnumber(L, 1)) /* get by number? */
1544 {
1545 int n = lua_tointeger(L, 1);
1546 for (win = firstwin; win != NULL; win = win->w_next, n--)
1547 if (n == 1) break;
Bram Moolenaar0ba04292010-07-14 23:23:17 +02001548 }
Bram Moolenaar1dced572012-04-05 16:54:08 +02001549 else
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001550 win = (lua_toboolean(L, 1)) ? firstwin : curwin; /* first window? */
Bram Moolenaar1dced572012-04-05 16:54:08 +02001551 luaV_pushwindow(L, win);
Bram Moolenaar0ba04292010-07-14 23:23:17 +02001552 return 1;
1553}
1554
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001555 static int
1556luaV_open(lua_State *L)
1557{
Bram Moolenaar0ba04292010-07-14 23:23:17 +02001558 char_u *s = NULL;
1559#ifdef HAVE_SANDBOX
1560 luaV_checksandbox(L);
1561#endif
1562 if (lua_isstring(L, 1)) s = (char_u *) lua_tostring(L, 1);
Bram Moolenaarfa263a52011-12-08 16:00:16 +01001563 luaV_pushbuffer(L, buflist_new(s, NULL, 1L, BLN_LISTED));
Bram Moolenaar0ba04292010-07-14 23:23:17 +02001564 return 1;
1565}
1566
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001567 static int
Bram Moolenaar1dced572012-04-05 16:54:08 +02001568luaV_type(lua_State *L)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001569{
Bram Moolenaar1dced572012-04-05 16:54:08 +02001570 luaL_checkany(L, 1);
1571 if (lua_type(L, 1) == LUA_TUSERDATA) /* check vim udata? */
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001572 {
Bram Moolenaar1dced572012-04-05 16:54:08 +02001573 lua_settop(L, 1);
1574 if (lua_getmetatable(L, 1))
1575 {
1576 luaV_getfield(L, LUAVIM_LIST);
1577 if (lua_rawequal(L, -1, 2))
1578 {
1579 lua_pushstring(L, "list");
1580 return 1;
1581 }
1582 luaV_getfield(L, LUAVIM_DICT);
1583 if (lua_rawequal(L, -1, 2))
1584 {
1585 lua_pushstring(L, "dict");
1586 return 1;
1587 }
1588 luaV_getfield(L, LUAVIM_BUFFER);
1589 if (lua_rawequal(L, -1, 2))
1590 {
1591 lua_pushstring(L, "buffer");
1592 return 1;
1593 }
1594 luaV_getfield(L, LUAVIM_WINDOW);
1595 if (lua_rawequal(L, -1, 2))
1596 {
1597 lua_pushstring(L, "window");
1598 return 1;
1599 }
1600 }
Bram Moolenaar0ba04292010-07-14 23:23:17 +02001601 }
Bram Moolenaar1dced572012-04-05 16:54:08 +02001602 lua_pushstring(L, luaL_typename(L, 1)); /* fallback */
1603 return 1;
Bram Moolenaar0ba04292010-07-14 23:23:17 +02001604}
1605
1606static const luaL_Reg luaV_module[] = {
1607 {"command", luaV_command},
1608 {"eval", luaV_eval},
1609 {"beep", luaV_beep},
1610 {"line", luaV_line},
Bram Moolenaar1dced572012-04-05 16:54:08 +02001611 {"list", luaV_list},
1612 {"dict", luaV_dict},
Bram Moolenaar0ba04292010-07-14 23:23:17 +02001613 {"buffer", luaV_buffer},
1614 {"window", luaV_window},
1615 {"open", luaV_open},
Bram Moolenaar1dced572012-04-05 16:54:08 +02001616 {"type", luaV_type},
Bram Moolenaar0ba04292010-07-14 23:23:17 +02001617 {NULL, NULL}
1618};
1619
Bram Moolenaar1dced572012-04-05 16:54:08 +02001620/* for freeing list, dict, buffer and window objects; lightuserdata as arg */
1621 static int
1622luaV_free(lua_State *L)
1623{
1624 lua_pushnil(L);
1625 luaV_setudata(L, lua_touserdata(L, 1));
1626 return 0;
1627}
1628
1629 static int
1630luaV_luaeval (lua_State *L)
1631{
1632 luaL_Buffer b;
1633 size_t l;
1634 const char *str = lua_tolstring(L, 1, &l);
1635 typval_T *arg = (typval_T *) lua_touserdata(L, 2);
1636 typval_T *rettv = (typval_T *) lua_touserdata(L, 3);
1637 luaL_buffinit(L, &b);
1638 luaL_addlstring(&b, LUAVIM_EVALHEADER, sizeof(LUAVIM_EVALHEADER) - 1);
1639 luaL_addlstring(&b, str, l);
1640 luaL_pushresult(&b);
1641 str = lua_tolstring(L, -1, &l);
1642 if (luaL_loadbuffer(L, str, l, LUAVIM_EVALNAME)) /* compile error? */
1643 {
1644 luaV_emsg(L);
1645 return 0;
1646 }
1647 luaV_pushtypval(L, arg);
1648 if (lua_pcall(L, 1, 1, 0)) /* running error? */
1649 {
1650 luaV_emsg(L);
1651 return 0;
1652 }
1653 luaV_totypval(L, -1, rettv);
1654 return 0;
1655}
1656
1657 static int
1658luaV_setref (lua_State *L)
1659{
1660 int copyID = lua_tointeger(L, 1);
1661 typval_T tv;
1662 luaV_getfield(L, LUAVIM_LIST);
1663 luaV_getfield(L, LUAVIM_DICT);
1664 lua_pushnil(L);
1665 while (lua_next(L, lua_upvalueindex(1)) != 0) /* traverse cache table */
1666 {
1667 lua_getmetatable(L, -1);
1668 if (lua_rawequal(L, -1, 2)) /* list? */
1669 {
1670 tv.v_type = VAR_LIST;
1671 tv.vval.v_list = (list_T *) lua_touserdata(L, 4); /* key */
1672 }
1673 else if (lua_rawequal(L, -1, 3)) /* dict? */
1674 {
1675 tv.v_type = VAR_DICT;
1676 tv.vval.v_dict = (dict_T *) lua_touserdata(L, 4); /* key */
1677 }
1678 lua_pop(L, 2); /* metatable and value */
1679 set_ref_in_tv(&tv, copyID);
1680 }
1681 return 0;
1682}
1683
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001684 static int
1685luaopen_vim(lua_State *L)
1686{
Bram Moolenaar1dced572012-04-05 16:54:08 +02001687 /* set cache table */
Bram Moolenaar0ba04292010-07-14 23:23:17 +02001688 lua_newtable(L);
1689 lua_newtable(L);
Bram Moolenaar1dced572012-04-05 16:54:08 +02001690 lua_pushstring(L, "v");
Bram Moolenaar0ba04292010-07-14 23:23:17 +02001691 lua_setfield(L, -2, "__mode");
Bram Moolenaar1dced572012-04-05 16:54:08 +02001692 lua_setmetatable(L, -2); /* cache is weak-valued */
Bram Moolenaar0ba04292010-07-14 23:23:17 +02001693 /* print */
1694 lua_pushcfunction(L, luaV_print);
1695 lua_setglobal(L, "print");
Bram Moolenaar38e2b062011-09-21 17:15:39 +02001696 /* debug.debug */
1697 lua_getglobal(L, "debug");
1698 lua_pushcfunction(L, luaV_debug);
1699 lua_setfield(L, -2, "debug");
1700 lua_pop(L, 1);
Bram Moolenaar0ba04292010-07-14 23:23:17 +02001701 /* free */
1702 lua_pushlightuserdata(L, (void *) LUAVIM_FREE);
Bram Moolenaar1dced572012-04-05 16:54:08 +02001703 lua_pushvalue(L, 1); /* cache table */
1704 lua_pushcclosure(L, luaV_free, 1);
1705 lua_rawset(L, LUA_REGISTRYINDEX);
1706 /* luaeval */
1707 lua_pushlightuserdata(L, (void *) LUAVIM_LUAEVAL);
1708 lua_pushvalue(L, 1); /* cache table */
1709 lua_pushcclosure(L, luaV_luaeval, 1);
1710 lua_rawset(L, LUA_REGISTRYINDEX);
1711 /* setref */
1712 lua_pushlightuserdata(L, (void *) LUAVIM_SETREF);
1713 lua_pushvalue(L, 1); /* cache table */
1714 lua_pushcclosure(L, luaV_setref, 1);
Bram Moolenaar0ba04292010-07-14 23:23:17 +02001715 lua_rawset(L, LUA_REGISTRYINDEX);
1716 /* register */
Bram Moolenaar1dced572012-04-05 16:54:08 +02001717 luaV_newmetatable(L, LUAVIM_LIST);
1718 lua_pushvalue(L, 1);
1719 luaV_openlib(L, luaV_List_mt, 1);
1720 luaV_newmetatable(L, LUAVIM_DICT);
1721 lua_pushvalue(L, 1);
1722 luaV_openlib(L, luaV_Dict_mt, 1);
Bram Moolenaar0ba04292010-07-14 23:23:17 +02001723 luaV_newmetatable(L, LUAVIM_BUFFER);
Bram Moolenaar1dced572012-04-05 16:54:08 +02001724 lua_pushvalue(L, 1); /* cache table */
1725 luaV_openlib(L, luaV_Buffer_mt, 1);
Bram Moolenaar0ba04292010-07-14 23:23:17 +02001726 luaV_newmetatable(L, LUAVIM_WINDOW);
Bram Moolenaar1dced572012-04-05 16:54:08 +02001727 lua_pushvalue(L, 1); /* cache table */
1728 luaV_openlib(L, luaV_Window_mt, 1);
1729 lua_newtable(L); /* vim table */
1730 lua_pushvalue(L, 1); /* cache table */
1731 luaV_openlib(L, luaV_module, 1);
1732 lua_setglobal(L, LUAVIM_NAME);
Bram Moolenaar0ba04292010-07-14 23:23:17 +02001733 return 0;
1734}
1735
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001736 static lua_State *
1737luaV_newstate(void)
1738{
Bram Moolenaar0ba04292010-07-14 23:23:17 +02001739 lua_State *L = luaL_newstate();
Bram Moolenaar16c98f92010-07-28 22:46:08 +02001740 luaL_openlibs(L); /* core libs */
1741 lua_pushcfunction(L, luaopen_vim); /* vim */
Bram Moolenaar0ba04292010-07-14 23:23:17 +02001742 lua_call(L, 0, 0);
1743 return L;
1744}
1745
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001746 static void
1747luaV_setrange(lua_State *L, int line1, int line2)
1748{
Bram Moolenaar0ba04292010-07-14 23:23:17 +02001749 lua_getglobal(L, LUAVIM_NAME);
1750 lua_pushinteger(L, line1);
1751 lua_setfield(L, -2, "firstline");
1752 lua_pushinteger(L, line2);
1753 lua_setfield(L, -2, "lastline");
1754 lua_pop(L, 1); /* vim table */
1755}
1756
1757
1758/* ======= Interface ======= */
1759
1760static lua_State *L = NULL;
1761
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001762 static int
Bram Moolenaar1dced572012-04-05 16:54:08 +02001763lua_isopen(void)
Bram Moolenaar2bd6a1b2010-08-12 22:14:01 +02001764{
1765 return L != NULL;
1766}
1767
1768 static int
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001769lua_init(void)
1770{
Bram Moolenaar1dced572012-04-05 16:54:08 +02001771 if (!lua_isopen())
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001772 {
Bram Moolenaar0ba04292010-07-14 23:23:17 +02001773#ifdef DYNAMIC_LUA
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001774 if (!lua_enabled(TRUE))
1775 {
1776 EMSG(_("Lua library cannot be loaded."));
1777 return FAIL;
1778 }
Bram Moolenaar0ba04292010-07-14 23:23:17 +02001779#endif
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001780 L = luaV_newstate();
Bram Moolenaar0ba04292010-07-14 23:23:17 +02001781 }
1782 return OK;
1783}
1784
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001785 void
1786lua_end(void)
1787{
Bram Moolenaar1dced572012-04-05 16:54:08 +02001788 if (lua_isopen())
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001789 {
1790 lua_close(L);
1791 L = NULL;
Bram Moolenaar0ba04292010-07-14 23:23:17 +02001792#ifdef DYNAMIC_LUA
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001793 end_dynamic_lua();
Bram Moolenaar0ba04292010-07-14 23:23:17 +02001794#endif
1795 }
1796}
1797
1798/* ex commands */
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001799 void
1800ex_lua(exarg_T *eap)
1801{
Bram Moolenaar0ba04292010-07-14 23:23:17 +02001802 char *script;
1803 if (lua_init() == FAIL) return;
1804 script = (char *) script_get(eap, eap->arg);
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001805 if (!eap->skip)
1806 {
1807 char *s = (script) ? script : (char *) eap->arg;
1808 luaV_setrange(L, eap->line1, eap->line2);
1809 if (luaL_loadbuffer(L, s, strlen(s), LUAVIM_CHUNKNAME)
1810 || lua_pcall(L, 0, 0, 0))
1811 luaV_emsg(L);
Bram Moolenaar0ba04292010-07-14 23:23:17 +02001812 }
1813 if (script != NULL) vim_free(script);
1814}
1815
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001816 void
1817ex_luado(exarg_T *eap)
1818{
Bram Moolenaar0ba04292010-07-14 23:23:17 +02001819 linenr_T l;
1820 const char *s = (const char *) eap->arg;
1821 luaL_Buffer b;
1822 size_t len;
1823 if (lua_init() == FAIL) return;
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001824 if (u_save(eap->line1 - 1, eap->line2 + 1) == FAIL)
1825 {
1826 EMSG(_("cannot save undo information"));
1827 return;
Bram Moolenaar0ba04292010-07-14 23:23:17 +02001828 }
1829 luaV_setrange(L, eap->line1, eap->line2);
1830 luaL_buffinit(L, &b);
1831 luaL_addlstring(&b, "return function(line) ", 22); /* header */
1832 luaL_addlstring(&b, s, strlen(s));
1833 luaL_addlstring(&b, " end", 4); /* footer */
1834 luaL_pushresult(&b);
1835 s = lua_tolstring(L, -1, &len);
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001836 if (luaL_loadbuffer(L, s, len, LUAVIM_CHUNKNAME))
1837 {
1838 luaV_emsg(L);
1839 lua_pop(L, 1); /* function body */
1840 return;
Bram Moolenaar0ba04292010-07-14 23:23:17 +02001841 }
1842 lua_call(L, 0, 1);
1843 lua_replace(L, -2); /* function -> body */
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001844 for (l = eap->line1; l <= eap->line2; l++)
1845 {
1846 lua_pushvalue(L, -1); /* function */
1847 luaV_pushline(L, curbuf, l); /* current line as arg */
1848 if (lua_pcall(L, 1, 1, 0))
1849 {
1850 luaV_emsg(L);
1851 break;
1852 }
1853 if (lua_isstring(L, -1)) /* update line? */
1854 {
Bram Moolenaar0ba04292010-07-14 23:23:17 +02001855#ifdef HAVE_SANDBOX
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001856 luaV_checksandbox(L);
Bram Moolenaar0ba04292010-07-14 23:23:17 +02001857#endif
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001858 ml_replace(l, luaV_toline(L, -1), TRUE);
1859 changed_bytes(l, 0);
1860 lua_pop(L, 1); /* result from luaV_toline */
1861 }
1862 lua_pop(L, 1); /* line */
Bram Moolenaar0ba04292010-07-14 23:23:17 +02001863 }
1864 lua_pop(L, 1); /* function */
1865 check_cursor();
1866 update_screen(NOT_VALID);
1867}
1868
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001869 void
1870ex_luafile(exarg_T *eap)
1871{
1872 if (lua_init() == FAIL)
1873 return;
1874 if (!eap->skip)
1875 {
1876 luaV_setrange(L, eap->line1, eap->line2);
1877 if (luaL_loadfile(L, (char *) eap->arg) || lua_pcall(L, 0, 0, 0))
1878 luaV_emsg(L);
Bram Moolenaar0ba04292010-07-14 23:23:17 +02001879 }
1880}
1881
Bram Moolenaar1dced572012-04-05 16:54:08 +02001882#define luaV_freetype(typ,tname) \
1883 void \
1884 lua_##tname##_free(typ *o) \
1885 { \
1886 if (!lua_isopen()) return; \
1887 luaV_getfield(L, LUAVIM_FREE); \
1888 lua_pushlightuserdata(L, (void *) o); \
1889 lua_call(L, 1, 0); \
1890 }
1891
1892luaV_freetype(buf_T, buffer)
1893luaV_freetype(win_T, window)
1894
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001895 void
Bram Moolenaar1dced572012-04-05 16:54:08 +02001896do_luaeval (char_u *str, typval_T *arg, typval_T *rettv)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001897{
Bram Moolenaar1dced572012-04-05 16:54:08 +02001898 lua_init();
1899 luaV_getfield(L, LUAVIM_LUAEVAL);
1900 lua_pushstring(L, (char *) str);
1901 lua_pushlightuserdata(L, (void *) arg);
1902 lua_pushlightuserdata(L, (void *) rettv);
1903 lua_call(L, 3, 0);
Bram Moolenaar0ba04292010-07-14 23:23:17 +02001904}
1905
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001906 void
Bram Moolenaar1dced572012-04-05 16:54:08 +02001907set_ref_in_lua (int copyID)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001908{
Bram Moolenaar1dced572012-04-05 16:54:08 +02001909 if (!lua_isopen()) return;
1910 luaV_getfield(L, LUAVIM_SETREF);
1911 lua_pushinteger(L, copyID);
Bram Moolenaar0ba04292010-07-14 23:23:17 +02001912 lua_call(L, 1, 0);
1913}
1914
1915#endif