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 int (*msgfunc_T)(char *); 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 luaV_CFuncState *state; 630 631 lua_pushvalue(L, pos); 632 state = ALLOC_CLEAR_ONE(luaV_CFuncState); 633 state->lua_funcref = luaL_ref(L, LUA_REGISTRYINDEX); 634 state->L = L; 635 state->lua_tableref = LUA_NOREF; 636 name = register_cfunc(&luaV_call_lua_func, 637 &luaV_call_lua_func_free, state); 638 tv->v_type = VAR_FUNC; 639 tv->vval.v_string = vim_strsave(name); 640 break; 641 } 642 case LUA_TTABLE: 643 { 644 int lua_tableref; 645 646 lua_pushvalue(L, pos); 647 lua_tableref = luaL_ref(L, LUA_REGISTRYINDEX); 648 if (lua_getmetatable(L, pos)) { 649 lua_getfield(L, -1, LUA___CALL); 650 if (lua_isfunction(L, -1)) { 651 char_u *name; 652 int lua_funcref = luaL_ref(L, LUA_REGISTRYINDEX); 653 luaV_CFuncState *state = ALLOC_CLEAR_ONE(luaV_CFuncState); 654 655 state->lua_funcref = lua_funcref; 656 state->L = L; 657 state->lua_tableref = lua_tableref; 658 name = register_cfunc(&luaV_call_lua_func, 659 &luaV_call_lua_func_free, state); 660 tv->v_type = VAR_FUNC; 661 tv->vval.v_string = vim_strsave(name); 662 break; 663 } 664 } 665 tv->v_type = VAR_NUMBER; 666 tv->vval.v_number = 0; 667 status = FAIL; 668 break; 669 } 670 case LUA_TUSERDATA: 671 { 672 void *p = lua_touserdata(L, pos); 673 674 if (lua_getmetatable(L, pos)) // has metatable? 675 { 676 // check list 677 luaV_getfield(L, LUAVIM_LIST); 678 if (lua_rawequal(L, -1, -2)) 679 { 680 tv->v_type = VAR_LIST; 681 tv->vval.v_list = *((luaV_List *) p); 682 ++tv->vval.v_list->lv_refcount; 683 lua_pop(L, 2); // MTs 684 break; 685 } 686 // check dict 687 luaV_getfield(L, LUAVIM_DICT); 688 if (lua_rawequal(L, -1, -3)) 689 { 690 tv->v_type = VAR_DICT; 691 tv->vval.v_dict = *((luaV_Dict *) p); 692 ++tv->vval.v_dict->dv_refcount; 693 lua_pop(L, 3); // MTs 694 break; 695 } 696 // check blob 697 luaV_getfield(L, LUAVIM_BLOB); 698 if (lua_rawequal(L, -1, -4)) 699 { 700 tv->v_type = VAR_BLOB; 701 tv->vval.v_blob = *((luaV_Blob *) p); 702 ++tv->vval.v_blob->bv_refcount; 703 lua_pop(L, 4); // MTs 704 break; 705 } 706 // check funcref 707 luaV_getfield(L, LUAVIM_FUNCREF); 708 if (lua_rawequal(L, -1, -5)) 709 { 710 luaV_Funcref *f = (luaV_Funcref *) p; 711 712 func_ref(f->name); 713 tv->v_type = VAR_FUNC; 714 tv->vval.v_string = vim_strsave(f->name); 715 lua_pop(L, 5); // MTs 716 break; 717 } 718 lua_pop(L, 4); // MTs 719 } 720 } 721 // FALLTHROUGH 722 default: 723 tv->v_type = VAR_NUMBER; 724 tv->vval.v_number = 0; 725 status = FAIL; 726 } 727 return status; 728 } 729 730 /* 731 * similar to luaL_addlstring, but replaces \0 with \n if toline and 732 * \n with \0 otherwise 733 */ 734 static void 735 luaV_addlstring(luaL_Buffer *b, const char *s, size_t l, int toline) 736 { 737 while (l--) 738 { 739 if (*s == '\0' && toline) 740 luaL_addchar(b, '\n'); 741 else if (*s == '\n' && !toline) 742 luaL_addchar(b, '\0'); 743 else 744 luaL_addchar(b, *s); 745 s++; 746 } 747 } 748 749 static void 750 luaV_pushline(lua_State *L, buf_T *buf, linenr_T n) 751 { 752 const char *s = (const char *) ml_get_buf(buf, n, FALSE); 753 luaL_Buffer b; 754 luaL_buffinit(L, &b); 755 luaV_addlstring(&b, s, strlen(s), 0); 756 luaL_pushresult(&b); 757 } 758 759 static char_u * 760 luaV_toline(lua_State *L, int pos) 761 { 762 size_t l; 763 const char *s = lua_tolstring(L, pos, &l); 764 765 luaL_Buffer b; 766 luaL_buffinit(L, &b); 767 luaV_addlstring(&b, s, l, 1); 768 luaL_pushresult(&b); 769 return (char_u *) lua_tostring(L, -1); 770 } 771 772 /* 773 * pops a string s from the top of the stack and calls mf(t) for pieces t of 774 * s separated by newlines 775 */ 776 static void 777 luaV_msgfunc(lua_State *L, msgfunc_T mf) 778 { 779 luaL_Buffer b; 780 size_t l; 781 const char *p, *s = lua_tolstring(L, -1, &l); 782 luaL_buffinit(L, &b); 783 luaV_addlstring(&b, s, l, 0); 784 luaL_pushresult(&b); 785 // break string 786 p = s = lua_tolstring(L, -1, &l); 787 while (l--) 788 { 789 if (*p++ == '\0') // break? 790 { 791 mf((char *)s); 792 s = p; 793 } 794 } 795 mf((char *)s); 796 lua_pop(L, 2); // original and modified strings 797 } 798 799 #define luaV_newtype(typ,tname,luatyp,luatname) \ 800 static luatyp * \ 801 luaV_new##tname(lua_State *L, typ *obj) \ 802 { \ 803 luatyp *o = (luatyp *) lua_newuserdata(L, sizeof(luatyp)); \ 804 *o = obj; \ 805 luaV_setudata(L, obj); /* cache[obj] = udata */ \ 806 luaV_getfield(L, luatname); \ 807 lua_setmetatable(L, -2); \ 808 return o; \ 809 } 810 811 #define luaV_pushtype(typ,tname,luatyp) \ 812 static luatyp * \ 813 luaV_push##tname(lua_State *L, typ *obj) \ 814 { \ 815 luatyp *o = NULL; \ 816 if (obj == NULL) \ 817 lua_pushnil(L); \ 818 else { \ 819 luaV_getudata(L, obj); \ 820 if (lua_isnil(L, -1)) /* not interned? */ \ 821 { \ 822 lua_pop(L, 1); \ 823 o = luaV_new##tname(L, obj); \ 824 } \ 825 else \ 826 o = (luatyp *) lua_touserdata(L, -1); \ 827 } \ 828 return o; \ 829 } 830 831 #define luaV_type_tostring(tname,luatname) \ 832 static int \ 833 luaV_##tname##_tostring(lua_State *L) \ 834 { \ 835 lua_pushfstring(L, "%s: %p", luatname, lua_touserdata(L, 1)); \ 836 return 1; \ 837 } 838 839 // ======= List type ======= 840 841 static luaV_List * 842 luaV_newlist(lua_State *L, list_T *lis) 843 { 844 luaV_List *l = (luaV_List *) lua_newuserdata(L, sizeof(luaV_List)); 845 *l = lis; 846 lis->lv_refcount++; // reference in Lua 847 luaV_setudata(L, lis); // cache[lis] = udata 848 luaV_getfield(L, LUAVIM_LIST); 849 lua_setmetatable(L, -2); 850 return l; 851 } 852 853 luaV_pushtype(list_T, list, luaV_List) 854 luaV_type_tostring(list, LUAVIM_LIST) 855 856 static int 857 luaV_list_len(lua_State *L) 858 { 859 list_T *l = luaV_unbox(L, luaV_List, 1); 860 lua_pushinteger(L, (int) list_len(l)); 861 return 1; 862 } 863 864 static int 865 luaV_list_iter(lua_State *L) 866 { 867 listitem_T *li = (listitem_T *) lua_touserdata(L, lua_upvalueindex(2)); 868 if (li == NULL) return 0; 869 luaV_pushtypval(L, &li->li_tv); 870 lua_pushlightuserdata(L, (void *) li->li_next); 871 lua_replace(L, lua_upvalueindex(2)); 872 return 1; 873 } 874 875 static int 876 luaV_list_call(lua_State *L) 877 { 878 list_T *l = luaV_unbox(L, luaV_List, 1); 879 lua_pushvalue(L, lua_upvalueindex(1)); // pass cache table along 880 lua_pushlightuserdata(L, (void *) l->lv_first); 881 lua_pushcclosure(L, luaV_list_iter, 2); 882 return 1; 883 } 884 885 static int 886 luaV_list_index(lua_State *L) 887 { 888 list_T *l = luaV_unbox(L, luaV_List, 1); 889 if (lua_isnumber(L, 2)) // list item? 890 { 891 long n = (long) luaL_checkinteger(L, 2); 892 listitem_T *li; 893 894 // Lua array index starts with 1 while Vim uses 0, subtract 1 to 895 // normalize. 896 n -= 1; 897 li = list_find(l, n); 898 if (li == NULL) 899 lua_pushnil(L); 900 else 901 luaV_pushtypval(L, &li->li_tv); 902 } 903 else if (lua_isstring(L, 2)) // method? 904 { 905 const char *s = lua_tostring(L, 2); 906 if (strncmp(s, "add", 3) == 0 907 || strncmp(s, "insert", 6) == 0) 908 { 909 lua_getmetatable(L, 1); 910 lua_getfield(L, -1, s); 911 } 912 else 913 lua_pushnil(L); 914 } 915 else 916 lua_pushnil(L); 917 return 1; 918 } 919 920 static int 921 luaV_list_newindex(lua_State *L) 922 { 923 list_T *l = luaV_unbox(L, luaV_List, 1); 924 long n = (long) luaL_checkinteger(L, 2); 925 listitem_T *li; 926 927 // Lua array index starts with 1 while Vim uses 0, subtract 1 to normalize. 928 n -= 1; 929 930 if (l->lv_lock) 931 luaL_error(L, "list is locked"); 932 li = list_find(l, n); 933 if (li == NULL) 934 { 935 if (!lua_isnil(L, 3)) 936 { 937 typval_T v; 938 luaV_checktypval(L, 3, &v, "inserting list item"); 939 if (list_insert_tv(l, &v, li) == FAIL) 940 luaL_error(L, "failed to add item to list"); 941 clear_tv(&v); 942 } 943 } 944 else 945 { 946 if (lua_isnil(L, 3)) // remove? 947 { 948 vimlist_remove(l, li, li); 949 listitem_free(l, li); 950 } 951 else 952 { 953 typval_T v; 954 luaV_checktypval(L, 3, &v, "setting list item"); 955 clear_tv(&li->li_tv); 956 li->li_tv = v; 957 } 958 } 959 return 0; 960 } 961 962 static int 963 luaV_list_add(lua_State *L) 964 { 965 luaV_List *lis = luaV_checkudata(L, 1, LUAVIM_LIST); 966 list_T *l = (list_T *) luaV_checkcache(L, (void *) *lis); 967 typval_T v; 968 if (l->lv_lock) 969 luaL_error(L, "list is locked"); 970 lua_settop(L, 2); 971 luaV_checktypval(L, 2, &v, "adding list item"); 972 if (list_append_tv(l, &v) == FAIL) 973 luaL_error(L, "failed to add item to list"); 974 clear_tv(&v); 975 lua_settop(L, 1); 976 return 1; 977 } 978 979 static int 980 luaV_list_insert(lua_State *L) 981 { 982 luaV_List *lis = luaV_checkudata(L, 1, LUAVIM_LIST); 983 list_T *l = (list_T *) luaV_checkcache(L, (void *) *lis); 984 long pos = (long) luaL_optinteger(L, 3, 0); 985 listitem_T *li = NULL; 986 typval_T v; 987 if (l->lv_lock) 988 luaL_error(L, "list is locked"); 989 if (pos < l->lv_len) 990 { 991 li = list_find(l, pos); 992 if (li == NULL) 993 luaL_error(L, "invalid position"); 994 } 995 lua_settop(L, 2); 996 luaV_checktypval(L, 2, &v, "inserting list item"); 997 if (list_insert_tv(l, &v, li) == FAIL) 998 luaL_error(L, "failed to add item to list"); 999 clear_tv(&v); 1000 lua_settop(L, 1); 1001 return 1; 1002 } 1003 1004 static const luaL_Reg luaV_List_mt[] = { 1005 {"__tostring", luaV_list_tostring}, 1006 {"__len", luaV_list_len}, 1007 {"__call", luaV_list_call}, 1008 {"__index", luaV_list_index}, 1009 {"__newindex", luaV_list_newindex}, 1010 {"add", luaV_list_add}, 1011 {"insert", luaV_list_insert}, 1012 {NULL, NULL} 1013 }; 1014 1015 1016 // ======= Dict type ======= 1017 1018 static luaV_Dict * 1019 luaV_newdict(lua_State *L, dict_T *dic) 1020 { 1021 luaV_Dict *d = (luaV_Dict *) lua_newuserdata(L, sizeof(luaV_Dict)); 1022 *d = dic; 1023 dic->dv_refcount++; // reference in Lua 1024 luaV_setudata(L, dic); // cache[dic] = udata 1025 luaV_getfield(L, LUAVIM_DICT); 1026 lua_setmetatable(L, -2); 1027 return d; 1028 } 1029 1030 luaV_pushtype(dict_T, dict, luaV_Dict) 1031 luaV_type_tostring(dict, LUAVIM_DICT) 1032 1033 static int 1034 luaV_dict_len(lua_State *L) 1035 { 1036 dict_T *d = luaV_unbox(L, luaV_Dict, 1); 1037 lua_pushinteger(L, (int) dict_len(d)); 1038 return 1; 1039 } 1040 1041 static int 1042 luaV_dict_iter(lua_State *L UNUSED) 1043 { 1044 #ifdef FEAT_EVAL 1045 hashitem_T *hi = (hashitem_T *) lua_touserdata(L, lua_upvalueindex(2)); 1046 int n = lua_tointeger(L, lua_upvalueindex(3)); 1047 dictitem_T *di; 1048 if (n <= 0) return 0; 1049 while (HASHITEM_EMPTY(hi)) hi++; 1050 di = dict_lookup(hi); 1051 lua_pushstring(L, (char *) hi->hi_key); 1052 luaV_pushtypval(L, &di->di_tv); 1053 lua_pushlightuserdata(L, (void *) (hi + 1)); 1054 lua_replace(L, lua_upvalueindex(2)); 1055 lua_pushinteger(L, n - 1); 1056 lua_replace(L, lua_upvalueindex(3)); 1057 return 2; 1058 #else 1059 return 0; 1060 #endif 1061 } 1062 1063 static int 1064 luaV_dict_call(lua_State *L) 1065 { 1066 dict_T *d = luaV_unbox(L, luaV_Dict, 1); 1067 hashtab_T *ht = &d->dv_hashtab; 1068 lua_pushvalue(L, lua_upvalueindex(1)); // pass cache table along 1069 lua_pushlightuserdata(L, (void *) ht->ht_array); 1070 lua_pushinteger(L, ht->ht_used); // # remaining items 1071 lua_pushcclosure(L, luaV_dict_iter, 3); 1072 return 1; 1073 } 1074 1075 static int 1076 luaV_dict_index(lua_State *L) 1077 { 1078 dict_T *d = luaV_unbox(L, luaV_Dict, 1); 1079 char_u *key = (char_u *) luaL_checkstring(L, 2); 1080 dictitem_T *di = dict_find(d, key, -1); 1081 1082 if (di == NULL) 1083 lua_pushnil(L); 1084 else 1085 { 1086 luaV_pushtypval(L, &di->di_tv); 1087 if (di->di_tv.v_type == VAR_FUNC) // funcref? 1088 { 1089 luaV_Funcref *f = (luaV_Funcref *) lua_touserdata(L, -1); 1090 f->self = d; // keep "self" reference 1091 d->dv_refcount++; 1092 } 1093 } 1094 return 1; 1095 } 1096 1097 static int 1098 luaV_dict_newindex(lua_State *L) 1099 { 1100 dict_T *d = luaV_unbox(L, luaV_Dict, 1); 1101 char_u *key = (char_u *) luaL_checkstring(L, 2); 1102 dictitem_T *di; 1103 typval_T tv; 1104 1105 if (d->dv_lock) 1106 luaL_error(L, "dict is locked"); 1107 if (key == NULL) 1108 return 0; 1109 if (*key == NUL) 1110 luaL_error(L, "empty key"); 1111 if (!lua_isnil(L, 3)) // read value? 1112 { 1113 luaV_checktypval(L, 3, &tv, "setting dict item"); 1114 if (d->dv_scope == VAR_DEF_SCOPE && tv.v_type == VAR_FUNC) 1115 { 1116 clear_tv(&tv); 1117 luaL_error(L, "cannot assign funcref to builtin scope"); 1118 } 1119 } 1120 di = dict_find(d, key, -1); 1121 if (di == NULL) // non-existing key? 1122 { 1123 if (lua_isnil(L, 3)) 1124 return 0; 1125 di = dictitem_alloc(key); 1126 if (di == NULL) 1127 { 1128 clear_tv(&tv); 1129 return 0; 1130 } 1131 if (dict_add(d, di) == FAIL) 1132 { 1133 vim_free(di); 1134 clear_tv(&tv); 1135 return 0; 1136 } 1137 } 1138 else 1139 clear_tv(&di->di_tv); 1140 if (lua_isnil(L, 3)) // remove? 1141 { 1142 hashitem_T *hi = hash_find(&d->dv_hashtab, di->di_key); 1143 hash_remove(&d->dv_hashtab, hi); 1144 dictitem_free(di); 1145 } 1146 else 1147 di->di_tv = tv; 1148 return 0; 1149 } 1150 1151 static const luaL_Reg luaV_Dict_mt[] = { 1152 {"__tostring", luaV_dict_tostring}, 1153 {"__len", luaV_dict_len}, 1154 {"__call", luaV_dict_call}, 1155 {"__index", luaV_dict_index}, 1156 {"__newindex", luaV_dict_newindex}, 1157 {NULL, NULL} 1158 }; 1159 1160 1161 // ======= Blob type ======= 1162 1163 static luaV_Blob * 1164 luaV_newblob(lua_State *L, blob_T *blo) 1165 { 1166 luaV_Blob *b = (luaV_Blob *) lua_newuserdata(L, sizeof(luaV_Blob)); 1167 *b = blo; 1168 blo->bv_refcount++; // reference in Lua 1169 luaV_setudata(L, blo); // cache[blo] = udata 1170 luaV_getfield(L, LUAVIM_BLOB); 1171 lua_setmetatable(L, -2); 1172 return b; 1173 } 1174 1175 luaV_pushtype(blob_T, blob, luaV_Blob) 1176 luaV_type_tostring(blob, LUAVIM_BLOB) 1177 1178 static int 1179 luaV_blob_gc(lua_State *L) 1180 { 1181 blob_T *b = luaV_unbox(L, luaV_Blob, 1); 1182 blob_unref(b); 1183 return 0; 1184 } 1185 1186 static int 1187 luaV_blob_len(lua_State *L) 1188 { 1189 blob_T *b = luaV_unbox(L, luaV_Blob, 1); 1190 lua_pushinteger(L, (int) blob_len(b)); 1191 return 1; 1192 } 1193 1194 static int 1195 luaV_blob_index(lua_State *L) 1196 { 1197 blob_T *b = luaV_unbox(L, luaV_Blob, 1); 1198 if (lua_isnumber(L, 2)) 1199 { 1200 int idx = luaL_checkinteger(L, 2); 1201 if (idx < blob_len(b)) 1202 lua_pushnumber(L, (lua_Number) blob_get(b, idx)); 1203 else 1204 lua_pushnil(L); 1205 } 1206 else if (lua_isstring(L, 2)) 1207 { 1208 const char *s = lua_tostring(L, 2); 1209 if (strncmp(s, "add", 3) == 0) 1210 { 1211 lua_getmetatable(L, 1); 1212 lua_getfield(L, -1, s); 1213 } 1214 else 1215 lua_pushnil(L); 1216 } 1217 else 1218 lua_pushnil(L); 1219 return 1; 1220 } 1221 1222 static int 1223 luaV_blob_newindex(lua_State *L) 1224 { 1225 blob_T *b = luaV_unbox(L, luaV_Blob, 1); 1226 if (b->bv_lock) 1227 luaL_error(L, "blob is locked"); 1228 if (lua_isnumber(L, 2)) 1229 { 1230 long len = blob_len(b); 1231 int idx = luaL_checkinteger(L, 2); 1232 int val = luaL_checkinteger(L, 3); 1233 if (idx < len || (idx == len && ga_grow(&b->bv_ga, 1) == OK)) 1234 { 1235 blob_set(b, idx, (char_u) val); 1236 if (idx == len) 1237 ++b->bv_ga.ga_len; 1238 } 1239 else 1240 luaL_error(L, "index out of range"); 1241 } 1242 return 0; 1243 } 1244 1245 static int 1246 luaV_blob_add(lua_State *L) 1247 { 1248 luaV_Blob *blo = luaV_checkudata(L, 1, LUAVIM_BLOB); 1249 blob_T *b = (blob_T *) luaV_checkcache(L, (void *) *blo); 1250 if (b->bv_lock) 1251 luaL_error(L, "blob is locked"); 1252 lua_settop(L, 2); 1253 if (!lua_isstring(L, 2)) 1254 luaL_error(L, "string expected, got %s", luaL_typename(L, 2)); 1255 else 1256 { 1257 size_t i, l = 0; 1258 const char *s = lua_tolstring(L, 2, &l); 1259 1260 if (ga_grow(&b->bv_ga, (int)l) == OK) 1261 for (i = 0; i < l; ++i) 1262 ga_append(&b->bv_ga, s[i]); 1263 } 1264 lua_settop(L, 1); 1265 return 1; 1266 } 1267 1268 static const luaL_Reg luaV_Blob_mt[] = { 1269 {"__tostring", luaV_blob_tostring}, 1270 {"__gc", luaV_blob_gc}, 1271 {"__len", luaV_blob_len}, 1272 {"__index", luaV_blob_index}, 1273 {"__newindex", luaV_blob_newindex}, 1274 {"add", luaV_blob_add}, 1275 {NULL, NULL} 1276 }; 1277 1278 1279 // ======= Funcref type ======= 1280 1281 static luaV_Funcref * 1282 luaV_newfuncref(lua_State *L, char_u *name) 1283 { 1284 luaV_Funcref *f = (luaV_Funcref *)lua_newuserdata(L, sizeof(luaV_Funcref)); 1285 1286 if (name != NULL) 1287 { 1288 func_ref(name); 1289 f->name = vim_strsave(name); 1290 } 1291 f->self = NULL; 1292 luaV_getfield(L, LUAVIM_FUNCREF); 1293 lua_setmetatable(L, -2); 1294 return f; 1295 } 1296 1297 static luaV_Funcref * 1298 luaV_pushfuncref(lua_State *L, char_u *name) 1299 { 1300 return luaV_newfuncref(L, name); 1301 } 1302 1303 1304 luaV_type_tostring(funcref, LUAVIM_FUNCREF) 1305 1306 static int 1307 luaV_funcref_gc(lua_State *L) 1308 { 1309 luaV_Funcref *f = (luaV_Funcref *) lua_touserdata(L, 1); 1310 1311 func_unref(f->name); 1312 vim_free(f->name); 1313 // NOTE: Don't call "dict_unref(f->self)", because the dict of "f->self" 1314 // will be (or has been already) freed by Vim's garbage collection. 1315 return 0; 1316 } 1317 1318 // equivalent to string(funcref) 1319 static int 1320 luaV_funcref_len(lua_State *L) 1321 { 1322 luaV_Funcref *f = (luaV_Funcref *) lua_touserdata(L, 1); 1323 1324 lua_pushstring(L, (const char *) f->name); 1325 return 1; 1326 } 1327 1328 static int 1329 luaV_funcref_call(lua_State *L) 1330 { 1331 luaV_Funcref *f = (luaV_Funcref *) lua_touserdata(L, 1); 1332 int i, n = lua_gettop(L) - 1; // #args 1333 int status = FAIL; 1334 typval_T args; 1335 typval_T rettv; 1336 1337 args.v_type = VAR_LIST; 1338 args.vval.v_list = list_alloc(); 1339 rettv.v_type = VAR_UNKNOWN; // as in clear_tv 1340 if (args.vval.v_list != NULL) 1341 { 1342 typval_T v; 1343 1344 for (i = 0; i < n; i++) 1345 { 1346 luaV_checktypval(L, i + 2, &v, "calling funcref"); 1347 list_append_tv(args.vval.v_list, &v); 1348 clear_tv(&v); 1349 } 1350 status = func_call(f->name, &args, NULL, f->self, &rettv); 1351 if (status == OK) 1352 luaV_pushtypval(L, &rettv); 1353 clear_tv(&args); 1354 clear_tv(&rettv); 1355 } 1356 if (status != OK) 1357 luaL_error(L, "cannot call funcref"); 1358 return 1; 1359 } 1360 1361 static const luaL_Reg luaV_Funcref_mt[] = { 1362 {"__tostring", luaV_funcref_tostring}, 1363 {"__gc", luaV_funcref_gc}, 1364 {"__len", luaV_funcref_len}, 1365 {"__call", luaV_funcref_call}, 1366 {NULL, NULL} 1367 }; 1368 1369 1370 // ======= Buffer type ======= 1371 1372 luaV_newtype(buf_T, buffer, luaV_Buffer, LUAVIM_BUFFER) 1373 luaV_pushtype(buf_T, buffer, luaV_Buffer) 1374 luaV_type_tostring(buffer, LUAVIM_BUFFER) 1375 1376 static int 1377 luaV_buffer_len(lua_State *L) 1378 { 1379 buf_T *b = (buf_T *) luaV_checkvalid(L, luaV_Buffer, 1); 1380 lua_pushinteger(L, b->b_ml.ml_line_count); 1381 return 1; 1382 } 1383 1384 static int 1385 luaV_buffer_call(lua_State *L) 1386 { 1387 buf_T *b = (buf_T *) luaV_checkvalid(L, luaV_Buffer, 1); 1388 lua_settop(L, 1); 1389 set_curbuf(b, DOBUF_SPLIT); 1390 return 1; 1391 } 1392 1393 static int 1394 luaV_buffer_index(lua_State *L) 1395 { 1396 buf_T *b = (buf_T *) luaV_checkvalid(L, luaV_Buffer, 1); 1397 linenr_T n = (linenr_T) lua_tointeger(L, 2); 1398 if (n > 0 && n <= b->b_ml.ml_line_count) 1399 luaV_pushline(L, b, n); 1400 else if (lua_isstring(L, 2)) 1401 { 1402 const char *s = lua_tostring(L, 2); 1403 if (strncmp(s, "name", 4) == 0) 1404 lua_pushstring(L, (b->b_sfname == NULL) 1405 ? "" : (char *) b->b_sfname); 1406 else if (strncmp(s, "fname", 5) == 0) 1407 lua_pushstring(L, (b->b_ffname == NULL) 1408 ? "" : (char *) b->b_ffname); 1409 else if (strncmp(s, "number", 6) == 0) 1410 lua_pushinteger(L, b->b_fnum); 1411 // methods 1412 else if (strncmp(s, "insert", 6) == 0 1413 || strncmp(s, "next", 4) == 0 1414 || strncmp(s, "previous", 8) == 0 1415 || strncmp(s, "isvalid", 7) == 0) 1416 { 1417 lua_getmetatable(L, 1); 1418 lua_getfield(L, -1, s); 1419 } 1420 else 1421 lua_pushnil(L); 1422 } 1423 else 1424 lua_pushnil(L); 1425 return 1; 1426 } 1427 1428 static int 1429 luaV_buffer_newindex(lua_State *L) 1430 { 1431 buf_T *b = (buf_T *) luaV_checkvalid(L, luaV_Buffer, 1); 1432 linenr_T n = (linenr_T) luaL_checkinteger(L, 2); 1433 #ifdef HAVE_SANDBOX 1434 luaV_checksandbox(L); 1435 #endif 1436 if (n < 1 || n > b->b_ml.ml_line_count) 1437 luaL_error(L, "invalid line number"); 1438 if (lua_isnil(L, 3)) // delete line 1439 { 1440 buf_T *buf = curbuf; 1441 curbuf = b; 1442 if (u_savedel(n, 1L) == FAIL) 1443 { 1444 curbuf = buf; 1445 luaL_error(L, "cannot save undo information"); 1446 } 1447 else if (ml_delete(n) == FAIL) 1448 { 1449 curbuf = buf; 1450 luaL_error(L, "cannot delete line"); 1451 } 1452 else 1453 { 1454 deleted_lines_mark(n, 1L); 1455 if (b == curwin->w_buffer) // fix cursor in current window? 1456 { 1457 if (curwin->w_cursor.lnum >= n) 1458 { 1459 if (curwin->w_cursor.lnum > n) 1460 { 1461 curwin->w_cursor.lnum -= 1; 1462 check_cursor_col(); 1463 } 1464 else 1465 check_cursor(); 1466 changed_cline_bef_curs(); 1467 } 1468 invalidate_botline(); 1469 } 1470 } 1471 curbuf = buf; 1472 } 1473 else if (lua_isstring(L, 3)) // update line 1474 { 1475 buf_T *buf = curbuf; 1476 curbuf = b; 1477 if (u_savesub(n) == FAIL) 1478 { 1479 curbuf = buf; 1480 luaL_error(L, "cannot save undo information"); 1481 } 1482 else if (ml_replace(n, luaV_toline(L, 3), TRUE) == FAIL) 1483 { 1484 curbuf = buf; 1485 luaL_error(L, "cannot replace line"); 1486 } 1487 else changed_bytes(n, 0); 1488 curbuf = buf; 1489 if (b == curwin->w_buffer) 1490 check_cursor_col(); 1491 } 1492 else 1493 luaL_error(L, "wrong argument to change line"); 1494 return 0; 1495 } 1496 1497 static int 1498 luaV_buffer_insert(lua_State *L) 1499 { 1500 luaV_Buffer *lb = luaV_checkudata(L, 1, LUAVIM_BUFFER); 1501 buf_T *b = (buf_T *) luaV_checkcache(L, (void *) *lb); 1502 linenr_T last = b->b_ml.ml_line_count; 1503 linenr_T n = (linenr_T) luaL_optinteger(L, 3, last); 1504 buf_T *buf; 1505 luaL_checktype(L, 2, LUA_TSTRING); 1506 #ifdef HAVE_SANDBOX 1507 luaV_checksandbox(L); 1508 #endif 1509 // fix insertion line 1510 if (n < 0) n = 0; 1511 if (n > last) n = last; 1512 // insert 1513 buf = curbuf; 1514 curbuf = b; 1515 if (u_save(n, n + 1) == FAIL) 1516 { 1517 curbuf = buf; 1518 luaL_error(L, "cannot save undo information"); 1519 } 1520 else if (ml_append(n, luaV_toline(L, 2), 0, FALSE) == FAIL) 1521 { 1522 curbuf = buf; 1523 luaL_error(L, "cannot insert line"); 1524 } 1525 else 1526 appended_lines_mark(n, 1L); 1527 curbuf = buf; 1528 update_screen(VALID); 1529 return 0; 1530 } 1531 1532 static int 1533 luaV_buffer_next(lua_State *L) 1534 { 1535 luaV_Buffer *b = luaV_checkudata(L, 1, LUAVIM_BUFFER); 1536 buf_T *buf = (buf_T *) luaV_checkcache(L, (void *) *b); 1537 luaV_pushbuffer(L, buf->b_next); 1538 return 1; 1539 } 1540 1541 static int 1542 luaV_buffer_previous(lua_State *L) 1543 { 1544 luaV_Buffer *b = luaV_checkudata(L, 1, LUAVIM_BUFFER); 1545 buf_T *buf = (buf_T *) luaV_checkcache(L, (void *) *b); 1546 luaV_pushbuffer(L, buf->b_prev); 1547 return 1; 1548 } 1549 1550 static int 1551 luaV_buffer_isvalid(lua_State *L) 1552 { 1553 luaV_Buffer *b = luaV_checkudata(L, 1, LUAVIM_BUFFER); 1554 luaV_getudata(L, *b); 1555 lua_pushboolean(L, !lua_isnil(L, -1)); 1556 return 1; 1557 } 1558 1559 static const luaL_Reg luaV_Buffer_mt[] = { 1560 {"__tostring", luaV_buffer_tostring}, 1561 {"__len", luaV_buffer_len}, 1562 {"__call", luaV_buffer_call}, 1563 {"__index", luaV_buffer_index}, 1564 {"__newindex", luaV_buffer_newindex}, 1565 {"insert", luaV_buffer_insert}, 1566 {"next", luaV_buffer_next}, 1567 {"previous", luaV_buffer_previous}, 1568 {"isvalid", luaV_buffer_isvalid}, 1569 {NULL, NULL} 1570 }; 1571 1572 1573 // ======= Window type ======= 1574 1575 luaV_newtype(win_T, window, luaV_Window, LUAVIM_WINDOW) 1576 luaV_pushtype(win_T, window, luaV_Window) 1577 luaV_type_tostring(window, LUAVIM_WINDOW) 1578 1579 static int 1580 luaV_window_call(lua_State *L) 1581 { 1582 win_T *w = (win_T *) luaV_checkvalid(L, luaV_Window, 1); 1583 lua_settop(L, 1); 1584 win_goto(w); 1585 return 1; 1586 } 1587 1588 static int 1589 luaV_window_index(lua_State *L) 1590 { 1591 win_T *w = (win_T *) luaV_checkvalid(L, luaV_Window, 1); 1592 const char *s = luaL_checkstring(L, 2); 1593 if (strncmp(s, "buffer", 6) == 0) 1594 luaV_pushbuffer(L, w->w_buffer); 1595 else if (strncmp(s, "line", 4) == 0) 1596 lua_pushinteger(L, w->w_cursor.lnum); 1597 else if (strncmp(s, "col", 3) == 0) 1598 lua_pushinteger(L, w->w_cursor.col + 1); 1599 else if (strncmp(s, "width", 5) == 0) 1600 lua_pushinteger(L, w->w_width); 1601 else if (strncmp(s, "height", 6) == 0) 1602 lua_pushinteger(L, w->w_height); 1603 // methods 1604 else if (strncmp(s, "next", 4) == 0 1605 || strncmp(s, "previous", 8) == 0 1606 || strncmp(s, "isvalid", 7) == 0) 1607 { 1608 lua_getmetatable(L, 1); 1609 lua_getfield(L, -1, s); 1610 } 1611 else 1612 lua_pushnil(L); 1613 return 1; 1614 } 1615 1616 static int 1617 luaV_window_newindex(lua_State *L) 1618 { 1619 win_T *w = (win_T *) luaV_checkvalid(L, luaV_Window, 1); 1620 const char *s = luaL_checkstring(L, 2); 1621 int v = luaL_checkinteger(L, 3); 1622 if (strncmp(s, "line", 4) == 0) 1623 { 1624 #ifdef HAVE_SANDBOX 1625 luaV_checksandbox(L); 1626 #endif 1627 if (v < 1 || v > w->w_buffer->b_ml.ml_line_count) 1628 luaL_error(L, "line out of range"); 1629 w->w_cursor.lnum = v; 1630 update_screen(VALID); 1631 } 1632 else if (strncmp(s, "col", 3) == 0) 1633 { 1634 #ifdef HAVE_SANDBOX 1635 luaV_checksandbox(L); 1636 #endif 1637 w->w_cursor.col = v - 1; 1638 w->w_set_curswant = TRUE; 1639 update_screen(VALID); 1640 } 1641 else if (strncmp(s, "width", 5) == 0) 1642 { 1643 win_T *win = curwin; 1644 #ifdef FEAT_GUI 1645 need_mouse_correct = TRUE; 1646 #endif 1647 curwin = w; 1648 win_setwidth(v); 1649 curwin = win; 1650 } 1651 else if (strncmp(s, "height", 6) == 0) 1652 { 1653 win_T *win = curwin; 1654 #ifdef FEAT_GUI 1655 need_mouse_correct = TRUE; 1656 #endif 1657 curwin = w; 1658 win_setheight(v); 1659 curwin = win; 1660 } 1661 else 1662 luaL_error(L, "invalid window property: `%s'", s); 1663 return 0; 1664 } 1665 1666 static int 1667 luaV_window_next(lua_State *L) 1668 { 1669 luaV_Window *w = luaV_checkudata(L, 1, LUAVIM_WINDOW); 1670 win_T *win = (win_T *) luaV_checkcache(L, (void *) *w); 1671 luaV_pushwindow(L, win->w_next); 1672 return 1; 1673 } 1674 1675 static int 1676 luaV_window_previous(lua_State *L) 1677 { 1678 luaV_Window *w = luaV_checkudata(L, 1, LUAVIM_WINDOW); 1679 win_T *win = (win_T *) luaV_checkcache(L, (void *) *w); 1680 luaV_pushwindow(L, win->w_prev); 1681 return 1; 1682 } 1683 1684 static int 1685 luaV_window_isvalid(lua_State *L) 1686 { 1687 luaV_Window *w = luaV_checkudata(L, 1, LUAVIM_WINDOW); 1688 luaV_getudata(L, *w); 1689 lua_pushboolean(L, !lua_isnil(L, -1)); 1690 return 1; 1691 } 1692 1693 static const luaL_Reg luaV_Window_mt[] = { 1694 {"__tostring", luaV_window_tostring}, 1695 {"__call", luaV_window_call}, 1696 {"__index", luaV_window_index}, 1697 {"__newindex", luaV_window_newindex}, 1698 {"next", luaV_window_next}, 1699 {"previous", luaV_window_previous}, 1700 {"isvalid", luaV_window_isvalid}, 1701 {NULL, NULL} 1702 }; 1703 1704 1705 // ======= Vim module ======= 1706 1707 static int 1708 luaV_print(lua_State *L) 1709 { 1710 int i, n = lua_gettop(L); // nargs 1711 const char *s; 1712 size_t l; 1713 luaL_Buffer b; 1714 luaL_buffinit(L, &b); 1715 lua_getglobal(L, "tostring"); 1716 for (i = 1; i <= n; i++) 1717 { 1718 lua_pushvalue(L, -1); // tostring 1719 lua_pushvalue(L, i); // arg 1720 lua_call(L, 1, 1); 1721 s = lua_tolstring(L, -1, &l); 1722 if (s == NULL) 1723 return luaL_error(L, "cannot convert to string"); 1724 if (i > 1) luaL_addchar(&b, ' '); // use space instead of tab 1725 luaV_addlstring(&b, s, l, 0); 1726 lua_pop(L, 1); 1727 } 1728 luaL_pushresult(&b); 1729 if (!got_int) 1730 luaV_msg(L); 1731 return 0; 1732 } 1733 1734 static int 1735 luaV_debug(lua_State *L) 1736 { 1737 lua_settop(L, 0); 1738 lua_getglobal(L, "vim"); 1739 lua_getfield(L, -1, "eval"); 1740 lua_remove(L, -2); // vim.eval at position 1 1741 for (;;) 1742 { 1743 const char *input; 1744 size_t l; 1745 lua_pushvalue(L, 1); // vim.eval 1746 lua_pushliteral(L, "input('lua_debug> ')"); 1747 lua_call(L, 1, 1); // return string 1748 input = lua_tolstring(L, -1, &l); 1749 if (l == 0 || strcmp(input, "cont") == 0) 1750 return 0; 1751 msg_putchar('\n'); // avoid outputting on input line 1752 if (luaL_loadbuffer(L, input, l, "=(debug command)") 1753 || lua_pcall(L, 0, 0, 0)) 1754 luaV_emsg(L); 1755 lua_settop(L, 1); // remove eventual returns, but keep vim.eval 1756 } 1757 } 1758 1759 static int 1760 luaV_command(lua_State *L) 1761 { 1762 do_cmdline_cmd((char_u *) luaL_checkstring(L, 1)); 1763 update_screen(VALID); 1764 return 0; 1765 } 1766 1767 static int 1768 luaV_eval(lua_State *L) 1769 { 1770 typval_T *tv = eval_expr((char_u *) luaL_checkstring(L, 1), NULL); 1771 if (tv == NULL) luaL_error(L, "invalid expression"); 1772 luaV_pushtypval(L, tv); 1773 free_tv(tv); 1774 return 1; 1775 } 1776 1777 static int 1778 luaV_beep(lua_State *L UNUSED) 1779 { 1780 vim_beep(BO_LANG); 1781 return 0; 1782 } 1783 1784 static int 1785 luaV_line(lua_State *L) 1786 { 1787 luaV_pushline(L, curbuf, curwin->w_cursor.lnum); 1788 return 1; 1789 } 1790 1791 static int 1792 luaV_list(lua_State *L) 1793 { 1794 list_T *l; 1795 int initarg = !lua_isnoneornil(L, 1); 1796 1797 if (initarg && lua_type(L, 1) != LUA_TTABLE) 1798 luaL_error(L, "table expected, got %s", luaL_typename(L, 1)); 1799 l = list_alloc(); 1800 if (l == NULL) 1801 lua_pushnil(L); 1802 else 1803 { 1804 luaV_newlist(L, l); 1805 if (initarg) // traverse table to init list 1806 { 1807 int notnil, i = 0; 1808 typval_T v; 1809 do 1810 { 1811 lua_rawgeti(L, 1, ++i); 1812 notnil = !lua_isnil(L, -1); 1813 if (notnil) 1814 { 1815 luaV_checktypval(L, -1, &v, "vim.list"); 1816 list_append_tv(l, &v); 1817 clear_tv(&v); 1818 } 1819 lua_pop(L, 1); // value 1820 } while (notnil); 1821 } 1822 } 1823 return 1; 1824 } 1825 1826 static int 1827 luaV_dict(lua_State *L) 1828 { 1829 dict_T *d; 1830 int initarg = !lua_isnoneornil(L, 1); 1831 1832 if (initarg && lua_type(L, 1) != LUA_TTABLE) 1833 luaL_error(L, "table expected, got %s", luaL_typename(L, 1)); 1834 d = dict_alloc(); 1835 if (d == NULL) 1836 lua_pushnil(L); 1837 else 1838 { 1839 luaV_newdict(L, d); 1840 if (initarg) // traverse table to init dict 1841 { 1842 lua_pushnil(L); 1843 while (lua_next(L, 1)) 1844 { 1845 char_u *key; 1846 dictitem_T *di; 1847 typval_T v; 1848 1849 lua_pushvalue(L, -2); // dup key in case it's a number 1850 key = (char_u *) lua_tostring(L, -1); 1851 if (key == NULL) 1852 { 1853 lua_pushnil(L); 1854 return 1; 1855 } 1856 if (*key == NUL) 1857 luaL_error(L, "table has empty key"); 1858 luaV_checktypval(L, -2, &v, "vim.dict"); // value 1859 di = dictitem_alloc(key); 1860 if (di == NULL || dict_add(d, di) == FAIL) 1861 { 1862 vim_free(di); 1863 lua_pushnil(L); 1864 return 1; 1865 } 1866 di->di_tv = v; 1867 lua_pop(L, 2); // key copy and value 1868 } 1869 } 1870 } 1871 return 1; 1872 } 1873 1874 static int 1875 luaV_blob(lua_State *L) 1876 { 1877 blob_T *b; 1878 int initarg = !lua_isnoneornil(L, 1); 1879 1880 if (initarg && !lua_isstring(L, 1)) 1881 luaL_error(L, "string expected, got %s", luaL_typename(L, 1)); 1882 b = blob_alloc(); 1883 if (b == NULL) 1884 lua_pushnil(L); 1885 else 1886 { 1887 luaV_newblob(L, b); 1888 if (initarg) 1889 { 1890 size_t i, l = 0; 1891 const char *s = lua_tolstring(L, 1, &l); 1892 1893 if (ga_grow(&b->bv_ga, (int)l) == OK) 1894 for (i = 0; i < l; ++i) 1895 ga_append(&b->bv_ga, s[i]); 1896 } 1897 } 1898 return 1; 1899 } 1900 1901 static int 1902 luaV_funcref(lua_State *L) 1903 { 1904 const char *name = luaL_checkstring(L, 1); 1905 // note: not checking if function exists (needs function_exists) 1906 if (name == NULL || *name == NUL || VIM_ISDIGIT(*name)) 1907 luaL_error(L, "invalid function name: %s", name); 1908 luaV_newfuncref(L, (char_u *) name); 1909 return 1; 1910 } 1911 1912 static int 1913 luaV_buffer(lua_State *L) 1914 { 1915 buf_T *buf; 1916 if (lua_isstring(L, 1)) // get by number or name? 1917 { 1918 if (lua_isnumber(L, 1)) // by number? 1919 { 1920 int n = lua_tointeger(L, 1); 1921 FOR_ALL_BUFFERS(buf) 1922 if (buf->b_fnum == n) break; 1923 } 1924 else // by name 1925 { 1926 size_t l; 1927 const char *s = lua_tolstring(L, 1, &l); 1928 FOR_ALL_BUFFERS(buf) 1929 { 1930 if (buf->b_ffname == NULL || buf->b_sfname == NULL) 1931 { 1932 if (l == 0) break; 1933 } 1934 else if (strncmp(s, (char *)buf->b_ffname, l) == 0 1935 || strncmp(s, (char *)buf->b_sfname, l) == 0) 1936 break; 1937 } 1938 } 1939 } 1940 else 1941 buf = (lua_toboolean(L, 1)) ? firstbuf : curbuf; // first buffer? 1942 luaV_pushbuffer(L, buf); 1943 return 1; 1944 } 1945 1946 static int 1947 luaV_window(lua_State *L) 1948 { 1949 win_T *win; 1950 if (lua_isnumber(L, 1)) // get by number? 1951 { 1952 int n = lua_tointeger(L, 1); 1953 for (win = firstwin; win != NULL; win = win->w_next, n--) 1954 if (n == 1) break; 1955 } 1956 else 1957 win = (lua_toboolean(L, 1)) ? firstwin : curwin; // first window? 1958 luaV_pushwindow(L, win); 1959 return 1; 1960 } 1961 1962 static int 1963 luaV_open(lua_State *L) 1964 { 1965 char_u *s = NULL; 1966 #ifdef HAVE_SANDBOX 1967 luaV_checksandbox(L); 1968 #endif 1969 if (lua_isstring(L, 1)) s = (char_u *) lua_tostring(L, 1); 1970 luaV_pushbuffer(L, buflist_new(s, NULL, 1L, BLN_LISTED)); 1971 return 1; 1972 } 1973 1974 static int 1975 luaV_type(lua_State *L) 1976 { 1977 luaL_checkany(L, 1); 1978 if (lua_type(L, 1) == LUA_TUSERDATA) // check vim udata? 1979 { 1980 lua_settop(L, 1); 1981 if (lua_getmetatable(L, 1)) 1982 { 1983 luaV_getfield(L, LUAVIM_LIST); 1984 if (lua_rawequal(L, -1, 2)) 1985 { 1986 lua_pushstring(L, "list"); 1987 return 1; 1988 } 1989 luaV_getfield(L, LUAVIM_DICT); 1990 if (lua_rawequal(L, -1, 2)) 1991 { 1992 lua_pushstring(L, "dict"); 1993 return 1; 1994 } 1995 luaV_getfield(L, LUAVIM_BLOB); 1996 if (lua_rawequal(L, -1, 2)) 1997 { 1998 lua_pushstring(L, "blob"); 1999 return 1; 2000 } 2001 luaV_getfield(L, LUAVIM_FUNCREF); 2002 if (lua_rawequal(L, -1, 2)) 2003 { 2004 lua_pushstring(L, "funcref"); 2005 return 1; 2006 } 2007 luaV_getfield(L, LUAVIM_BUFFER); 2008 if (lua_rawequal(L, -1, 2)) 2009 { 2010 lua_pushstring(L, "buffer"); 2011 return 1; 2012 } 2013 luaV_getfield(L, LUAVIM_WINDOW); 2014 if (lua_rawequal(L, -1, 2)) 2015 { 2016 lua_pushstring(L, "window"); 2017 return 1; 2018 } 2019 } 2020 } 2021 lua_pushstring(L, luaL_typename(L, 1)); // fallback 2022 return 1; 2023 } 2024 2025 static int 2026 luaV_call(lua_State *L) 2027 { 2028 int argc = lua_gettop(L) - 1; 2029 size_t funcname_len; 2030 char_u *funcname; 2031 char *error = NULL; 2032 typval_T rettv; 2033 typval_T argv[MAX_FUNC_ARGS + 1]; 2034 int i = 0; 2035 2036 if (argc > MAX_FUNC_ARGS) 2037 return luaL_error(L, "Function called with too many arguments"); 2038 2039 funcname = (char_u *)luaL_checklstring(L, 1, &funcname_len); 2040 2041 for (; i < argc; i++) 2042 { 2043 if (luaV_totypval(L, i + 2, &argv[i]) == FAIL) 2044 { 2045 error = "lua: cannot convert value"; 2046 goto free_vim_args; 2047 } 2048 } 2049 2050 argv[argc].v_type = VAR_UNKNOWN; 2051 2052 if (call_vim_function(funcname, argc, argv, &rettv) == FAIL) 2053 { 2054 error = "lua: call_vim_function failed"; 2055 goto free_vim_args; 2056 } 2057 2058 luaV_pushtypval(L, &rettv); 2059 clear_tv(&rettv); 2060 2061 free_vim_args: 2062 while (i > 0) 2063 clear_tv(&argv[--i]); 2064 2065 if (error == NULL) 2066 return 1; 2067 else 2068 return luaL_error(L, error); 2069 } 2070 2071 static const luaL_Reg luaV_module[] = { 2072 {"command", luaV_command}, 2073 {"eval", luaV_eval}, 2074 {"beep", luaV_beep}, 2075 {"line", luaV_line}, 2076 {"list", luaV_list}, 2077 {"dict", luaV_dict}, 2078 {"blob", luaV_blob}, 2079 {"funcref", luaV_funcref}, 2080 {"buffer", luaV_buffer}, 2081 {"window", luaV_window}, 2082 {"open", luaV_open}, 2083 {"type", luaV_type}, 2084 {"call", luaV_call}, 2085 {NULL, NULL} 2086 }; 2087 2088 /* 2089 * for freeing list, dict, buffer and window objects; lightuserdata as arg 2090 */ 2091 static int 2092 luaV_free(lua_State *L) 2093 { 2094 lua_pushnil(L); 2095 luaV_setudata(L, lua_touserdata(L, 1)); 2096 return 0; 2097 } 2098 2099 static int 2100 luaV_luaeval(lua_State *L) 2101 { 2102 luaL_Buffer b; 2103 size_t l; 2104 const char *str = lua_tolstring(L, 1, &l); 2105 typval_T *arg = (typval_T *) lua_touserdata(L, 2); 2106 typval_T *rettv = (typval_T *) lua_touserdata(L, 3); 2107 luaL_buffinit(L, &b); 2108 luaL_addlstring(&b, LUAVIM_EVALHEADER, sizeof(LUAVIM_EVALHEADER) - 1); 2109 luaL_addlstring(&b, str, l); 2110 luaL_pushresult(&b); 2111 str = lua_tolstring(L, -1, &l); 2112 if (luaL_loadbuffer(L, str, l, LUAVIM_EVALNAME)) // compile error? 2113 { 2114 luaV_emsg(L); 2115 return 0; 2116 } 2117 luaV_pushtypval(L, arg); 2118 if (lua_pcall(L, 1, 1, 0)) // running error? 2119 { 2120 luaV_emsg(L); 2121 return 0; 2122 } 2123 if (luaV_totypval(L, -1, rettv) == FAIL) 2124 emsg("luaeval: cannot convert value"); 2125 return 0; 2126 } 2127 2128 static int 2129 luaV_setref(lua_State *L) 2130 { 2131 int copyID = lua_tointeger(L, 1); 2132 int abort = FALSE; 2133 2134 luaV_getfield(L, LUAVIM_LIST); 2135 luaV_getfield(L, LUAVIM_DICT); 2136 luaV_getfield(L, LUAVIM_FUNCREF); 2137 lua_pushnil(L); 2138 // traverse cache table 2139 while (!abort && lua_next(L, lua_upvalueindex(1)) != 0) 2140 { 2141 lua_getmetatable(L, -1); 2142 if (lua_rawequal(L, -1, 2)) // list? 2143 { 2144 list_T *l = (list_T *)lua_touserdata(L, 5); // key 2145 2146 abort = set_ref_in_list(l, copyID); 2147 } 2148 else if (lua_rawequal(L, -1, 3)) // dict? 2149 { 2150 dict_T *d = (dict_T *)lua_touserdata(L, 5); // key 2151 2152 abort = set_ref_in_dict(d, copyID); 2153 } 2154 else if (lua_rawequal(L, -1, 4)) // funcref? 2155 { 2156 luaV_Funcref *f = (luaV_Funcref *)lua_touserdata(L, 5); // key 2157 2158 abort = set_ref_in_dict(f->self, copyID); 2159 } 2160 lua_pop(L, 2); // metatable and value 2161 } 2162 lua_pushinteger(L, abort); 2163 return 1; 2164 } 2165 2166 #define LUA_VIM_FN_CODE \ 2167 "vim.fn = setmetatable({}, {\n"\ 2168 " __index = function (t, key)\n"\ 2169 " local function _fn(...)\n"\ 2170 " return vim.call(key, ...)\n"\ 2171 " end\n"\ 2172 " t[key] = _fn\n"\ 2173 " return _fn\n"\ 2174 " end\n"\ 2175 " })" 2176 2177 #define LUA_VIM_UPDATE_PACKAGE_PATHS \ 2178 "local last_vim_paths = {}\n"\ 2179 "vim._update_package_paths = function ()\n"\ 2180 " local cur_vim_paths = {}\n"\ 2181 " local function split(s, delimiter)\n"\ 2182 " result = {}\n"\ 2183 " for match in (s..delimiter):gmatch(\"(.-)\"..delimiter) do\n"\ 2184 " table.insert(result, match)\n"\ 2185 " end\n"\ 2186 " return result\n"\ 2187 " end\n"\ 2188 " local rtps = split(vim.eval('&runtimepath'), ',')\n"\ 2189 " local sep = package.config:sub(1, 1)\n"\ 2190 " for _, key in ipairs({'path', 'cpath'}) do\n"\ 2191 " local orig_str = package[key] .. ';'\n"\ 2192 " local pathtrails_ordered = {}\n"\ 2193 " -- Note: ignores trailing item without trailing `;`. Not using something\n"\ 2194 " -- simpler in order to preserve empty items (stand for default path).\n"\ 2195 " local orig = {}\n"\ 2196 " for s in orig_str:gmatch('[^;]*;') do\n"\ 2197 " s = s:sub(1, -2) -- Strip trailing semicolon\n"\ 2198 " orig[#orig + 1] = s\n"\ 2199 " end\n"\ 2200 " if key == 'path' then\n"\ 2201 " -- /?.lua and /?/init.lua\n"\ 2202 " pathtrails_ordered = {sep .. '?.lua', sep .. '?' .. sep .. 'init.lua'}\n"\ 2203 " else\n"\ 2204 " local pathtrails = {}\n"\ 2205 " for _, s in ipairs(orig) do\n"\ 2206 " -- Find out path patterns. pathtrail should contain something like\n"\ 2207 " -- /?.so, \?.dll. This allows not to bother determining what correct\n"\ 2208 " -- suffixes are.\n"\ 2209 " local pathtrail = s:match('[/\\\\][^/\\\\]*%?.*$')\n"\ 2210 " if pathtrail and not pathtrails[pathtrail] then\n"\ 2211 " pathtrails[pathtrail] = true\n"\ 2212 " pathtrails_ordered[#pathtrails_ordered + 1] = pathtrail\n"\ 2213 " end\n"\ 2214 " end\n"\ 2215 " end\n"\ 2216 " local new = {}\n"\ 2217 " for _, rtp in ipairs(rtps) do\n"\ 2218 " if not rtp:match(';') then\n"\ 2219 " for _, pathtrail in pairs(pathtrails_ordered) do\n"\ 2220 " local new_path = rtp .. sep .. 'lua' .. pathtrail\n"\ 2221 " -- Always keep paths from &runtimepath at the start:\n"\ 2222 " -- append them here disregarding orig possibly containing one of them.\n"\ 2223 " new[#new + 1] = new_path\n"\ 2224 " cur_vim_paths[new_path] = true\n"\ 2225 " end\n"\ 2226 " end\n"\ 2227 " end\n"\ 2228 " for _, orig_path in ipairs(orig) do\n"\ 2229 " -- Handle removing obsolete paths originating from &runtimepath: such\n"\ 2230 " -- paths either belong to cur_nvim_paths and were already added above or\n"\ 2231 " -- to last_nvim_paths and should not be added at all if corresponding\n"\ 2232 " -- entry was removed from &runtimepath list.\n"\ 2233 " if not (cur_vim_paths[orig_path] or last_vim_paths[orig_path]) then\n"\ 2234 " new[#new + 1] = orig_path\n"\ 2235 " end\n"\ 2236 " end\n"\ 2237 " package[key] = table.concat(new, ';')\n"\ 2238 " end\n"\ 2239 " last_vim_paths = cur_vim_paths\n"\ 2240 "end" 2241 2242 static int 2243 luaopen_vim(lua_State *L) 2244 { 2245 // set cache table 2246 lua_newtable(L); 2247 lua_newtable(L); 2248 lua_pushstring(L, "v"); 2249 lua_setfield(L, -2, "__mode"); 2250 lua_setmetatable(L, -2); // cache is weak-valued 2251 // print 2252 lua_pushcfunction(L, luaV_print); 2253 lua_setglobal(L, "print"); 2254 // debug.debug 2255 lua_getglobal(L, "debug"); 2256 lua_pushcfunction(L, luaV_debug); 2257 lua_setfield(L, -2, "debug"); 2258 lua_pop(L, 1); 2259 // free 2260 lua_pushlightuserdata(L, (void *) LUAVIM_FREE); 2261 lua_pushvalue(L, 1); // cache table 2262 lua_pushcclosure(L, luaV_free, 1); 2263 lua_rawset(L, LUA_REGISTRYINDEX); 2264 // luaeval 2265 lua_pushlightuserdata(L, (void *) LUAVIM_LUAEVAL); 2266 lua_pushvalue(L, 1); // cache table 2267 lua_pushcclosure(L, luaV_luaeval, 1); 2268 lua_rawset(L, LUA_REGISTRYINDEX); 2269 // setref 2270 lua_pushlightuserdata(L, (void *) LUAVIM_SETREF); 2271 lua_pushvalue(L, 1); // cache table 2272 lua_pushcclosure(L, luaV_setref, 1); 2273 lua_rawset(L, LUA_REGISTRYINDEX); 2274 // register 2275 luaV_newmetatable(L, LUAVIM_LIST); 2276 lua_pushvalue(L, 1); 2277 luaV_openlib(L, luaV_List_mt, 1); 2278 luaV_newmetatable(L, LUAVIM_DICT); 2279 lua_pushvalue(L, 1); 2280 luaV_openlib(L, luaV_Dict_mt, 1); 2281 luaV_newmetatable(L, LUAVIM_BLOB); 2282 lua_pushvalue(L, 1); 2283 luaV_openlib(L, luaV_Blob_mt, 1); 2284 luaV_newmetatable(L, LUAVIM_FUNCREF); 2285 lua_pushvalue(L, 1); 2286 luaV_openlib(L, luaV_Funcref_mt, 1); 2287 luaV_newmetatable(L, LUAVIM_BUFFER); 2288 lua_pushvalue(L, 1); // cache table 2289 luaV_openlib(L, luaV_Buffer_mt, 1); 2290 luaV_newmetatable(L, LUAVIM_WINDOW); 2291 lua_pushvalue(L, 1); // cache table 2292 luaV_openlib(L, luaV_Window_mt, 1); 2293 lua_newtable(L); // vim table 2294 lua_pushvalue(L, 1); // cache table 2295 luaV_openlib(L, luaV_module, 1); 2296 lua_setglobal(L, LUAVIM_NAME); 2297 // custom code 2298 (void)luaL_dostring(L, LUA_VIM_FN_CODE); 2299 (void)luaL_dostring(L, LUA_VIM_UPDATE_PACKAGE_PATHS); 2300 2301 lua_getglobal(L, "vim"); 2302 lua_getfield(L, -1, "_update_package_paths"); 2303 2304 if (lua_pcall(L, 0, 0, 0)) 2305 luaV_emsg(L); 2306 2307 return 0; 2308 } 2309 2310 static lua_State * 2311 luaV_newstate(void) 2312 { 2313 lua_State *L = luaL_newstate(); 2314 luaL_openlibs(L); // core libs 2315 lua_pushcfunction(L, luaopen_vim); // vim 2316 lua_call(L, 0, 0); 2317 return L; 2318 } 2319 2320 static void 2321 luaV_setrange(lua_State *L, int line1, int line2) 2322 { 2323 lua_getglobal(L, LUAVIM_NAME); 2324 lua_pushinteger(L, line1); 2325 lua_setfield(L, -2, "firstline"); 2326 lua_pushinteger(L, line2); 2327 lua_setfield(L, -2, "lastline"); 2328 lua_pop(L, 1); // vim table 2329 } 2330 2331 2332 // ======= Interface ======= 2333 2334 static lua_State *L = NULL; 2335 2336 static int 2337 lua_isopen(void) 2338 { 2339 return L != NULL; 2340 } 2341 2342 static int 2343 lua_init(void) 2344 { 2345 if (!lua_isopen()) 2346 { 2347 #ifdef DYNAMIC_LUA 2348 if (!lua_enabled(TRUE)) 2349 { 2350 emsg(_("Lua library cannot be loaded.")); 2351 return FAIL; 2352 } 2353 #endif 2354 L = luaV_newstate(); 2355 } 2356 return OK; 2357 } 2358 2359 void 2360 lua_end(void) 2361 { 2362 if (lua_isopen()) 2363 { 2364 lua_close(L); 2365 L = NULL; 2366 } 2367 } 2368 2369 /* 2370 * ex commands 2371 */ 2372 void 2373 ex_lua(exarg_T *eap) 2374 { 2375 char *script = (char *)script_get(eap, eap->arg); 2376 2377 if (!eap->skip && lua_init() == OK) 2378 { 2379 char *s = script != NULL ? script : (char *)eap->arg; 2380 2381 luaV_setrange(L, eap->line1, eap->line2); 2382 if (luaL_loadbuffer(L, s, strlen(s), LUAVIM_CHUNKNAME) 2383 || lua_pcall(L, 0, 0, 0)) 2384 luaV_emsg(L); 2385 } 2386 if (script != NULL) 2387 vim_free(script); 2388 } 2389 2390 void 2391 ex_luado(exarg_T *eap) 2392 { 2393 linenr_T l; 2394 const char *s = (const char *) eap->arg; 2395 luaL_Buffer b; 2396 size_t len; 2397 buf_T *was_curbuf = curbuf; 2398 2399 if (lua_init() == FAIL) return; 2400 if (u_save(eap->line1 - 1, eap->line2 + 1) == FAIL) 2401 { 2402 emsg(_("cannot save undo information")); 2403 return; 2404 } 2405 luaV_setrange(L, eap->line1, eap->line2); 2406 luaL_buffinit(L, &b); 2407 luaL_addlstring(&b, "return function(line, linenr) ", 30); // header 2408 luaL_addlstring(&b, s, strlen(s)); 2409 luaL_addlstring(&b, " end", 4); // footer 2410 luaL_pushresult(&b); 2411 s = lua_tolstring(L, -1, &len); 2412 if (luaL_loadbuffer(L, s, len, LUAVIM_CHUNKNAME)) 2413 { 2414 luaV_emsg(L); 2415 lua_pop(L, 1); // function body 2416 return; 2417 } 2418 lua_call(L, 0, 1); 2419 lua_replace(L, -2); // function -> body 2420 for (l = eap->line1; l <= eap->line2; l++) 2421 { 2422 // Check the line number, the command may have deleted lines. 2423 if (l > curbuf->b_ml.ml_line_count) 2424 break; 2425 2426 lua_pushvalue(L, -1); // function 2427 luaV_pushline(L, curbuf, l); // current line as arg 2428 lua_pushinteger(L, l); // current line number as arg 2429 if (lua_pcall(L, 2, 1, 0)) 2430 { 2431 luaV_emsg(L); 2432 break; 2433 } 2434 // Catch the command switching to another buffer. 2435 if (curbuf != was_curbuf) 2436 break; 2437 if (lua_isstring(L, -1)) // update line? 2438 { 2439 #ifdef HAVE_SANDBOX 2440 luaV_checksandbox(L); 2441 #endif 2442 ml_replace(l, luaV_toline(L, -1), TRUE); 2443 changed_bytes(l, 0); 2444 lua_pop(L, 1); // result from luaV_toline 2445 } 2446 lua_pop(L, 1); // line 2447 } 2448 lua_pop(L, 1); // function 2449 check_cursor(); 2450 update_screen(NOT_VALID); 2451 } 2452 2453 void 2454 ex_luafile(exarg_T *eap) 2455 { 2456 if (lua_init() == FAIL) 2457 return; 2458 if (!eap->skip) 2459 { 2460 luaV_setrange(L, eap->line1, eap->line2); 2461 if (luaL_loadfile(L, (char *) eap->arg) || lua_pcall(L, 0, 0, 0)) 2462 luaV_emsg(L); 2463 } 2464 } 2465 2466 #define luaV_freetype(typ,tname) \ 2467 void \ 2468 lua_##tname##_free(typ *o) \ 2469 { \ 2470 if (!lua_isopen()) return; \ 2471 luaV_getfield(L, LUAVIM_FREE); \ 2472 lua_pushlightuserdata(L, (void *) o); \ 2473 lua_call(L, 1, 0); \ 2474 } 2475 2476 luaV_freetype(buf_T, buffer) 2477 luaV_freetype(win_T, window) 2478 2479 void 2480 do_luaeval(char_u *str, typval_T *arg, typval_T *rettv) 2481 { 2482 lua_init(); 2483 luaV_getfield(L, LUAVIM_LUAEVAL); 2484 lua_pushstring(L, (char *) str); 2485 lua_pushlightuserdata(L, (void *) arg); 2486 lua_pushlightuserdata(L, (void *) rettv); 2487 lua_call(L, 3, 0); 2488 } 2489 2490 int 2491 set_ref_in_lua(int copyID) 2492 { 2493 int aborted = 0; 2494 2495 if (lua_isopen()) 2496 { 2497 luaV_getfield(L, LUAVIM_SETREF); 2498 // call the function with 1 arg, getting 1 result back 2499 lua_pushinteger(L, copyID); 2500 lua_call(L, 1, 1); 2501 // get the result 2502 aborted = lua_tointeger(L, -1); 2503 // pop result off the stack 2504 lua_pop(L, 1); 2505 } 2506 return aborted; 2507 } 2508 2509 void 2510 update_package_paths_in_lua() 2511 { 2512 if (lua_isopen()) 2513 { 2514 lua_getglobal(L, "vim"); 2515 lua_getfield(L, -1, "_update_package_paths"); 2516 2517 if (lua_pcall(L, 0, 0, 0)) 2518 luaV_emsg(L); 2519 } 2520 } 2521 2522 /* 2523 * Native C function callback 2524 */ 2525 static int 2526 luaV_call_lua_func( 2527 int argcount, 2528 typval_T *argvars, 2529 typval_T *rettv, 2530 void *state) 2531 { 2532 int i; 2533 int luaargcount = argcount; 2534 luaV_CFuncState *funcstate = (luaV_CFuncState*)state; 2535 lua_rawgeti(funcstate->L, LUA_REGISTRYINDEX, funcstate->lua_funcref); 2536 2537 if (funcstate->lua_tableref != LUA_NOREF) 2538 { 2539 // First arg for metatable __call method is a table 2540 luaargcount += 1; 2541 lua_rawgeti(funcstate->L, LUA_REGISTRYINDEX, funcstate->lua_tableref); 2542 } 2543 2544 for (i = 0; i < argcount; ++i) 2545 luaV_pushtypval(funcstate->L, &argvars[i]); 2546 2547 if (lua_pcall(funcstate->L, luaargcount, 1, 0)) 2548 { 2549 luaV_emsg(funcstate->L); 2550 return FCERR_OTHER; 2551 } 2552 2553 luaV_checktypval(funcstate->L, -1, rettv, "get return value"); 2554 return FCERR_NONE; 2555 } 2556 2557 /* 2558 * Free up any lua references held by the func state. 2559 */ 2560 static void 2561 luaV_call_lua_func_free(void *state) 2562 { 2563 luaV_CFuncState *funcstate = (luaV_CFuncState*)state; 2564 luaL_unref(L, LUA_REGISTRYINDEX, funcstate->lua_funcref); 2565 funcstate->L = NULL; 2566 if (funcstate->lua_tableref != LUA_NOREF) 2567 luaL_unref(L, LUA_REGISTRYINDEX, funcstate->lua_tableref); 2568 VIM_CLEAR(funcstate); 2569 } 2570 2571 #endif 2572