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 EMSG2(_(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 EMSG2(_(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_TSTRING: 566 tv->v_type = VAR_STRING; 567 tv->vval.v_string = vim_strsave((char_u *) lua_tostring(L, pos)); 568 break; 569 case LUA_TNUMBER: 570 #ifdef FEAT_FLOAT 571 tv->v_type = VAR_FLOAT; 572 tv->vval.v_float = (float_T) lua_tonumber(L, pos); 573 #else 574 tv->v_type = VAR_NUMBER; 575 tv->vval.v_number = (varnumber_T) lua_tointeger(L, pos); 576 #endif 577 break; 578 case LUA_TUSERDATA: 579 { 580 void *p = lua_touserdata(L, pos); 581 582 if (lua_getmetatable(L, pos)) /* has metatable? */ 583 { 584 /* check list */ 585 luaV_getfield(L, LUAVIM_LIST); 586 if (lua_rawequal(L, -1, -2)) 587 { 588 tv->v_type = VAR_LIST; 589 tv->vval.v_list = *((luaV_List *) p); 590 ++tv->vval.v_list->lv_refcount; 591 lua_pop(L, 2); /* MTs */ 592 break; 593 } 594 /* check dict */ 595 luaV_getfield(L, LUAVIM_DICT); 596 if (lua_rawequal(L, -1, -3)) 597 { 598 tv->v_type = VAR_DICT; 599 tv->vval.v_dict = *((luaV_Dict *) p); 600 ++tv->vval.v_dict->dv_refcount; 601 lua_pop(L, 3); /* MTs */ 602 break; 603 } 604 /* check funcref */ 605 luaV_getfield(L, LUAVIM_FUNCREF); 606 if (lua_rawequal(L, -1, -4)) 607 { 608 luaV_Funcref *f = (luaV_Funcref *) p; 609 copy_tv(&f->tv, tv); 610 lua_pop(L, 4); /* MTs */ 611 break; 612 } 613 lua_pop(L, 4); /* MTs */ 614 } 615 } 616 /* FALLTHROUGH */ 617 default: 618 tv->v_type = VAR_NUMBER; 619 tv->vval.v_number = 0; 620 status = FAIL; 621 } 622 return status; 623 } 624 625 /* similar to luaL_addlstring, but replaces \0 with \n if toline and 626 * \n with \0 otherwise */ 627 static void 628 luaV_addlstring(luaL_Buffer *b, const char *s, size_t l, int toline) 629 { 630 while (l--) 631 { 632 if (*s == '\0' && toline) 633 luaL_addchar(b, '\n'); 634 else if (*s == '\n' && !toline) 635 luaL_addchar(b, '\0'); 636 else 637 luaL_addchar(b, *s); 638 s++; 639 } 640 } 641 642 static void 643 luaV_pushline(lua_State *L, buf_T *buf, linenr_T n) 644 { 645 const char *s = (const char *) ml_get_buf(buf, n, FALSE); 646 luaL_Buffer b; 647 luaL_buffinit(L, &b); 648 luaV_addlstring(&b, s, strlen(s), 0); 649 luaL_pushresult(&b); 650 } 651 652 static char_u * 653 luaV_toline(lua_State *L, int pos) 654 { 655 size_t l; 656 const char *s = lua_tolstring(L, pos, &l); 657 658 luaL_Buffer b; 659 luaL_buffinit(L, &b); 660 luaV_addlstring(&b, s, l, 1); 661 luaL_pushresult(&b); 662 return (char_u *) lua_tostring(L, -1); 663 } 664 665 /* pops a string s from the top of the stack and calls mf(t) for pieces t of 666 * s separated by newlines */ 667 static void 668 luaV_msgfunc(lua_State *L, msgfunc_T mf) 669 { 670 luaL_Buffer b; 671 size_t l; 672 const char *p, *s = lua_tolstring(L, -1, &l); 673 luaL_buffinit(L, &b); 674 luaV_addlstring(&b, s, l, 0); 675 luaL_pushresult(&b); 676 /* break string */ 677 p = s = lua_tolstring(L, -1, &l); 678 while (l--) 679 { 680 if (*p++ == '\0') /* break? */ 681 { 682 mf((char_u *) s); 683 s = p; 684 } 685 } 686 mf((char_u *) s); 687 lua_pop(L, 2); /* original and modified strings */ 688 } 689 690 #define luaV_newtype(typ,tname,luatyp,luatname) \ 691 static luatyp * \ 692 luaV_new##tname (lua_State *L, typ *obj) \ 693 { \ 694 luatyp *o = (luatyp *) lua_newuserdata(L, sizeof(luatyp)); \ 695 *o = obj; \ 696 luaV_setudata(L, obj); /* cache[obj] = udata */ \ 697 luaV_getfield(L, luatname); \ 698 lua_setmetatable(L, -2); \ 699 return o; \ 700 } 701 702 #define luaV_pushtype(typ,tname,luatyp) \ 703 static luatyp * \ 704 luaV_push##tname(lua_State *L, typ *obj) \ 705 { \ 706 luatyp *o = NULL; \ 707 if (obj == NULL) \ 708 lua_pushnil(L); \ 709 else { \ 710 luaV_getudata(L, obj); \ 711 if (lua_isnil(L, -1)) /* not interned? */ \ 712 { \ 713 lua_pop(L, 1); \ 714 o = luaV_new##tname(L, obj); \ 715 } \ 716 else \ 717 o = (luatyp *) lua_touserdata(L, -1); \ 718 } \ 719 return o; \ 720 } 721 722 #define luaV_type_tostring(tname,luatname) \ 723 static int \ 724 luaV_##tname##_tostring (lua_State *L) \ 725 { \ 726 lua_pushfstring(L, "%s: %p", luatname, lua_touserdata(L, 1)); \ 727 return 1; \ 728 } 729 730 /* ======= List type ======= */ 731 732 static luaV_List * 733 luaV_newlist (lua_State *L, list_T *lis) 734 { 735 luaV_List *l = (luaV_List *) lua_newuserdata(L, sizeof(luaV_List)); 736 *l = lis; 737 lis->lv_refcount++; /* reference in Lua */ 738 luaV_setudata(L, lis); /* cache[lis] = udata */ 739 luaV_getfield(L, LUAVIM_LIST); 740 lua_setmetatable(L, -2); 741 return l; 742 } 743 744 luaV_pushtype(list_T, list, luaV_List) 745 luaV_type_tostring(list, LUAVIM_LIST) 746 747 static int 748 luaV_list_len (lua_State *L) 749 { 750 list_T *l = luaV_unbox(L, luaV_List, 1); 751 lua_pushinteger(L, (l == NULL) ? 0 : (int) l->lv_len); 752 return 1; 753 } 754 755 static int 756 luaV_list_iter (lua_State *L) 757 { 758 listitem_T *li = (listitem_T *) lua_touserdata(L, lua_upvalueindex(2)); 759 if (li == NULL) return 0; 760 luaV_pushtypval(L, &li->li_tv); 761 lua_pushlightuserdata(L, (void *) li->li_next); 762 lua_replace(L, lua_upvalueindex(2)); 763 return 1; 764 } 765 766 static int 767 luaV_list_call (lua_State *L) 768 { 769 list_T *l = luaV_unbox(L, luaV_List, 1); 770 lua_pushvalue(L, lua_upvalueindex(1)); /* pass cache table along */ 771 lua_pushlightuserdata(L, (void *) l->lv_first); 772 lua_pushcclosure(L, luaV_list_iter, 2); 773 return 1; 774 } 775 776 static int 777 luaV_list_index (lua_State *L) 778 { 779 list_T *l = luaV_unbox(L, luaV_List, 1); 780 if (lua_isnumber(L, 2)) /* list item? */ 781 { 782 listitem_T *li = list_find(l, (long) luaL_checkinteger(L, 2)); 783 if (li == NULL) 784 lua_pushnil(L); 785 else 786 luaV_pushtypval(L, &li->li_tv); 787 } 788 else if (lua_isstring(L, 2)) /* method? */ 789 { 790 const char *s = lua_tostring(L, 2); 791 if (strncmp(s, "add", 3) == 0 792 || strncmp(s, "insert", 6) == 0) 793 { 794 lua_getmetatable(L, 1); 795 lua_getfield(L, -1, s); 796 } 797 else 798 lua_pushnil(L); 799 } 800 else 801 lua_pushnil(L); 802 return 1; 803 } 804 805 static int 806 luaV_list_newindex (lua_State *L) 807 { 808 list_T *l = luaV_unbox(L, luaV_List, 1); 809 long n = (long) luaL_checkinteger(L, 2); 810 listitem_T *li; 811 if (l->lv_lock) 812 luaL_error(L, "list is locked"); 813 li = list_find(l, n); 814 if (li == NULL) return 0; 815 if (lua_isnil(L, 3)) /* remove? */ 816 { 817 vimlist_remove(l, li, li); 818 clear_tv(&li->li_tv); 819 vim_free(li); 820 } 821 else 822 { 823 typval_T v; 824 luaV_checktypval(L, 3, &v, "setting list item"); 825 clear_tv(&li->li_tv); 826 copy_tv(&v, &li->li_tv); 827 clear_tv(&v); 828 } 829 return 0; 830 } 831 832 static int 833 luaV_list_add (lua_State *L) 834 { 835 luaV_List *lis = luaV_checkudata(L, 1, LUAVIM_LIST); 836 list_T *l = (list_T *) luaV_checkcache(L, (void *) *lis); 837 typval_T v; 838 if (l->lv_lock) 839 luaL_error(L, "list is locked"); 840 lua_settop(L, 2); 841 luaV_checktypval(L, 2, &v, "adding list item"); 842 if (list_append_tv(l, &v) == FAIL) 843 { 844 clear_tv(&v); 845 luaL_error(L, "failed to add item to list"); 846 } 847 clear_tv(&v); 848 lua_settop(L, 1); 849 return 1; 850 } 851 852 static int 853 luaV_list_insert (lua_State *L) 854 { 855 luaV_List *lis = luaV_checkudata(L, 1, LUAVIM_LIST); 856 list_T *l = (list_T *) luaV_checkcache(L, (void *) *lis); 857 long pos = (long) luaL_optinteger(L, 3, 0); 858 listitem_T *li = NULL; 859 typval_T v; 860 if (l->lv_lock) 861 luaL_error(L, "list is locked"); 862 if (pos < l->lv_len) 863 { 864 li = list_find(l, pos); 865 if (li == NULL) 866 luaL_error(L, "invalid position"); 867 } 868 lua_settop(L, 2); 869 luaV_checktypval(L, 2, &v, "inserting list item"); 870 if (list_insert_tv(l, &v, li) == FAIL) 871 { 872 clear_tv(&v); 873 luaL_error(L, "failed to add item to list"); 874 } 875 clear_tv(&v); 876 lua_settop(L, 1); 877 return 1; 878 } 879 880 static const luaL_Reg luaV_List_mt[] = { 881 {"__tostring", luaV_list_tostring}, 882 {"__len", luaV_list_len}, 883 {"__call", luaV_list_call}, 884 {"__index", luaV_list_index}, 885 {"__newindex", luaV_list_newindex}, 886 {"add", luaV_list_add}, 887 {"insert", luaV_list_insert}, 888 {NULL, NULL} 889 }; 890 891 892 /* ======= Dict type ======= */ 893 894 static luaV_Dict * 895 luaV_newdict (lua_State *L, dict_T *dic) 896 { 897 luaV_Dict *d = (luaV_Dict *) lua_newuserdata(L, sizeof(luaV_Dict)); 898 *d = dic; 899 dic->dv_refcount++; /* reference in Lua */ 900 luaV_setudata(L, dic); /* cache[dic] = udata */ 901 luaV_getfield(L, LUAVIM_DICT); 902 lua_setmetatable(L, -2); 903 return d; 904 } 905 906 luaV_pushtype(dict_T, dict, luaV_Dict) 907 luaV_type_tostring(dict, LUAVIM_DICT) 908 909 static int 910 luaV_dict_len (lua_State *L) 911 { 912 dict_T *d = luaV_unbox(L, luaV_Dict, 1); 913 lua_pushinteger(L, (d == NULL) ? 0 : (int) d->dv_hashtab.ht_used); 914 return 1; 915 } 916 917 static int 918 luaV_dict_iter (lua_State *L UNUSED) 919 { 920 #ifdef FEAT_EVAL 921 hashitem_T *hi = (hashitem_T *) lua_touserdata(L, lua_upvalueindex(2)); 922 int n = lua_tointeger(L, lua_upvalueindex(3)); 923 dictitem_T *di; 924 if (n <= 0) return 0; 925 while (HASHITEM_EMPTY(hi)) hi++; 926 di = dict_lookup(hi); 927 lua_pushstring(L, (char *) hi->hi_key); 928 luaV_pushtypval(L, &di->di_tv); 929 lua_pushlightuserdata(L, (void *) (hi + 1)); 930 lua_replace(L, lua_upvalueindex(2)); 931 lua_pushinteger(L, n - 1); 932 lua_replace(L, lua_upvalueindex(3)); 933 return 2; 934 #else 935 return 0; 936 #endif 937 } 938 939 static int 940 luaV_dict_call (lua_State *L) 941 { 942 dict_T *d = luaV_unbox(L, luaV_Dict, 1); 943 hashtab_T *ht = &d->dv_hashtab; 944 lua_pushvalue(L, lua_upvalueindex(1)); /* pass cache table along */ 945 lua_pushlightuserdata(L, (void *) ht->ht_array); 946 lua_pushinteger(L, ht->ht_used); /* # remaining items */ 947 lua_pushcclosure(L, luaV_dict_iter, 3); 948 return 1; 949 } 950 951 static int 952 luaV_dict_index(lua_State *L) 953 { 954 dict_T *d = luaV_unbox(L, luaV_Dict, 1); 955 char_u *key = (char_u *) luaL_checkstring(L, 2); 956 dictitem_T *di = dict_find(d, key, -1); 957 958 if (di == NULL) 959 lua_pushnil(L); 960 else 961 { 962 luaV_pushtypval(L, &di->di_tv); 963 if (di->di_tv.v_type == VAR_FUNC) /* funcref? */ 964 { 965 luaV_Funcref *f = (luaV_Funcref *) lua_touserdata(L, -1); 966 f->self = d; /* keep "self" reference */ 967 d->dv_refcount++; 968 } 969 } 970 return 1; 971 } 972 973 static int 974 luaV_dict_newindex(lua_State *L) 975 { 976 dict_T *d = luaV_unbox(L, luaV_Dict, 1); 977 char_u *key = (char_u *) luaL_checkstring(L, 2); 978 dictitem_T *di; 979 typval_T v; 980 if (d->dv_lock) 981 luaL_error(L, "dict is locked"); 982 if (key == NULL) 983 return 0; 984 if (*key == NUL) 985 luaL_error(L, "empty key"); 986 if (!lua_isnil(L, 3)) /* read value? */ 987 { 988 luaV_checktypval(L, 3, &v, "setting dict item"); 989 if (d->dv_scope == VAR_DEF_SCOPE && v.v_type == VAR_FUNC) 990 luaL_error(L, "cannot assign funcref to builtin scope"); 991 } 992 di = dict_find(d, key, -1); 993 if (di == NULL) /* non-existing key? */ 994 { 995 if (lua_isnil(L, 3)) 996 return 0; 997 di = dictitem_alloc(key); 998 if (di == NULL) 999 return 0; 1000 if (dict_add(d, di) == FAIL) 1001 { 1002 vim_free(di); 1003 return 0; 1004 } 1005 } 1006 else 1007 clear_tv(&di->di_tv); 1008 if (lua_isnil(L, 3)) /* remove? */ 1009 { 1010 hashitem_T *hi = hash_find(&d->dv_hashtab, di->di_key); 1011 hash_remove(&d->dv_hashtab, hi); 1012 dictitem_free(di); 1013 } 1014 else 1015 { 1016 copy_tv(&v, &di->di_tv); 1017 clear_tv(&v); 1018 } 1019 return 0; 1020 } 1021 1022 static const luaL_Reg luaV_Dict_mt[] = { 1023 {"__tostring", luaV_dict_tostring}, 1024 {"__len", luaV_dict_len}, 1025 {"__call", luaV_dict_call}, 1026 {"__index", luaV_dict_index}, 1027 {"__newindex", luaV_dict_newindex}, 1028 {NULL, NULL} 1029 }; 1030 1031 1032 /* ======= Funcref type ======= */ 1033 1034 static luaV_Funcref * 1035 luaV_newfuncref(lua_State *L, char_u *name) 1036 { 1037 luaV_Funcref *f = (luaV_Funcref *)lua_newuserdata(L, sizeof(luaV_Funcref)); 1038 1039 if (name != NULL) 1040 { 1041 func_ref(name); /* as in copy_tv */ 1042 f->tv.vval.v_string = vim_strsave(name); 1043 } 1044 f->tv.v_type = VAR_FUNC; 1045 f->args.v_type = VAR_LIST; 1046 f->self = NULL; 1047 luaV_getfield(L, LUAVIM_FUNCREF); 1048 lua_setmetatable(L, -2); 1049 return f; 1050 } 1051 1052 static luaV_Funcref * 1053 luaV_pushfuncref(lua_State *L, typval_T *tv) 1054 { 1055 luaV_Funcref *f = luaV_newfuncref(L, NULL); 1056 copy_tv(tv, &f->tv); 1057 clear_tv(tv); 1058 return f; 1059 } 1060 1061 1062 luaV_type_tostring(funcref, LUAVIM_FUNCREF) 1063 1064 static int 1065 luaV_funcref_gc(lua_State *L) 1066 { 1067 luaV_Funcref *f = (luaV_Funcref *) lua_touserdata(L, 1); 1068 1069 func_unref(f->tv.vval.v_string); 1070 vim_free(f->tv.vval.v_string); 1071 dict_unref(f->self); 1072 return 0; 1073 } 1074 1075 /* equivalent to string(funcref) */ 1076 static int 1077 luaV_funcref_len(lua_State *L) 1078 { 1079 luaV_Funcref *f = (luaV_Funcref *) lua_touserdata(L, 1); 1080 1081 lua_pushstring(L, (const char *) f->tv.vval.v_string); 1082 return 1; 1083 } 1084 1085 static int 1086 luaV_funcref_call(lua_State *L) 1087 { 1088 luaV_Funcref *f = (luaV_Funcref *) lua_touserdata(L, 1); 1089 int i, n = lua_gettop(L) - 1; /* #args */ 1090 int status; 1091 typval_T v, rettv; 1092 1093 f->args.vval.v_list = list_alloc(); 1094 rettv.v_type = VAR_UNKNOWN; /* as in clear_tv */ 1095 if (f->args.vval.v_list == NULL) 1096 status = FAIL; 1097 else 1098 { 1099 for (i = 0; i < n; i++) 1100 { 1101 luaV_checktypval(L, i + 2, &v, "calling funcref"); 1102 list_append_tv(f->args.vval.v_list, &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 } 1571 lua_pop(L, 1); /* value */ 1572 } while (notnil); 1573 } 1574 } 1575 return 1; 1576 } 1577 1578 static int 1579 luaV_dict(lua_State *L) 1580 { 1581 dict_T *d; 1582 int initarg = !lua_isnoneornil(L, 1); 1583 1584 if (initarg && lua_type(L, 1) != LUA_TTABLE) 1585 luaL_error(L, "table expected, got %s", luaL_typename(L, 1)); 1586 d = dict_alloc(); 1587 if (d == NULL) 1588 lua_pushnil(L); 1589 else 1590 { 1591 luaV_newdict(L, d); 1592 if (initarg) /* traverse table to init dict */ 1593 { 1594 lua_pushnil(L); 1595 while (lua_next(L, 1)) 1596 { 1597 char_u *key; 1598 dictitem_T *di; 1599 typval_T v; 1600 1601 lua_pushvalue(L, -2); /* dup key in case it's a number */ 1602 key = (char_u *) lua_tostring(L, -1); 1603 if (key == NULL) 1604 { 1605 lua_pushnil(L); 1606 return 1; 1607 } 1608 if (*key == NUL) 1609 luaL_error(L, "table has empty key"); 1610 luaV_checktypval(L, -2, &v, "vim.dict"); /* value */ 1611 di = dictitem_alloc(key); 1612 if (di == NULL || dict_add(d, di) == FAIL) 1613 { 1614 vim_free(di); 1615 lua_pushnil(L); 1616 return 1; 1617 } 1618 copy_tv(&v, &di->di_tv); 1619 clear_tv(&v); 1620 lua_pop(L, 2); /* key copy and value */ 1621 } 1622 } 1623 } 1624 return 1; 1625 } 1626 1627 static int 1628 luaV_funcref(lua_State *L) 1629 { 1630 const char *name = luaL_checkstring(L, 1); 1631 /* note: not checking if function exists (needs function_exists) */ 1632 if (name == NULL || *name == NUL || VIM_ISDIGIT(*name)) 1633 luaL_error(L, "invalid function name: %s", name); 1634 luaV_newfuncref(L, (char_u *) name); 1635 return 1; 1636 } 1637 1638 static int 1639 luaV_buffer(lua_State *L) 1640 { 1641 buf_T *buf; 1642 if (lua_isstring(L, 1)) /* get by number or name? */ 1643 { 1644 if (lua_isnumber(L, 1)) /* by number? */ 1645 { 1646 int n = lua_tointeger(L, 1); 1647 FOR_ALL_BUFFERS(buf) 1648 if (buf->b_fnum == n) break; 1649 } 1650 else // by name 1651 { 1652 size_t l; 1653 const char *s = lua_tolstring(L, 1, &l); 1654 FOR_ALL_BUFFERS(buf) 1655 { 1656 if (buf->b_ffname == NULL || buf->b_sfname == NULL) 1657 { 1658 if (l == 0) break; 1659 } 1660 else if (strncmp(s, (char *)buf->b_ffname, l) == 0 1661 || strncmp(s, (char *)buf->b_sfname, l) == 0) 1662 break; 1663 } 1664 } 1665 } 1666 else 1667 buf = (lua_toboolean(L, 1)) ? firstbuf : curbuf; /* first buffer? */ 1668 luaV_pushbuffer(L, buf); 1669 return 1; 1670 } 1671 1672 static int 1673 luaV_window(lua_State *L) 1674 { 1675 win_T *win; 1676 if (lua_isnumber(L, 1)) /* get by number? */ 1677 { 1678 int n = lua_tointeger(L, 1); 1679 for (win = firstwin; win != NULL; win = win->w_next, n--) 1680 if (n == 1) break; 1681 } 1682 else 1683 win = (lua_toboolean(L, 1)) ? firstwin : curwin; /* first window? */ 1684 luaV_pushwindow(L, win); 1685 return 1; 1686 } 1687 1688 static int 1689 luaV_open(lua_State *L) 1690 { 1691 char_u *s = NULL; 1692 #ifdef HAVE_SANDBOX 1693 luaV_checksandbox(L); 1694 #endif 1695 if (lua_isstring(L, 1)) s = (char_u *) lua_tostring(L, 1); 1696 luaV_pushbuffer(L, buflist_new(s, NULL, 1L, BLN_LISTED)); 1697 return 1; 1698 } 1699 1700 static int 1701 luaV_type(lua_State *L) 1702 { 1703 luaL_checkany(L, 1); 1704 if (lua_type(L, 1) == LUA_TUSERDATA) /* check vim udata? */ 1705 { 1706 lua_settop(L, 1); 1707 if (lua_getmetatable(L, 1)) 1708 { 1709 luaV_getfield(L, LUAVIM_LIST); 1710 if (lua_rawequal(L, -1, 2)) 1711 { 1712 lua_pushstring(L, "list"); 1713 return 1; 1714 } 1715 luaV_getfield(L, LUAVIM_DICT); 1716 if (lua_rawequal(L, -1, 2)) 1717 { 1718 lua_pushstring(L, "dict"); 1719 return 1; 1720 } 1721 luaV_getfield(L, LUAVIM_FUNCREF); 1722 if (lua_rawequal(L, -1, 2)) 1723 { 1724 lua_pushstring(L, "funcref"); 1725 return 1; 1726 } 1727 luaV_getfield(L, LUAVIM_BUFFER); 1728 if (lua_rawequal(L, -1, 2)) 1729 { 1730 lua_pushstring(L, "buffer"); 1731 return 1; 1732 } 1733 luaV_getfield(L, LUAVIM_WINDOW); 1734 if (lua_rawequal(L, -1, 2)) 1735 { 1736 lua_pushstring(L, "window"); 1737 return 1; 1738 } 1739 } 1740 } 1741 lua_pushstring(L, luaL_typename(L, 1)); /* fallback */ 1742 return 1; 1743 } 1744 1745 static const luaL_Reg luaV_module[] = { 1746 {"command", luaV_command}, 1747 {"eval", luaV_eval}, 1748 {"beep", luaV_beep}, 1749 {"line", luaV_line}, 1750 {"list", luaV_list}, 1751 {"dict", luaV_dict}, 1752 {"funcref", luaV_funcref}, 1753 {"buffer", luaV_buffer}, 1754 {"window", luaV_window}, 1755 {"open", luaV_open}, 1756 {"type", luaV_type}, 1757 {NULL, NULL} 1758 }; 1759 1760 /* for freeing list, dict, buffer and window objects; lightuserdata as arg */ 1761 static int 1762 luaV_free(lua_State *L) 1763 { 1764 lua_pushnil(L); 1765 luaV_setudata(L, lua_touserdata(L, 1)); 1766 return 0; 1767 } 1768 1769 static int 1770 luaV_luaeval (lua_State *L) 1771 { 1772 luaL_Buffer b; 1773 size_t l; 1774 const char *str = lua_tolstring(L, 1, &l); 1775 typval_T *arg = (typval_T *) lua_touserdata(L, 2); 1776 typval_T *rettv = (typval_T *) lua_touserdata(L, 3); 1777 luaL_buffinit(L, &b); 1778 luaL_addlstring(&b, LUAVIM_EVALHEADER, sizeof(LUAVIM_EVALHEADER) - 1); 1779 luaL_addlstring(&b, str, l); 1780 luaL_pushresult(&b); 1781 str = lua_tolstring(L, -1, &l); 1782 if (luaL_loadbuffer(L, str, l, LUAVIM_EVALNAME)) /* compile error? */ 1783 { 1784 luaV_emsg(L); 1785 return 0; 1786 } 1787 luaV_pushtypval(L, arg); 1788 if (lua_pcall(L, 1, 1, 0)) /* running error? */ 1789 { 1790 luaV_emsg(L); 1791 return 0; 1792 } 1793 if (luaV_totypval(L, -1, rettv) == FAIL) 1794 EMSG("luaeval: cannot convert value"); 1795 return 0; 1796 } 1797 1798 static int 1799 luaV_setref (lua_State *L) 1800 { 1801 int copyID = lua_tointeger(L, 1); 1802 int abort = FALSE; 1803 typval_T tv; 1804 1805 luaV_getfield(L, LUAVIM_LIST); 1806 luaV_getfield(L, LUAVIM_DICT); 1807 lua_pushnil(L); 1808 /* traverse cache table */ 1809 while (!abort && lua_next(L, lua_upvalueindex(1)) != 0) 1810 { 1811 lua_getmetatable(L, -1); 1812 if (lua_rawequal(L, -1, 2)) /* list? */ 1813 { 1814 tv.v_type = VAR_LIST; 1815 tv.vval.v_list = (list_T *) lua_touserdata(L, 4); /* key */ 1816 abort = set_ref_in_item(&tv, copyID, NULL, NULL); 1817 } 1818 else if (lua_rawequal(L, -1, 3)) /* dict? */ 1819 { 1820 tv.v_type = VAR_DICT; 1821 tv.vval.v_dict = (dict_T *) lua_touserdata(L, 4); /* key */ 1822 abort = set_ref_in_item(&tv, copyID, NULL, NULL); 1823 } 1824 lua_pop(L, 2); /* metatable and value */ 1825 } 1826 lua_pushinteger(L, abort); 1827 return 1; 1828 } 1829 1830 static int 1831 luaopen_vim(lua_State *L) 1832 { 1833 /* set cache table */ 1834 lua_newtable(L); 1835 lua_newtable(L); 1836 lua_pushstring(L, "v"); 1837 lua_setfield(L, -2, "__mode"); 1838 lua_setmetatable(L, -2); /* cache is weak-valued */ 1839 /* print */ 1840 lua_pushcfunction(L, luaV_print); 1841 lua_setglobal(L, "print"); 1842 /* debug.debug */ 1843 lua_getglobal(L, "debug"); 1844 lua_pushcfunction(L, luaV_debug); 1845 lua_setfield(L, -2, "debug"); 1846 lua_pop(L, 1); 1847 /* free */ 1848 lua_pushlightuserdata(L, (void *) LUAVIM_FREE); 1849 lua_pushvalue(L, 1); /* cache table */ 1850 lua_pushcclosure(L, luaV_free, 1); 1851 lua_rawset(L, LUA_REGISTRYINDEX); 1852 /* luaeval */ 1853 lua_pushlightuserdata(L, (void *) LUAVIM_LUAEVAL); 1854 lua_pushvalue(L, 1); /* cache table */ 1855 lua_pushcclosure(L, luaV_luaeval, 1); 1856 lua_rawset(L, LUA_REGISTRYINDEX); 1857 /* setref */ 1858 lua_pushlightuserdata(L, (void *) LUAVIM_SETREF); 1859 lua_pushvalue(L, 1); /* cache table */ 1860 lua_pushcclosure(L, luaV_setref, 1); 1861 lua_rawset(L, LUA_REGISTRYINDEX); 1862 /* register */ 1863 luaV_newmetatable(L, LUAVIM_LIST); 1864 lua_pushvalue(L, 1); 1865 luaV_openlib(L, luaV_List_mt, 1); 1866 luaV_newmetatable(L, LUAVIM_DICT); 1867 lua_pushvalue(L, 1); 1868 luaV_openlib(L, luaV_Dict_mt, 1); 1869 luaV_newmetatable(L, LUAVIM_FUNCREF); 1870 lua_pushvalue(L, 1); 1871 luaV_openlib(L, luaV_Funcref_mt, 1); 1872 luaV_newmetatable(L, LUAVIM_BUFFER); 1873 lua_pushvalue(L, 1); /* cache table */ 1874 luaV_openlib(L, luaV_Buffer_mt, 1); 1875 luaV_newmetatable(L, LUAVIM_WINDOW); 1876 lua_pushvalue(L, 1); /* cache table */ 1877 luaV_openlib(L, luaV_Window_mt, 1); 1878 lua_newtable(L); /* vim table */ 1879 lua_pushvalue(L, 1); /* cache table */ 1880 luaV_openlib(L, luaV_module, 1); 1881 lua_setglobal(L, LUAVIM_NAME); 1882 return 0; 1883 } 1884 1885 static lua_State * 1886 luaV_newstate(void) 1887 { 1888 lua_State *L = luaL_newstate(); 1889 luaL_openlibs(L); /* core libs */ 1890 lua_pushcfunction(L, luaopen_vim); /* vim */ 1891 lua_call(L, 0, 0); 1892 return L; 1893 } 1894 1895 static void 1896 luaV_setrange(lua_State *L, int line1, int line2) 1897 { 1898 lua_getglobal(L, LUAVIM_NAME); 1899 lua_pushinteger(L, line1); 1900 lua_setfield(L, -2, "firstline"); 1901 lua_pushinteger(L, line2); 1902 lua_setfield(L, -2, "lastline"); 1903 lua_pop(L, 1); /* vim table */ 1904 } 1905 1906 1907 /* ======= Interface ======= */ 1908 1909 static lua_State *L = NULL; 1910 1911 static int 1912 lua_isopen(void) 1913 { 1914 return L != NULL; 1915 } 1916 1917 static int 1918 lua_init(void) 1919 { 1920 if (!lua_isopen()) 1921 { 1922 #ifdef DYNAMIC_LUA 1923 if (!lua_enabled(TRUE)) 1924 { 1925 EMSG(_("Lua library cannot be loaded.")); 1926 return FAIL; 1927 } 1928 #endif 1929 L = luaV_newstate(); 1930 } 1931 return OK; 1932 } 1933 1934 void 1935 lua_end(void) 1936 { 1937 if (lua_isopen()) 1938 { 1939 lua_close(L); 1940 L = NULL; 1941 #ifdef DYNAMIC_LUA 1942 end_dynamic_lua(); 1943 #endif 1944 } 1945 } 1946 1947 /* ex commands */ 1948 void 1949 ex_lua(exarg_T *eap) 1950 { 1951 char *script; 1952 if (lua_init() == FAIL) return; 1953 script = (char *) script_get(eap, eap->arg); 1954 if (!eap->skip) 1955 { 1956 char *s = (script) ? script : (char *) eap->arg; 1957 luaV_setrange(L, eap->line1, eap->line2); 1958 if (luaL_loadbuffer(L, s, strlen(s), LUAVIM_CHUNKNAME) 1959 || lua_pcall(L, 0, 0, 0)) 1960 luaV_emsg(L); 1961 } 1962 if (script != NULL) vim_free(script); 1963 } 1964 1965 void 1966 ex_luado(exarg_T *eap) 1967 { 1968 linenr_T l; 1969 const char *s = (const char *) eap->arg; 1970 luaL_Buffer b; 1971 size_t len; 1972 buf_T *was_curbuf = curbuf; 1973 1974 if (lua_init() == FAIL) return; 1975 if (u_save(eap->line1 - 1, eap->line2 + 1) == FAIL) 1976 { 1977 EMSG(_("cannot save undo information")); 1978 return; 1979 } 1980 luaV_setrange(L, eap->line1, eap->line2); 1981 luaL_buffinit(L, &b); 1982 luaL_addlstring(&b, "return function(line, linenr) ", 30); /* header */ 1983 luaL_addlstring(&b, s, strlen(s)); 1984 luaL_addlstring(&b, " end", 4); /* footer */ 1985 luaL_pushresult(&b); 1986 s = lua_tolstring(L, -1, &len); 1987 if (luaL_loadbuffer(L, s, len, LUAVIM_CHUNKNAME)) 1988 { 1989 luaV_emsg(L); 1990 lua_pop(L, 1); /* function body */ 1991 return; 1992 } 1993 lua_call(L, 0, 1); 1994 lua_replace(L, -2); /* function -> body */ 1995 for (l = eap->line1; l <= eap->line2; l++) 1996 { 1997 /* Check the line number, the command my have deleted lines. */ 1998 if (l > curbuf->b_ml.ml_line_count) 1999 break; 2000 2001 lua_pushvalue(L, -1); /* function */ 2002 luaV_pushline(L, curbuf, l); /* current line as arg */ 2003 lua_pushinteger(L, l); /* current line number as arg */ 2004 if (lua_pcall(L, 2, 1, 0)) 2005 { 2006 luaV_emsg(L); 2007 break; 2008 } 2009 /* Catch the command switching to another buffer. */ 2010 if (curbuf != was_curbuf) 2011 break; 2012 if (lua_isstring(L, -1)) /* update line? */ 2013 { 2014 #ifdef HAVE_SANDBOX 2015 luaV_checksandbox(L); 2016 #endif 2017 ml_replace(l, luaV_toline(L, -1), TRUE); 2018 changed_bytes(l, 0); 2019 lua_pop(L, 1); /* result from luaV_toline */ 2020 } 2021 lua_pop(L, 1); /* line */ 2022 } 2023 lua_pop(L, 1); /* function */ 2024 check_cursor(); 2025 update_screen(NOT_VALID); 2026 } 2027 2028 void 2029 ex_luafile(exarg_T *eap) 2030 { 2031 if (lua_init() == FAIL) 2032 return; 2033 if (!eap->skip) 2034 { 2035 luaV_setrange(L, eap->line1, eap->line2); 2036 if (luaL_loadfile(L, (char *) eap->arg) || lua_pcall(L, 0, 0, 0)) 2037 luaV_emsg(L); 2038 } 2039 } 2040 2041 #define luaV_freetype(typ,tname) \ 2042 void \ 2043 lua_##tname##_free(typ *o) \ 2044 { \ 2045 if (!lua_isopen()) return; \ 2046 luaV_getfield(L, LUAVIM_FREE); \ 2047 lua_pushlightuserdata(L, (void *) o); \ 2048 lua_call(L, 1, 0); \ 2049 } 2050 2051 luaV_freetype(buf_T, buffer) 2052 luaV_freetype(win_T, window) 2053 2054 void 2055 do_luaeval (char_u *str, typval_T *arg, typval_T *rettv) 2056 { 2057 lua_init(); 2058 luaV_getfield(L, LUAVIM_LUAEVAL); 2059 lua_pushstring(L, (char *) str); 2060 lua_pushlightuserdata(L, (void *) arg); 2061 lua_pushlightuserdata(L, (void *) rettv); 2062 lua_call(L, 3, 0); 2063 } 2064 2065 int 2066 set_ref_in_lua (int copyID) 2067 { 2068 int aborted = 0; 2069 2070 if (lua_isopen()) 2071 { 2072 luaV_getfield(L, LUAVIM_SETREF); 2073 /* call the function with 1 arg, getting 1 result back */ 2074 lua_pushinteger(L, copyID); 2075 lua_call(L, 1, 1); 2076 /* get the result */ 2077 aborted = lua_tointeger(L, -1); 2078 /* pop result off the stack */ 2079 lua_pop(L, 1); 2080 } 2081 return aborted; 2082 } 2083 2084 #endif 2085