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 garray_T msg_ga; 1727 1728 ga_init2(&msg_ga, 1, 128); 1729 lua_getglobal(L, "tostring"); 1730 for (i = 1; i <= n; i++) 1731 { 1732 lua_pushvalue(L, -1); // tostring 1733 lua_pushvalue(L, i); // arg 1734 lua_call(L, 1, 1); 1735 s = lua_tolstring(L, -1, &l); 1736 if (s == NULL) 1737 return luaL_error(L, "cannot convert to string"); 1738 if (i > 1) 1739 ga_append(&msg_ga, ' '); // use space instead of tab 1740 ga_concat_len(&msg_ga, (char_u *)s, l); 1741 lua_pop(L, 1); 1742 } 1743 // Replace any "\n" with "\0" 1744 for (i = 0; i < msg_ga.ga_len; i++) 1745 if (((char *)msg_ga.ga_data)[i] == '\n') 1746 ((char *)msg_ga.ga_data)[i] = '\0'; 1747 lua_pushlstring(L, msg_ga.ga_data, msg_ga.ga_len); 1748 if (!got_int) 1749 luaV_msg(L); 1750 1751 ga_clear(&msg_ga); 1752 return 0; 1753 } 1754 1755 static int 1756 luaV_debug(lua_State *L) 1757 { 1758 lua_settop(L, 0); 1759 lua_getglobal(L, "vim"); 1760 lua_getfield(L, -1, "eval"); 1761 lua_remove(L, -2); // vim.eval at position 1 1762 for (;;) 1763 { 1764 const char *input; 1765 size_t l; 1766 lua_pushvalue(L, 1); // vim.eval 1767 lua_pushliteral(L, "input('lua_debug> ')"); 1768 lua_call(L, 1, 1); // return string 1769 input = lua_tolstring(L, -1, &l); 1770 if (l == 0 || strcmp(input, "cont") == 0) 1771 return 0; 1772 msg_putchar('\n'); // avoid outputting on input line 1773 if (luaL_loadbuffer(L, input, l, "=(debug command)") 1774 || lua_pcall(L, 0, 0, 0)) 1775 luaV_emsg(L); 1776 lua_settop(L, 1); // remove eventual returns, but keep vim.eval 1777 } 1778 } 1779 1780 static dict_T * 1781 luaV_get_var_scope(lua_State *L) 1782 { 1783 const char *scope = luaL_checkstring(L, 1); 1784 dict_T *dict = NULL; 1785 1786 if (STRICMP((char *)scope, "g") == 0) 1787 dict = get_globvar_dict(); 1788 else if (STRICMP((char *)scope, "v") == 0) 1789 dict = get_vimvar_dict(); 1790 else if (STRICMP((char *)scope, "b") == 0) 1791 dict = curbuf->b_vars; 1792 else if (STRICMP((char *)scope, "w") == 0) 1793 dict = curwin->w_vars; 1794 else if (STRICMP((char *)scope, "t") == 0) 1795 dict = curtab->tp_vars; 1796 else 1797 { 1798 luaL_error(L, "invalid scope %s", scope); 1799 return NULL; 1800 } 1801 1802 return dict; 1803 } 1804 1805 static int 1806 luaV_setvar(lua_State *L) 1807 { 1808 dict_T *dict; 1809 dictitem_T *di; 1810 size_t len; 1811 char *name; 1812 int del; 1813 char *error = NULL; 1814 1815 name = (char *)luaL_checklstring(L, 3, &len); 1816 del = (lua_gettop(L) < 4) || lua_isnil(L, 4); 1817 1818 dict = luaV_get_var_scope(L); 1819 if (dict == NULL) 1820 return 0; 1821 1822 di = dict_find(dict, (char_u *)name, len); 1823 if (di != NULL) 1824 { 1825 if (di->di_flags & DI_FLAGS_RO) 1826 error = "variable is read-only"; 1827 else if (di->di_flags & DI_FLAGS_LOCK) 1828 error = "variable is locked"; 1829 else if (del && di->di_flags & DI_FLAGS_FIX) 1830 error = "variable is fixed"; 1831 if (error != NULL) 1832 return luaL_error(L, error); 1833 } 1834 else if (dict->dv_lock) 1835 return luaL_error(L, "Dictionary is locked"); 1836 1837 if (del) 1838 { 1839 // Delete the key 1840 if (di == NULL) 1841 // Doesn't exist, nothing to do 1842 return 0; 1843 else 1844 // Delete the entry 1845 dictitem_remove(dict, di); 1846 } 1847 else 1848 { 1849 // Update the key 1850 typval_T tv; 1851 1852 // Convert the lua value to a vimscript type in the temporary variable 1853 lua_pushvalue(L, 4); 1854 if (luaV_totypval(L, -1, &tv) == FAIL) 1855 return luaL_error(L, "Couldn't convert lua value"); 1856 1857 if (di == NULL) 1858 { 1859 // Need to create an entry 1860 di = dictitem_alloc((char_u *)name); 1861 if (di == NULL) 1862 return 0; 1863 // Update the value 1864 copy_tv(&tv, &di->di_tv); 1865 dict_add(dict, di); 1866 } else 1867 { 1868 // Clear the old value 1869 clear_tv(&di->di_tv); 1870 // Update the value 1871 copy_tv(&tv, &di->di_tv); 1872 } 1873 1874 // Clear the temporary variable 1875 clear_tv(&tv); 1876 } 1877 1878 return 0; 1879 } 1880 1881 static int 1882 luaV_getvar(lua_State *L) 1883 { 1884 dict_T *dict = luaV_get_var_scope(L); 1885 size_t len; 1886 const char *name = luaL_checklstring(L, 3, &len); 1887 1888 dictitem_T *di = dict_find(dict, (char_u *)name, len); 1889 if (di == NULL) 1890 return 0; // nil 1891 1892 luaV_pushtypval(L, &di->di_tv); 1893 return 1; 1894 } 1895 1896 static int 1897 luaV_command(lua_State *L) 1898 { 1899 do_cmdline_cmd((char_u *) luaL_checkstring(L, 1)); 1900 update_screen(VALID); 1901 return 0; 1902 } 1903 1904 static int 1905 luaV_eval(lua_State *L) 1906 { 1907 typval_T *tv = eval_expr((char_u *) luaL_checkstring(L, 1), NULL); 1908 if (tv == NULL) luaL_error(L, "invalid expression"); 1909 luaV_pushtypval(L, tv); 1910 free_tv(tv); 1911 return 1; 1912 } 1913 1914 static int 1915 luaV_beep(lua_State *L UNUSED) 1916 { 1917 vim_beep(BO_LANG); 1918 return 0; 1919 } 1920 1921 static int 1922 luaV_line(lua_State *L) 1923 { 1924 luaV_pushline(L, curbuf, curwin->w_cursor.lnum); 1925 return 1; 1926 } 1927 1928 static int 1929 luaV_list(lua_State *L) 1930 { 1931 list_T *l; 1932 int initarg = !lua_isnoneornil(L, 1); 1933 1934 if (initarg && lua_type(L, 1) != LUA_TTABLE) 1935 luaL_error(L, "table expected, got %s", luaL_typename(L, 1)); 1936 l = list_alloc(); 1937 if (l == NULL) 1938 lua_pushnil(L); 1939 else 1940 { 1941 luaV_newlist(L, l); 1942 if (initarg) // traverse table to init list 1943 { 1944 int notnil, i = 0; 1945 typval_T v; 1946 do 1947 { 1948 lua_rawgeti(L, 1, ++i); 1949 notnil = !lua_isnil(L, -1); 1950 if (notnil) 1951 { 1952 luaV_checktypval(L, -1, &v, "vim.list"); 1953 list_append_tv(l, &v); 1954 clear_tv(&v); 1955 } 1956 lua_pop(L, 1); // value 1957 } while (notnil); 1958 } 1959 } 1960 return 1; 1961 } 1962 1963 static int 1964 luaV_dict(lua_State *L) 1965 { 1966 dict_T *d; 1967 int initarg = !lua_isnoneornil(L, 1); 1968 1969 if (initarg && lua_type(L, 1) != LUA_TTABLE) 1970 luaL_error(L, "table expected, got %s", luaL_typename(L, 1)); 1971 d = dict_alloc(); 1972 if (d == NULL) 1973 lua_pushnil(L); 1974 else 1975 { 1976 luaV_newdict(L, d); 1977 if (initarg) // traverse table to init dict 1978 { 1979 lua_pushnil(L); 1980 while (lua_next(L, 1)) 1981 { 1982 char_u *key; 1983 dictitem_T *di; 1984 typval_T v; 1985 1986 lua_pushvalue(L, -2); // dup key in case it's a number 1987 key = (char_u *) lua_tostring(L, -1); 1988 if (key == NULL) 1989 { 1990 lua_pushnil(L); 1991 return 1; 1992 } 1993 if (*key == NUL) 1994 luaL_error(L, "table has empty key"); 1995 luaV_checktypval(L, -2, &v, "vim.dict"); // value 1996 di = dictitem_alloc(key); 1997 if (di == NULL || dict_add(d, di) == FAIL) 1998 { 1999 vim_free(di); 2000 lua_pushnil(L); 2001 return 1; 2002 } 2003 di->di_tv = v; 2004 lua_pop(L, 2); // key copy and value 2005 } 2006 } 2007 } 2008 return 1; 2009 } 2010 2011 static int 2012 luaV_blob(lua_State *L) 2013 { 2014 blob_T *b; 2015 int initarg = !lua_isnoneornil(L, 1); 2016 2017 if (initarg && !lua_isstring(L, 1)) 2018 luaL_error(L, "string expected, got %s", luaL_typename(L, 1)); 2019 b = blob_alloc(); 2020 if (b == NULL) 2021 lua_pushnil(L); 2022 else 2023 { 2024 luaV_newblob(L, b); 2025 if (initarg) 2026 { 2027 size_t i, l = 0; 2028 const char *s = lua_tolstring(L, 1, &l); 2029 2030 if (ga_grow(&b->bv_ga, (int)l) == OK) 2031 for (i = 0; i < l; ++i) 2032 ga_append(&b->bv_ga, s[i]); 2033 } 2034 } 2035 return 1; 2036 } 2037 2038 static int 2039 luaV_funcref(lua_State *L) 2040 { 2041 const char *name = luaL_checkstring(L, 1); 2042 // note: not checking if function exists (needs function_exists) 2043 if (name == NULL || *name == NUL || VIM_ISDIGIT(*name)) 2044 luaL_error(L, "invalid function name: %s", name); 2045 luaV_newfuncref(L, (char_u *) name); 2046 return 1; 2047 } 2048 2049 static int 2050 luaV_buffer(lua_State *L) 2051 { 2052 buf_T *buf; 2053 if (lua_isstring(L, 1)) // get by number or name? 2054 { 2055 if (lua_isnumber(L, 1)) // by number? 2056 { 2057 int n = lua_tointeger(L, 1); 2058 FOR_ALL_BUFFERS(buf) 2059 if (buf->b_fnum == n) break; 2060 } 2061 else // by name 2062 { 2063 size_t l; 2064 const char *s = lua_tolstring(L, 1, &l); 2065 FOR_ALL_BUFFERS(buf) 2066 { 2067 if (buf->b_ffname == NULL || buf->b_sfname == NULL) 2068 { 2069 if (l == 0) break; 2070 } 2071 else if (strncmp(s, (char *)buf->b_ffname, l) == 0 2072 || strncmp(s, (char *)buf->b_sfname, l) == 0) 2073 break; 2074 } 2075 } 2076 } 2077 else 2078 buf = (lua_toboolean(L, 1)) ? firstbuf : curbuf; // first buffer? 2079 luaV_pushbuffer(L, buf); 2080 return 1; 2081 } 2082 2083 static int 2084 luaV_window(lua_State *L) 2085 { 2086 win_T *win; 2087 if (lua_isnumber(L, 1)) // get by number? 2088 { 2089 int n = lua_tointeger(L, 1); 2090 for (win = firstwin; win != NULL; win = win->w_next, n--) 2091 if (n == 1) break; 2092 } 2093 else 2094 win = (lua_toboolean(L, 1)) ? firstwin : curwin; // first window? 2095 luaV_pushwindow(L, win); 2096 return 1; 2097 } 2098 2099 static int 2100 luaV_open(lua_State *L) 2101 { 2102 char_u *s = NULL; 2103 #ifdef HAVE_SANDBOX 2104 luaV_checksandbox(L); 2105 #endif 2106 if (lua_isstring(L, 1)) s = (char_u *) lua_tostring(L, 1); 2107 luaV_pushbuffer(L, buflist_new(s, NULL, 1L, BLN_LISTED)); 2108 return 1; 2109 } 2110 2111 static int 2112 luaV_type(lua_State *L) 2113 { 2114 luaL_checkany(L, 1); 2115 if (lua_type(L, 1) == LUA_TUSERDATA) // check vim udata? 2116 { 2117 lua_settop(L, 1); 2118 if (lua_getmetatable(L, 1)) 2119 { 2120 luaV_getfield(L, LUAVIM_LIST); 2121 if (lua_rawequal(L, -1, 2)) 2122 { 2123 lua_pushstring(L, "list"); 2124 return 1; 2125 } 2126 luaV_getfield(L, LUAVIM_DICT); 2127 if (lua_rawequal(L, -1, 2)) 2128 { 2129 lua_pushstring(L, "dict"); 2130 return 1; 2131 } 2132 luaV_getfield(L, LUAVIM_BLOB); 2133 if (lua_rawequal(L, -1, 2)) 2134 { 2135 lua_pushstring(L, "blob"); 2136 return 1; 2137 } 2138 luaV_getfield(L, LUAVIM_FUNCREF); 2139 if (lua_rawequal(L, -1, 2)) 2140 { 2141 lua_pushstring(L, "funcref"); 2142 return 1; 2143 } 2144 luaV_getfield(L, LUAVIM_BUFFER); 2145 if (lua_rawequal(L, -1, 2)) 2146 { 2147 lua_pushstring(L, "buffer"); 2148 return 1; 2149 } 2150 luaV_getfield(L, LUAVIM_WINDOW); 2151 if (lua_rawequal(L, -1, 2)) 2152 { 2153 lua_pushstring(L, "window"); 2154 return 1; 2155 } 2156 } 2157 } 2158 lua_pushstring(L, luaL_typename(L, 1)); // fallback 2159 return 1; 2160 } 2161 2162 static int 2163 luaV_call(lua_State *L) 2164 { 2165 int argc = lua_gettop(L) - 1; 2166 size_t funcname_len; 2167 char_u *funcname; 2168 char *error = NULL; 2169 typval_T rettv; 2170 typval_T argv[MAX_FUNC_ARGS + 1]; 2171 int i = 0; 2172 2173 if (argc > MAX_FUNC_ARGS) 2174 return luaL_error(L, "Function called with too many arguments"); 2175 2176 funcname = (char_u *)luaL_checklstring(L, 1, &funcname_len); 2177 2178 for (; i < argc; i++) 2179 { 2180 if (luaV_totypval(L, i + 2, &argv[i]) == FAIL) 2181 { 2182 error = "lua: cannot convert value"; 2183 goto free_vim_args; 2184 } 2185 } 2186 2187 argv[argc].v_type = VAR_UNKNOWN; 2188 2189 if (call_vim_function(funcname, argc, argv, &rettv) == FAIL) 2190 { 2191 error = "lua: call_vim_function failed"; 2192 goto free_vim_args; 2193 } 2194 2195 luaV_pushtypval(L, &rettv); 2196 clear_tv(&rettv); 2197 2198 free_vim_args: 2199 while (i > 0) 2200 clear_tv(&argv[--i]); 2201 2202 if (error == NULL) 2203 return 1; 2204 else 2205 return luaL_error(L, error); 2206 } 2207 2208 static const luaL_Reg luaV_module[] = { 2209 {"command", luaV_command}, 2210 {"eval", luaV_eval}, 2211 {"beep", luaV_beep}, 2212 {"line", luaV_line}, 2213 {"list", luaV_list}, 2214 {"dict", luaV_dict}, 2215 {"blob", luaV_blob}, 2216 {"funcref", luaV_funcref}, 2217 {"buffer", luaV_buffer}, 2218 {"window", luaV_window}, 2219 {"open", luaV_open}, 2220 {"type", luaV_type}, 2221 {"call", luaV_call}, 2222 {"_getvar", luaV_getvar}, 2223 {"_setvar", luaV_setvar}, 2224 {"lua_version", NULL}, 2225 {NULL, NULL} 2226 }; 2227 2228 /* 2229 * for freeing list, dict, buffer and window objects; lightuserdata as arg 2230 */ 2231 static int 2232 luaV_free(lua_State *L) 2233 { 2234 lua_pushnil(L); 2235 luaV_setudata(L, lua_touserdata(L, 1)); 2236 return 0; 2237 } 2238 2239 static int 2240 luaV_luaeval(lua_State *L) 2241 { 2242 luaL_Buffer b; 2243 size_t l; 2244 const char *str = lua_tolstring(L, 1, &l); 2245 typval_T *arg = (typval_T *) lua_touserdata(L, 2); 2246 typval_T *rettv = (typval_T *) lua_touserdata(L, 3); 2247 luaL_buffinit(L, &b); 2248 luaL_addlstring(&b, LUAVIM_EVALHEADER, sizeof(LUAVIM_EVALHEADER) - 1); 2249 luaL_addlstring(&b, str, l); 2250 luaL_pushresult(&b); 2251 str = lua_tolstring(L, -1, &l); 2252 if (luaL_loadbuffer(L, str, l, LUAVIM_EVALNAME)) // compile error? 2253 { 2254 luaV_emsg(L); 2255 return 0; 2256 } 2257 luaV_pushtypval(L, arg); 2258 if (lua_pcall(L, 1, 1, 0)) // running error? 2259 { 2260 luaV_emsg(L); 2261 return 0; 2262 } 2263 if (luaV_totypval(L, -1, rettv) == FAIL) 2264 emsg("luaeval: cannot convert value"); 2265 return 0; 2266 } 2267 2268 static int 2269 luaV_setref(lua_State *L) 2270 { 2271 int copyID = lua_tointeger(L, 1); 2272 int abort = FALSE; 2273 2274 luaV_getfield(L, LUAVIM_LIST); 2275 luaV_getfield(L, LUAVIM_DICT); 2276 luaV_getfield(L, LUAVIM_FUNCREF); 2277 lua_pushnil(L); 2278 // traverse cache table 2279 while (!abort && lua_next(L, lua_upvalueindex(1)) != 0) 2280 { 2281 lua_getmetatable(L, -1); 2282 if (lua_rawequal(L, -1, 2)) // list? 2283 { 2284 list_T *l = (list_T *)lua_touserdata(L, 5); // key 2285 2286 abort = set_ref_in_list(l, copyID); 2287 } 2288 else if (lua_rawequal(L, -1, 3)) // dict? 2289 { 2290 dict_T *d = (dict_T *)lua_touserdata(L, 5); // key 2291 2292 abort = set_ref_in_dict(d, copyID); 2293 } 2294 else if (lua_rawequal(L, -1, 4)) // funcref? 2295 { 2296 luaV_Funcref *f = (luaV_Funcref *)lua_touserdata(L, 5); // key 2297 2298 abort = set_ref_in_dict(f->self, copyID); 2299 } 2300 lua_pop(L, 2); // metatable and value 2301 } 2302 lua_pushinteger(L, abort); 2303 return 1; 2304 } 2305 2306 static int 2307 luaV_pushversion(lua_State *L) 2308 { 2309 int major = 0; 2310 int minor = 0; 2311 int patch = 0; 2312 char s[16]; 2313 2314 sscanf(LUAVIM_VERSION, "Lua %d.%d.%d", &major, &minor, &patch); 2315 vim_snprintf(s, sizeof(s), "%d.%d.%d", major, minor, patch); 2316 lua_pushstring(L, s); 2317 return 0; 2318 } 2319 2320 #define LUA_VIM_FN_CODE \ 2321 "vim.fn = setmetatable({}, {\n"\ 2322 " __index = function (t, key)\n"\ 2323 " local function _fn(...)\n"\ 2324 " return vim.call(key, ...)\n"\ 2325 " end\n"\ 2326 " t[key] = _fn\n"\ 2327 " return _fn\n"\ 2328 " end\n"\ 2329 " })" 2330 2331 #define LUA_VIM_UPDATE_PACKAGE_PATHS \ 2332 "local last_vim_paths = {}\n"\ 2333 "vim._update_package_paths = function ()\n"\ 2334 " local cur_vim_paths = {}\n"\ 2335 " local function split(s, delimiter)\n"\ 2336 " result = {}\n"\ 2337 " for match in (s..delimiter):gmatch(\"(.-)\"..delimiter) do\n"\ 2338 " table.insert(result, match)\n"\ 2339 " end\n"\ 2340 " return result\n"\ 2341 " end\n"\ 2342 " local rtps = split(vim.eval('&runtimepath'), ',')\n"\ 2343 " local sep = package.config:sub(1, 1)\n"\ 2344 " for _, key in ipairs({'path', 'cpath'}) do\n"\ 2345 " local orig_str = package[key] .. ';'\n"\ 2346 " local pathtrails_ordered = {}\n"\ 2347 " -- Note: ignores trailing item without trailing `;`. Not using something\n"\ 2348 " -- simpler in order to preserve empty items (stand for default path).\n"\ 2349 " local orig = {}\n"\ 2350 " for s in orig_str:gmatch('[^;]*;') do\n"\ 2351 " s = s:sub(1, -2) -- Strip trailing semicolon\n"\ 2352 " orig[#orig + 1] = s\n"\ 2353 " end\n"\ 2354 " if key == 'path' then\n"\ 2355 " -- /?.lua and /?/init.lua\n"\ 2356 " pathtrails_ordered = {sep .. '?.lua', sep .. '?' .. sep .. 'init.lua'}\n"\ 2357 " else\n"\ 2358 " local pathtrails = {}\n"\ 2359 " for _, s in ipairs(orig) do\n"\ 2360 " -- Find out path patterns. pathtrail should contain something like\n"\ 2361 " -- /?.so, \?.dll. This allows not to bother determining what correct\n"\ 2362 " -- suffixes are.\n"\ 2363 " local pathtrail = s:match('[/\\\\][^/\\\\]*%?.*$')\n"\ 2364 " if pathtrail and not pathtrails[pathtrail] then\n"\ 2365 " pathtrails[pathtrail] = true\n"\ 2366 " pathtrails_ordered[#pathtrails_ordered + 1] = pathtrail\n"\ 2367 " end\n"\ 2368 " end\n"\ 2369 " end\n"\ 2370 " local new = {}\n"\ 2371 " for _, rtp in ipairs(rtps) do\n"\ 2372 " if not rtp:match(';') then\n"\ 2373 " for _, pathtrail in pairs(pathtrails_ordered) do\n"\ 2374 " local new_path = rtp .. sep .. 'lua' .. pathtrail\n"\ 2375 " -- Always keep paths from &runtimepath at the start:\n"\ 2376 " -- append them here disregarding orig possibly containing one of them.\n"\ 2377 " new[#new + 1] = new_path\n"\ 2378 " cur_vim_paths[new_path] = true\n"\ 2379 " end\n"\ 2380 " end\n"\ 2381 " end\n"\ 2382 " for _, orig_path in ipairs(orig) do\n"\ 2383 " -- Handle removing obsolete paths originating from &runtimepath: such\n"\ 2384 " -- paths either belong to cur_nvim_paths and were already added above or\n"\ 2385 " -- to last_nvim_paths and should not be added at all if corresponding\n"\ 2386 " -- entry was removed from &runtimepath list.\n"\ 2387 " if not (cur_vim_paths[orig_path] or last_vim_paths[orig_path]) then\n"\ 2388 " new[#new + 1] = orig_path\n"\ 2389 " end\n"\ 2390 " end\n"\ 2391 " package[key] = table.concat(new, ';')\n"\ 2392 " end\n"\ 2393 " last_vim_paths = cur_vim_paths\n"\ 2394 "end" 2395 2396 #define LUA_VIM_SETUP_VARIABLE_DICTS \ 2397 "do\n"\ 2398 " local function make_dict_accessor(scope)\n"\ 2399 " local mt = {}\n"\ 2400 " function mt:__newindex(k, v)\n"\ 2401 " return vim._setvar(scope, 0, k, v)\n"\ 2402 " end\n"\ 2403 " function mt:__index(k)\n"\ 2404 " return vim._getvar(scope, 0, k)\n"\ 2405 " end\n"\ 2406 " return setmetatable({}, mt)\n"\ 2407 " end\n"\ 2408 " vim.g = make_dict_accessor('g')\n"\ 2409 " vim.v = make_dict_accessor('v')\n"\ 2410 " vim.b = make_dict_accessor('b')\n"\ 2411 " vim.w = make_dict_accessor('w')\n"\ 2412 " vim.t = make_dict_accessor('t')\n"\ 2413 "end" 2414 2415 static int 2416 luaopen_vim(lua_State *L) 2417 { 2418 // set cache table 2419 lua_newtable(L); 2420 lua_newtable(L); 2421 lua_pushstring(L, "v"); 2422 lua_setfield(L, -2, "__mode"); 2423 lua_setmetatable(L, -2); // cache is weak-valued 2424 // print 2425 lua_pushcfunction(L, luaV_print); 2426 lua_setglobal(L, "print"); 2427 // debug.debug 2428 lua_getglobal(L, "debug"); 2429 lua_pushcfunction(L, luaV_debug); 2430 lua_setfield(L, -2, "debug"); 2431 lua_pop(L, 1); 2432 // free 2433 lua_pushlightuserdata(L, (void *) LUAVIM_FREE); 2434 lua_pushvalue(L, 1); // cache table 2435 lua_pushcclosure(L, luaV_free, 1); 2436 lua_rawset(L, LUA_REGISTRYINDEX); 2437 // luaeval 2438 lua_pushlightuserdata(L, (void *) LUAVIM_LUAEVAL); 2439 lua_pushvalue(L, 1); // cache table 2440 lua_pushcclosure(L, luaV_luaeval, 1); 2441 lua_rawset(L, LUA_REGISTRYINDEX); 2442 // setref 2443 lua_pushlightuserdata(L, (void *) LUAVIM_SETREF); 2444 lua_pushvalue(L, 1); // cache table 2445 lua_pushcclosure(L, luaV_setref, 1); 2446 lua_rawset(L, LUA_REGISTRYINDEX); 2447 // register 2448 luaV_newmetatable(L, LUAVIM_LIST); 2449 lua_pushvalue(L, 1); 2450 luaV_openlib(L, luaV_List_mt, 1); 2451 luaV_newmetatable(L, LUAVIM_DICT); 2452 lua_pushvalue(L, 1); 2453 luaV_openlib(L, luaV_Dict_mt, 1); 2454 luaV_newmetatable(L, LUAVIM_BLOB); 2455 lua_pushvalue(L, 1); 2456 luaV_openlib(L, luaV_Blob_mt, 1); 2457 luaV_newmetatable(L, LUAVIM_FUNCREF); 2458 lua_pushvalue(L, 1); 2459 luaV_openlib(L, luaV_Funcref_mt, 1); 2460 luaV_newmetatable(L, LUAVIM_BUFFER); 2461 lua_pushvalue(L, 1); // cache table 2462 luaV_openlib(L, luaV_Buffer_mt, 1); 2463 luaV_newmetatable(L, LUAVIM_WINDOW); 2464 lua_pushvalue(L, 1); // cache table 2465 luaV_openlib(L, luaV_Window_mt, 1); 2466 lua_newtable(L); // vim table 2467 lua_pushvalue(L, 1); // cache table 2468 luaV_openlib(L, luaV_module, 1); 2469 luaV_pushversion(L); 2470 lua_setfield(L, -2, "lua_version"); 2471 lua_setglobal(L, LUAVIM_NAME); 2472 // custom code 2473 (void)luaL_dostring(L, LUA_VIM_FN_CODE); 2474 (void)luaL_dostring(L, LUA_VIM_UPDATE_PACKAGE_PATHS); 2475 (void)luaL_dostring(L, LUA_VIM_SETUP_VARIABLE_DICTS); 2476 2477 lua_getglobal(L, "vim"); 2478 lua_getfield(L, -1, "_update_package_paths"); 2479 2480 if (lua_pcall(L, 0, 0, 0)) 2481 luaV_emsg(L); 2482 2483 return 0; 2484 } 2485 2486 static lua_State * 2487 luaV_newstate(void) 2488 { 2489 lua_State *L = luaL_newstate(); 2490 luaL_openlibs(L); // core libs 2491 lua_pushcfunction(L, luaopen_vim); // vim 2492 lua_call(L, 0, 0); 2493 return L; 2494 } 2495 2496 static void 2497 luaV_setrange(lua_State *L, int line1, int line2) 2498 { 2499 lua_getglobal(L, LUAVIM_NAME); 2500 lua_pushinteger(L, line1); 2501 lua_setfield(L, -2, "firstline"); 2502 lua_pushinteger(L, line2); 2503 lua_setfield(L, -2, "lastline"); 2504 lua_pop(L, 1); // vim table 2505 } 2506 2507 2508 // ======= Interface ======= 2509 2510 static lua_State *L = NULL; 2511 2512 static int 2513 lua_isopen(void) 2514 { 2515 return L != NULL; 2516 } 2517 2518 static int 2519 lua_init(void) 2520 { 2521 if (!lua_isopen()) 2522 { 2523 #ifdef DYNAMIC_LUA 2524 if (!lua_enabled(TRUE)) 2525 { 2526 emsg(_("Lua library cannot be loaded.")); 2527 return FAIL; 2528 } 2529 #endif 2530 L = luaV_newstate(); 2531 } 2532 return OK; 2533 } 2534 2535 void 2536 lua_end(void) 2537 { 2538 if (lua_isopen()) 2539 { 2540 lua_close(L); 2541 L = NULL; 2542 } 2543 } 2544 2545 /* 2546 * ex commands 2547 */ 2548 void 2549 ex_lua(exarg_T *eap) 2550 { 2551 char *script = (char *)script_get(eap, eap->arg); 2552 2553 if (!eap->skip && lua_init() == OK) 2554 { 2555 char *s = script != NULL ? script : (char *)eap->arg; 2556 2557 luaV_setrange(L, eap->line1, eap->line2); 2558 if (luaL_loadbuffer(L, s, strlen(s), LUAVIM_CHUNKNAME) 2559 || lua_pcall(L, 0, 0, 0)) 2560 luaV_emsg(L); 2561 } 2562 if (script != NULL) 2563 vim_free(script); 2564 } 2565 2566 void 2567 ex_luado(exarg_T *eap) 2568 { 2569 linenr_T l; 2570 const char *s = (const char *) eap->arg; 2571 luaL_Buffer b; 2572 size_t len; 2573 buf_T *was_curbuf = curbuf; 2574 2575 if (lua_init() == FAIL) return; 2576 if (u_save(eap->line1 - 1, eap->line2 + 1) == FAIL) 2577 { 2578 emsg(_("cannot save undo information")); 2579 return; 2580 } 2581 luaV_setrange(L, eap->line1, eap->line2); 2582 luaL_buffinit(L, &b); 2583 luaL_addlstring(&b, "return function(line, linenr) ", 30); // header 2584 luaL_addlstring(&b, s, strlen(s)); 2585 luaL_addlstring(&b, " end", 4); // footer 2586 luaL_pushresult(&b); 2587 s = lua_tolstring(L, -1, &len); 2588 if (luaL_loadbuffer(L, s, len, LUAVIM_CHUNKNAME)) 2589 { 2590 luaV_emsg(L); 2591 lua_pop(L, 1); // function body 2592 return; 2593 } 2594 lua_call(L, 0, 1); 2595 lua_replace(L, -2); // function -> body 2596 for (l = eap->line1; l <= eap->line2; l++) 2597 { 2598 // Check the line number, the command may have deleted lines. 2599 if (l > curbuf->b_ml.ml_line_count) 2600 break; 2601 2602 lua_pushvalue(L, -1); // function 2603 luaV_pushline(L, curbuf, l); // current line as arg 2604 lua_pushinteger(L, l); // current line number as arg 2605 if (lua_pcall(L, 2, 1, 0)) 2606 { 2607 luaV_emsg(L); 2608 break; 2609 } 2610 // Catch the command switching to another buffer. 2611 if (curbuf != was_curbuf) 2612 break; 2613 if (lua_isstring(L, -1)) // update line? 2614 { 2615 #ifdef HAVE_SANDBOX 2616 luaV_checksandbox(L); 2617 #endif 2618 ml_replace(l, luaV_toline(L, -1), TRUE); 2619 changed_bytes(l, 0); 2620 lua_pop(L, 1); // result from luaV_toline 2621 } 2622 lua_pop(L, 1); // line 2623 } 2624 lua_pop(L, 1); // function 2625 check_cursor(); 2626 update_screen(NOT_VALID); 2627 } 2628 2629 void 2630 ex_luafile(exarg_T *eap) 2631 { 2632 if (lua_init() == FAIL) 2633 return; 2634 if (!eap->skip) 2635 { 2636 luaV_setrange(L, eap->line1, eap->line2); 2637 if (luaL_loadfile(L, (char *) eap->arg) || lua_pcall(L, 0, 0, 0)) 2638 luaV_emsg(L); 2639 } 2640 } 2641 2642 #define luaV_freetype(typ,tname) \ 2643 void \ 2644 lua_##tname##_free(typ *o) \ 2645 { \ 2646 if (!lua_isopen()) return; \ 2647 luaV_getfield(L, LUAVIM_FREE); \ 2648 lua_pushlightuserdata(L, (void *) o); \ 2649 lua_call(L, 1, 0); \ 2650 } 2651 2652 luaV_freetype(buf_T, buffer) 2653 luaV_freetype(win_T, window) 2654 2655 void 2656 do_luaeval(char_u *str, typval_T *arg, typval_T *rettv) 2657 { 2658 lua_init(); 2659 luaV_getfield(L, LUAVIM_LUAEVAL); 2660 lua_pushstring(L, (char *) str); 2661 lua_pushlightuserdata(L, (void *) arg); 2662 lua_pushlightuserdata(L, (void *) rettv); 2663 lua_call(L, 3, 0); 2664 } 2665 2666 int 2667 set_ref_in_lua(int copyID) 2668 { 2669 int aborted = 0; 2670 2671 if (lua_isopen()) 2672 { 2673 luaV_getfield(L, LUAVIM_SETREF); 2674 // call the function with 1 arg, getting 1 result back 2675 lua_pushinteger(L, copyID); 2676 lua_call(L, 1, 1); 2677 // get the result 2678 aborted = lua_tointeger(L, -1); 2679 // pop result off the stack 2680 lua_pop(L, 1); 2681 } 2682 return aborted; 2683 } 2684 2685 void 2686 update_package_paths_in_lua() 2687 { 2688 if (lua_isopen()) 2689 { 2690 lua_getglobal(L, "vim"); 2691 lua_getfield(L, -1, "_update_package_paths"); 2692 2693 if (lua_pcall(L, 0, 0, 0)) 2694 luaV_emsg(L); 2695 } 2696 } 2697 2698 /* 2699 * Native C function callback 2700 */ 2701 static int 2702 luaV_call_lua_func( 2703 int argcount, 2704 typval_T *argvars, 2705 typval_T *rettv, 2706 void *state) 2707 { 2708 int i; 2709 int luaargcount = argcount; 2710 luaV_CFuncState *funcstate = (luaV_CFuncState*)state; 2711 lua_rawgeti(funcstate->L, LUA_REGISTRYINDEX, funcstate->lua_funcref); 2712 2713 if (funcstate->lua_tableref != LUA_NOREF) 2714 { 2715 // First arg for metatable __call method is a table 2716 luaargcount += 1; 2717 lua_rawgeti(funcstate->L, LUA_REGISTRYINDEX, funcstate->lua_tableref); 2718 } 2719 2720 for (i = 0; i < argcount; ++i) 2721 luaV_pushtypval(funcstate->L, &argvars[i]); 2722 2723 if (lua_pcall(funcstate->L, luaargcount, 1, 0)) 2724 { 2725 luaV_emsg(funcstate->L); 2726 return FCERR_OTHER; 2727 } 2728 2729 luaV_checktypval(funcstate->L, -1, rettv, "get return value"); 2730 return FCERR_NONE; 2731 } 2732 2733 /* 2734 * Free up any lua references held by the func state. 2735 */ 2736 static void 2737 luaV_call_lua_func_free(void *state) 2738 { 2739 luaV_CFuncState *funcstate = (luaV_CFuncState*)state; 2740 luaL_unref(L, LUA_REGISTRYINDEX, funcstate->lua_funcref); 2741 funcstate->L = NULL; 2742 if (funcstate->lua_tableref != LUA_NOREF) 2743 luaL_unref(L, LUA_REGISTRYINDEX, funcstate->lua_tableref); 2744 VIM_CLEAR(funcstate); 2745 } 2746 2747 #endif 2748