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 MSWIN 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 luaL_error(L, "failed to add item to list"); 848 clear_tv(&v); 849 lua_settop(L, 1); 850 return 1; 851 } 852 853 static int 854 luaV_list_insert (lua_State *L) 855 { 856 luaV_List *lis = luaV_checkudata(L, 1, LUAVIM_LIST); 857 list_T *l = (list_T *) luaV_checkcache(L, (void *) *lis); 858 long pos = (long) luaL_optinteger(L, 3, 0); 859 listitem_T *li = NULL; 860 typval_T v; 861 if (l->lv_lock) 862 luaL_error(L, "list is locked"); 863 if (pos < l->lv_len) 864 { 865 li = list_find(l, pos); 866 if (li == NULL) 867 luaL_error(L, "invalid position"); 868 } 869 lua_settop(L, 2); 870 luaV_checktypval(L, 2, &v, "inserting list item"); 871 if (list_insert_tv(l, &v, li) == FAIL) 872 luaL_error(L, "failed to add item to list"); 873 clear_tv(&v); 874 lua_settop(L, 1); 875 return 1; 876 } 877 878 static const luaL_Reg luaV_List_mt[] = { 879 {"__tostring", luaV_list_tostring}, 880 {"__len", luaV_list_len}, 881 {"__call", luaV_list_call}, 882 {"__index", luaV_list_index}, 883 {"__newindex", luaV_list_newindex}, 884 {"add", luaV_list_add}, 885 {"insert", luaV_list_insert}, 886 {NULL, NULL} 887 }; 888 889 890 /* ======= Dict type ======= */ 891 892 static luaV_Dict * 893 luaV_newdict (lua_State *L, dict_T *dic) 894 { 895 luaV_Dict *d = (luaV_Dict *) lua_newuserdata(L, sizeof(luaV_Dict)); 896 *d = dic; 897 dic->dv_refcount++; /* reference in Lua */ 898 luaV_setudata(L, dic); /* cache[dic] = udata */ 899 luaV_getfield(L, LUAVIM_DICT); 900 lua_setmetatable(L, -2); 901 return d; 902 } 903 904 luaV_pushtype(dict_T, dict, luaV_Dict) 905 luaV_type_tostring(dict, LUAVIM_DICT) 906 907 static int 908 luaV_dict_len (lua_State *L) 909 { 910 dict_T *d = luaV_unbox(L, luaV_Dict, 1); 911 lua_pushinteger(L, (d == NULL) ? 0 : (int) d->dv_hashtab.ht_used); 912 return 1; 913 } 914 915 static int 916 luaV_dict_iter (lua_State *L UNUSED) 917 { 918 #ifdef FEAT_EVAL 919 hashitem_T *hi = (hashitem_T *) lua_touserdata(L, lua_upvalueindex(2)); 920 int n = lua_tointeger(L, lua_upvalueindex(3)); 921 dictitem_T *di; 922 if (n <= 0) return 0; 923 while (HASHITEM_EMPTY(hi)) hi++; 924 di = dict_lookup(hi); 925 lua_pushstring(L, (char *) hi->hi_key); 926 luaV_pushtypval(L, &di->di_tv); 927 lua_pushlightuserdata(L, (void *) (hi + 1)); 928 lua_replace(L, lua_upvalueindex(2)); 929 lua_pushinteger(L, n - 1); 930 lua_replace(L, lua_upvalueindex(3)); 931 return 2; 932 #else 933 return 0; 934 #endif 935 } 936 937 static int 938 luaV_dict_call (lua_State *L) 939 { 940 dict_T *d = luaV_unbox(L, luaV_Dict, 1); 941 hashtab_T *ht = &d->dv_hashtab; 942 lua_pushvalue(L, lua_upvalueindex(1)); /* pass cache table along */ 943 lua_pushlightuserdata(L, (void *) ht->ht_array); 944 lua_pushinteger(L, ht->ht_used); /* # remaining items */ 945 lua_pushcclosure(L, luaV_dict_iter, 3); 946 return 1; 947 } 948 949 static int 950 luaV_dict_index(lua_State *L) 951 { 952 dict_T *d = luaV_unbox(L, luaV_Dict, 1); 953 char_u *key = (char_u *) luaL_checkstring(L, 2); 954 dictitem_T *di = dict_find(d, key, -1); 955 956 if (di == NULL) 957 lua_pushnil(L); 958 else 959 { 960 luaV_pushtypval(L, &di->di_tv); 961 if (di->di_tv.v_type == VAR_FUNC) /* funcref? */ 962 { 963 luaV_Funcref *f = (luaV_Funcref *) lua_touserdata(L, -1); 964 f->self = d; /* keep "self" reference */ 965 d->dv_refcount++; 966 } 967 } 968 return 1; 969 } 970 971 static int 972 luaV_dict_newindex(lua_State *L) 973 { 974 dict_T *d = luaV_unbox(L, luaV_Dict, 1); 975 char_u *key = (char_u *) luaL_checkstring(L, 2); 976 dictitem_T *di; 977 typval_T v; 978 979 if (d->dv_lock) 980 luaL_error(L, "dict is locked"); 981 if (key == NULL) 982 return 0; 983 if (*key == NUL) 984 luaL_error(L, "empty key"); 985 if (!lua_isnil(L, 3)) /* read value? */ 986 { 987 luaV_checktypval(L, 3, &v, "setting dict item"); 988 if (d->dv_scope == VAR_DEF_SCOPE && v.v_type == VAR_FUNC) 989 luaL_error(L, "cannot assign funcref to builtin scope"); 990 } 991 di = dict_find(d, key, -1); 992 if (di == NULL) /* non-existing key? */ 993 { 994 if (lua_isnil(L, 3)) 995 return 0; 996 di = dictitem_alloc(key); 997 if (di == NULL) 998 return 0; 999 if (dict_add(d, di) == FAIL) 1000 { 1001 vim_free(di); 1002 return 0; 1003 } 1004 } 1005 else 1006 clear_tv(&di->di_tv); 1007 if (lua_isnil(L, 3)) /* remove? */ 1008 { 1009 hashitem_T *hi = hash_find(&d->dv_hashtab, di->di_key); 1010 hash_remove(&d->dv_hashtab, hi); 1011 dictitem_free(di); 1012 } 1013 else 1014 { 1015 copy_tv(&v, &di->di_tv); 1016 clear_tv(&v); 1017 } 1018 return 0; 1019 } 1020 1021 static const luaL_Reg luaV_Dict_mt[] = { 1022 {"__tostring", luaV_dict_tostring}, 1023 {"__len", luaV_dict_len}, 1024 {"__call", luaV_dict_call}, 1025 {"__index", luaV_dict_index}, 1026 {"__newindex", luaV_dict_newindex}, 1027 {NULL, NULL} 1028 }; 1029 1030 1031 /* ======= Funcref type ======= */ 1032 1033 static luaV_Funcref * 1034 luaV_newfuncref(lua_State *L, char_u *name) 1035 { 1036 luaV_Funcref *f = (luaV_Funcref *)lua_newuserdata(L, sizeof(luaV_Funcref)); 1037 1038 if (name != NULL) 1039 { 1040 func_ref(name); /* as in copy_tv */ 1041 f->tv.vval.v_string = vim_strsave(name); 1042 } 1043 f->tv.v_type = VAR_FUNC; 1044 f->args.v_type = VAR_LIST; 1045 f->self = NULL; 1046 luaV_getfield(L, LUAVIM_FUNCREF); 1047 lua_setmetatable(L, -2); 1048 return f; 1049 } 1050 1051 static luaV_Funcref * 1052 luaV_pushfuncref(lua_State *L, typval_T *tv) 1053 { 1054 luaV_Funcref *f = luaV_newfuncref(L, NULL); 1055 copy_tv(tv, &f->tv); 1056 clear_tv(tv); 1057 return f; 1058 } 1059 1060 1061 luaV_type_tostring(funcref, LUAVIM_FUNCREF) 1062 1063 static int 1064 luaV_funcref_gc(lua_State *L) 1065 { 1066 luaV_Funcref *f = (luaV_Funcref *) lua_touserdata(L, 1); 1067 1068 func_unref(f->tv.vval.v_string); 1069 vim_free(f->tv.vval.v_string); 1070 dict_unref(f->self); 1071 return 0; 1072 } 1073 1074 /* equivalent to string(funcref) */ 1075 static int 1076 luaV_funcref_len(lua_State *L) 1077 { 1078 luaV_Funcref *f = (luaV_Funcref *) lua_touserdata(L, 1); 1079 1080 lua_pushstring(L, (const char *) f->tv.vval.v_string); 1081 return 1; 1082 } 1083 1084 static int 1085 luaV_funcref_call(lua_State *L) 1086 { 1087 luaV_Funcref *f = (luaV_Funcref *) lua_touserdata(L, 1); 1088 int i, n = lua_gettop(L) - 1; /* #args */ 1089 int status; 1090 typval_T v, rettv; 1091 1092 f->args.vval.v_list = list_alloc(); 1093 rettv.v_type = VAR_UNKNOWN; /* as in clear_tv */ 1094 if (f->args.vval.v_list == NULL) 1095 status = FAIL; 1096 else 1097 { 1098 for (i = 0; i < n; i++) 1099 { 1100 luaV_checktypval(L, i + 2, &v, "calling funcref"); 1101 list_append_tv(f->args.vval.v_list, &v); 1102 clear_tv(&v); 1103 } 1104 status = func_call(f->tv.vval.v_string, &f->args, 1105 NULL, f->self, &rettv); 1106 if (status == OK) 1107 luaV_pushtypval(L, &rettv); 1108 clear_tv(&f->args); 1109 clear_tv(&rettv); 1110 } 1111 if (status != OK) 1112 luaL_error(L, "cannot call funcref"); 1113 return 1; 1114 } 1115 1116 static const luaL_Reg luaV_Funcref_mt[] = { 1117 {"__tostring", luaV_funcref_tostring}, 1118 {"__gc", luaV_funcref_gc}, 1119 {"__len", luaV_funcref_len}, 1120 {"__call", luaV_funcref_call}, 1121 {NULL, NULL} 1122 }; 1123 1124 1125 /* ======= Buffer type ======= */ 1126 1127 luaV_newtype(buf_T, buffer, luaV_Buffer, LUAVIM_BUFFER) 1128 luaV_pushtype(buf_T, buffer, luaV_Buffer) 1129 luaV_type_tostring(buffer, LUAVIM_BUFFER) 1130 1131 static int 1132 luaV_buffer_len(lua_State *L) 1133 { 1134 buf_T *b = (buf_T *) luaV_checkvalid(L, luaV_Buffer, 1); 1135 lua_pushinteger(L, b->b_ml.ml_line_count); 1136 return 1; 1137 } 1138 1139 static int 1140 luaV_buffer_call(lua_State *L) 1141 { 1142 buf_T *b = (buf_T *) luaV_checkvalid(L, luaV_Buffer, 1); 1143 lua_settop(L, 1); 1144 set_curbuf(b, DOBUF_SPLIT); 1145 return 1; 1146 } 1147 1148 static int 1149 luaV_buffer_index(lua_State *L) 1150 { 1151 buf_T *b = (buf_T *) luaV_checkvalid(L, luaV_Buffer, 1); 1152 linenr_T n = (linenr_T) lua_tointeger(L, 2); 1153 if (n > 0 && n <= b->b_ml.ml_line_count) 1154 luaV_pushline(L, b, n); 1155 else if (lua_isstring(L, 2)) 1156 { 1157 const char *s = lua_tostring(L, 2); 1158 if (strncmp(s, "name", 4) == 0) 1159 lua_pushstring(L, (b->b_sfname == NULL) 1160 ? "" : (char *) b->b_sfname); 1161 else if (strncmp(s, "fname", 5) == 0) 1162 lua_pushstring(L, (b->b_ffname == NULL) 1163 ? "" : (char *) b->b_ffname); 1164 else if (strncmp(s, "number", 6) == 0) 1165 lua_pushinteger(L, b->b_fnum); 1166 /* methods */ 1167 else if (strncmp(s, "insert", 6) == 0 1168 || strncmp(s, "next", 4) == 0 1169 || strncmp(s, "previous", 8) == 0 1170 || strncmp(s, "isvalid", 7) == 0) 1171 { 1172 lua_getmetatable(L, 1); 1173 lua_getfield(L, -1, s); 1174 } 1175 else 1176 lua_pushnil(L); 1177 } 1178 else 1179 lua_pushnil(L); 1180 return 1; 1181 } 1182 1183 static int 1184 luaV_buffer_newindex(lua_State *L) 1185 { 1186 buf_T *b = (buf_T *) luaV_checkvalid(L, luaV_Buffer, 1); 1187 linenr_T n = (linenr_T) luaL_checkinteger(L, 2); 1188 #ifdef HAVE_SANDBOX 1189 luaV_checksandbox(L); 1190 #endif 1191 if (n < 1 || n > b->b_ml.ml_line_count) 1192 luaL_error(L, "invalid line number"); 1193 if (lua_isnil(L, 3)) /* delete line */ 1194 { 1195 buf_T *buf = curbuf; 1196 curbuf = b; 1197 if (u_savedel(n, 1L) == FAIL) 1198 { 1199 curbuf = buf; 1200 luaL_error(L, "cannot save undo information"); 1201 } 1202 else if (ml_delete(n, FALSE) == FAIL) 1203 { 1204 curbuf = buf; 1205 luaL_error(L, "cannot delete line"); 1206 } 1207 else 1208 { 1209 deleted_lines_mark(n, 1L); 1210 if (b == curwin->w_buffer) /* fix cursor in current window? */ 1211 { 1212 if (curwin->w_cursor.lnum >= n) 1213 { 1214 if (curwin->w_cursor.lnum > n) 1215 { 1216 curwin->w_cursor.lnum -= 1; 1217 check_cursor_col(); 1218 } 1219 else check_cursor(); 1220 changed_cline_bef_curs(); 1221 } 1222 invalidate_botline(); 1223 } 1224 } 1225 curbuf = buf; 1226 } 1227 else if (lua_isstring(L, 3)) /* update line */ 1228 { 1229 buf_T *buf = curbuf; 1230 curbuf = b; 1231 if (u_savesub(n) == FAIL) 1232 { 1233 curbuf = buf; 1234 luaL_error(L, "cannot save undo information"); 1235 } 1236 else if (ml_replace(n, luaV_toline(L, 3), TRUE) == FAIL) 1237 { 1238 curbuf = buf; 1239 luaL_error(L, "cannot replace line"); 1240 } 1241 else changed_bytes(n, 0); 1242 curbuf = buf; 1243 if (b == curwin->w_buffer) 1244 check_cursor_col(); 1245 } 1246 else 1247 luaL_error(L, "wrong argument to change line"); 1248 return 0; 1249 } 1250 1251 static int 1252 luaV_buffer_insert(lua_State *L) 1253 { 1254 luaV_Buffer *lb = luaV_checkudata(L, 1, LUAVIM_BUFFER); 1255 buf_T *b = (buf_T *) luaV_checkcache(L, (void *) *lb); 1256 linenr_T last = b->b_ml.ml_line_count; 1257 linenr_T n = (linenr_T) luaL_optinteger(L, 3, last); 1258 buf_T *buf; 1259 luaL_checktype(L, 2, LUA_TSTRING); 1260 #ifdef HAVE_SANDBOX 1261 luaV_checksandbox(L); 1262 #endif 1263 /* fix insertion line */ 1264 if (n < 0) n = 0; 1265 if (n > last) n = last; 1266 /* insert */ 1267 buf = curbuf; 1268 curbuf = b; 1269 if (u_save(n, n + 1) == FAIL) 1270 { 1271 curbuf = buf; 1272 luaL_error(L, "cannot save undo information"); 1273 } 1274 else if (ml_append(n, luaV_toline(L, 2), 0, FALSE) == FAIL) 1275 { 1276 curbuf = buf; 1277 luaL_error(L, "cannot insert line"); 1278 } 1279 else 1280 appended_lines_mark(n, 1L); 1281 curbuf = buf; 1282 update_screen(VALID); 1283 return 0; 1284 } 1285 1286 static int 1287 luaV_buffer_next(lua_State *L) 1288 { 1289 luaV_Buffer *b = luaV_checkudata(L, 1, LUAVIM_BUFFER); 1290 buf_T *buf = (buf_T *) luaV_checkcache(L, (void *) *b); 1291 luaV_pushbuffer(L, buf->b_next); 1292 return 1; 1293 } 1294 1295 static int 1296 luaV_buffer_previous(lua_State *L) 1297 { 1298 luaV_Buffer *b = luaV_checkudata(L, 1, LUAVIM_BUFFER); 1299 buf_T *buf = (buf_T *) luaV_checkcache(L, (void *) *b); 1300 luaV_pushbuffer(L, buf->b_prev); 1301 return 1; 1302 } 1303 1304 static int 1305 luaV_buffer_isvalid(lua_State *L) 1306 { 1307 luaV_Buffer *b = luaV_checkudata(L, 1, LUAVIM_BUFFER); 1308 luaV_getudata(L, *b); 1309 lua_pushboolean(L, !lua_isnil(L, -1)); 1310 return 1; 1311 } 1312 1313 static const luaL_Reg luaV_Buffer_mt[] = { 1314 {"__tostring", luaV_buffer_tostring}, 1315 {"__len", luaV_buffer_len}, 1316 {"__call", luaV_buffer_call}, 1317 {"__index", luaV_buffer_index}, 1318 {"__newindex", luaV_buffer_newindex}, 1319 {"insert", luaV_buffer_insert}, 1320 {"next", luaV_buffer_next}, 1321 {"previous", luaV_buffer_previous}, 1322 {"isvalid", luaV_buffer_isvalid}, 1323 {NULL, NULL} 1324 }; 1325 1326 1327 /* ======= Window type ======= */ 1328 1329 luaV_newtype(win_T, window, luaV_Window, LUAVIM_WINDOW) 1330 luaV_pushtype(win_T, window, luaV_Window) 1331 luaV_type_tostring(window, LUAVIM_WINDOW) 1332 1333 static int 1334 luaV_window_call(lua_State *L) 1335 { 1336 win_T *w = (win_T *) luaV_checkvalid(L, luaV_Window, 1); 1337 lua_settop(L, 1); 1338 win_goto(w); 1339 return 1; 1340 } 1341 1342 static int 1343 luaV_window_index(lua_State *L) 1344 { 1345 win_T *w = (win_T *) luaV_checkvalid(L, luaV_Window, 1); 1346 const char *s = luaL_checkstring(L, 2); 1347 if (strncmp(s, "buffer", 6) == 0) 1348 luaV_pushbuffer(L, w->w_buffer); 1349 else if (strncmp(s, "line", 4) == 0) 1350 lua_pushinteger(L, w->w_cursor.lnum); 1351 else if (strncmp(s, "col", 3) == 0) 1352 lua_pushinteger(L, w->w_cursor.col + 1); 1353 else if (strncmp(s, "width", 5) == 0) 1354 lua_pushinteger(L, w->w_width); 1355 else if (strncmp(s, "height", 6) == 0) 1356 lua_pushinteger(L, w->w_height); 1357 /* methods */ 1358 else if (strncmp(s, "next", 4) == 0 1359 || strncmp(s, "previous", 8) == 0 1360 || strncmp(s, "isvalid", 7) == 0) 1361 { 1362 lua_getmetatable(L, 1); 1363 lua_getfield(L, -1, s); 1364 } 1365 else 1366 lua_pushnil(L); 1367 return 1; 1368 } 1369 1370 static int 1371 luaV_window_newindex (lua_State *L) 1372 { 1373 win_T *w = (win_T *) luaV_checkvalid(L, luaV_Window, 1); 1374 const char *s = luaL_checkstring(L, 2); 1375 int v = luaL_checkinteger(L, 3); 1376 if (strncmp(s, "line", 4) == 0) 1377 { 1378 #ifdef HAVE_SANDBOX 1379 luaV_checksandbox(L); 1380 #endif 1381 if (v < 1 || v > w->w_buffer->b_ml.ml_line_count) 1382 luaL_error(L, "line out of range"); 1383 w->w_cursor.lnum = v; 1384 update_screen(VALID); 1385 } 1386 else if (strncmp(s, "col", 3) == 0) 1387 { 1388 #ifdef HAVE_SANDBOX 1389 luaV_checksandbox(L); 1390 #endif 1391 w->w_cursor.col = v - 1; 1392 w->w_set_curswant = TRUE; 1393 update_screen(VALID); 1394 } 1395 else if (strncmp(s, "width", 5) == 0) 1396 { 1397 win_T *win = curwin; 1398 #ifdef FEAT_GUI 1399 need_mouse_correct = TRUE; 1400 #endif 1401 curwin = w; 1402 win_setwidth(v); 1403 curwin = win; 1404 } 1405 else if (strncmp(s, "height", 6) == 0) 1406 { 1407 win_T *win = curwin; 1408 #ifdef FEAT_GUI 1409 need_mouse_correct = TRUE; 1410 #endif 1411 curwin = w; 1412 win_setheight(v); 1413 curwin = win; 1414 } 1415 else 1416 luaL_error(L, "invalid window property: `%s'", s); 1417 return 0; 1418 } 1419 1420 static int 1421 luaV_window_next(lua_State *L) 1422 { 1423 luaV_Window *w = luaV_checkudata(L, 1, LUAVIM_WINDOW); 1424 win_T *win = (win_T *) luaV_checkcache(L, (void *) *w); 1425 luaV_pushwindow(L, win->w_next); 1426 return 1; 1427 } 1428 1429 static int 1430 luaV_window_previous(lua_State *L) 1431 { 1432 luaV_Window *w = luaV_checkudata(L, 1, LUAVIM_WINDOW); 1433 win_T *win = (win_T *) luaV_checkcache(L, (void *) *w); 1434 luaV_pushwindow(L, win->w_prev); 1435 return 1; 1436 } 1437 1438 static int 1439 luaV_window_isvalid(lua_State *L) 1440 { 1441 luaV_Window *w = luaV_checkudata(L, 1, LUAVIM_WINDOW); 1442 luaV_getudata(L, *w); 1443 lua_pushboolean(L, !lua_isnil(L, -1)); 1444 return 1; 1445 } 1446 1447 static const luaL_Reg luaV_Window_mt[] = { 1448 {"__tostring", luaV_window_tostring}, 1449 {"__call", luaV_window_call}, 1450 {"__index", luaV_window_index}, 1451 {"__newindex", luaV_window_newindex}, 1452 {"next", luaV_window_next}, 1453 {"previous", luaV_window_previous}, 1454 {"isvalid", luaV_window_isvalid}, 1455 {NULL, NULL} 1456 }; 1457 1458 1459 /* ======= Vim module ======= */ 1460 1461 static int 1462 luaV_print(lua_State *L) 1463 { 1464 int i, n = lua_gettop(L); /* nargs */ 1465 const char *s; 1466 size_t l; 1467 luaL_Buffer b; 1468 luaL_buffinit(L, &b); 1469 lua_getglobal(L, "tostring"); 1470 for (i = 1; i <= n; i++) 1471 { 1472 lua_pushvalue(L, -1); /* tostring */ 1473 lua_pushvalue(L, i); /* arg */ 1474 lua_call(L, 1, 1); 1475 s = lua_tolstring(L, -1, &l); 1476 if (s == NULL) 1477 return luaL_error(L, "cannot convert to string"); 1478 if (i > 1) luaL_addchar(&b, ' '); /* use space instead of tab */ 1479 luaV_addlstring(&b, s, l, 0); 1480 lua_pop(L, 1); 1481 } 1482 luaL_pushresult(&b); 1483 luaV_msg(L); 1484 return 0; 1485 } 1486 1487 static int 1488 luaV_debug(lua_State *L) 1489 { 1490 lua_settop(L, 0); 1491 lua_getglobal(L, "vim"); 1492 lua_getfield(L, -1, "eval"); 1493 lua_remove(L, -2); /* vim.eval at position 1 */ 1494 for (;;) 1495 { 1496 const char *input; 1497 size_t l; 1498 lua_pushvalue(L, 1); /* vim.eval */ 1499 lua_pushliteral(L, "input('lua_debug> ')"); 1500 lua_call(L, 1, 1); /* return string */ 1501 input = lua_tolstring(L, -1, &l); 1502 if (l == 0 || strcmp(input, "cont") == 0) 1503 return 0; 1504 msg_putchar('\n'); /* avoid outputting on input line */ 1505 if (luaL_loadbuffer(L, input, l, "=(debug command)") 1506 || lua_pcall(L, 0, 0, 0)) 1507 luaV_emsg(L); 1508 lua_settop(L, 1); /* remove eventual returns, but keep vim.eval */ 1509 } 1510 } 1511 1512 static int 1513 luaV_command(lua_State *L) 1514 { 1515 do_cmdline_cmd((char_u *) luaL_checkstring(L, 1)); 1516 update_screen(VALID); 1517 return 0; 1518 } 1519 1520 static int 1521 luaV_eval(lua_State *L) 1522 { 1523 typval_T *tv = eval_expr((char_u *) luaL_checkstring(L, 1), NULL); 1524 if (tv == NULL) luaL_error(L, "invalid expression"); 1525 luaV_pushtypval(L, tv); 1526 free_tv(tv); 1527 return 1; 1528 } 1529 1530 static int 1531 luaV_beep(lua_State *L UNUSED) 1532 { 1533 vim_beep(BO_LANG); 1534 return 0; 1535 } 1536 1537 static int 1538 luaV_line(lua_State *L) 1539 { 1540 luaV_pushline(L, curbuf, curwin->w_cursor.lnum); 1541 return 1; 1542 } 1543 1544 static int 1545 luaV_list(lua_State *L) 1546 { 1547 list_T *l; 1548 int initarg = !lua_isnoneornil(L, 1); 1549 1550 if (initarg && lua_type(L, 1) != LUA_TTABLE) 1551 luaL_error(L, "table expected, got %s", luaL_typename(L, 1)); 1552 l = list_alloc(); 1553 if (l == NULL) 1554 lua_pushnil(L); 1555 else 1556 { 1557 luaV_newlist(L, l); 1558 if (initarg) /* traverse table to init list */ 1559 { 1560 int notnil, i = 0; 1561 typval_T v; 1562 do 1563 { 1564 lua_rawgeti(L, 1, ++i); 1565 notnil = !lua_isnil(L, -1); 1566 if (notnil) 1567 { 1568 luaV_checktypval(L, -1, &v, "vim.list"); 1569 list_append_tv(l, &v); 1570 clear_tv(&v); 1571 } 1572 lua_pop(L, 1); /* value */ 1573 } while (notnil); 1574 } 1575 } 1576 return 1; 1577 } 1578 1579 static int 1580 luaV_dict(lua_State *L) 1581 { 1582 dict_T *d; 1583 int initarg = !lua_isnoneornil(L, 1); 1584 1585 if (initarg && lua_type(L, 1) != LUA_TTABLE) 1586 luaL_error(L, "table expected, got %s", luaL_typename(L, 1)); 1587 d = dict_alloc(); 1588 if (d == NULL) 1589 lua_pushnil(L); 1590 else 1591 { 1592 luaV_newdict(L, d); 1593 if (initarg) /* traverse table to init dict */ 1594 { 1595 lua_pushnil(L); 1596 while (lua_next(L, 1)) 1597 { 1598 char_u *key; 1599 dictitem_T *di; 1600 typval_T v; 1601 1602 lua_pushvalue(L, -2); /* dup key in case it's a number */ 1603 key = (char_u *) lua_tostring(L, -1); 1604 if (key == NULL) 1605 { 1606 lua_pushnil(L); 1607 return 1; 1608 } 1609 if (*key == NUL) 1610 luaL_error(L, "table has empty key"); 1611 luaV_checktypval(L, -2, &v, "vim.dict"); /* value */ 1612 di = dictitem_alloc(key); 1613 if (di == NULL || dict_add(d, di) == FAIL) 1614 { 1615 vim_free(di); 1616 lua_pushnil(L); 1617 return 1; 1618 } 1619 copy_tv(&v, &di->di_tv); 1620 clear_tv(&v); 1621 lua_pop(L, 2); /* key copy and value */ 1622 } 1623 } 1624 } 1625 return 1; 1626 } 1627 1628 static int 1629 luaV_funcref(lua_State *L) 1630 { 1631 const char *name = luaL_checkstring(L, 1); 1632 /* note: not checking if function exists (needs function_exists) */ 1633 if (name == NULL || *name == NUL || VIM_ISDIGIT(*name)) 1634 luaL_error(L, "invalid function name: %s", name); 1635 luaV_newfuncref(L, (char_u *) name); 1636 return 1; 1637 } 1638 1639 static int 1640 luaV_buffer(lua_State *L) 1641 { 1642 buf_T *buf; 1643 if (lua_isstring(L, 1)) /* get by number or name? */ 1644 { 1645 if (lua_isnumber(L, 1)) /* by number? */ 1646 { 1647 int n = lua_tointeger(L, 1); 1648 FOR_ALL_BUFFERS(buf) 1649 if (buf->b_fnum == n) break; 1650 } 1651 else // by name 1652 { 1653 size_t l; 1654 const char *s = lua_tolstring(L, 1, &l); 1655 FOR_ALL_BUFFERS(buf) 1656 { 1657 if (buf->b_ffname == NULL || buf->b_sfname == NULL) 1658 { 1659 if (l == 0) break; 1660 } 1661 else if (strncmp(s, (char *)buf->b_ffname, l) == 0 1662 || strncmp(s, (char *)buf->b_sfname, l) == 0) 1663 break; 1664 } 1665 } 1666 } 1667 else 1668 buf = (lua_toboolean(L, 1)) ? firstbuf : curbuf; /* first buffer? */ 1669 luaV_pushbuffer(L, buf); 1670 return 1; 1671 } 1672 1673 static int 1674 luaV_window(lua_State *L) 1675 { 1676 win_T *win; 1677 if (lua_isnumber(L, 1)) /* get by number? */ 1678 { 1679 int n = lua_tointeger(L, 1); 1680 for (win = firstwin; win != NULL; win = win->w_next, n--) 1681 if (n == 1) break; 1682 } 1683 else 1684 win = (lua_toboolean(L, 1)) ? firstwin : curwin; /* first window? */ 1685 luaV_pushwindow(L, win); 1686 return 1; 1687 } 1688 1689 static int 1690 luaV_open(lua_State *L) 1691 { 1692 char_u *s = NULL; 1693 #ifdef HAVE_SANDBOX 1694 luaV_checksandbox(L); 1695 #endif 1696 if (lua_isstring(L, 1)) s = (char_u *) lua_tostring(L, 1); 1697 luaV_pushbuffer(L, buflist_new(s, NULL, 1L, BLN_LISTED)); 1698 return 1; 1699 } 1700 1701 static int 1702 luaV_type(lua_State *L) 1703 { 1704 luaL_checkany(L, 1); 1705 if (lua_type(L, 1) == LUA_TUSERDATA) /* check vim udata? */ 1706 { 1707 lua_settop(L, 1); 1708 if (lua_getmetatable(L, 1)) 1709 { 1710 luaV_getfield(L, LUAVIM_LIST); 1711 if (lua_rawequal(L, -1, 2)) 1712 { 1713 lua_pushstring(L, "list"); 1714 return 1; 1715 } 1716 luaV_getfield(L, LUAVIM_DICT); 1717 if (lua_rawequal(L, -1, 2)) 1718 { 1719 lua_pushstring(L, "dict"); 1720 return 1; 1721 } 1722 luaV_getfield(L, LUAVIM_FUNCREF); 1723 if (lua_rawequal(L, -1, 2)) 1724 { 1725 lua_pushstring(L, "funcref"); 1726 return 1; 1727 } 1728 luaV_getfield(L, LUAVIM_BUFFER); 1729 if (lua_rawequal(L, -1, 2)) 1730 { 1731 lua_pushstring(L, "buffer"); 1732 return 1; 1733 } 1734 luaV_getfield(L, LUAVIM_WINDOW); 1735 if (lua_rawequal(L, -1, 2)) 1736 { 1737 lua_pushstring(L, "window"); 1738 return 1; 1739 } 1740 } 1741 } 1742 lua_pushstring(L, luaL_typename(L, 1)); /* fallback */ 1743 return 1; 1744 } 1745 1746 static const luaL_Reg luaV_module[] = { 1747 {"command", luaV_command}, 1748 {"eval", luaV_eval}, 1749 {"beep", luaV_beep}, 1750 {"line", luaV_line}, 1751 {"list", luaV_list}, 1752 {"dict", luaV_dict}, 1753 {"funcref", luaV_funcref}, 1754 {"buffer", luaV_buffer}, 1755 {"window", luaV_window}, 1756 {"open", luaV_open}, 1757 {"type", luaV_type}, 1758 {NULL, NULL} 1759 }; 1760 1761 /* for freeing list, dict, buffer and window objects; lightuserdata as arg */ 1762 static int 1763 luaV_free(lua_State *L) 1764 { 1765 lua_pushnil(L); 1766 luaV_setudata(L, lua_touserdata(L, 1)); 1767 return 0; 1768 } 1769 1770 static int 1771 luaV_luaeval (lua_State *L) 1772 { 1773 luaL_Buffer b; 1774 size_t l; 1775 const char *str = lua_tolstring(L, 1, &l); 1776 typval_T *arg = (typval_T *) lua_touserdata(L, 2); 1777 typval_T *rettv = (typval_T *) lua_touserdata(L, 3); 1778 luaL_buffinit(L, &b); 1779 luaL_addlstring(&b, LUAVIM_EVALHEADER, sizeof(LUAVIM_EVALHEADER) - 1); 1780 luaL_addlstring(&b, str, l); 1781 luaL_pushresult(&b); 1782 str = lua_tolstring(L, -1, &l); 1783 if (luaL_loadbuffer(L, str, l, LUAVIM_EVALNAME)) /* compile error? */ 1784 { 1785 luaV_emsg(L); 1786 return 0; 1787 } 1788 luaV_pushtypval(L, arg); 1789 if (lua_pcall(L, 1, 1, 0)) /* running error? */ 1790 { 1791 luaV_emsg(L); 1792 return 0; 1793 } 1794 if (luaV_totypval(L, -1, rettv) == FAIL) 1795 emsg("luaeval: cannot convert value"); 1796 return 0; 1797 } 1798 1799 static int 1800 luaV_setref (lua_State *L) 1801 { 1802 int copyID = lua_tointeger(L, 1); 1803 int abort = FALSE; 1804 typval_T tv; 1805 1806 luaV_getfield(L, LUAVIM_LIST); 1807 luaV_getfield(L, LUAVIM_DICT); 1808 lua_pushnil(L); 1809 /* traverse cache table */ 1810 while (!abort && lua_next(L, lua_upvalueindex(1)) != 0) 1811 { 1812 lua_getmetatable(L, -1); 1813 if (lua_rawequal(L, -1, 2)) /* list? */ 1814 { 1815 tv.v_type = VAR_LIST; 1816 tv.vval.v_list = (list_T *) lua_touserdata(L, 4); /* key */ 1817 abort = set_ref_in_item(&tv, copyID, NULL, NULL); 1818 } 1819 else if (lua_rawequal(L, -1, 3)) /* dict? */ 1820 { 1821 tv.v_type = VAR_DICT; 1822 tv.vval.v_dict = (dict_T *) lua_touserdata(L, 4); /* key */ 1823 abort = set_ref_in_item(&tv, copyID, NULL, NULL); 1824 } 1825 lua_pop(L, 2); /* metatable and value */ 1826 } 1827 lua_pushinteger(L, abort); 1828 return 1; 1829 } 1830 1831 static int 1832 luaopen_vim(lua_State *L) 1833 { 1834 /* set cache table */ 1835 lua_newtable(L); 1836 lua_newtable(L); 1837 lua_pushstring(L, "v"); 1838 lua_setfield(L, -2, "__mode"); 1839 lua_setmetatable(L, -2); /* cache is weak-valued */ 1840 /* print */ 1841 lua_pushcfunction(L, luaV_print); 1842 lua_setglobal(L, "print"); 1843 /* debug.debug */ 1844 lua_getglobal(L, "debug"); 1845 lua_pushcfunction(L, luaV_debug); 1846 lua_setfield(L, -2, "debug"); 1847 lua_pop(L, 1); 1848 /* free */ 1849 lua_pushlightuserdata(L, (void *) LUAVIM_FREE); 1850 lua_pushvalue(L, 1); /* cache table */ 1851 lua_pushcclosure(L, luaV_free, 1); 1852 lua_rawset(L, LUA_REGISTRYINDEX); 1853 /* luaeval */ 1854 lua_pushlightuserdata(L, (void *) LUAVIM_LUAEVAL); 1855 lua_pushvalue(L, 1); /* cache table */ 1856 lua_pushcclosure(L, luaV_luaeval, 1); 1857 lua_rawset(L, LUA_REGISTRYINDEX); 1858 /* setref */ 1859 lua_pushlightuserdata(L, (void *) LUAVIM_SETREF); 1860 lua_pushvalue(L, 1); /* cache table */ 1861 lua_pushcclosure(L, luaV_setref, 1); 1862 lua_rawset(L, LUA_REGISTRYINDEX); 1863 /* register */ 1864 luaV_newmetatable(L, LUAVIM_LIST); 1865 lua_pushvalue(L, 1); 1866 luaV_openlib(L, luaV_List_mt, 1); 1867 luaV_newmetatable(L, LUAVIM_DICT); 1868 lua_pushvalue(L, 1); 1869 luaV_openlib(L, luaV_Dict_mt, 1); 1870 luaV_newmetatable(L, LUAVIM_FUNCREF); 1871 lua_pushvalue(L, 1); 1872 luaV_openlib(L, luaV_Funcref_mt, 1); 1873 luaV_newmetatable(L, LUAVIM_BUFFER); 1874 lua_pushvalue(L, 1); /* cache table */ 1875 luaV_openlib(L, luaV_Buffer_mt, 1); 1876 luaV_newmetatable(L, LUAVIM_WINDOW); 1877 lua_pushvalue(L, 1); /* cache table */ 1878 luaV_openlib(L, luaV_Window_mt, 1); 1879 lua_newtable(L); /* vim table */ 1880 lua_pushvalue(L, 1); /* cache table */ 1881 luaV_openlib(L, luaV_module, 1); 1882 lua_setglobal(L, LUAVIM_NAME); 1883 return 0; 1884 } 1885 1886 static lua_State * 1887 luaV_newstate(void) 1888 { 1889 lua_State *L = luaL_newstate(); 1890 luaL_openlibs(L); /* core libs */ 1891 lua_pushcfunction(L, luaopen_vim); /* vim */ 1892 lua_call(L, 0, 0); 1893 return L; 1894 } 1895 1896 static void 1897 luaV_setrange(lua_State *L, int line1, int line2) 1898 { 1899 lua_getglobal(L, LUAVIM_NAME); 1900 lua_pushinteger(L, line1); 1901 lua_setfield(L, -2, "firstline"); 1902 lua_pushinteger(L, line2); 1903 lua_setfield(L, -2, "lastline"); 1904 lua_pop(L, 1); /* vim table */ 1905 } 1906 1907 1908 /* ======= Interface ======= */ 1909 1910 static lua_State *L = NULL; 1911 1912 static int 1913 lua_isopen(void) 1914 { 1915 return L != NULL; 1916 } 1917 1918 static int 1919 lua_init(void) 1920 { 1921 if (!lua_isopen()) 1922 { 1923 #ifdef DYNAMIC_LUA 1924 if (!lua_enabled(TRUE)) 1925 { 1926 emsg(_("Lua library cannot be loaded.")); 1927 return FAIL; 1928 } 1929 #endif 1930 L = luaV_newstate(); 1931 } 1932 return OK; 1933 } 1934 1935 void 1936 lua_end(void) 1937 { 1938 if (lua_isopen()) 1939 { 1940 lua_close(L); 1941 L = NULL; 1942 #ifdef DYNAMIC_LUA 1943 end_dynamic_lua(); 1944 #endif 1945 } 1946 } 1947 1948 /* ex commands */ 1949 void 1950 ex_lua(exarg_T *eap) 1951 { 1952 char *script; 1953 if (lua_init() == FAIL) return; 1954 script = (char *) script_get(eap, eap->arg); 1955 if (!eap->skip) 1956 { 1957 char *s = (script) ? script : (char *) eap->arg; 1958 luaV_setrange(L, eap->line1, eap->line2); 1959 if (luaL_loadbuffer(L, s, strlen(s), LUAVIM_CHUNKNAME) 1960 || lua_pcall(L, 0, 0, 0)) 1961 luaV_emsg(L); 1962 } 1963 if (script != NULL) vim_free(script); 1964 } 1965 1966 void 1967 ex_luado(exarg_T *eap) 1968 { 1969 linenr_T l; 1970 const char *s = (const char *) eap->arg; 1971 luaL_Buffer b; 1972 size_t len; 1973 buf_T *was_curbuf = curbuf; 1974 1975 if (lua_init() == FAIL) return; 1976 if (u_save(eap->line1 - 1, eap->line2 + 1) == FAIL) 1977 { 1978 emsg(_("cannot save undo information")); 1979 return; 1980 } 1981 luaV_setrange(L, eap->line1, eap->line2); 1982 luaL_buffinit(L, &b); 1983 luaL_addlstring(&b, "return function(line, linenr) ", 30); /* header */ 1984 luaL_addlstring(&b, s, strlen(s)); 1985 luaL_addlstring(&b, " end", 4); /* footer */ 1986 luaL_pushresult(&b); 1987 s = lua_tolstring(L, -1, &len); 1988 if (luaL_loadbuffer(L, s, len, LUAVIM_CHUNKNAME)) 1989 { 1990 luaV_emsg(L); 1991 lua_pop(L, 1); /* function body */ 1992 return; 1993 } 1994 lua_call(L, 0, 1); 1995 lua_replace(L, -2); /* function -> body */ 1996 for (l = eap->line1; l <= eap->line2; l++) 1997 { 1998 /* Check the line number, the command my have deleted lines. */ 1999 if (l > curbuf->b_ml.ml_line_count) 2000 break; 2001 2002 lua_pushvalue(L, -1); /* function */ 2003 luaV_pushline(L, curbuf, l); /* current line as arg */ 2004 lua_pushinteger(L, l); /* current line number as arg */ 2005 if (lua_pcall(L, 2, 1, 0)) 2006 { 2007 luaV_emsg(L); 2008 break; 2009 } 2010 /* Catch the command switching to another buffer. */ 2011 if (curbuf != was_curbuf) 2012 break; 2013 if (lua_isstring(L, -1)) /* update line? */ 2014 { 2015 #ifdef HAVE_SANDBOX 2016 luaV_checksandbox(L); 2017 #endif 2018 ml_replace(l, luaV_toline(L, -1), TRUE); 2019 changed_bytes(l, 0); 2020 lua_pop(L, 1); /* result from luaV_toline */ 2021 } 2022 lua_pop(L, 1); /* line */ 2023 } 2024 lua_pop(L, 1); /* function */ 2025 check_cursor(); 2026 update_screen(NOT_VALID); 2027 } 2028 2029 void 2030 ex_luafile(exarg_T *eap) 2031 { 2032 if (lua_init() == FAIL) 2033 return; 2034 if (!eap->skip) 2035 { 2036 luaV_setrange(L, eap->line1, eap->line2); 2037 if (luaL_loadfile(L, (char *) eap->arg) || lua_pcall(L, 0, 0, 0)) 2038 luaV_emsg(L); 2039 } 2040 } 2041 2042 #define luaV_freetype(typ,tname) \ 2043 void \ 2044 lua_##tname##_free(typ *o) \ 2045 { \ 2046 if (!lua_isopen()) return; \ 2047 luaV_getfield(L, LUAVIM_FREE); \ 2048 lua_pushlightuserdata(L, (void *) o); \ 2049 lua_call(L, 1, 0); \ 2050 } 2051 2052 luaV_freetype(buf_T, buffer) 2053 luaV_freetype(win_T, window) 2054 2055 void 2056 do_luaeval (char_u *str, typval_T *arg, typval_T *rettv) 2057 { 2058 lua_init(); 2059 luaV_getfield(L, LUAVIM_LUAEVAL); 2060 lua_pushstring(L, (char *) str); 2061 lua_pushlightuserdata(L, (void *) arg); 2062 lua_pushlightuserdata(L, (void *) rettv); 2063 lua_call(L, 3, 0); 2064 } 2065 2066 int 2067 set_ref_in_lua (int copyID) 2068 { 2069 int aborted = 0; 2070 2071 if (lua_isopen()) 2072 { 2073 luaV_getfield(L, LUAVIM_SETREF); 2074 /* call the function with 1 arg, getting 1 result back */ 2075 lua_pushinteger(L, copyID); 2076 lua_call(L, 1, 1); 2077 /* get the result */ 2078 aborted = lua_tointeger(L, -1); 2079 /* pop result off the stack */ 2080 lua_pop(L, 1); 2081 } 2082 return aborted; 2083 } 2084 2085 #endif 2086