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