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