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