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