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