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