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