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 listitem_T *li = list_find(l, (long) luaL_checkinteger(L, 2)); 875 if (li == NULL) 876 lua_pushnil(L); 877 else 878 luaV_pushtypval(L, &li->li_tv); 879 } 880 else if (lua_isstring(L, 2)) // method? 881 { 882 const char *s = lua_tostring(L, 2); 883 if (strncmp(s, "add", 3) == 0 884 || strncmp(s, "insert", 6) == 0) 885 { 886 lua_getmetatable(L, 1); 887 lua_getfield(L, -1, s); 888 } 889 else 890 lua_pushnil(L); 891 } 892 else 893 lua_pushnil(L); 894 return 1; 895 } 896 897 static int 898 luaV_list_newindex(lua_State *L) 899 { 900 list_T *l = luaV_unbox(L, luaV_List, 1); 901 long n = (long) luaL_checkinteger(L, 2); 902 listitem_T *li; 903 if (l->lv_lock) 904 luaL_error(L, "list is locked"); 905 li = list_find(l, n); 906 if (li == NULL) return 0; 907 if (lua_isnil(L, 3)) // remove? 908 { 909 vimlist_remove(l, li, li); 910 listitem_free(l, li); 911 } 912 else 913 { 914 typval_T v; 915 luaV_checktypval(L, 3, &v, "setting list item"); 916 clear_tv(&li->li_tv); 917 copy_tv(&v, &li->li_tv); 918 clear_tv(&v); 919 } 920 return 0; 921 } 922 923 static int 924 luaV_list_add(lua_State *L) 925 { 926 luaV_List *lis = luaV_checkudata(L, 1, LUAVIM_LIST); 927 list_T *l = (list_T *) luaV_checkcache(L, (void *) *lis); 928 typval_T v; 929 if (l->lv_lock) 930 luaL_error(L, "list is locked"); 931 lua_settop(L, 2); 932 luaV_checktypval(L, 2, &v, "adding list item"); 933 if (list_append_tv(l, &v) == FAIL) 934 luaL_error(L, "failed to add item to list"); 935 clear_tv(&v); 936 lua_settop(L, 1); 937 return 1; 938 } 939 940 static int 941 luaV_list_insert(lua_State *L) 942 { 943 luaV_List *lis = luaV_checkudata(L, 1, LUAVIM_LIST); 944 list_T *l = (list_T *) luaV_checkcache(L, (void *) *lis); 945 long pos = (long) luaL_optinteger(L, 3, 0); 946 listitem_T *li = NULL; 947 typval_T v; 948 if (l->lv_lock) 949 luaL_error(L, "list is locked"); 950 if (pos < l->lv_len) 951 { 952 li = list_find(l, pos); 953 if (li == NULL) 954 luaL_error(L, "invalid position"); 955 } 956 lua_settop(L, 2); 957 luaV_checktypval(L, 2, &v, "inserting list item"); 958 if (list_insert_tv(l, &v, li) == FAIL) 959 luaL_error(L, "failed to add item to list"); 960 clear_tv(&v); 961 lua_settop(L, 1); 962 return 1; 963 } 964 965 static const luaL_Reg luaV_List_mt[] = { 966 {"__tostring", luaV_list_tostring}, 967 {"__len", luaV_list_len}, 968 {"__call", luaV_list_call}, 969 {"__index", luaV_list_index}, 970 {"__newindex", luaV_list_newindex}, 971 {"add", luaV_list_add}, 972 {"insert", luaV_list_insert}, 973 {NULL, NULL} 974 }; 975 976 977 // ======= Dict type ======= 978 979 static luaV_Dict * 980 luaV_newdict(lua_State *L, dict_T *dic) 981 { 982 luaV_Dict *d = (luaV_Dict *) lua_newuserdata(L, sizeof(luaV_Dict)); 983 *d = dic; 984 dic->dv_refcount++; // reference in Lua 985 luaV_setudata(L, dic); // cache[dic] = udata 986 luaV_getfield(L, LUAVIM_DICT); 987 lua_setmetatable(L, -2); 988 return d; 989 } 990 991 luaV_pushtype(dict_T, dict, luaV_Dict) 992 luaV_type_tostring(dict, LUAVIM_DICT) 993 994 static int 995 luaV_dict_len(lua_State *L) 996 { 997 dict_T *d = luaV_unbox(L, luaV_Dict, 1); 998 lua_pushinteger(L, (int) dict_len(d)); 999 return 1; 1000 } 1001 1002 static int 1003 luaV_dict_iter(lua_State *L UNUSED) 1004 { 1005 #ifdef FEAT_EVAL 1006 hashitem_T *hi = (hashitem_T *) lua_touserdata(L, lua_upvalueindex(2)); 1007 int n = lua_tointeger(L, lua_upvalueindex(3)); 1008 dictitem_T *di; 1009 if (n <= 0) return 0; 1010 while (HASHITEM_EMPTY(hi)) hi++; 1011 di = dict_lookup(hi); 1012 lua_pushstring(L, (char *) hi->hi_key); 1013 luaV_pushtypval(L, &di->di_tv); 1014 lua_pushlightuserdata(L, (void *) (hi + 1)); 1015 lua_replace(L, lua_upvalueindex(2)); 1016 lua_pushinteger(L, n - 1); 1017 lua_replace(L, lua_upvalueindex(3)); 1018 return 2; 1019 #else 1020 return 0; 1021 #endif 1022 } 1023 1024 static int 1025 luaV_dict_call(lua_State *L) 1026 { 1027 dict_T *d = luaV_unbox(L, luaV_Dict, 1); 1028 hashtab_T *ht = &d->dv_hashtab; 1029 lua_pushvalue(L, lua_upvalueindex(1)); // pass cache table along 1030 lua_pushlightuserdata(L, (void *) ht->ht_array); 1031 lua_pushinteger(L, ht->ht_used); // # remaining items 1032 lua_pushcclosure(L, luaV_dict_iter, 3); 1033 return 1; 1034 } 1035 1036 static int 1037 luaV_dict_index(lua_State *L) 1038 { 1039 dict_T *d = luaV_unbox(L, luaV_Dict, 1); 1040 char_u *key = (char_u *) luaL_checkstring(L, 2); 1041 dictitem_T *di = dict_find(d, key, -1); 1042 1043 if (di == NULL) 1044 lua_pushnil(L); 1045 else 1046 { 1047 luaV_pushtypval(L, &di->di_tv); 1048 if (di->di_tv.v_type == VAR_FUNC) // funcref? 1049 { 1050 luaV_Funcref *f = (luaV_Funcref *) lua_touserdata(L, -1); 1051 f->self = d; // keep "self" reference 1052 d->dv_refcount++; 1053 } 1054 } 1055 return 1; 1056 } 1057 1058 static int 1059 luaV_dict_newindex(lua_State *L) 1060 { 1061 dict_T *d = luaV_unbox(L, luaV_Dict, 1); 1062 char_u *key = (char_u *) luaL_checkstring(L, 2); 1063 dictitem_T *di; 1064 typval_T v; 1065 1066 if (d->dv_lock) 1067 luaL_error(L, "dict is locked"); 1068 if (key == NULL) 1069 return 0; 1070 if (*key == NUL) 1071 luaL_error(L, "empty key"); 1072 if (!lua_isnil(L, 3)) // read value? 1073 { 1074 luaV_checktypval(L, 3, &v, "setting dict item"); 1075 if (d->dv_scope == VAR_DEF_SCOPE && v.v_type == VAR_FUNC) 1076 luaL_error(L, "cannot assign funcref to builtin scope"); 1077 } 1078 di = dict_find(d, key, -1); 1079 if (di == NULL) // non-existing key? 1080 { 1081 if (lua_isnil(L, 3)) 1082 return 0; 1083 di = dictitem_alloc(key); 1084 if (di == NULL) 1085 return 0; 1086 if (dict_add(d, di) == FAIL) 1087 { 1088 vim_free(di); 1089 return 0; 1090 } 1091 } 1092 else 1093 clear_tv(&di->di_tv); 1094 if (lua_isnil(L, 3)) // remove? 1095 { 1096 hashitem_T *hi = hash_find(&d->dv_hashtab, di->di_key); 1097 hash_remove(&d->dv_hashtab, hi); 1098 dictitem_free(di); 1099 } 1100 else 1101 { 1102 copy_tv(&v, &di->di_tv); 1103 clear_tv(&v); 1104 } 1105 return 0; 1106 } 1107 1108 static const luaL_Reg luaV_Dict_mt[] = { 1109 {"__tostring", luaV_dict_tostring}, 1110 {"__len", luaV_dict_len}, 1111 {"__call", luaV_dict_call}, 1112 {"__index", luaV_dict_index}, 1113 {"__newindex", luaV_dict_newindex}, 1114 {NULL, NULL} 1115 }; 1116 1117 1118 // ======= Blob type ======= 1119 1120 static luaV_Blob * 1121 luaV_newblob(lua_State *L, blob_T *blo) 1122 { 1123 luaV_Blob *b = (luaV_Blob *) lua_newuserdata(L, sizeof(luaV_Blob)); 1124 *b = blo; 1125 blo->bv_refcount++; // reference in Lua 1126 luaV_setudata(L, blo); // cache[blo] = udata 1127 luaV_getfield(L, LUAVIM_BLOB); 1128 lua_setmetatable(L, -2); 1129 return b; 1130 } 1131 1132 luaV_pushtype(blob_T, blob, luaV_Blob) 1133 luaV_type_tostring(blob, LUAVIM_BLOB) 1134 1135 static int 1136 luaV_blob_gc(lua_State *L) 1137 { 1138 blob_T *b = luaV_unbox(L, luaV_Blob, 1); 1139 blob_unref(b); 1140 return 0; 1141 } 1142 1143 static int 1144 luaV_blob_len(lua_State *L) 1145 { 1146 blob_T *b = luaV_unbox(L, luaV_Blob, 1); 1147 lua_pushinteger(L, (int) blob_len(b)); 1148 return 1; 1149 } 1150 1151 static int 1152 luaV_blob_index(lua_State *L) 1153 { 1154 blob_T *b = luaV_unbox(L, luaV_Blob, 1); 1155 if (lua_isnumber(L, 2)) 1156 { 1157 int idx = luaL_checkinteger(L, 2); 1158 if (idx < blob_len(b)) 1159 lua_pushnumber(L, (lua_Number) blob_get(b, idx)); 1160 else 1161 lua_pushnil(L); 1162 } 1163 else if (lua_isstring(L, 2)) 1164 { 1165 const char *s = lua_tostring(L, 2); 1166 if (strncmp(s, "add", 3) == 0) 1167 { 1168 lua_getmetatable(L, 1); 1169 lua_getfield(L, -1, s); 1170 } 1171 else 1172 lua_pushnil(L); 1173 } 1174 else 1175 lua_pushnil(L); 1176 return 1; 1177 } 1178 1179 static int 1180 luaV_blob_newindex(lua_State *L) 1181 { 1182 blob_T *b = luaV_unbox(L, luaV_Blob, 1); 1183 if (b->bv_lock) 1184 luaL_error(L, "blob is locked"); 1185 if (lua_isnumber(L, 2)) 1186 { 1187 long len = blob_len(b); 1188 int idx = luaL_checkinteger(L, 2); 1189 int val = luaL_checkinteger(L, 3); 1190 if (idx < len || (idx == len && ga_grow(&b->bv_ga, 1) == OK)) 1191 { 1192 blob_set(b, idx, (char_u) val); 1193 if (idx == len) 1194 ++b->bv_ga.ga_len; 1195 } 1196 else 1197 luaL_error(L, "index out of range"); 1198 } 1199 return 0; 1200 } 1201 1202 static int 1203 luaV_blob_add(lua_State *L) 1204 { 1205 luaV_Blob *blo = luaV_checkudata(L, 1, LUAVIM_BLOB); 1206 blob_T *b = (blob_T *) luaV_checkcache(L, (void *) *blo); 1207 if (b->bv_lock) 1208 luaL_error(L, "blob is locked"); 1209 lua_settop(L, 2); 1210 if (!lua_isstring(L, 2)) 1211 luaL_error(L, "string expected, got %s", luaL_typename(L, 2)); 1212 else 1213 { 1214 size_t i, l = 0; 1215 const char *s = lua_tolstring(L, 2, &l); 1216 1217 if (ga_grow(&b->bv_ga, (int)l) == OK) 1218 for (i = 0; i < l; ++i) 1219 ga_append(&b->bv_ga, s[i]); 1220 } 1221 lua_settop(L, 1); 1222 return 1; 1223 } 1224 1225 static const luaL_Reg luaV_Blob_mt[] = { 1226 {"__tostring", luaV_blob_tostring}, 1227 {"__gc", luaV_blob_gc}, 1228 {"__len", luaV_blob_len}, 1229 {"__index", luaV_blob_index}, 1230 {"__newindex", luaV_blob_newindex}, 1231 {"add", luaV_blob_add}, 1232 {NULL, NULL} 1233 }; 1234 1235 1236 // ======= Funcref type ======= 1237 1238 static luaV_Funcref * 1239 luaV_newfuncref(lua_State *L, char_u *name) 1240 { 1241 luaV_Funcref *f = (luaV_Funcref *)lua_newuserdata(L, sizeof(luaV_Funcref)); 1242 1243 if (name != NULL) 1244 { 1245 func_ref(name); 1246 f->name = vim_strsave(name); 1247 } 1248 f->self = NULL; 1249 luaV_getfield(L, LUAVIM_FUNCREF); 1250 lua_setmetatable(L, -2); 1251 return f; 1252 } 1253 1254 static luaV_Funcref * 1255 luaV_pushfuncref(lua_State *L, char_u *name) 1256 { 1257 return luaV_newfuncref(L, name); 1258 } 1259 1260 1261 luaV_type_tostring(funcref, LUAVIM_FUNCREF) 1262 1263 static int 1264 luaV_funcref_gc(lua_State *L) 1265 { 1266 luaV_Funcref *f = (luaV_Funcref *) lua_touserdata(L, 1); 1267 1268 func_unref(f->name); 1269 vim_free(f->name); 1270 // NOTE: Don't call "dict_unref(f->self)", because the dict of "f->self" 1271 // will be (or has been already) freed by Vim's garbage collection. 1272 return 0; 1273 } 1274 1275 // equivalent to string(funcref) 1276 static int 1277 luaV_funcref_len(lua_State *L) 1278 { 1279 luaV_Funcref *f = (luaV_Funcref *) lua_touserdata(L, 1); 1280 1281 lua_pushstring(L, (const char *) f->name); 1282 return 1; 1283 } 1284 1285 static int 1286 luaV_funcref_call(lua_State *L) 1287 { 1288 luaV_Funcref *f = (luaV_Funcref *) lua_touserdata(L, 1); 1289 int i, n = lua_gettop(L) - 1; // #args 1290 int status = FAIL; 1291 typval_T args; 1292 typval_T rettv; 1293 1294 args.v_type = VAR_LIST; 1295 args.vval.v_list = list_alloc(); 1296 rettv.v_type = VAR_UNKNOWN; // as in clear_tv 1297 if (args.vval.v_list != NULL) 1298 { 1299 typval_T v; 1300 1301 for (i = 0; i < n; i++) 1302 { 1303 luaV_checktypval(L, i + 2, &v, "calling funcref"); 1304 list_append_tv(args.vval.v_list, &v); 1305 clear_tv(&v); 1306 } 1307 status = func_call(f->name, &args, NULL, f->self, &rettv); 1308 if (status == OK) 1309 luaV_pushtypval(L, &rettv); 1310 clear_tv(&args); 1311 clear_tv(&rettv); 1312 } 1313 if (status != OK) 1314 luaL_error(L, "cannot call funcref"); 1315 return 1; 1316 } 1317 1318 static const luaL_Reg luaV_Funcref_mt[] = { 1319 {"__tostring", luaV_funcref_tostring}, 1320 {"__gc", luaV_funcref_gc}, 1321 {"__len", luaV_funcref_len}, 1322 {"__call", luaV_funcref_call}, 1323 {NULL, NULL} 1324 }; 1325 1326 1327 // ======= Buffer type ======= 1328 1329 luaV_newtype(buf_T, buffer, luaV_Buffer, LUAVIM_BUFFER) 1330 luaV_pushtype(buf_T, buffer, luaV_Buffer) 1331 luaV_type_tostring(buffer, LUAVIM_BUFFER) 1332 1333 static int 1334 luaV_buffer_len(lua_State *L) 1335 { 1336 buf_T *b = (buf_T *) luaV_checkvalid(L, luaV_Buffer, 1); 1337 lua_pushinteger(L, b->b_ml.ml_line_count); 1338 return 1; 1339 } 1340 1341 static int 1342 luaV_buffer_call(lua_State *L) 1343 { 1344 buf_T *b = (buf_T *) luaV_checkvalid(L, luaV_Buffer, 1); 1345 lua_settop(L, 1); 1346 set_curbuf(b, DOBUF_SPLIT); 1347 return 1; 1348 } 1349 1350 static int 1351 luaV_buffer_index(lua_State *L) 1352 { 1353 buf_T *b = (buf_T *) luaV_checkvalid(L, luaV_Buffer, 1); 1354 linenr_T n = (linenr_T) lua_tointeger(L, 2); 1355 if (n > 0 && n <= b->b_ml.ml_line_count) 1356 luaV_pushline(L, b, n); 1357 else if (lua_isstring(L, 2)) 1358 { 1359 const char *s = lua_tostring(L, 2); 1360 if (strncmp(s, "name", 4) == 0) 1361 lua_pushstring(L, (b->b_sfname == NULL) 1362 ? "" : (char *) b->b_sfname); 1363 else if (strncmp(s, "fname", 5) == 0) 1364 lua_pushstring(L, (b->b_ffname == NULL) 1365 ? "" : (char *) b->b_ffname); 1366 else if (strncmp(s, "number", 6) == 0) 1367 lua_pushinteger(L, b->b_fnum); 1368 // methods 1369 else if (strncmp(s, "insert", 6) == 0 1370 || strncmp(s, "next", 4) == 0 1371 || strncmp(s, "previous", 8) == 0 1372 || strncmp(s, "isvalid", 7) == 0) 1373 { 1374 lua_getmetatable(L, 1); 1375 lua_getfield(L, -1, s); 1376 } 1377 else 1378 lua_pushnil(L); 1379 } 1380 else 1381 lua_pushnil(L); 1382 return 1; 1383 } 1384 1385 static int 1386 luaV_buffer_newindex(lua_State *L) 1387 { 1388 buf_T *b = (buf_T *) luaV_checkvalid(L, luaV_Buffer, 1); 1389 linenr_T n = (linenr_T) luaL_checkinteger(L, 2); 1390 #ifdef HAVE_SANDBOX 1391 luaV_checksandbox(L); 1392 #endif 1393 if (n < 1 || n > b->b_ml.ml_line_count) 1394 luaL_error(L, "invalid line number"); 1395 if (lua_isnil(L, 3)) // delete line 1396 { 1397 buf_T *buf = curbuf; 1398 curbuf = b; 1399 if (u_savedel(n, 1L) == FAIL) 1400 { 1401 curbuf = buf; 1402 luaL_error(L, "cannot save undo information"); 1403 } 1404 else if (ml_delete(n) == FAIL) 1405 { 1406 curbuf = buf; 1407 luaL_error(L, "cannot delete line"); 1408 } 1409 else 1410 { 1411 deleted_lines_mark(n, 1L); 1412 if (b == curwin->w_buffer) // fix cursor in current window? 1413 { 1414 if (curwin->w_cursor.lnum >= n) 1415 { 1416 if (curwin->w_cursor.lnum > n) 1417 { 1418 curwin->w_cursor.lnum -= 1; 1419 check_cursor_col(); 1420 } 1421 else check_cursor(); 1422 changed_cline_bef_curs(); 1423 } 1424 invalidate_botline(); 1425 } 1426 } 1427 curbuf = buf; 1428 } 1429 else if (lua_isstring(L, 3)) // update line 1430 { 1431 buf_T *buf = curbuf; 1432 curbuf = b; 1433 if (u_savesub(n) == FAIL) 1434 { 1435 curbuf = buf; 1436 luaL_error(L, "cannot save undo information"); 1437 } 1438 else if (ml_replace(n, luaV_toline(L, 3), TRUE) == FAIL) 1439 { 1440 curbuf = buf; 1441 luaL_error(L, "cannot replace line"); 1442 } 1443 else changed_bytes(n, 0); 1444 curbuf = buf; 1445 if (b == curwin->w_buffer) 1446 check_cursor_col(); 1447 } 1448 else 1449 luaL_error(L, "wrong argument to change line"); 1450 return 0; 1451 } 1452 1453 static int 1454 luaV_buffer_insert(lua_State *L) 1455 { 1456 luaV_Buffer *lb = luaV_checkudata(L, 1, LUAVIM_BUFFER); 1457 buf_T *b = (buf_T *) luaV_checkcache(L, (void *) *lb); 1458 linenr_T last = b->b_ml.ml_line_count; 1459 linenr_T n = (linenr_T) luaL_optinteger(L, 3, last); 1460 buf_T *buf; 1461 luaL_checktype(L, 2, LUA_TSTRING); 1462 #ifdef HAVE_SANDBOX 1463 luaV_checksandbox(L); 1464 #endif 1465 // fix insertion line 1466 if (n < 0) n = 0; 1467 if (n > last) n = last; 1468 // insert 1469 buf = curbuf; 1470 curbuf = b; 1471 if (u_save(n, n + 1) == FAIL) 1472 { 1473 curbuf = buf; 1474 luaL_error(L, "cannot save undo information"); 1475 } 1476 else if (ml_append(n, luaV_toline(L, 2), 0, FALSE) == FAIL) 1477 { 1478 curbuf = buf; 1479 luaL_error(L, "cannot insert line"); 1480 } 1481 else 1482 appended_lines_mark(n, 1L); 1483 curbuf = buf; 1484 update_screen(VALID); 1485 return 0; 1486 } 1487 1488 static int 1489 luaV_buffer_next(lua_State *L) 1490 { 1491 luaV_Buffer *b = luaV_checkudata(L, 1, LUAVIM_BUFFER); 1492 buf_T *buf = (buf_T *) luaV_checkcache(L, (void *) *b); 1493 luaV_pushbuffer(L, buf->b_next); 1494 return 1; 1495 } 1496 1497 static int 1498 luaV_buffer_previous(lua_State *L) 1499 { 1500 luaV_Buffer *b = luaV_checkudata(L, 1, LUAVIM_BUFFER); 1501 buf_T *buf = (buf_T *) luaV_checkcache(L, (void *) *b); 1502 luaV_pushbuffer(L, buf->b_prev); 1503 return 1; 1504 } 1505 1506 static int 1507 luaV_buffer_isvalid(lua_State *L) 1508 { 1509 luaV_Buffer *b = luaV_checkudata(L, 1, LUAVIM_BUFFER); 1510 luaV_getudata(L, *b); 1511 lua_pushboolean(L, !lua_isnil(L, -1)); 1512 return 1; 1513 } 1514 1515 static const luaL_Reg luaV_Buffer_mt[] = { 1516 {"__tostring", luaV_buffer_tostring}, 1517 {"__len", luaV_buffer_len}, 1518 {"__call", luaV_buffer_call}, 1519 {"__index", luaV_buffer_index}, 1520 {"__newindex", luaV_buffer_newindex}, 1521 {"insert", luaV_buffer_insert}, 1522 {"next", luaV_buffer_next}, 1523 {"previous", luaV_buffer_previous}, 1524 {"isvalid", luaV_buffer_isvalid}, 1525 {NULL, NULL} 1526 }; 1527 1528 1529 // ======= Window type ======= 1530 1531 luaV_newtype(win_T, window, luaV_Window, LUAVIM_WINDOW) 1532 luaV_pushtype(win_T, window, luaV_Window) 1533 luaV_type_tostring(window, LUAVIM_WINDOW) 1534 1535 static int 1536 luaV_window_call(lua_State *L) 1537 { 1538 win_T *w = (win_T *) luaV_checkvalid(L, luaV_Window, 1); 1539 lua_settop(L, 1); 1540 win_goto(w); 1541 return 1; 1542 } 1543 1544 static int 1545 luaV_window_index(lua_State *L) 1546 { 1547 win_T *w = (win_T *) luaV_checkvalid(L, luaV_Window, 1); 1548 const char *s = luaL_checkstring(L, 2); 1549 if (strncmp(s, "buffer", 6) == 0) 1550 luaV_pushbuffer(L, w->w_buffer); 1551 else if (strncmp(s, "line", 4) == 0) 1552 lua_pushinteger(L, w->w_cursor.lnum); 1553 else if (strncmp(s, "col", 3) == 0) 1554 lua_pushinteger(L, w->w_cursor.col + 1); 1555 else if (strncmp(s, "width", 5) == 0) 1556 lua_pushinteger(L, w->w_width); 1557 else if (strncmp(s, "height", 6) == 0) 1558 lua_pushinteger(L, w->w_height); 1559 // methods 1560 else if (strncmp(s, "next", 4) == 0 1561 || strncmp(s, "previous", 8) == 0 1562 || strncmp(s, "isvalid", 7) == 0) 1563 { 1564 lua_getmetatable(L, 1); 1565 lua_getfield(L, -1, s); 1566 } 1567 else 1568 lua_pushnil(L); 1569 return 1; 1570 } 1571 1572 static int 1573 luaV_window_newindex(lua_State *L) 1574 { 1575 win_T *w = (win_T *) luaV_checkvalid(L, luaV_Window, 1); 1576 const char *s = luaL_checkstring(L, 2); 1577 int v = luaL_checkinteger(L, 3); 1578 if (strncmp(s, "line", 4) == 0) 1579 { 1580 #ifdef HAVE_SANDBOX 1581 luaV_checksandbox(L); 1582 #endif 1583 if (v < 1 || v > w->w_buffer->b_ml.ml_line_count) 1584 luaL_error(L, "line out of range"); 1585 w->w_cursor.lnum = v; 1586 update_screen(VALID); 1587 } 1588 else if (strncmp(s, "col", 3) == 0) 1589 { 1590 #ifdef HAVE_SANDBOX 1591 luaV_checksandbox(L); 1592 #endif 1593 w->w_cursor.col = v - 1; 1594 w->w_set_curswant = TRUE; 1595 update_screen(VALID); 1596 } 1597 else if (strncmp(s, "width", 5) == 0) 1598 { 1599 win_T *win = curwin; 1600 #ifdef FEAT_GUI 1601 need_mouse_correct = TRUE; 1602 #endif 1603 curwin = w; 1604 win_setwidth(v); 1605 curwin = win; 1606 } 1607 else if (strncmp(s, "height", 6) == 0) 1608 { 1609 win_T *win = curwin; 1610 #ifdef FEAT_GUI 1611 need_mouse_correct = TRUE; 1612 #endif 1613 curwin = w; 1614 win_setheight(v); 1615 curwin = win; 1616 } 1617 else 1618 luaL_error(L, "invalid window property: `%s'", s); 1619 return 0; 1620 } 1621 1622 static int 1623 luaV_window_next(lua_State *L) 1624 { 1625 luaV_Window *w = luaV_checkudata(L, 1, LUAVIM_WINDOW); 1626 win_T *win = (win_T *) luaV_checkcache(L, (void *) *w); 1627 luaV_pushwindow(L, win->w_next); 1628 return 1; 1629 } 1630 1631 static int 1632 luaV_window_previous(lua_State *L) 1633 { 1634 luaV_Window *w = luaV_checkudata(L, 1, LUAVIM_WINDOW); 1635 win_T *win = (win_T *) luaV_checkcache(L, (void *) *w); 1636 luaV_pushwindow(L, win->w_prev); 1637 return 1; 1638 } 1639 1640 static int 1641 luaV_window_isvalid(lua_State *L) 1642 { 1643 luaV_Window *w = luaV_checkudata(L, 1, LUAVIM_WINDOW); 1644 luaV_getudata(L, *w); 1645 lua_pushboolean(L, !lua_isnil(L, -1)); 1646 return 1; 1647 } 1648 1649 static const luaL_Reg luaV_Window_mt[] = { 1650 {"__tostring", luaV_window_tostring}, 1651 {"__call", luaV_window_call}, 1652 {"__index", luaV_window_index}, 1653 {"__newindex", luaV_window_newindex}, 1654 {"next", luaV_window_next}, 1655 {"previous", luaV_window_previous}, 1656 {"isvalid", luaV_window_isvalid}, 1657 {NULL, NULL} 1658 }; 1659 1660 1661 // ======= Vim module ======= 1662 1663 static int 1664 luaV_print(lua_State *L) 1665 { 1666 int i, n = lua_gettop(L); // nargs 1667 const char *s; 1668 size_t l; 1669 luaL_Buffer b; 1670 luaL_buffinit(L, &b); 1671 lua_getglobal(L, "tostring"); 1672 for (i = 1; i <= n; i++) 1673 { 1674 lua_pushvalue(L, -1); // tostring 1675 lua_pushvalue(L, i); // arg 1676 lua_call(L, 1, 1); 1677 s = lua_tolstring(L, -1, &l); 1678 if (s == NULL) 1679 return luaL_error(L, "cannot convert to string"); 1680 if (i > 1) luaL_addchar(&b, ' '); // use space instead of tab 1681 luaV_addlstring(&b, s, l, 0); 1682 lua_pop(L, 1); 1683 } 1684 luaL_pushresult(&b); 1685 if (!got_int) 1686 luaV_msg(L); 1687 return 0; 1688 } 1689 1690 static int 1691 luaV_debug(lua_State *L) 1692 { 1693 lua_settop(L, 0); 1694 lua_getglobal(L, "vim"); 1695 lua_getfield(L, -1, "eval"); 1696 lua_remove(L, -2); // vim.eval at position 1 1697 for (;;) 1698 { 1699 const char *input; 1700 size_t l; 1701 lua_pushvalue(L, 1); // vim.eval 1702 lua_pushliteral(L, "input('lua_debug> ')"); 1703 lua_call(L, 1, 1); // return string 1704 input = lua_tolstring(L, -1, &l); 1705 if (l == 0 || strcmp(input, "cont") == 0) 1706 return 0; 1707 msg_putchar('\n'); // avoid outputting on input line 1708 if (luaL_loadbuffer(L, input, l, "=(debug command)") 1709 || lua_pcall(L, 0, 0, 0)) 1710 luaV_emsg(L); 1711 lua_settop(L, 1); // remove eventual returns, but keep vim.eval 1712 } 1713 } 1714 1715 static int 1716 luaV_command(lua_State *L) 1717 { 1718 do_cmdline_cmd((char_u *) luaL_checkstring(L, 1)); 1719 update_screen(VALID); 1720 return 0; 1721 } 1722 1723 static int 1724 luaV_eval(lua_State *L) 1725 { 1726 typval_T *tv = eval_expr((char_u *) luaL_checkstring(L, 1), NULL); 1727 if (tv == NULL) luaL_error(L, "invalid expression"); 1728 luaV_pushtypval(L, tv); 1729 free_tv(tv); 1730 return 1; 1731 } 1732 1733 static int 1734 luaV_beep(lua_State *L UNUSED) 1735 { 1736 vim_beep(BO_LANG); 1737 return 0; 1738 } 1739 1740 static int 1741 luaV_line(lua_State *L) 1742 { 1743 luaV_pushline(L, curbuf, curwin->w_cursor.lnum); 1744 return 1; 1745 } 1746 1747 static int 1748 luaV_list(lua_State *L) 1749 { 1750 list_T *l; 1751 int initarg = !lua_isnoneornil(L, 1); 1752 1753 if (initarg && lua_type(L, 1) != LUA_TTABLE) 1754 luaL_error(L, "table expected, got %s", luaL_typename(L, 1)); 1755 l = list_alloc(); 1756 if (l == NULL) 1757 lua_pushnil(L); 1758 else 1759 { 1760 luaV_newlist(L, l); 1761 if (initarg) // traverse table to init list 1762 { 1763 int notnil, i = 0; 1764 typval_T v; 1765 do 1766 { 1767 lua_rawgeti(L, 1, ++i); 1768 notnil = !lua_isnil(L, -1); 1769 if (notnil) 1770 { 1771 luaV_checktypval(L, -1, &v, "vim.list"); 1772 list_append_tv(l, &v); 1773 clear_tv(&v); 1774 } 1775 lua_pop(L, 1); // value 1776 } while (notnil); 1777 } 1778 } 1779 return 1; 1780 } 1781 1782 static int 1783 luaV_dict(lua_State *L) 1784 { 1785 dict_T *d; 1786 int initarg = !lua_isnoneornil(L, 1); 1787 1788 if (initarg && lua_type(L, 1) != LUA_TTABLE) 1789 luaL_error(L, "table expected, got %s", luaL_typename(L, 1)); 1790 d = dict_alloc(); 1791 if (d == NULL) 1792 lua_pushnil(L); 1793 else 1794 { 1795 luaV_newdict(L, d); 1796 if (initarg) // traverse table to init dict 1797 { 1798 lua_pushnil(L); 1799 while (lua_next(L, 1)) 1800 { 1801 char_u *key; 1802 dictitem_T *di; 1803 typval_T v; 1804 1805 lua_pushvalue(L, -2); // dup key in case it's a number 1806 key = (char_u *) lua_tostring(L, -1); 1807 if (key == NULL) 1808 { 1809 lua_pushnil(L); 1810 return 1; 1811 } 1812 if (*key == NUL) 1813 luaL_error(L, "table has empty key"); 1814 luaV_checktypval(L, -2, &v, "vim.dict"); // value 1815 di = dictitem_alloc(key); 1816 if (di == NULL || dict_add(d, di) == FAIL) 1817 { 1818 vim_free(di); 1819 lua_pushnil(L); 1820 return 1; 1821 } 1822 copy_tv(&v, &di->di_tv); 1823 clear_tv(&v); 1824 lua_pop(L, 2); // key copy and value 1825 } 1826 } 1827 } 1828 return 1; 1829 } 1830 1831 static int 1832 luaV_blob(lua_State *L) 1833 { 1834 blob_T *b; 1835 int initarg = !lua_isnoneornil(L, 1); 1836 1837 if (initarg && !lua_isstring(L, 1)) 1838 luaL_error(L, "string expected, got %s", luaL_typename(L, 1)); 1839 b = blob_alloc(); 1840 if (b == NULL) 1841 lua_pushnil(L); 1842 else 1843 { 1844 luaV_newblob(L, b); 1845 if (initarg) 1846 { 1847 size_t i, l = 0; 1848 const char *s = lua_tolstring(L, 1, &l); 1849 1850 if (ga_grow(&b->bv_ga, (int)l) == OK) 1851 for (i = 0; i < l; ++i) 1852 ga_append(&b->bv_ga, s[i]); 1853 } 1854 } 1855 return 1; 1856 } 1857 1858 static int 1859 luaV_funcref(lua_State *L) 1860 { 1861 const char *name = luaL_checkstring(L, 1); 1862 // note: not checking if function exists (needs function_exists) 1863 if (name == NULL || *name == NUL || VIM_ISDIGIT(*name)) 1864 luaL_error(L, "invalid function name: %s", name); 1865 luaV_newfuncref(L, (char_u *) name); 1866 return 1; 1867 } 1868 1869 static int 1870 luaV_buffer(lua_State *L) 1871 { 1872 buf_T *buf; 1873 if (lua_isstring(L, 1)) // get by number or name? 1874 { 1875 if (lua_isnumber(L, 1)) // by number? 1876 { 1877 int n = lua_tointeger(L, 1); 1878 FOR_ALL_BUFFERS(buf) 1879 if (buf->b_fnum == n) break; 1880 } 1881 else // by name 1882 { 1883 size_t l; 1884 const char *s = lua_tolstring(L, 1, &l); 1885 FOR_ALL_BUFFERS(buf) 1886 { 1887 if (buf->b_ffname == NULL || buf->b_sfname == NULL) 1888 { 1889 if (l == 0) break; 1890 } 1891 else if (strncmp(s, (char *)buf->b_ffname, l) == 0 1892 || strncmp(s, (char *)buf->b_sfname, l) == 0) 1893 break; 1894 } 1895 } 1896 } 1897 else 1898 buf = (lua_toboolean(L, 1)) ? firstbuf : curbuf; // first buffer? 1899 luaV_pushbuffer(L, buf); 1900 return 1; 1901 } 1902 1903 static int 1904 luaV_window(lua_State *L) 1905 { 1906 win_T *win; 1907 if (lua_isnumber(L, 1)) // get by number? 1908 { 1909 int n = lua_tointeger(L, 1); 1910 for (win = firstwin; win != NULL; win = win->w_next, n--) 1911 if (n == 1) break; 1912 } 1913 else 1914 win = (lua_toboolean(L, 1)) ? firstwin : curwin; // first window? 1915 luaV_pushwindow(L, win); 1916 return 1; 1917 } 1918 1919 static int 1920 luaV_open(lua_State *L) 1921 { 1922 char_u *s = NULL; 1923 #ifdef HAVE_SANDBOX 1924 luaV_checksandbox(L); 1925 #endif 1926 if (lua_isstring(L, 1)) s = (char_u *) lua_tostring(L, 1); 1927 luaV_pushbuffer(L, buflist_new(s, NULL, 1L, BLN_LISTED)); 1928 return 1; 1929 } 1930 1931 static int 1932 luaV_type(lua_State *L) 1933 { 1934 luaL_checkany(L, 1); 1935 if (lua_type(L, 1) == LUA_TUSERDATA) // check vim udata? 1936 { 1937 lua_settop(L, 1); 1938 if (lua_getmetatable(L, 1)) 1939 { 1940 luaV_getfield(L, LUAVIM_LIST); 1941 if (lua_rawequal(L, -1, 2)) 1942 { 1943 lua_pushstring(L, "list"); 1944 return 1; 1945 } 1946 luaV_getfield(L, LUAVIM_DICT); 1947 if (lua_rawequal(L, -1, 2)) 1948 { 1949 lua_pushstring(L, "dict"); 1950 return 1; 1951 } 1952 luaV_getfield(L, LUAVIM_BLOB); 1953 if (lua_rawequal(L, -1, 2)) 1954 { 1955 lua_pushstring(L, "blob"); 1956 return 1; 1957 } 1958 luaV_getfield(L, LUAVIM_FUNCREF); 1959 if (lua_rawequal(L, -1, 2)) 1960 { 1961 lua_pushstring(L, "funcref"); 1962 return 1; 1963 } 1964 luaV_getfield(L, LUAVIM_BUFFER); 1965 if (lua_rawequal(L, -1, 2)) 1966 { 1967 lua_pushstring(L, "buffer"); 1968 return 1; 1969 } 1970 luaV_getfield(L, LUAVIM_WINDOW); 1971 if (lua_rawequal(L, -1, 2)) 1972 { 1973 lua_pushstring(L, "window"); 1974 return 1; 1975 } 1976 } 1977 } 1978 lua_pushstring(L, luaL_typename(L, 1)); // fallback 1979 return 1; 1980 } 1981 1982 static int 1983 luaV_call(lua_State *L) 1984 { 1985 int argc = lua_gettop(L) - 1; 1986 size_t funcname_len; 1987 char_u *funcname; 1988 char *error = NULL; 1989 typval_T rettv; 1990 typval_T argv[MAX_FUNC_ARGS + 1]; 1991 int i = 0; 1992 1993 if (argc > MAX_FUNC_ARGS) 1994 return luaL_error(L, "Function called with too many arguments"); 1995 1996 funcname = (char_u *)luaL_checklstring(L, 1, &funcname_len); 1997 1998 for (; i < argc; i++) 1999 { 2000 if (luaV_totypval(L, i + 2, &argv[i]) == FAIL) 2001 { 2002 error = "lua: cannot convert value"; 2003 goto free_vim_args; 2004 } 2005 } 2006 2007 argv[argc].v_type = VAR_UNKNOWN; 2008 2009 if (call_vim_function(funcname, argc, argv, &rettv) == FAIL) 2010 { 2011 error = "lua: call_vim_function failed"; 2012 goto free_vim_args; 2013 } 2014 2015 luaV_pushtypval(L, &rettv); 2016 clear_tv(&rettv); 2017 2018 free_vim_args: 2019 while (i > 0) 2020 clear_tv(&argv[--i]); 2021 2022 if (error == NULL) 2023 return 1; 2024 else 2025 return luaL_error(L, error); 2026 } 2027 2028 static const luaL_Reg luaV_module[] = { 2029 {"command", luaV_command}, 2030 {"eval", luaV_eval}, 2031 {"beep", luaV_beep}, 2032 {"line", luaV_line}, 2033 {"list", luaV_list}, 2034 {"dict", luaV_dict}, 2035 {"blob", luaV_blob}, 2036 {"funcref", luaV_funcref}, 2037 {"buffer", luaV_buffer}, 2038 {"window", luaV_window}, 2039 {"open", luaV_open}, 2040 {"type", luaV_type}, 2041 {"call", luaV_call}, 2042 {NULL, NULL} 2043 }; 2044 2045 /* 2046 * for freeing list, dict, buffer and window objects; lightuserdata as arg 2047 */ 2048 static int 2049 luaV_free(lua_State *L) 2050 { 2051 lua_pushnil(L); 2052 luaV_setudata(L, lua_touserdata(L, 1)); 2053 return 0; 2054 } 2055 2056 static int 2057 luaV_luaeval(lua_State *L) 2058 { 2059 luaL_Buffer b; 2060 size_t l; 2061 const char *str = lua_tolstring(L, 1, &l); 2062 typval_T *arg = (typval_T *) lua_touserdata(L, 2); 2063 typval_T *rettv = (typval_T *) lua_touserdata(L, 3); 2064 luaL_buffinit(L, &b); 2065 luaL_addlstring(&b, LUAVIM_EVALHEADER, sizeof(LUAVIM_EVALHEADER) - 1); 2066 luaL_addlstring(&b, str, l); 2067 luaL_pushresult(&b); 2068 str = lua_tolstring(L, -1, &l); 2069 if (luaL_loadbuffer(L, str, l, LUAVIM_EVALNAME)) // compile error? 2070 { 2071 luaV_emsg(L); 2072 return 0; 2073 } 2074 luaV_pushtypval(L, arg); 2075 if (lua_pcall(L, 1, 1, 0)) // running error? 2076 { 2077 luaV_emsg(L); 2078 return 0; 2079 } 2080 if (luaV_totypval(L, -1, rettv) == FAIL) 2081 emsg("luaeval: cannot convert value"); 2082 return 0; 2083 } 2084 2085 static int 2086 luaV_setref(lua_State *L) 2087 { 2088 int copyID = lua_tointeger(L, 1); 2089 int abort = FALSE; 2090 2091 luaV_getfield(L, LUAVIM_LIST); 2092 luaV_getfield(L, LUAVIM_DICT); 2093 luaV_getfield(L, LUAVIM_FUNCREF); 2094 lua_pushnil(L); 2095 // traverse cache table 2096 while (!abort && lua_next(L, lua_upvalueindex(1)) != 0) 2097 { 2098 lua_getmetatable(L, -1); 2099 if (lua_rawequal(L, -1, 2)) // list? 2100 { 2101 list_T *l = (list_T *)lua_touserdata(L, 5); // key 2102 2103 abort = set_ref_in_list(l, copyID); 2104 } 2105 else if (lua_rawequal(L, -1, 3)) // dict? 2106 { 2107 dict_T *d = (dict_T *)lua_touserdata(L, 5); // key 2108 2109 abort = set_ref_in_dict(d, copyID); 2110 } 2111 else if (lua_rawequal(L, -1, 4)) // funcref? 2112 { 2113 luaV_Funcref *f = (luaV_Funcref *)lua_touserdata(L, 5); // key 2114 2115 abort = set_ref_in_dict(f->self, copyID); 2116 } 2117 lua_pop(L, 2); // metatable and value 2118 } 2119 lua_pushinteger(L, abort); 2120 return 1; 2121 } 2122 2123 #define LUA_VIM_FN_CODE \ 2124 "vim.fn = setmetatable({}, {\n"\ 2125 " __index = function (t, key)\n"\ 2126 " local function _fn(...)\n"\ 2127 " return vim.call(key, ...)\n"\ 2128 " end\n"\ 2129 " t[key] = _fn\n"\ 2130 " return _fn\n"\ 2131 " end\n"\ 2132 " })" 2133 2134 #define LUA_VIM_UPDATE_PACKAGE_PATHS \ 2135 "local last_vim_paths = {}\n"\ 2136 "vim._update_package_paths = function ()\n"\ 2137 " local cur_vim_paths = {}\n"\ 2138 " local function split(s, delimiter)\n"\ 2139 " result = {}\n"\ 2140 " for match in (s..delimiter):gmatch(\"(.-)\"..delimiter) do\n"\ 2141 " table.insert(result, match)\n"\ 2142 " end\n"\ 2143 " return result\n"\ 2144 " end\n"\ 2145 " local rtps = split(vim.eval('&runtimepath'), ',')\n"\ 2146 " local sep = package.config:sub(1, 1)\n"\ 2147 " for _, key in ipairs({'path', 'cpath'}) do\n"\ 2148 " local orig_str = package[key] .. ';'\n"\ 2149 " local pathtrails_ordered = {}\n"\ 2150 " -- Note: ignores trailing item without trailing `;`. Not using something\n"\ 2151 " -- simpler in order to preserve empty items (stand for default path).\n"\ 2152 " local orig = {}\n"\ 2153 " for s in orig_str:gmatch('[^;]*;') do\n"\ 2154 " s = s:sub(1, -2) -- Strip trailing semicolon\n"\ 2155 " orig[#orig + 1] = s\n"\ 2156 " end\n"\ 2157 " if key == 'path' then\n"\ 2158 " -- /?.lua and /?/init.lua\n"\ 2159 " pathtrails_ordered = {sep .. '?.lua', sep .. '?' .. sep .. 'init.lua'}\n"\ 2160 " else\n"\ 2161 " local pathtrails = {}\n"\ 2162 " for _, s in ipairs(orig) do\n"\ 2163 " -- Find out path patterns. pathtrail should contain something like\n"\ 2164 " -- /?.so, \?.dll. This allows not to bother determining what correct\n"\ 2165 " -- suffixes are.\n"\ 2166 " local pathtrail = s:match('[/\\\\][^/\\\\]*%?.*$')\n"\ 2167 " if pathtrail and not pathtrails[pathtrail] then\n"\ 2168 " pathtrails[pathtrail] = true\n"\ 2169 " pathtrails_ordered[#pathtrails_ordered + 1] = pathtrail\n"\ 2170 " end\n"\ 2171 " end\n"\ 2172 " end\n"\ 2173 " local new = {}\n"\ 2174 " for _, rtp in ipairs(rtps) do\n"\ 2175 " if not rtp:match(';') then\n"\ 2176 " for _, pathtrail in pairs(pathtrails_ordered) do\n"\ 2177 " local new_path = rtp .. sep .. 'lua' .. pathtrail\n"\ 2178 " -- Always keep paths from &runtimepath at the start:\n"\ 2179 " -- append them here disregarding orig possibly containing one of them.\n"\ 2180 " new[#new + 1] = new_path\n"\ 2181 " cur_vim_paths[new_path] = true\n"\ 2182 " end\n"\ 2183 " end\n"\ 2184 " end\n"\ 2185 " for _, orig_path in ipairs(orig) do\n"\ 2186 " -- Handle removing obsolete paths originating from &runtimepath: such\n"\ 2187 " -- paths either belong to cur_nvim_paths and were already added above or\n"\ 2188 " -- to last_nvim_paths and should not be added at all if corresponding\n"\ 2189 " -- entry was removed from &runtimepath list.\n"\ 2190 " if not (cur_vim_paths[orig_path] or last_vim_paths[orig_path]) then\n"\ 2191 " new[#new + 1] = orig_path\n"\ 2192 " end\n"\ 2193 " end\n"\ 2194 " package[key] = table.concat(new, ';')\n"\ 2195 " end\n"\ 2196 " last_vim_paths = cur_vim_paths\n"\ 2197 "end" 2198 2199 static int 2200 luaopen_vim(lua_State *L) 2201 { 2202 // set cache table 2203 lua_newtable(L); 2204 lua_newtable(L); 2205 lua_pushstring(L, "v"); 2206 lua_setfield(L, -2, "__mode"); 2207 lua_setmetatable(L, -2); // cache is weak-valued 2208 // print 2209 lua_pushcfunction(L, luaV_print); 2210 lua_setglobal(L, "print"); 2211 // debug.debug 2212 lua_getglobal(L, "debug"); 2213 lua_pushcfunction(L, luaV_debug); 2214 lua_setfield(L, -2, "debug"); 2215 lua_pop(L, 1); 2216 // free 2217 lua_pushlightuserdata(L, (void *) LUAVIM_FREE); 2218 lua_pushvalue(L, 1); // cache table 2219 lua_pushcclosure(L, luaV_free, 1); 2220 lua_rawset(L, LUA_REGISTRYINDEX); 2221 // luaeval 2222 lua_pushlightuserdata(L, (void *) LUAVIM_LUAEVAL); 2223 lua_pushvalue(L, 1); // cache table 2224 lua_pushcclosure(L, luaV_luaeval, 1); 2225 lua_rawset(L, LUA_REGISTRYINDEX); 2226 // setref 2227 lua_pushlightuserdata(L, (void *) LUAVIM_SETREF); 2228 lua_pushvalue(L, 1); // cache table 2229 lua_pushcclosure(L, luaV_setref, 1); 2230 lua_rawset(L, LUA_REGISTRYINDEX); 2231 // register 2232 luaV_newmetatable(L, LUAVIM_LIST); 2233 lua_pushvalue(L, 1); 2234 luaV_openlib(L, luaV_List_mt, 1); 2235 luaV_newmetatable(L, LUAVIM_DICT); 2236 lua_pushvalue(L, 1); 2237 luaV_openlib(L, luaV_Dict_mt, 1); 2238 luaV_newmetatable(L, LUAVIM_BLOB); 2239 lua_pushvalue(L, 1); 2240 luaV_openlib(L, luaV_Blob_mt, 1); 2241 luaV_newmetatable(L, LUAVIM_FUNCREF); 2242 lua_pushvalue(L, 1); 2243 luaV_openlib(L, luaV_Funcref_mt, 1); 2244 luaV_newmetatable(L, LUAVIM_BUFFER); 2245 lua_pushvalue(L, 1); // cache table 2246 luaV_openlib(L, luaV_Buffer_mt, 1); 2247 luaV_newmetatable(L, LUAVIM_WINDOW); 2248 lua_pushvalue(L, 1); // cache table 2249 luaV_openlib(L, luaV_Window_mt, 1); 2250 lua_newtable(L); // vim table 2251 lua_pushvalue(L, 1); // cache table 2252 luaV_openlib(L, luaV_module, 1); 2253 lua_setglobal(L, LUAVIM_NAME); 2254 // custom code 2255 (void)luaL_dostring(L, LUA_VIM_FN_CODE); 2256 (void)luaL_dostring(L, LUA_VIM_UPDATE_PACKAGE_PATHS); 2257 2258 lua_getglobal(L, "vim"); 2259 lua_getfield(L, -1, "_update_package_paths"); 2260 2261 if (lua_pcall(L, 0, 0, 0)) 2262 luaV_emsg(L); 2263 2264 return 0; 2265 } 2266 2267 static lua_State * 2268 luaV_newstate(void) 2269 { 2270 lua_State *L = luaL_newstate(); 2271 luaL_openlibs(L); // core libs 2272 lua_pushcfunction(L, luaopen_vim); // vim 2273 lua_call(L, 0, 0); 2274 return L; 2275 } 2276 2277 static void 2278 luaV_setrange(lua_State *L, int line1, int line2) 2279 { 2280 lua_getglobal(L, LUAVIM_NAME); 2281 lua_pushinteger(L, line1); 2282 lua_setfield(L, -2, "firstline"); 2283 lua_pushinteger(L, line2); 2284 lua_setfield(L, -2, "lastline"); 2285 lua_pop(L, 1); // vim table 2286 } 2287 2288 2289 // ======= Interface ======= 2290 2291 static lua_State *L = NULL; 2292 2293 static int 2294 lua_isopen(void) 2295 { 2296 return L != NULL; 2297 } 2298 2299 static int 2300 lua_init(void) 2301 { 2302 if (!lua_isopen()) 2303 { 2304 #ifdef DYNAMIC_LUA 2305 if (!lua_enabled(TRUE)) 2306 { 2307 emsg(_("Lua library cannot be loaded.")); 2308 return FAIL; 2309 } 2310 #endif 2311 L = luaV_newstate(); 2312 } 2313 return OK; 2314 } 2315 2316 void 2317 lua_end(void) 2318 { 2319 if (lua_isopen()) 2320 { 2321 lua_close(L); 2322 L = NULL; 2323 } 2324 } 2325 2326 /* 2327 * ex commands 2328 */ 2329 void 2330 ex_lua(exarg_T *eap) 2331 { 2332 char *script; 2333 if (lua_init() == FAIL) return; 2334 script = (char *) script_get(eap, eap->arg); 2335 if (!eap->skip) 2336 { 2337 char *s = (script) ? script : (char *) eap->arg; 2338 luaV_setrange(L, eap->line1, eap->line2); 2339 if (luaL_loadbuffer(L, s, strlen(s), LUAVIM_CHUNKNAME) 2340 || lua_pcall(L, 0, 0, 0)) 2341 luaV_emsg(L); 2342 } 2343 if (script != NULL) vim_free(script); 2344 } 2345 2346 void 2347 ex_luado(exarg_T *eap) 2348 { 2349 linenr_T l; 2350 const char *s = (const char *) eap->arg; 2351 luaL_Buffer b; 2352 size_t len; 2353 buf_T *was_curbuf = curbuf; 2354 2355 if (lua_init() == FAIL) return; 2356 if (u_save(eap->line1 - 1, eap->line2 + 1) == FAIL) 2357 { 2358 emsg(_("cannot save undo information")); 2359 return; 2360 } 2361 luaV_setrange(L, eap->line1, eap->line2); 2362 luaL_buffinit(L, &b); 2363 luaL_addlstring(&b, "return function(line, linenr) ", 30); // header 2364 luaL_addlstring(&b, s, strlen(s)); 2365 luaL_addlstring(&b, " end", 4); // footer 2366 luaL_pushresult(&b); 2367 s = lua_tolstring(L, -1, &len); 2368 if (luaL_loadbuffer(L, s, len, LUAVIM_CHUNKNAME)) 2369 { 2370 luaV_emsg(L); 2371 lua_pop(L, 1); // function body 2372 return; 2373 } 2374 lua_call(L, 0, 1); 2375 lua_replace(L, -2); // function -> body 2376 for (l = eap->line1; l <= eap->line2; l++) 2377 { 2378 // Check the line number, the command my have deleted lines. 2379 if (l > curbuf->b_ml.ml_line_count) 2380 break; 2381 2382 lua_pushvalue(L, -1); // function 2383 luaV_pushline(L, curbuf, l); // current line as arg 2384 lua_pushinteger(L, l); // current line number as arg 2385 if (lua_pcall(L, 2, 1, 0)) 2386 { 2387 luaV_emsg(L); 2388 break; 2389 } 2390 // Catch the command switching to another buffer. 2391 if (curbuf != was_curbuf) 2392 break; 2393 if (lua_isstring(L, -1)) // update line? 2394 { 2395 #ifdef HAVE_SANDBOX 2396 luaV_checksandbox(L); 2397 #endif 2398 ml_replace(l, luaV_toline(L, -1), TRUE); 2399 changed_bytes(l, 0); 2400 lua_pop(L, 1); // result from luaV_toline 2401 } 2402 lua_pop(L, 1); // line 2403 } 2404 lua_pop(L, 1); // function 2405 check_cursor(); 2406 update_screen(NOT_VALID); 2407 } 2408 2409 void 2410 ex_luafile(exarg_T *eap) 2411 { 2412 if (lua_init() == FAIL) 2413 return; 2414 if (!eap->skip) 2415 { 2416 luaV_setrange(L, eap->line1, eap->line2); 2417 if (luaL_loadfile(L, (char *) eap->arg) || lua_pcall(L, 0, 0, 0)) 2418 luaV_emsg(L); 2419 } 2420 } 2421 2422 #define luaV_freetype(typ,tname) \ 2423 void \ 2424 lua_##tname##_free(typ *o) \ 2425 { \ 2426 if (!lua_isopen()) return; \ 2427 luaV_getfield(L, LUAVIM_FREE); \ 2428 lua_pushlightuserdata(L, (void *) o); \ 2429 lua_call(L, 1, 0); \ 2430 } 2431 2432 luaV_freetype(buf_T, buffer) 2433 luaV_freetype(win_T, window) 2434 2435 void 2436 do_luaeval(char_u *str, typval_T *arg, typval_T *rettv) 2437 { 2438 lua_init(); 2439 luaV_getfield(L, LUAVIM_LUAEVAL); 2440 lua_pushstring(L, (char *) str); 2441 lua_pushlightuserdata(L, (void *) arg); 2442 lua_pushlightuserdata(L, (void *) rettv); 2443 lua_call(L, 3, 0); 2444 } 2445 2446 int 2447 set_ref_in_lua(int copyID) 2448 { 2449 int aborted = 0; 2450 2451 if (lua_isopen()) 2452 { 2453 luaV_getfield(L, LUAVIM_SETREF); 2454 // call the function with 1 arg, getting 1 result back 2455 lua_pushinteger(L, copyID); 2456 lua_call(L, 1, 1); 2457 // get the result 2458 aborted = lua_tointeger(L, -1); 2459 // pop result off the stack 2460 lua_pop(L, 1); 2461 } 2462 return aborted; 2463 } 2464 2465 void 2466 update_package_paths_in_lua() 2467 { 2468 if (lua_isopen()) 2469 { 2470 lua_getglobal(L, "vim"); 2471 lua_getfield(L, -1, "_update_package_paths"); 2472 2473 if (lua_pcall(L, 0, 0, 0)) 2474 luaV_emsg(L); 2475 } 2476 } 2477 2478 /* 2479 * Native C function callback 2480 */ 2481 static int 2482 luaV_call_lua_func( 2483 int argcount, 2484 typval_T *argvars, 2485 typval_T *rettv, 2486 void *state) 2487 { 2488 int i; 2489 int luaargcount = argcount; 2490 luaV_CFuncState *funcstate = (luaV_CFuncState*)state; 2491 lua_rawgeti(funcstate->L, LUA_REGISTRYINDEX, funcstate->lua_funcref); 2492 2493 if (funcstate->lua_tableref != LUA_NOREF) 2494 { 2495 // First arg for metatable __call method is a table 2496 luaargcount += 1; 2497 lua_rawgeti(funcstate->L, LUA_REGISTRYINDEX, funcstate->lua_tableref); 2498 } 2499 2500 for (i = 0; i < argcount; ++i) 2501 luaV_pushtypval(funcstate->L, &argvars[i]); 2502 2503 if (lua_pcall(funcstate->L, luaargcount, 1, 0)) 2504 { 2505 luaV_emsg(funcstate->L); 2506 return FCERR_OTHER; 2507 } 2508 2509 luaV_checktypval(funcstate->L, -1, rettv, "get return value"); 2510 return FCERR_NONE; 2511 } 2512 2513 /* 2514 * Free up any lua references held by the func state. 2515 */ 2516 static void 2517 luaV_call_lua_func_free(void *state) 2518 { 2519 luaV_CFuncState *funcstate = (luaV_CFuncState*)state; 2520 luaL_unref(L, LUA_REGISTRYINDEX, funcstate->lua_funcref); 2521 funcstate->L = NULL; 2522 if (funcstate->lua_tableref != LUA_NOREF) 2523 luaL_unref(L, LUA_REGISTRYINDEX, funcstate->lua_tableref); 2524 VIM_CLEAR(funcstate); 2525 } 2526 2527 #endif 2528