summaryrefslogtreecommitdiffstats
path: root/source/ap/vim/patches/7.3.490
diff options
context:
space:
mode:
author Patrick J Volkerding <volkerdi@slackware.com>2012-09-26 01:10:42 +0000
committer Eric Hameleers <alien@slackware.com>2018-05-31 22:51:55 +0200
commit9664bee729d487bcc0a0bc35859f8e13d5421c75 (patch)
treeb428a16618e36ed864a8d76ea3435e19a452bf90 /source/ap/vim/patches/7.3.490
parent75a4a592e5ccda30715f93563d741b83e0dcf39e (diff)
downloadcurrent-9664bee729d487bcc0a0bc35859f8e13d5421c75.tar.gz
current-9664bee729d487bcc0a0bc35859f8e13d5421c75.tar.xz
Slackware 14.0slackware-14.0
Wed Sep 26 01:10:42 UTC 2012 Slackware 14.0 x86_64 stable is released! We're perfectionists here at Slackware, so this release has been a long time a-brewing. But we think you'll agree that it was worth the wait. Slackware 14.0 combines modern components, ease of use, and flexible configuration... our "KISS" philosophy demands it. The ISOs are off to be replicated, a 6 CD-ROM 32-bit set and a dual-sided 32-bit/64-bit x86/x86_64 DVD. Please consider supporting the Slackware project by picking up a copy from store.slackware.com. We're taking pre-orders now, and offer a discount if you sign up for a subscription. Thanks to everyone who helped make this happen. The Slackware team, the upstream developers, and (of course) the awesome Slackware user community. Have fun! :-)
Diffstat (limited to 'source/ap/vim/patches/7.3.490')
-rw-r--r--source/ap/vim/patches/7.3.4902517
1 files changed, 2517 insertions, 0 deletions
diff --git a/source/ap/vim/patches/7.3.490 b/source/ap/vim/patches/7.3.490
new file mode 100644
index 000000000..6c49a48d5
--- /dev/null
+++ b/source/ap/vim/patches/7.3.490
@@ -0,0 +1,2517 @@
+To: vim_dev@googlegroups.com
+Subject: Patch 7.3.490
+Fcc: outbox
+From: Bram Moolenaar <Bram@moolenaar.net>
+Mime-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+------------
+
+Patch 7.3.490
+Problem: Member confusion in Lua interface.
+Solution: Fix it. Add luaeval(). (Taro Muraoka, Luis Carvalho)
+Files: runtime/doc/if_lua.txt, src/eval.c, src/if_lua.c,
+ src/proto/if_lua.pro
+
+
+*** ../vim-7.3.489/runtime/doc/if_lua.txt 2010-08-15 21:57:14.000000000 +0200
+--- runtime/doc/if_lua.txt 2012-04-05 16:41:35.000000000 +0200
+***************
+*** 1,4 ****
+! *if_lua.txt* For Vim version 7.3. Last change: 2010 Jul 22
+
+
+ VIM REFERENCE MANUAL by Luis Carvalho
+--- 1,4 ----
+! *if_lua.txt* For Vim version 7.3. Last change: 2012 Jan 16
+
+
+ VIM REFERENCE MANUAL by Luis Carvalho
+***************
+*** 8,15 ****
+
+ 1. Commands |lua-commands|
+ 2. The vim module |lua-vim|
+! 3. Buffer userdata |lua-buffer|
+! 4. Window userdata |lua-window|
+
+ {Vi does not have any of these commands}
+
+--- 8,18 ----
+
+ 1. Commands |lua-commands|
+ 2. The vim module |lua-vim|
+! 3. List userdata |lua-list|
+! 4. Dict userdata |lua-dict|
+! 5. Buffer userdata |lua-buffer|
+! 6. Window userdata |lua-window|
+! 7. The luaeval function |lua-luaeval|
+
+ {Vi does not have any of these commands}
+
+***************
+*** 88,98 ****
+ All these commands execute a Lua chunk from either the command line (:lua and
+ :luado) or a file (:luafile) with the given line [range]. Similarly to the Lua
+ interpreter, each chunk has its own scope and so only global variables are
+! shared between command calls. Lua default libraries "table", "string", "math",
+! and "package" are available, "io" and "debug" are not, and "os" is restricted
+! to functions "date", "clock", "time", "difftime", and "getenv". In addition,
+! Lua "print" function has its output redirected to the Vim message area, with
+! arguments separated by a white space instead of a tab.
+
+ Lua uses the "vim" module (see |lua-vim|) to issue commands to Vim
+ and manage buffers (|lua-buffer|) and windows (|lua-window|). However,
+--- 91,99 ----
+ All these commands execute a Lua chunk from either the command line (:lua and
+ :luado) or a file (:luafile) with the given line [range]. Similarly to the Lua
+ interpreter, each chunk has its own scope and so only global variables are
+! shared between command calls. All Lua default libraries are available. In
+! addition, Lua "print" function has its output redirected to the Vim message
+! area, with arguments separated by a white space instead of a tab.
+
+ Lua uses the "vim" module (see |lua-vim|) to issue commands to Vim
+ and manage buffers (|lua-buffer|) and windows (|lua-window|). However,
+***************
+*** 108,116 ****
+ module also includes routines for buffer, window, and current line queries,
+ Vim evaluation and command execution, and others.
+
+! vim.isbuffer(value) Returns 'true' (boolean, not string) if
+! "value" is a buffer userdata and 'false'
+! otherwise (see |lua-buffer|).
+
+ vim.buffer([arg]) If "arg" is a number, returns buffer with
+ number "arg" in the buffer list or, if "arg"
+--- 109,117 ----
+ module also includes routines for buffer, window, and current line queries,
+ Vim evaluation and command execution, and others.
+
+! vim.list() Returns an empty list (see |List|).
+!
+! vim.dict() Returns an empty dictionary (see |Dictionary|).
+
+ vim.buffer([arg]) If "arg" is a number, returns buffer with
+ number "arg" in the buffer list or, if "arg"
+***************
+*** 121,136 ****
+ 'true' returns the first buffer in the buffer
+ list or else the current buffer.
+
+- vim.iswindow(value) Returns 'true' (boolean, not string) if
+- "value" is a window userdata and
+- 'false' otherwise (see |lua-window|).
+-
+ vim.window([arg]) If "arg" is a number, returns window with
+ number "arg" or 'nil' (nil value, not string)
+ if not found. Otherwise, if "toboolean(arg)"
+ is 'true' returns the first window or else the
+ current window.
+
+ vim.command({cmd}) Executes the vim (ex-mode) command {cmd}.
+ Examples: >
+ :lua vim.command"set tw=60"
+--- 122,142 ----
+ 'true' returns the first buffer in the buffer
+ list or else the current buffer.
+
+ vim.window([arg]) If "arg" is a number, returns window with
+ number "arg" or 'nil' (nil value, not string)
+ if not found. Otherwise, if "toboolean(arg)"
+ is 'true' returns the first window or else the
+ current window.
+
++ vim.type({arg}) Returns the type of {arg}. It is equivalent to
++ Lua's "type" function, but returns "list",
++ "dict", "buffer", or "window" if {arg} is a
++ list, dictionary, buffer, or window,
++ respectively. Examples: >
++ :lua l = vim.list()
++ :lua print(type(l), vim.type(l))
++ :" userdata list
++ <
+ vim.command({cmd}) Executes the vim (ex-mode) command {cmd}.
+ Examples: >
+ :lua vim.command"set tw=60"
+***************
+*** 141,147 ****
+ Vim strings and numbers are directly converted
+ to Lua strings and numbers respectively. Vim
+ lists and dictionaries are converted to Lua
+! tables (lists become integer-keyed tables).
+ Examples: >
+ :lua tw = vim.eval"&tw"
+ :lua print(vim.eval"{'a': 'one'}".a)
+--- 147,153 ----
+ Vim strings and numbers are directly converted
+ to Lua strings and numbers respectively. Vim
+ lists and dictionaries are converted to Lua
+! userdata (see |lua-list| and |lua-dict|).
+ Examples: >
+ :lua tw = vim.eval"&tw"
+ :lua print(vim.eval"{'a': 'one'}".a)
+***************
+*** 157,163 ****
+
+
+ ==============================================================================
+! 3. Buffer userdata *lua-buffer*
+
+ Buffer userdata represent vim buffers. A buffer userdata "b" has the following
+ properties and methods:
+--- 163,234 ----
+
+
+ ==============================================================================
+! 3. List userdata *lua-list*
+!
+! List userdata represent vim lists, and the interface tries to follow closely
+! Vim's syntax for lists. Since lists are objects, changes in list references in
+! Lua are reflected in Vim and vice-versa. A list "l" has the following
+! properties and methods:
+!
+! Properties
+! ----------
+! o "#l" is the number of items in list "l", equivalent to "len(l)"
+! in Vim.
+! o "l[k]" returns the k-th item in "l"; "l" is zero-indexed, as in Vim.
+! To modify the k-th item, simply do "l[k] = newitem"; in
+! particular, "l[k] = nil" removes the k-th item from "l".
+! o "l()" returns an iterator for "l".
+!
+! Methods
+! -------
+! o "l:add(item)" appends "item" to the end of "l".
+! o "l:insert(item[, pos])" inserts "item" at (optional)
+! position "pos" in the list. The default value for "pos" is 0.
+!
+! Examples:
+! >
+! :let l = [1, 'item']
+! :lua l = vim.eval('l') -- same 'l'
+! :lua l:add(vim.list())
+! :lua l[0] = math.pi
+! :echo l[0] " 3.141593
+! :lua l[0] = nil -- remove first item
+! :lua l:insert(true, 1)
+! :lua print(l, #l, l[0], l[1], l[-1])
+! :lua for item in l() do print(item) end
+! <
+!
+! ==============================================================================
+! 4. Dict userdata *lua-dict*
+!
+! Similarly to list userdata, dict userdata represent vim dictionaries; since
+! dictionaries are also objects, references are kept between Lua and Vim. A dict
+! "d" has the following properties:
+!
+! Properties
+! ----------
+! o "#d" is the number of items in dict "d", equivalent to "len(d)"
+! in Vim.
+! o "d.key" or "d['key']" returns the value at entry "key" in "d".
+! To modify the entry at this key, simply do "d.key = newvalue"; in
+! particular, "d.key = nil" removes the entry from "d".
+! o "d()" returns an iterator for "d" and is equivalent to "items(d)" in
+! Vim.
+!
+! Examples:
+! >
+! :let d = {'n':10}
+! :lua d = vim.eval('d') -- same 'd'
+! :lua print(d, d.n, #d)
+! :let d.self = d
+! :lua for k, v in d() do print(d, k, v) end
+! :lua d.x = math.pi
+! :lua d.self = nil -- remove entry
+! :echo d
+! <
+!
+! ==============================================================================
+! 5. Buffer userdata *lua-buffer*
+
+ Buffer userdata represent vim buffers. A buffer userdata "b" has the following
+ properties and methods:
+***************
+*** 209,215 ****
+ <
+
+ ==============================================================================
+! 4. Window userdata *lua-window*
+
+ Window objects represent vim windows. A window userdata "w" has the following
+ properties and methods:
+--- 280,286 ----
+ <
+
+ ==============================================================================
+! 6. Window userdata *lua-window*
+
+ Window objects represent vim windows. A window userdata "w" has the following
+ properties and methods:
+***************
+*** 241,244 ****
+ <
+
+ ==============================================================================
+! vim:tw=78:ts=8:ft=help:norl:
+--- 312,340 ----
+ <
+
+ ==============================================================================
+! 7. The luaeval function *lua-luaeval*
+!
+! The (dual) equivalent of "vim.eval" for passing Lua values to Vim is
+! "luaeval". "luaeval" takes an expression string and an optional argument and
+! returns the result of the expression. It is semantically equivalent in Lua to:
+! >
+! local chunkheader = "local _A = select(1, ...) return "
+! function luaeval (expstr, arg)
+! local chunk = assert(loadstring(chunkheader .. expstr, "luaeval"))
+! return chunk(arg) -- return typval
+! end
+! <
+! Note that "_A" receives the argument to "luaeval". Examples: >
+!
+! :echo luaeval('math.pi')
+! :lua a = vim.list():add('newlist')
+! :let a = luaeval('a')
+! :echo a[0] " 'newlist'
+! :function Rand(x,y) " random uniform between x and y
+! : return luaeval('(_A.y-_A.x)*math.random()+_A.x', {'x':a:x,'y':a:y})
+! : endfunction
+! :echo Rand(1,10)
+!
+!
+! ==============================================================================
+! vim:tw=78:ts=8:noet:ft=help:norl:
+*** ../vim-7.3.489/src/eval.c 2012-03-28 16:49:25.000000000 +0200
+--- src/eval.c 2012-04-05 16:41:35.000000000 +0200
+***************
+*** 622,627 ****
+--- 622,630 ----
+ static void f_log __ARGS((typval_T *argvars, typval_T *rettv));
+ static void f_log10 __ARGS((typval_T *argvars, typval_T *rettv));
+ #endif
++ #ifdef FEAT_LUA
++ static void f_luaeval __ARGS((typval_T *argvars, typval_T *rettv));
++ #endif
+ static void f_map __ARGS((typval_T *argvars, typval_T *rettv));
+ static void f_maparg __ARGS((typval_T *argvars, typval_T *rettv));
+ static void f_mapcheck __ARGS((typval_T *argvars, typval_T *rettv));
+***************
+*** 6777,6782 ****
+--- 6780,6789 ----
+ /* v: vars */
+ set_ref_in_ht(&vimvarht, copyID);
+
++ #ifdef FEAT_LUA
++ set_ref_in_lua(copyID);
++ #endif
++
+ /*
+ * 2. Free lists and dictionaries that are not referenced.
+ */
+***************
+*** 7946,7951 ****
+--- 7953,7961 ----
+ {"log", 1, 1, f_log},
+ {"log10", 1, 1, f_log10},
+ #endif
++ #ifdef FEAT_LUA
++ {"luaeval", 1, 2, f_luaeval},
++ #endif
+ {"map", 2, 2, f_map},
+ {"maparg", 1, 4, f_maparg},
+ {"mapcheck", 1, 3, f_mapcheck},
+***************
+*** 13626,13631 ****
+--- 13636,13658 ----
+ }
+ #endif
+
++ #ifdef FEAT_LUA
++ /*
++ * "luaeval()" function
++ */
++ static void
++ f_luaeval(argvars, rettv)
++ typval_T *argvars;
++ typval_T *rettv;
++ {
++ char_u *str;
++ char_u buf[NUMBUFLEN];
++
++ str = get_tv_string_buf(&argvars[0], buf);
++ do_luaeval(str, argvars + 1, rettv);
++ }
++ #endif
++
+ /*
+ * "map()" function
+ */
+*** ../vim-7.3.489/src/if_lua.c 2011-12-08 16:00:12.000000000 +0100
+--- src/if_lua.c 2012-04-05 16:41:35.000000000 +0200
+***************
+*** 1,4 ****
+! /* vi:set ts=8 sts=4 sw=4:
+ *
+ * VIM - Vi IMproved by Bram Moolenaar
+ *
+--- 1,4 ----
+! /* vi:set ts=8 sts=4 sw=4 noet:
+ *
+ * VIM - Vi IMproved by Bram Moolenaar
+ *
+***************
+*** 21,35 ****
+--- 21,53 ----
+
+ #define LUAVIM_CHUNKNAME "vim chunk"
+ #define LUAVIM_NAME "vim"
++ #define LUAVIM_EVALNAME "luaeval"
++ #define LUAVIM_EVALHEADER "local _A=select(1,...) return "
+
+ typedef buf_T *luaV_Buffer;
+ typedef win_T *luaV_Window;
++ typedef dict_T *luaV_Dict;
++ typedef list_T *luaV_List;
+ typedef void (*msgfunc_T)(char_u *);
+
++ static const char LUAVIM_DICT[] = "dict";
++ static const char LUAVIM_LIST[] = "list";
+ static const char LUAVIM_BUFFER[] = "buffer";
+ static const char LUAVIM_WINDOW[] = "window";
+ static const char LUAVIM_FREE[] = "luaV_free";
++ static const char LUAVIM_LUAEVAL[] = "luaV_luaeval";
++ static const char LUAVIM_SETREF[] = "luaV_setref";
+
++ /* most functions are closures with a cache table as first upvalue;
++ * get/setudata manage references to vim userdata in cache table through
++ * object pointers (light userdata) */
++ #define luaV_getudata(L, v) \
++ lua_pushlightuserdata((L), (void *) (v)); \
++ lua_rawget((L), lua_upvalueindex(1))
++ #define luaV_setudata(L, v) \
++ lua_pushlightuserdata((L), (void *) (v)); \
++ lua_pushvalue((L), -2); \
++ lua_rawset((L), lua_upvalueindex(1))
+ #define luaV_getfield(L, s) \
+ lua_pushlightuserdata((L), (void *)(s)); \
+ lua_rawget((L), LUA_REGISTRYINDEX)
+***************
+*** 38,43 ****
+--- 56,70 ----
+ #define luaV_msg(L) luaV_msgfunc((L), (msgfunc_T) msg)
+ #define luaV_emsg(L) luaV_msgfunc((L), (msgfunc_T) emsg)
+
++ static luaV_List *luaV_pushlist (lua_State *L, list_T *lis);
++ static luaV_Dict *luaV_pushdict (lua_State *L, dict_T *dic);
++
++ #if LUA_VERSION_NUM <= 501
++ #define luaV_openlib(L, l, n) luaL_openlib(L, NULL, l, n)
++ #define luaL_typeerror luaL_typerror
++ #else
++ #define luaV_openlib luaL_setfuncs
++ #endif
+
+ #ifdef DYNAMIC_LUA
+
+***************
+*** 54,85 ****
+ #endif
+
+ /* lauxlib */
+ #define luaL_register dll_luaL_register
+ #define luaL_typerror dll_luaL_typerror
+ #define luaL_checklstring dll_luaL_checklstring
+ #define luaL_checkinteger dll_luaL_checkinteger
+ #define luaL_optinteger dll_luaL_optinteger
+ #define luaL_checktype dll_luaL_checktype
+ #define luaL_error dll_luaL_error
+- #define luaL_loadfile dll_luaL_loadfile
+- #define luaL_loadbuffer dll_luaL_loadbuffer
+ #define luaL_newstate dll_luaL_newstate
+ #define luaL_buffinit dll_luaL_buffinit
+- #define luaL_prepbuffer dll_luaL_prepbuffer
+ #define luaL_addlstring dll_luaL_addlstring
+ #define luaL_pushresult dll_luaL_pushresult
+ /* lua */
+ #define lua_close dll_lua_close
+ #define lua_gettop dll_lua_gettop
+ #define lua_settop dll_lua_settop
+ #define lua_pushvalue dll_lua_pushvalue
+ #define lua_replace dll_lua_replace
+ #define lua_isnumber dll_lua_isnumber
+ #define lua_isstring dll_lua_isstring
+ #define lua_type dll_lua_type
+ #define lua_rawequal dll_lua_rawequal
+- #define lua_tonumber dll_lua_tonumber
+- #define lua_tointeger dll_lua_tointeger
+ #define lua_toboolean dll_lua_toboolean
+ #define lua_tolstring dll_lua_tolstring
+ #define lua_touserdata dll_lua_touserdata
+--- 81,134 ----
+ #endif
+
+ /* lauxlib */
++ #if LUA_VERSION_NUM <= 501
+ #define luaL_register dll_luaL_register
++ #define luaL_prepbuffer dll_luaL_prepbuffer
++ #define luaL_openlib dll_luaL_openlib
+ #define luaL_typerror dll_luaL_typerror
++ #define luaL_loadfile dll_luaL_loadfile
++ #define luaL_loadbuffer dll_luaL_loadbuffer
++ #else
++ #define luaL_prepbuffsize dll_luaL_prepbuffsize
++ #define luaL_setfuncs dll_luaL_setfuncs
++ #define luaL_loadfilex dll_luaL_loadfilex
++ #define luaL_loadbufferx dll_luaL_loadbufferx
++ #define luaL_argerror dll_luaL_argerror
++ #endif
+ #define luaL_checklstring dll_luaL_checklstring
+ #define luaL_checkinteger dll_luaL_checkinteger
+ #define luaL_optinteger dll_luaL_optinteger
+ #define luaL_checktype dll_luaL_checktype
+ #define luaL_error dll_luaL_error
+ #define luaL_newstate dll_luaL_newstate
+ #define luaL_buffinit dll_luaL_buffinit
+ #define luaL_addlstring dll_luaL_addlstring
+ #define luaL_pushresult dll_luaL_pushresult
+ /* lua */
++ #if LUA_VERSION_NUM <= 501
++ #define lua_tonumber dll_lua_tonumber
++ #define lua_tointeger dll_lua_tointeger
++ #define lua_call dll_lua_call
++ #define lua_pcall dll_lua_pcall
++ #else
++ #define lua_tonumberx dll_lua_tonumberx
++ #define lua_tointegerx dll_lua_tointegerx
++ #define lua_callk dll_lua_callk
++ #define lua_pcallk dll_lua_pcallk
++ #define lua_getglobal dll_lua_getglobal
++ #define lua_setglobal dll_lua_setglobal
++ #define lua_typename dll_lua_typename
++ #endif
+ #define lua_close dll_lua_close
+ #define lua_gettop dll_lua_gettop
+ #define lua_settop dll_lua_settop
+ #define lua_pushvalue dll_lua_pushvalue
+ #define lua_replace dll_lua_replace
++ #define lua_remove dll_lua_remove
+ #define lua_isnumber dll_lua_isnumber
+ #define lua_isstring dll_lua_isstring
+ #define lua_type dll_lua_type
+ #define lua_rawequal dll_lua_rawequal
+ #define lua_toboolean dll_lua_toboolean
+ #define lua_tolstring dll_lua_tolstring
+ #define lua_touserdata dll_lua_touserdata
+***************
+*** 94,109 ****
+ #define lua_pushlightuserdata dll_lua_pushlightuserdata
+ #define lua_getfield dll_lua_getfield
+ #define lua_rawget dll_lua_rawget
+ #define lua_createtable dll_lua_createtable
+ #define lua_newuserdata dll_lua_newuserdata
+ #define lua_getmetatable dll_lua_getmetatable
+ #define lua_setfield dll_lua_setfield
+ #define lua_rawset dll_lua_rawset
+ #define lua_rawseti dll_lua_rawseti
+- #define lua_remove dll_lua_remove
+ #define lua_setmetatable dll_lua_setmetatable
+- #define lua_call dll_lua_call
+- #define lua_pcall dll_lua_pcall
+ /* libs */
+ #define luaopen_base dll_luaopen_base
+ #define luaopen_table dll_luaopen_table
+--- 143,156 ----
+ #define lua_pushlightuserdata dll_lua_pushlightuserdata
+ #define lua_getfield dll_lua_getfield
+ #define lua_rawget dll_lua_rawget
++ #define lua_rawgeti dll_lua_rawgeti
+ #define lua_createtable dll_lua_createtable
+ #define lua_newuserdata dll_lua_newuserdata
+ #define lua_getmetatable dll_lua_getmetatable
+ #define lua_setfield dll_lua_setfield
+ #define lua_rawset dll_lua_rawset
+ #define lua_rawseti dll_lua_rawseti
+ #define lua_setmetatable dll_lua_setmetatable
+ /* libs */
+ #define luaopen_base dll_luaopen_base
+ #define luaopen_table dll_luaopen_table
+***************
+*** 116,147 ****
+ #define luaL_openlibs dll_luaL_openlibs
+
+ /* lauxlib */
+ void (*dll_luaL_register) (lua_State *L, const char *libname, const luaL_Reg *l);
+ int (*dll_luaL_typerror) (lua_State *L, int narg, const char *tname);
+ const char *(*dll_luaL_checklstring) (lua_State *L, int numArg, size_t *l);
+ lua_Integer (*dll_luaL_checkinteger) (lua_State *L, int numArg);
+ lua_Integer (*dll_luaL_optinteger) (lua_State *L, int nArg, lua_Integer def);
+ void (*dll_luaL_checktype) (lua_State *L, int narg, int t);
+ int (*dll_luaL_error) (lua_State *L, const char *fmt, ...);
+- int (*dll_luaL_loadfile) (lua_State *L, const char *filename);
+- int (*dll_luaL_loadbuffer) (lua_State *L, const char *buff, size_t sz, const char *name);
+ lua_State *(*dll_luaL_newstate) (void);
+ void (*dll_luaL_buffinit) (lua_State *L, luaL_Buffer *B);
+- char *(*dll_luaL_prepbuffer) (luaL_Buffer *B);
+ void (*dll_luaL_addlstring) (luaL_Buffer *B, const char *s, size_t l);
+ void (*dll_luaL_pushresult) (luaL_Buffer *B);
+ /* lua */
+ void (*dll_lua_close) (lua_State *L);
+ int (*dll_lua_gettop) (lua_State *L);
+ void (*dll_lua_settop) (lua_State *L, int idx);
+ void (*dll_lua_pushvalue) (lua_State *L, int idx);
+ void (*dll_lua_replace) (lua_State *L, int idx);
+ int (*dll_lua_isnumber) (lua_State *L, int idx);
+ int (*dll_lua_isstring) (lua_State *L, int idx);
+ int (*dll_lua_type) (lua_State *L, int idx);
+ int (*dll_lua_rawequal) (lua_State *L, int idx1, int idx2);
+- lua_Number (*dll_lua_tonumber) (lua_State *L, int idx);
+- lua_Integer (*dll_lua_tointeger) (lua_State *L, int idx);
+ int (*dll_lua_toboolean) (lua_State *L, int idx);
+ const char *(*dll_lua_tolstring) (lua_State *L, int idx, size_t *len);
+ void *(*dll_lua_touserdata) (lua_State *L, int idx);
+--- 163,218 ----
+ #define luaL_openlibs dll_luaL_openlibs
+
+ /* lauxlib */
++ #if LUA_VERSION_NUM <= 501
+ void (*dll_luaL_register) (lua_State *L, const char *libname, const luaL_Reg *l);
++ char *(*dll_luaL_prepbuffer) (luaL_Buffer *B);
++ void (*dll_luaL_openlib) (lua_State *L, const char *libname, const luaL_Reg *l, int nup);
+ int (*dll_luaL_typerror) (lua_State *L, int narg, const char *tname);
++ int (*dll_luaL_loadfile) (lua_State *L, const char *filename);
++ int (*dll_luaL_loadbuffer) (lua_State *L, const char *buff, size_t sz, const char *name);
++ #else
++ char *(*dll_luaL_prepbuffsize) (luaL_Buffer *B, size_t sz);
++ void (*dll_luaL_setfuncs) (lua_State *L, const luaL_Reg *l, int nup);
++ int (*dll_luaL_loadfilex) (lua_State *L, const char *filename, const char *mode);
++ int (*dll_luaL_loadbufferx) (lua_State *L, const char *buff, size_t sz, const char *name, const char *mode);
++ int (*dll_luaL_argerror) (lua_State *L, int numarg, const char *extramsg);
++ #endif
+ const char *(*dll_luaL_checklstring) (lua_State *L, int numArg, size_t *l);
+ lua_Integer (*dll_luaL_checkinteger) (lua_State *L, int numArg);
+ lua_Integer (*dll_luaL_optinteger) (lua_State *L, int nArg, lua_Integer def);
+ void (*dll_luaL_checktype) (lua_State *L, int narg, int t);
+ int (*dll_luaL_error) (lua_State *L, const char *fmt, ...);
+ lua_State *(*dll_luaL_newstate) (void);
+ void (*dll_luaL_buffinit) (lua_State *L, luaL_Buffer *B);
+ void (*dll_luaL_addlstring) (luaL_Buffer *B, const char *s, size_t l);
+ void (*dll_luaL_pushresult) (luaL_Buffer *B);
+ /* lua */
++ #if LUA_VERSION_NUM <= 501
++ lua_Number (*dll_lua_tonumber) (lua_State *L, int idx);
++ lua_Integer (*dll_lua_tointeger) (lua_State *L, int idx);
++ void (*dll_lua_call) (lua_State *L, int nargs, int nresults);
++ int (*dll_lua_pcall) (lua_State *L, int nargs, int nresults, int errfunc);
++ #else
++ lua_Number (*dll_lua_tonumberx) (lua_State *L, int idx, int *isnum);
++ lua_Integer (*dll_lua_tointegerx) (lua_State *L, int idx, int *isnum);
++ void (*dll_lua_callk) (lua_State *L, int nargs, int nresults, int ctx,
++ lua_CFunction k);
++ int (*dll_lua_pcallk) (lua_State *L, int nargs, int nresults, int errfunc,
++ int ctx, lua_CFunction k);
++ void (*dll_lua_getglobal) (lua_State *L, const char *var);
++ void (*dll_lua_setglobal) (lua_State *L, const char *var);
++ const char *(*dll_lua_typename) (lua_State *L, int tp);
++ #endif
+ void (*dll_lua_close) (lua_State *L);
+ int (*dll_lua_gettop) (lua_State *L);
+ void (*dll_lua_settop) (lua_State *L, int idx);
+ void (*dll_lua_pushvalue) (lua_State *L, int idx);
+ void (*dll_lua_replace) (lua_State *L, int idx);
++ void (*dll_lua_remove) (lua_State *L, int idx);
+ int (*dll_lua_isnumber) (lua_State *L, int idx);
+ int (*dll_lua_isstring) (lua_State *L, int idx);
+ int (*dll_lua_type) (lua_State *L, int idx);
+ int (*dll_lua_rawequal) (lua_State *L, int idx1, int idx2);
+ int (*dll_lua_toboolean) (lua_State *L, int idx);
+ const char *(*dll_lua_tolstring) (lua_State *L, int idx, size_t *len);
+ void *(*dll_lua_touserdata) (lua_State *L, int idx);
+***************
+*** 156,171 ****
+ void (*dll_lua_pushlightuserdata) (lua_State *L, void *p);
+ void (*dll_lua_getfield) (lua_State *L, int idx, const char *k);
+ void (*dll_lua_rawget) (lua_State *L, int idx);
+ void (*dll_lua_createtable) (lua_State *L, int narr, int nrec);
+ void *(*dll_lua_newuserdata) (lua_State *L, size_t sz);
+ int (*dll_lua_getmetatable) (lua_State *L, int objindex);
+ void (*dll_lua_setfield) (lua_State *L, int idx, const char *k);
+ void (*dll_lua_rawset) (lua_State *L, int idx);
+ void (*dll_lua_rawseti) (lua_State *L, int idx, int n);
+- void (*dll_lua_remove) (lua_State *L, int idx);
+ int (*dll_lua_setmetatable) (lua_State *L, int objindex);
+- void (*dll_lua_call) (lua_State *L, int nargs, int nresults);
+- int (*dll_lua_pcall) (lua_State *L, int nargs, int nresults, int errfunc);
+ /* libs */
+ int (*dll_luaopen_base) (lua_State *L);
+ int (*dll_luaopen_table) (lua_State *L);
+--- 227,240 ----
+ void (*dll_lua_pushlightuserdata) (lua_State *L, void *p);
+ void (*dll_lua_getfield) (lua_State *L, int idx, const char *k);
+ void (*dll_lua_rawget) (lua_State *L, int idx);
++ void (*dll_lua_rawgeti) (lua_State *L, int idx, int n);
+ void (*dll_lua_createtable) (lua_State *L, int narr, int nrec);
+ void *(*dll_lua_newuserdata) (lua_State *L, size_t sz);
+ int (*dll_lua_getmetatable) (lua_State *L, int objindex);
+ void (*dll_lua_setfield) (lua_State *L, int idx, const char *k);
+ void (*dll_lua_rawset) (lua_State *L, int idx);
+ void (*dll_lua_rawseti) (lua_State *L, int idx, int n);
+ int (*dll_lua_setmetatable) (lua_State *L, int objindex);
+ /* libs */
+ int (*dll_luaopen_base) (lua_State *L);
+ int (*dll_luaopen_table) (lua_State *L);
+***************
+*** 185,216 ****
+
+ static const luaV_Reg luaV_dll[] = {
+ /* lauxlib */
+ {"luaL_register", (luaV_function) &dll_luaL_register},
+ {"luaL_typerror", (luaV_function) &dll_luaL_typerror},
+ {"luaL_checklstring", (luaV_function) &dll_luaL_checklstring},
+ {"luaL_checkinteger", (luaV_function) &dll_luaL_checkinteger},
+ {"luaL_optinteger", (luaV_function) &dll_luaL_optinteger},
+ {"luaL_checktype", (luaV_function) &dll_luaL_checktype},
+ {"luaL_error", (luaV_function) &dll_luaL_error},
+- {"luaL_loadfile", (luaV_function) &dll_luaL_loadfile},
+- {"luaL_loadbuffer", (luaV_function) &dll_luaL_loadbuffer},
+ {"luaL_newstate", (luaV_function) &dll_luaL_newstate},
+ {"luaL_buffinit", (luaV_function) &dll_luaL_buffinit},
+- {"luaL_prepbuffer", (luaV_function) &dll_luaL_prepbuffer},
+ {"luaL_addlstring", (luaV_function) &dll_luaL_addlstring},
+ {"luaL_pushresult", (luaV_function) &dll_luaL_pushresult},
+ /* lua */
+ {"lua_close", (luaV_function) &dll_lua_close},
+ {"lua_gettop", (luaV_function) &dll_lua_gettop},
+ {"lua_settop", (luaV_function) &dll_lua_settop},
+ {"lua_pushvalue", (luaV_function) &dll_lua_pushvalue},
+ {"lua_replace", (luaV_function) &dll_lua_replace},
+ {"lua_isnumber", (luaV_function) &dll_lua_isnumber},
+ {"lua_isstring", (luaV_function) &dll_lua_isstring},
+ {"lua_type", (luaV_function) &dll_lua_type},
+ {"lua_rawequal", (luaV_function) &dll_lua_rawequal},
+- {"lua_tonumber", (luaV_function) &dll_lua_tonumber},
+- {"lua_tointeger", (luaV_function) &dll_lua_tointeger},
+ {"lua_toboolean", (luaV_function) &dll_lua_toboolean},
+ {"lua_tolstring", (luaV_function) &dll_lua_tolstring},
+ {"lua_touserdata", (luaV_function) &dll_lua_touserdata},
+--- 254,307 ----
+
+ static const luaV_Reg luaV_dll[] = {
+ /* lauxlib */
++ #if LUA_VERSION_NUM <= 501
+ {"luaL_register", (luaV_function) &dll_luaL_register},
++ {"luaL_prepbuffer", (luaV_function) &dll_luaL_prepbuffer},
++ {"luaL_openlib", (luaV_function) &dll_luaL_openlib},
+ {"luaL_typerror", (luaV_function) &dll_luaL_typerror},
++ {"luaL_loadfile", (luaV_function) &dll_luaL_loadfile},
++ {"luaL_loadbuffer", (luaV_function) &dll_luaL_loadbuffer},
++ #else
++ {"luaL_prepbuffsize", (luaV_function) &dll_luaL_prepbuffsize},
++ {"luaL_setfuncs", (luaV_function) &dll_luaL_setfuncs},
++ {"luaL_loadfilex", (luaV_function) &dll_luaL_loadfilex},
++ {"luaL_loadbufferx", (luaV_function) &dll_luaL_loadbufferx},
++ {"luaL_argerror", (luaV_function) &dll_luaL_argerror},
++ #endif
+ {"luaL_checklstring", (luaV_function) &dll_luaL_checklstring},
+ {"luaL_checkinteger", (luaV_function) &dll_luaL_checkinteger},
+ {"luaL_optinteger", (luaV_function) &dll_luaL_optinteger},
+ {"luaL_checktype", (luaV_function) &dll_luaL_checktype},
+ {"luaL_error", (luaV_function) &dll_luaL_error},
+ {"luaL_newstate", (luaV_function) &dll_luaL_newstate},
+ {"luaL_buffinit", (luaV_function) &dll_luaL_buffinit},
+ {"luaL_addlstring", (luaV_function) &dll_luaL_addlstring},
+ {"luaL_pushresult", (luaV_function) &dll_luaL_pushresult},
+ /* lua */
++ #if LUA_VERSION_NUM <= 501
++ {"lua_tonumber", (luaV_function) &dll_lua_tonumber},
++ {"lua_tointeger", (luaV_function) &dll_lua_tointeger},
++ {"lua_call", (luaV_function) &dll_lua_call},
++ {"lua_pcall", (luaV_function) &dll_lua_pcall},
++ #else
++ {"lua_tonumberx", (luaV_function) &dll_lua_tonumberx},
++ {"lua_tointegerx", (luaV_function) &dll_lua_tointegerx},
++ {"lua_callk", (luaV_function) &dll_lua_callk},
++ {"lua_pcallk", (luaV_function) &dll_lua_pcallk},
++ {"lua_getglobal", (luaV_function) &dll_lua_getglobal},
++ {"lua_setglobal", (luaV_function) &dll_lua_setglobal},
++ {"lua_typename", (luaV_function) &dll_lua_typename},
++ #endif
+ {"lua_close", (luaV_function) &dll_lua_close},
+ {"lua_gettop", (luaV_function) &dll_lua_gettop},
+ {"lua_settop", (luaV_function) &dll_lua_settop},
+ {"lua_pushvalue", (luaV_function) &dll_lua_pushvalue},
+ {"lua_replace", (luaV_function) &dll_lua_replace},
++ {"lua_remove", (luaV_function) &dll_lua_remove},
+ {"lua_isnumber", (luaV_function) &dll_lua_isnumber},
+ {"lua_isstring", (luaV_function) &dll_lua_isstring},
+ {"lua_type", (luaV_function) &dll_lua_type},
+ {"lua_rawequal", (luaV_function) &dll_lua_rawequal},
+ {"lua_toboolean", (luaV_function) &dll_lua_toboolean},
+ {"lua_tolstring", (luaV_function) &dll_lua_tolstring},
+ {"lua_touserdata", (luaV_function) &dll_lua_touserdata},
+***************
+*** 225,240 ****
+ {"lua_pushlightuserdata", (luaV_function) &dll_lua_pushlightuserdata},
+ {"lua_getfield", (luaV_function) &dll_lua_getfield},
+ {"lua_rawget", (luaV_function) &dll_lua_rawget},
+ {"lua_createtable", (luaV_function) &dll_lua_createtable},
+ {"lua_newuserdata", (luaV_function) &dll_lua_newuserdata},
+ {"lua_getmetatable", (luaV_function) &dll_lua_getmetatable},
+ {"lua_setfield", (luaV_function) &dll_lua_setfield},
+ {"lua_rawset", (luaV_function) &dll_lua_rawset},
+ {"lua_rawseti", (luaV_function) &dll_lua_rawseti},
+- {"lua_remove", (luaV_function) &dll_lua_remove},
+ {"lua_setmetatable", (luaV_function) &dll_lua_setmetatable},
+- {"lua_call", (luaV_function) &dll_lua_call},
+- {"lua_pcall", (luaV_function) &dll_lua_pcall},
+ /* libs */
+ {"luaopen_base", (luaV_function) &dll_luaopen_base},
+ {"luaopen_table", (luaV_function) &dll_luaopen_table},
+--- 316,329 ----
+ {"lua_pushlightuserdata", (luaV_function) &dll_lua_pushlightuserdata},
+ {"lua_getfield", (luaV_function) &dll_lua_getfield},
+ {"lua_rawget", (luaV_function) &dll_lua_rawget},
++ {"lua_rawgeti", (luaV_function) &dll_lua_rawgeti},
+ {"lua_createtable", (luaV_function) &dll_lua_createtable},
+ {"lua_newuserdata", (luaV_function) &dll_lua_newuserdata},
+ {"lua_getmetatable", (luaV_function) &dll_lua_getmetatable},
+ {"lua_setfield", (luaV_function) &dll_lua_setfield},
+ {"lua_rawset", (luaV_function) &dll_lua_rawset},
+ {"lua_rawseti", (luaV_function) &dll_lua_rawseti},
+ {"lua_setmetatable", (luaV_function) &dll_lua_setmetatable},
+ /* libs */
+ {"luaopen_base", (luaV_function) &dll_luaopen_base},
+ {"luaopen_table", (luaV_function) &dll_luaopen_table},
+***************
+*** 294,299 ****
+--- 383,398 ----
+
+ #endif /* DYNAMIC_LUA */
+
++ #if LUA_VERSION_NUM > 501
++ static int
++ luaL_typeerror (lua_State *L, int narg, const char *tname)
++ {
++ const char *msg = lua_pushfstring(L, "%s expected, got %s",
++ tname, luaL_typename(L, narg));
++ return luaL_argerror(L, narg, msg);
++ }
++ #endif
++
+
+ /* ======= Internal ======= */
+
+***************
+*** 327,343 ****
+ }
+
+ static void *
+ luaV_checkudata(lua_State *L, int ud, const char *tname)
+ {
+ void *p = luaV_toudata(L, ud, tname);
+! if (p == NULL) luaL_typerror(L, ud, tname);
+ return p;
+ }
+
+ static void
+ luaV_pushtypval(lua_State *L, typval_T *tv)
+ {
+! if (tv == NULL) luaL_error(L, "null type");
+ switch (tv->v_type)
+ {
+ case VAR_STRING:
+--- 426,460 ----
+ }
+
+ static void *
++ luaV_checkcache(lua_State *L, void *p)
++ {
++ luaV_getudata(L, p);
++ if (lua_isnil(L, -1)) luaL_error(L, "invalid object");
++ lua_pop(L, 1);
++ return p;
++ }
++
++ #define luaV_unbox(L,luatyp,ud) (*((luatyp *) lua_touserdata((L),(ud))))
++
++ #define luaV_checkvalid(L,luatyp,ud) \
++ luaV_checkcache((L), (void *) luaV_unbox((L),luatyp,(ud)))
++
++ static void *
+ luaV_checkudata(lua_State *L, int ud, const char *tname)
+ {
+ void *p = luaV_toudata(L, ud, tname);
+! if (p == NULL) luaL_typeerror(L, ud, tname);
+ return p;
+ }
+
+ static void
+ luaV_pushtypval(lua_State *L, typval_T *tv)
+ {
+! if (tv == NULL)
+! {
+! lua_pushnil(L);
+! return;
+! }
+ switch (tv->v_type)
+ {
+ case VAR_STRING:
+***************
+*** 351,418 ****
+ lua_pushnumber(L, (lua_Number) tv->vval.v_float);
+ break;
+ #endif
+! case VAR_LIST: {
+! list_T *l = tv->vval.v_list;
+
+! if (l != NULL)
+ {
+! /* check cache */
+! lua_pushlightuserdata(L, (void *) l);
+! lua_rawget(L, LUA_ENVIRONINDEX);
+! if (lua_isnil(L, -1)) /* not interned? */
+ {
+! listitem_T *li;
+! int n = 0;
+! lua_pop(L, 1); /* nil */
+! lua_newtable(L);
+! lua_pushlightuserdata(L, (void *) l);
+! lua_pushvalue(L, -2);
+! lua_rawset(L, LUA_ENVIRONINDEX);
+! for (li = l->lv_first; li != NULL; li = li->li_next)
+! {
+! luaV_pushtypval(L, &li->li_tv);
+! lua_rawseti(L, -2, ++n);
+! }
+ }
+! }
+! else lua_pushnil(L);
+! break;
+! }
+! case VAR_DICT: {
+! dict_T *d = tv->vval.v_dict;
+!
+! if (d != NULL)
+! {
+! /* check cache */
+! lua_pushlightuserdata(L, (void *) d);
+! lua_rawget(L, LUA_ENVIRONINDEX);
+! if (lua_isnil(L, -1)) /* not interned? */
+ {
+! hashtab_T *ht = &d->dv_hashtab;
+! hashitem_T *hi;
+! int n = ht->ht_used; /* remaining items */
+! lua_pop(L, 1); /* nil */
+! lua_newtable(L);
+! lua_pushlightuserdata(L, (void *) d);
+! lua_pushvalue(L, -2);
+! lua_rawset(L, LUA_ENVIRONINDEX);
+! for (hi = ht->ht_array; n > 0; hi++)
+! {
+! if (!HASHITEM_EMPTY(hi))
+! {
+! dictitem_T *di = dict_lookup(hi);
+! luaV_pushtypval(L, &di->di_tv);
+! lua_setfield(L, -2, (char *) hi->hi_key);
+! n--;
+! }
+! }
+ }
+ }
+- else lua_pushnil(L);
+ break;
+ }
+ default:
+! luaL_error(L, "invalid type");
+ }
+ }
+
+--- 468,537 ----
+ lua_pushnumber(L, (lua_Number) tv->vval.v_float);
+ break;
+ #endif
+! case VAR_LIST:
+! luaV_pushlist(L, tv->vval.v_list);
+! break;
+! case VAR_DICT:
+! luaV_pushdict(L, tv->vval.v_dict);
+! break;
+! default:
+! lua_pushnil(L);
+! }
+! }
+
+! /* converts lua value at 'pos' to typval 'tv' */
+! static void
+! luaV_totypval (lua_State *L, int pos, typval_T *tv)
+! {
+! switch(lua_type(L, pos)) {
+! case LUA_TBOOLEAN:
+! tv->v_type = VAR_NUMBER;
+! tv->vval.v_number = (varnumber_T) lua_toboolean(L, pos);
+! break;
+! case LUA_TSTRING:
+! tv->v_type = VAR_STRING;
+! tv->vval.v_string = vim_strsave((char_u *) lua_tostring(L, pos));
+! break;
+! case LUA_TNUMBER:
+! #ifdef FEAT_FLOAT
+! tv->v_type = VAR_FLOAT;
+! tv->vval.v_float = (float_T) lua_tonumber(L, pos);
+! #else
+! tv->v_type = VAR_NUMBER;
+! tv->vval.v_number = (varnumber_T) lua_tointeger(L, pos);
+! #endif
+! break;
+! case LUA_TUSERDATA: {
+! void *p = lua_touserdata(L, pos);
+! if (lua_getmetatable(L, pos)) /* has metatable? */
+ {
+! /* check list */
+! luaV_getfield(L, LUAVIM_LIST);
+! if (lua_rawequal(L, -1, -2))
+ {
+! tv->v_type = VAR_LIST;
+! tv->vval.v_list = *((luaV_List *) p);
+! ++tv->vval.v_list->lv_refcount;
+! lua_pop(L, 2); /* MTs */
+! return;
+ }
+! /* check dict */
+! luaV_getfield(L, LUAVIM_DICT);
+! if (lua_rawequal(L, -1, -3))
+ {
+! tv->v_type = VAR_DICT;
+! tv->vval.v_dict = *((luaV_Dict *) p);
+! ++tv->vval.v_dict->dv_refcount;
+! lua_pop(L, 3); /* MTs */
+! return;
+ }
++ lua_pop(L, 3); /* MTs */
+ }
+ break;
+ }
+ default:
+! tv->v_type = VAR_NUMBER;
+! tv->vval.v_number = 0;
+ }
+ }
+
+***************
+*** 481,569 ****
+ lua_pop(L, 2); /* original and modified strings */
+ }
+
+
+! /* ======= Buffer type ======= */
+
+! static luaV_Buffer *
+! luaV_newbuffer(lua_State *L, buf_T *buf)
+ {
+! luaV_Buffer *b = (luaV_Buffer *) lua_newuserdata(L, sizeof(luaV_Buffer));
+! *b = buf;
+! lua_pushlightuserdata(L, (void *) buf);
+! lua_pushvalue(L, -2);
+! lua_rawset(L, LUA_ENVIRONINDEX); /* env[buf] = udata */
+! /* to avoid GC, store as key in env */
+! lua_pushvalue(L, -1);
+! lua_pushboolean(L, 1);
+! lua_rawset(L, LUA_ENVIRONINDEX); /* env[udata] = true */
+! /* set metatable */
+! luaV_getfield(L, LUAVIM_BUFFER);
+ lua_setmetatable(L, -2);
+! return b;
+ }
+
+! static luaV_Buffer *
+! luaV_pushbuffer (lua_State *L, buf_T *buf)
+ {
+! luaV_Buffer *b = NULL;
+! if (buf == NULL)
+! lua_pushnil(L);
+! else {
+! lua_pushlightuserdata(L, (void *) buf);
+! lua_rawget(L, LUA_ENVIRONINDEX);
+! if (lua_isnil(L, -1)) /* not interned? */
+ {
+! lua_pop(L, 1);
+! b = luaV_newbuffer(L, buf);
+ }
+ else
+! b = (luaV_Buffer *) lua_touserdata(L, -1);
+ }
+! return b;
+ }
+
+! /* Buffer metamethods */
+
+ static int
+! luaV_buffer_tostring(lua_State *L)
+ {
+! lua_pushfstring(L, "%s: %p", LUAVIM_BUFFER, lua_touserdata(L, 1));
+ return 1;
+ }
+
+ static int
+ luaV_buffer_len(lua_State *L)
+ {
+! luaV_Buffer *b = lua_touserdata(L, 1);
+! lua_pushinteger(L, (*b)->b_ml.ml_line_count);
+ return 1;
+ }
+
+ static int
+ luaV_buffer_call(lua_State *L)
+ {
+! luaV_Buffer *b = (luaV_Buffer *) lua_touserdata(L, 1);
+ lua_settop(L, 1);
+! set_curbuf(*b, DOBUF_SPLIT);
+ return 1;
+ }
+
+ static int
+ luaV_buffer_index(lua_State *L)
+ {
+! luaV_Buffer *b = (luaV_Buffer *) lua_touserdata(L, 1);
+ linenr_T n = (linenr_T) lua_tointeger(L, 2);
+! if (n > 0 && n <= (*b)->b_ml.ml_line_count)
+! luaV_pushline(L, *b, n);
+ else if (lua_isstring(L, 2))
+ {
+ const char *s = lua_tostring(L, 2);
+ if (strncmp(s, "name", 4) == 0)
+! lua_pushstring(L, (char *) (*b)->b_sfname);
+ else if (strncmp(s, "fname", 5) == 0)
+! lua_pushstring(L, (char *) (*b)->b_ffname);
+ else if (strncmp(s, "number", 6) == 0)
+! lua_pushinteger(L, (*b)->b_fnum);
+ /* methods */
+ else if (strncmp(s, "insert", 6) == 0
+ || strncmp(s, "next", 4) == 0
+--- 600,1107 ----
+ lua_pop(L, 2); /* original and modified strings */
+ }
+
++ #define luaV_newtype(typ,tname,luatyp,luatname) \
++ static luatyp * \
++ luaV_new##tname (lua_State *L, typ *obj) \
++ { \
++ luatyp *o = (luatyp *) lua_newuserdata(L, sizeof(luatyp)); \
++ *o = obj; \
++ luaV_setudata(L, obj); /* cache[obj] = udata */ \
++ luaV_getfield(L, luatname); \
++ lua_setmetatable(L, -2); \
++ return o; \
++ }
++
++ #define luaV_pushtype(typ,tname,luatyp) \
++ static luatyp * \
++ luaV_push##tname (lua_State *L, typ *obj) \
++ { \
++ luatyp *o = NULL; \
++ if (obj == NULL) \
++ lua_pushnil(L); \
++ else { \
++ luaV_getudata(L, obj); \
++ if (lua_isnil(L, -1)) /* not interned? */ \
++ { \
++ lua_pop(L, 1); \
++ o = luaV_new##tname(L, obj); \
++ } \
++ else \
++ o = (luatyp *) lua_touserdata(L, -1); \
++ } \
++ return o; \
++ }
++
++ #define luaV_type_tostring(tname,luatname) \
++ static int \
++ luaV_##tname##_tostring (lua_State *L) \
++ { \
++ lua_pushfstring(L, "%s: %p", luatname, lua_touserdata(L, 1)); \
++ return 1; \
++ }
++
+
+! /* adapted from eval.c */
+!
+! #define listitem_alloc() (listitem_T *)alloc(sizeof(listitem_T))
+!
+! static listitem_T *
+! list_find (list_T *l, long n)
+! {
+! listitem_T *li;
+! if (l == NULL || n < -l->lv_len || n >= l->lv_len)
+! return NULL;
+! if (n < 0) /* search backward? */
+! for (li = l->lv_last; n < -1; li = li->li_prev)
+! n++;
+! else /* search forward */
+! for (li = l->lv_first; n > 0; li = li->li_next)
+! n--;
+! return li;
+! }
+
+! static void
+! list_remove (list_T *l, listitem_T *li)
+ {
+! listwatch_T *lw;
+! --l->lv_len;
+! /* fix watchers */
+! for (lw = l->lv_watch; lw != NULL; lw = lw->lw_next)
+! if (lw->lw_item == li)
+! lw->lw_item = li->li_next;
+! /* fix list pointers */
+! if (li->li_next == NULL) /* last? */
+! l->lv_last = li->li_prev;
+! else
+! li->li_next->li_prev = li->li_prev;
+! if (li->li_prev == NULL) /* first? */
+! l->lv_first = li->li_next;
+! else
+! li->li_prev->li_next = li->li_next;
+! l->lv_idx_item = NULL;
+! }
+!
+! static void
+! list_append(list_T *l, listitem_T *item)
+! {
+! if (l->lv_last == NULL) /* empty list? */
+! l->lv_first = item;
+! else
+! l->lv_last->li_next = item;
+! item->li_prev = l->lv_last;
+! item->li_next = NULL;
+! l->lv_last = item;
+! ++l->lv_len;
+! }
+!
+! static int
+! list_insert_tv(list_T *l, typval_T *tv, listitem_T *item)
+! {
+! listitem_T *ni = listitem_alloc();
+!
+! if (ni == NULL)
+! return FAIL;
+! copy_tv(tv, &ni->li_tv);
+! if (item == NULL)
+! list_append(l, ni);
+! else
+! {
+! ni->li_prev = item->li_prev;
+! ni->li_next = item;
+! if (item->li_prev == NULL)
+! {
+! l->lv_first = ni;
+! ++l->lv_idx;
+! }
+! else
+! {
+! item->li_prev->li_next = ni;
+! l->lv_idx_item = NULL;
+! }
+! item->li_prev = ni;
+! ++l->lv_len;
+! }
+! return OK;
+! }
+!
+! /* set references */
+!
+! static void set_ref_in_tv (typval_T *tv, int copyID);
+!
+! static void
+! set_ref_in_dict(dict_T *d, int copyID)
+! {
+! hashtab_T *ht = &d->dv_hashtab;
+! int n = ht->ht_used;
+! hashitem_T *hi;
+! for (hi = ht->ht_array; n > 0; ++hi)
+! if (!HASHITEM_EMPTY(hi))
+! {
+! dictitem_T *di = dict_lookup(hi);
+! set_ref_in_tv(&di->di_tv, copyID);
+! --n;
+! }
+! }
+!
+! static void
+! set_ref_in_list(list_T *l, int copyID)
+! {
+! listitem_T *li;
+! for (li = l->lv_first; li != NULL; li = li->li_next)
+! set_ref_in_tv(&li->li_tv, copyID);
+! }
+!
+! static void
+! set_ref_in_tv(typval_T *tv, int copyID)
+! {
+! if (tv->v_type == VAR_LIST)
+! {
+! list_T *l = tv->vval.v_list;
+! if (l != NULL && l->lv_copyID != copyID)
+! {
+! l->lv_copyID = copyID;
+! set_ref_in_list(l, copyID);
+! }
+! }
+! else if (tv->v_type == VAR_DICT)
+! {
+! dict_T *d = tv->vval.v_dict;
+! if (d != NULL && d->dv_copyID != copyID)
+! {
+! d->dv_copyID = copyID;
+! set_ref_in_dict(d, copyID);
+! }
+! }
+! }
+!
+!
+! /* ======= List type ======= */
+!
+! static luaV_List *
+! luaV_newlist (lua_State *L, list_T *lis)
+! {
+! luaV_List *l = (luaV_List *) lua_newuserdata(L, sizeof(luaV_List));
+! *l = lis;
+! lis->lv_refcount++; /* reference in Lua */
+! luaV_setudata(L, lis); /* cache[lis] = udata */
+! luaV_getfield(L, LUAVIM_LIST);
+ lua_setmetatable(L, -2);
+! return l;
+ }
+
+! luaV_pushtype(list_T, list, luaV_List)
+! luaV_type_tostring(list, LUAVIM_LIST)
+!
+! static int
+! luaV_list_gc (lua_State *L)
+ {
+! list_unref(luaV_unbox(L, luaV_List, 1));
+! return 0;
+! }
+!
+! static int
+! luaV_list_len (lua_State *L)
+! {
+! list_T *l = luaV_unbox(L, luaV_List, 1);
+! lua_pushinteger(L, (l == NULL) ? 0 : (int) l->lv_len);
+! return 1;
+! }
+!
+! static int
+! luaV_list_iter (lua_State *L)
+! {
+! listitem_T *li = (listitem_T *) lua_touserdata(L, lua_upvalueindex(2));
+! if (li == NULL) return 0;
+! luaV_pushtypval(L, &li->li_tv);
+! lua_pushlightuserdata(L, (void *) li->li_next);
+! lua_replace(L, lua_upvalueindex(2));
+! return 1;
+! }
+!
+! static int
+! luaV_list_call (lua_State *L)
+! {
+! list_T *l = luaV_unbox(L, luaV_List, 1);
+! lua_pushvalue(L, lua_upvalueindex(1)); /* pass cache table along */
+! lua_pushlightuserdata(L, (void *) l->lv_first);
+! lua_pushcclosure(L, luaV_list_iter, 2);
+! return 1;
+! }
+!
+! static int
+! luaV_list_index (lua_State *L)
+! {
+! list_T *l = luaV_unbox(L, luaV_List, 1);
+! if (lua_isnumber(L, 2)) /* list item? */
+! {
+! listitem_T *li = list_find(l, (long) luaL_checkinteger(L, 2));
+! if (li == NULL)
+! lua_pushnil(L);
+! else
+! luaV_pushtypval(L, &li->li_tv);
+! }
+! else if (lua_isstring(L, 2)) /* method? */
+! {
+! const char *s = lua_tostring(L, 2);
+! if (strncmp(s, "add", 3) == 0
+! || strncmp(s, "insert", 6) == 0
+! || strncmp(s, "extend", 6) == 0)
+ {
+! lua_getmetatable(L, 1);
+! lua_getfield(L, -1, s);
+ }
+ else
+! lua_pushnil(L);
+ }
+! else
+! lua_pushnil(L);
+! return 1;
+ }
+
+! static int
+! luaV_list_newindex (lua_State *L)
+! {
+! list_T *l = luaV_unbox(L, luaV_List, 1);
+! long n = (long) luaL_checkinteger(L, 2);
+! listitem_T *li;
+! if (l->lv_lock)
+! luaL_error(L, "list is locked");
+! li = list_find(l, n);
+! if (li == NULL) return 0;
+! if (lua_isnil(L, 3)) /* remove? */
+! {
+! list_remove(l, li);
+! clear_tv(&li->li_tv);
+! vim_free(li);
+! }
+! else
+! {
+! typval_T v;
+! luaV_totypval(L, 3, &v);
+! clear_tv(&li->li_tv);
+! copy_tv(&v, &li->li_tv);
+! }
+! return 0;
+! }
+
+ static int
+! luaV_list_add (lua_State *L)
+ {
+! luaV_List *lis = luaV_checkudata(L, 1, LUAVIM_LIST);
+! list_T *l = (list_T *) luaV_checkcache(L, (void *) *lis);
+! listitem_T *li;
+! if (l->lv_lock)
+! luaL_error(L, "list is locked");
+! li = listitem_alloc();
+! if (li != NULL)
+! {
+! typval_T v;
+! lua_settop(L, 2);
+! luaV_totypval(L, 2, &v);
+! copy_tv(&v, &li->li_tv);
+! list_append(l, li);
+! }
+! lua_settop(L, 1);
+ return 1;
+ }
+
+ static int
++ luaV_list_insert (lua_State *L)
++ {
++ luaV_List *lis = luaV_checkudata(L, 1, LUAVIM_LIST);
++ list_T *l = (list_T *) luaV_checkcache(L, (void *) *lis);
++ long pos = luaL_optlong(L, 3, 0);
++ listitem_T *li = NULL;
++ typval_T v;
++ if (l->lv_lock)
++ luaL_error(L, "list is locked");
++ if (pos < l->lv_len)
++ {
++ li = list_find(l, pos);
++ if (li == NULL)
++ luaL_error(L, "invalid position");
++ }
++ lua_settop(L, 2);
++ luaV_totypval(L, 2, &v);
++ list_insert_tv(l, &v, li);
++ lua_settop(L, 1);
++ return 1;
++ }
++
++ static const luaL_Reg luaV_List_mt[] = {
++ {"__tostring", luaV_list_tostring},
++ {"__gc", luaV_list_gc},
++ {"__len", luaV_list_len},
++ {"__call", luaV_list_call},
++ {"__index", luaV_list_index},
++ {"__newindex", luaV_list_newindex},
++ {"add", luaV_list_add},
++ {"insert", luaV_list_insert},
++ {NULL, NULL}
++ };
++
++
++ /* ======= Dict type ======= */
++
++ static luaV_Dict *
++ luaV_newdict (lua_State *L, dict_T *dic)
++ {
++ luaV_Dict *d = (luaV_Dict *) lua_newuserdata(L, sizeof(luaV_Dict));
++ *d = dic;
++ dic->dv_refcount++; /* reference in Lua */
++ luaV_setudata(L, dic); /* cache[dic] = udata */
++ luaV_getfield(L, LUAVIM_DICT);
++ lua_setmetatable(L, -2);
++ return d;
++ }
++
++ luaV_pushtype(dict_T, dict, luaV_Dict)
++ luaV_type_tostring(dict, LUAVIM_DICT)
++
++ static int
++ luaV_dict_gc (lua_State *L)
++ {
++ dict_unref(luaV_unbox(L, luaV_Dict, 1));
++ return 0;
++ }
++
++ static int
++ luaV_dict_len (lua_State *L)
++ {
++ dict_T *d = luaV_unbox(L, luaV_Dict, 1);
++ lua_pushinteger(L, (d == NULL) ? 0 : (int) d->dv_hashtab.ht_used);
++ return 1;
++ }
++
++ static int
++ luaV_dict_iter (lua_State *L)
++ {
++ hashitem_T *hi = (hashitem_T *) lua_touserdata(L, lua_upvalueindex(2));
++ int n = lua_tointeger(L, lua_upvalueindex(3));
++ dictitem_T *di;
++ if (n <= 0) return 0;
++ while (HASHITEM_EMPTY(hi)) hi++;
++ di = dict_lookup(hi);
++ lua_pushstring(L, (char *) hi->hi_key);
++ luaV_pushtypval(L, &di->di_tv);
++ lua_pushlightuserdata(L, (void *) (hi + 1));
++ lua_replace(L, lua_upvalueindex(2));
++ lua_pushinteger(L, n - 1);
++ lua_replace(L, lua_upvalueindex(3));
++ return 2;
++ }
++
++ static int
++ luaV_dict_call (lua_State *L)
++ {
++ dict_T *d = luaV_unbox(L, luaV_Dict, 1);
++ hashtab_T *ht = &d->dv_hashtab;
++ lua_pushvalue(L, lua_upvalueindex(1)); /* pass cache table along */
++ lua_pushlightuserdata(L, (void *) ht->ht_array);
++ lua_pushinteger(L, ht->ht_used); /* # remaining items */
++ lua_pushcclosure(L, luaV_dict_iter, 3);
++ return 1;
++ }
++
++ static int
++ luaV_dict_index (lua_State *L)
++ {
++ dict_T *d = luaV_unbox(L, luaV_Dict, 1);
++ char_u *key = (char_u *) luaL_checkstring(L, 2);
++ dictitem_T *di = dict_find(d, key, -1);
++ if (di == NULL)
++ lua_pushnil(L);
++ else
++ luaV_pushtypval(L, &di->di_tv);
++ return 1;
++ }
++
++ static int
++ luaV_dict_newindex (lua_State *L)
++ {
++ dict_T *d = luaV_unbox(L, luaV_Dict, 1);
++ char_u *key = (char_u *) luaL_checkstring(L, 2);
++ dictitem_T *di;
++ if (d->dv_lock)
++ luaL_error(L, "dict is locked");
++ di = dict_find(d, key, -1);
++ if (di == NULL) /* non-existing key? */
++ {
++ if (lua_isnil(L, 3)) return 0;
++ di = dictitem_alloc(key);
++ if (di == NULL) return 0;
++ if (dict_add(d, di) == FAIL)
++ {
++ vim_free(di);
++ return 0;
++ }
++ }
++ else
++ clear_tv(&di->di_tv);
++ if (lua_isnil(L, 3)) /* remove? */
++ {
++ hashitem_T *hi = hash_find(&d->dv_hashtab, di->di_key);
++ hash_remove(&d->dv_hashtab, hi);
++ dictitem_free(di);
++ }
++ else {
++ typval_T v;
++ luaV_totypval(L, 3, &v);
++ copy_tv(&v, &di->di_tv);
++ }
++ return 0;
++ }
++
++ static const luaL_Reg luaV_Dict_mt[] = {
++ {"__tostring", luaV_dict_tostring},
++ {"__gc", luaV_dict_gc},
++ {"__len", luaV_dict_len},
++ {"__call", luaV_dict_call},
++ {"__index", luaV_dict_index},
++ {"__newindex", luaV_dict_newindex},
++ {NULL, NULL}
++ };
++
++
++ /* ======= Buffer type ======= */
++
++ luaV_newtype(buf_T, buffer, luaV_Buffer, LUAVIM_BUFFER)
++ luaV_pushtype(buf_T, buffer, luaV_Buffer)
++ luaV_type_tostring(buffer, LUAVIM_BUFFER)
++
++ static int
+ luaV_buffer_len(lua_State *L)
+ {
+! buf_T *b = (buf_T *) luaV_checkvalid(L, luaV_Buffer, 1);
+! lua_pushinteger(L, b->b_ml.ml_line_count);
+ return 1;
+ }
+
+ static int
+ luaV_buffer_call(lua_State *L)
+ {
+! buf_T *b = (buf_T *) luaV_checkvalid(L, luaV_Buffer, 1);
+ lua_settop(L, 1);
+! set_curbuf(b, DOBUF_SPLIT);
+ return 1;
+ }
+
+ static int
+ luaV_buffer_index(lua_State *L)
+ {
+! buf_T *b = (buf_T *) luaV_checkvalid(L, luaV_Buffer, 1);
+ linenr_T n = (linenr_T) lua_tointeger(L, 2);
+! if (n > 0 && n <= b->b_ml.ml_line_count)
+! luaV_pushline(L, b, n);
+ else if (lua_isstring(L, 2))
+ {
+ const char *s = lua_tostring(L, 2);
+ if (strncmp(s, "name", 4) == 0)
+! lua_pushstring(L, (char *) b->b_sfname);
+ else if (strncmp(s, "fname", 5) == 0)
+! lua_pushstring(L, (char *) b->b_ffname);
+ else if (strncmp(s, "number", 6) == 0)
+! lua_pushinteger(L, b->b_fnum);
+ /* methods */
+ else if (strncmp(s, "insert", 6) == 0
+ || strncmp(s, "next", 4) == 0
+***************
+*** 584,600 ****
+ static int
+ luaV_buffer_newindex(lua_State *L)
+ {
+! luaV_Buffer *b = (luaV_Buffer *) lua_touserdata(L, 1);
+ linenr_T n = (linenr_T) luaL_checkinteger(L, 2);
+ #ifdef HAVE_SANDBOX
+ luaV_checksandbox(L);
+ #endif
+! if (n < 1 || n > (*b)->b_ml.ml_line_count)
+ luaL_error(L, "invalid line number");
+ if (lua_isnil(L, 3)) /* delete line */
+ {
+ buf_T *buf = curbuf;
+! curbuf = *b;
+ if (u_savedel(n, 1L) == FAIL)
+ {
+ curbuf = buf;
+--- 1122,1138 ----
+ static int
+ luaV_buffer_newindex(lua_State *L)
+ {
+! buf_T *b = (buf_T *) luaV_checkvalid(L, luaV_Buffer, 1);
+ linenr_T n = (linenr_T) luaL_checkinteger(L, 2);
+ #ifdef HAVE_SANDBOX
+ luaV_checksandbox(L);
+ #endif
+! if (n < 1 || n > b->b_ml.ml_line_count)
+ luaL_error(L, "invalid line number");
+ if (lua_isnil(L, 3)) /* delete line */
+ {
+ buf_T *buf = curbuf;
+! curbuf = b;
+ if (u_savedel(n, 1L) == FAIL)
+ {
+ curbuf = buf;
+***************
+*** 607,613 ****
+ }
+ else {
+ deleted_lines_mark(n, 1L);
+! if (*b == curwin->w_buffer) /* fix cursor in current window? */
+ {
+ if (curwin->w_cursor.lnum >= n)
+ {
+--- 1145,1151 ----
+ }
+ else {
+ deleted_lines_mark(n, 1L);
+! if (b == curwin->w_buffer) /* fix cursor in current window? */
+ {
+ if (curwin->w_cursor.lnum >= n)
+ {
+***************
+*** 627,633 ****
+ else if (lua_isstring(L, 3)) /* update line */
+ {
+ buf_T *buf = curbuf;
+! curbuf = *b;
+ if (u_savesub(n) == FAIL)
+ {
+ curbuf = buf;
+--- 1165,1171 ----
+ else if (lua_isstring(L, 3)) /* update line */
+ {
+ buf_T *buf = curbuf;
+! curbuf = b;
+ if (u_savesub(n) == FAIL)
+ {
+ curbuf = buf;
+***************
+*** 640,646 ****
+ }
+ else changed_bytes(n, 0);
+ curbuf = buf;
+! if (*b == curwin->w_buffer)
+ check_cursor_col();
+ }
+ else
+--- 1178,1184 ----
+ }
+ else changed_bytes(n, 0);
+ curbuf = buf;
+! if (b == curwin->w_buffer)
+ check_cursor_col();
+ }
+ else
+***************
+*** 651,658 ****
+ static int
+ luaV_buffer_insert(lua_State *L)
+ {
+! luaV_Buffer *b = luaV_checkudata(L, 1, LUAVIM_BUFFER);
+! linenr_T last = (*b)->b_ml.ml_line_count;
+ linenr_T n = (linenr_T) luaL_optinteger(L, 3, last);
+ buf_T *buf;
+ luaL_checktype(L, 2, LUA_TSTRING);
+--- 1189,1197 ----
+ static int
+ luaV_buffer_insert(lua_State *L)
+ {
+! luaV_Buffer *lb = luaV_checkudata(L, 1, LUAVIM_BUFFER);
+! buf_T *b = (buf_T *) luaV_checkcache(L, (void *) *lb);
+! linenr_T last = b->b_ml.ml_line_count;
+ linenr_T n = (linenr_T) luaL_optinteger(L, 3, last);
+ buf_T *buf;
+ luaL_checktype(L, 2, LUA_TSTRING);
+***************
+*** 664,670 ****
+ if (n > last) n = last;
+ /* insert */
+ buf = curbuf;
+! curbuf = *b;
+ if (u_save(n, n + 1) == FAIL)
+ {
+ curbuf = buf;
+--- 1203,1209 ----
+ if (n > last) n = last;
+ /* insert */
+ buf = curbuf;
+! curbuf = b;
+ if (u_save(n, n + 1) == FAIL)
+ {
+ curbuf = buf;
+***************
+*** 686,692 ****
+ luaV_buffer_next(lua_State *L)
+ {
+ luaV_Buffer *b = luaV_checkudata(L, 1, LUAVIM_BUFFER);
+! luaV_pushbuffer(L, (*b)->b_next);
+ return 1;
+ }
+
+--- 1225,1232 ----
+ luaV_buffer_next(lua_State *L)
+ {
+ luaV_Buffer *b = luaV_checkudata(L, 1, LUAVIM_BUFFER);
+! buf_T *buf = (buf_T *) luaV_checkcache(L, (void *) *b);
+! luaV_pushbuffer(L, buf->b_next);
+ return 1;
+ }
+
+***************
+*** 694,700 ****
+ luaV_buffer_previous(lua_State *L)
+ {
+ luaV_Buffer *b = luaV_checkudata(L, 1, LUAVIM_BUFFER);
+! luaV_pushbuffer(L, (*b)->b_prev);
+ return 1;
+ }
+
+--- 1234,1241 ----
+ luaV_buffer_previous(lua_State *L)
+ {
+ luaV_Buffer *b = luaV_checkudata(L, 1, LUAVIM_BUFFER);
+! buf_T *buf = (buf_T *) luaV_checkcache(L, (void *) *b);
+! luaV_pushbuffer(L, buf->b_prev);
+ return 1;
+ }
+
+***************
+*** 702,709 ****
+ luaV_buffer_isvalid(lua_State *L)
+ {
+ luaV_Buffer *b = luaV_checkudata(L, 1, LUAVIM_BUFFER);
+! lua_pushlightuserdata(L, (void *) (*b));
+! lua_rawget(L, LUA_ENVIRONINDEX);
+ lua_pushboolean(L, !lua_isnil(L, -1));
+ return 1;
+ }
+--- 1243,1249 ----
+ luaV_buffer_isvalid(lua_State *L)
+ {
+ luaV_Buffer *b = luaV_checkudata(L, 1, LUAVIM_BUFFER);
+! luaV_getudata(L, *b);
+ lua_pushboolean(L, !lua_isnil(L, -1));
+ return 1;
+ }
+***************
+*** 724,801 ****
+
+ /* ======= Window type ======= */
+
+! static luaV_Window *
+! luaV_newwindow(lua_State *L, win_T *win)
+! {
+! luaV_Window *w = (luaV_Window *) lua_newuserdata(L, sizeof(luaV_Window));
+! *w = win;
+! lua_pushlightuserdata(L, (void *) win);
+! lua_pushvalue(L, -2);
+! lua_rawset(L, LUA_ENVIRONINDEX); /* env[win] = udata */
+! /* to avoid GC, store as key in env */
+! lua_pushvalue(L, -1);
+! lua_pushboolean(L, 1);
+! lua_rawset(L, LUA_ENVIRONINDEX); /* env[udata] = true */
+! /* set metatable */
+! luaV_getfield(L, LUAVIM_WINDOW);
+! lua_setmetatable(L, -2);
+! return w;
+! }
+!
+! static luaV_Window *
+! luaV_pushwindow(lua_State *L, win_T *win)
+! {
+! luaV_Window *w = NULL;
+! if (win == NULL)
+! lua_pushnil(L);
+! else {
+! lua_pushlightuserdata(L, (void *) win);
+! lua_rawget(L, LUA_ENVIRONINDEX);
+! if (lua_isnil(L, -1)) /* not interned? */
+! {
+! lua_pop(L, 1);
+! w = luaV_newwindow(L, win);
+! }
+! else w = (luaV_Window *) lua_touserdata(L, -1);
+! }
+! return w;
+! }
+!
+! /* Window metamethods */
+!
+! static int
+! luaV_window_tostring(lua_State *L)
+! {
+! lua_pushfstring(L, "%s: %p", LUAVIM_WINDOW, lua_touserdata(L, 1));
+! return 1;
+! }
+
+ static int
+ luaV_window_call(lua_State *L)
+ {
+! luaV_Window *w = (luaV_Window *) lua_touserdata(L, 1);
+ lua_settop(L, 1);
+! win_goto(*w);
+ return 1;
+ }
+
+ static int
+ luaV_window_index(lua_State *L)
+ {
+! luaV_Window *w = (luaV_Window *) lua_touserdata(L, 1);
+ const char *s = luaL_checkstring(L, 2);
+ if (strncmp(s, "buffer", 6) == 0)
+! luaV_pushbuffer(L, (*w)->w_buffer);
+ else if (strncmp(s, "line", 4) == 0)
+! lua_pushinteger(L, (*w)->w_cursor.lnum);
+ else if (strncmp(s, "col", 3) == 0)
+! lua_pushinteger(L, (*w)->w_cursor.col + 1);
+ #ifdef FEAT_VERTSPLIT
+ else if (strncmp(s, "width", 5) == 0)
+! lua_pushinteger(L, W_WIDTH((*w)));
+ #endif
+ else if (strncmp(s, "height", 6) == 0)
+! lua_pushinteger(L, (*w)->w_height);
+ /* methods */
+ else if (strncmp(s, "next", 4) == 0
+ || strncmp(s, "previous", 8) == 0
+--- 1264,1299 ----
+
+ /* ======= Window type ======= */
+
+! luaV_newtype(win_T, window, luaV_Window, LUAVIM_WINDOW)
+! luaV_pushtype(win_T, window, luaV_Window)
+! luaV_type_tostring(window, LUAVIM_WINDOW)
+
+ static int
+ luaV_window_call(lua_State *L)
+ {
+! win_T *w = (win_T *) luaV_checkvalid(L, luaV_Window, 1);
+ lua_settop(L, 1);
+! win_goto(w);
+ return 1;
+ }
+
+ static int
+ luaV_window_index(lua_State *L)
+ {
+! win_T *w = (win_T *) luaV_checkvalid(L, luaV_Window, 1);
+ const char *s = luaL_checkstring(L, 2);
+ if (strncmp(s, "buffer", 6) == 0)
+! luaV_pushbuffer(L, w->w_buffer);
+ else if (strncmp(s, "line", 4) == 0)
+! lua_pushinteger(L, w->w_cursor.lnum);
+ else if (strncmp(s, "col", 3) == 0)
+! lua_pushinteger(L, w->w_cursor.col + 1);
+ #ifdef FEAT_VERTSPLIT
+ else if (strncmp(s, "width", 5) == 0)
+! lua_pushinteger(L, W_WIDTH(w));
+ #endif
+ else if (strncmp(s, "height", 6) == 0)
+! lua_pushinteger(L, w->w_height);
+ /* methods */
+ else if (strncmp(s, "next", 4) == 0
+ || strncmp(s, "previous", 8) == 0
+***************
+*** 812,818 ****
+ static int
+ luaV_window_newindex (lua_State *L)
+ {
+! luaV_Window *w = (luaV_Window *) lua_touserdata(L, 1);
+ const char *s = luaL_checkstring(L, 2);
+ int v = luaL_checkinteger(L, 3);
+ if (strncmp(s, "line", 4) == 0)
+--- 1310,1316 ----
+ static int
+ luaV_window_newindex (lua_State *L)
+ {
+! win_T *w = (win_T *) luaV_checkvalid(L, luaV_Window, 1);
+ const char *s = luaL_checkstring(L, 2);
+ int v = luaL_checkinteger(L, 3);
+ if (strncmp(s, "line", 4) == 0)
+***************
+*** 820,828 ****
+ #ifdef HAVE_SANDBOX
+ luaV_checksandbox(L);
+ #endif
+! if (v < 1 || v > (*w)->w_buffer->b_ml.ml_line_count)
+ luaL_error(L, "line out of range");
+! (*w)->w_cursor.lnum = v;
+ update_screen(VALID);
+ }
+ else if (strncmp(s, "col", 3) == 0)
+--- 1318,1326 ----
+ #ifdef HAVE_SANDBOX
+ luaV_checksandbox(L);
+ #endif
+! if (v < 1 || v > w->w_buffer->b_ml.ml_line_count)
+ luaL_error(L, "line out of range");
+! w->w_cursor.lnum = v;
+ update_screen(VALID);
+ }
+ else if (strncmp(s, "col", 3) == 0)
+***************
+*** 830,836 ****
+ #ifdef HAVE_SANDBOX
+ luaV_checksandbox(L);
+ #endif
+! (*w)->w_cursor.col = v - 1;
+ update_screen(VALID);
+ }
+ #ifdef FEAT_VERTSPLIT
+--- 1328,1334 ----
+ #ifdef HAVE_SANDBOX
+ luaV_checksandbox(L);
+ #endif
+! w->w_cursor.col = v - 1;
+ update_screen(VALID);
+ }
+ #ifdef FEAT_VERTSPLIT
+***************
+*** 840,846 ****
+ #ifdef FEAT_GUI
+ need_mouse_correct = TRUE;
+ #endif
+! curwin = *w;
+ win_setwidth(v);
+ curwin = win;
+ }
+--- 1338,1344 ----
+ #ifdef FEAT_GUI
+ need_mouse_correct = TRUE;
+ #endif
+! curwin = w;
+ win_setwidth(v);
+ curwin = win;
+ }
+***************
+*** 851,857 ****
+ #ifdef FEAT_GUI
+ need_mouse_correct = TRUE;
+ #endif
+! curwin = *w;
+ win_setheight(v);
+ curwin = win;
+ }
+--- 1349,1355 ----
+ #ifdef FEAT_GUI
+ need_mouse_correct = TRUE;
+ #endif
+! curwin = w;
+ win_setheight(v);
+ curwin = win;
+ }
+***************
+*** 864,870 ****
+ luaV_window_next(lua_State *L)
+ {
+ luaV_Window *w = luaV_checkudata(L, 1, LUAVIM_WINDOW);
+! luaV_pushwindow(L, (*w)->w_next);
+ return 1;
+ }
+
+--- 1362,1369 ----
+ luaV_window_next(lua_State *L)
+ {
+ luaV_Window *w = luaV_checkudata(L, 1, LUAVIM_WINDOW);
+! win_T *win = (win_T *) luaV_checkcache(L, (void *) *w);
+! luaV_pushwindow(L, win->w_next);
+ return 1;
+ }
+
+***************
+*** 872,878 ****
+ luaV_window_previous(lua_State *L)
+ {
+ luaV_Window *w = luaV_checkudata(L, 1, LUAVIM_WINDOW);
+! luaV_pushwindow(L, (*w)->w_prev);
+ return 1;
+ }
+
+--- 1371,1378 ----
+ luaV_window_previous(lua_State *L)
+ {
+ luaV_Window *w = luaV_checkudata(L, 1, LUAVIM_WINDOW);
+! win_T *win = (win_T *) luaV_checkcache(L, (void *) *w);
+! luaV_pushwindow(L, win->w_prev);
+ return 1;
+ }
+
+***************
+*** 880,887 ****
+ luaV_window_isvalid(lua_State *L)
+ {
+ luaV_Window *w = luaV_checkudata(L, 1, LUAVIM_WINDOW);
+! lua_pushlightuserdata(L, (void *) (*w));
+! lua_rawget(L, LUA_ENVIRONINDEX);
+ lua_pushboolean(L, !lua_isnil(L, -1));
+ return 1;
+ }
+--- 1380,1386 ----
+ luaV_window_isvalid(lua_State *L)
+ {
+ luaV_Window *w = luaV_checkudata(L, 1, LUAVIM_WINDOW);
+! luaV_getudata(L, *w);
+ lua_pushboolean(L, !lua_isnil(L, -1));
+ return 1;
+ }
+***************
+*** 983,988 ****
+--- 1482,1509 ----
+ }
+
+ static int
++ luaV_list(lua_State *L)
++ {
++ list_T *l = list_alloc();
++ if (l == NULL)
++ lua_pushnil(L);
++ else
++ luaV_newlist(L, l);
++ return 1;
++ }
++
++ static int
++ luaV_dict(lua_State *L)
++ {
++ dict_T *d = dict_alloc();
++ if (d == NULL)
++ lua_pushnil(L);
++ else
++ luaV_newdict(L, d);
++ return 1;
++ }
++
++ static int
+ luaV_buffer(lua_State *L)
+ {
+ buf_T *buf;
+***************
+*** 1008,1022 ****
+ break;
+ }
+ }
+- if (buf == NULL) /* not found? */
+- lua_pushnil(L);
+- else
+- luaV_pushbuffer(L, buf);
+ }
+! else {
+ buf = (lua_toboolean(L, 1)) ? firstbuf : curbuf; /* first buffer? */
+! luaV_pushbuffer(L, buf);
+! }
+ return 1;
+ }
+
+--- 1529,1538 ----
+ break;
+ }
+ }
+ }
+! else
+ buf = (lua_toboolean(L, 1)) ? firstbuf : curbuf; /* first buffer? */
+! luaV_pushbuffer(L, buf);
+ return 1;
+ }
+
+***************
+*** 1029,1043 ****
+ int n = lua_tointeger(L, 1);
+ for (win = firstwin; win != NULL; win = win->w_next, n--)
+ if (n == 1) break;
+- if (win == NULL) /* not found? */
+- lua_pushnil(L);
+- else
+- luaV_pushwindow(L, win);
+ }
+! else {
+ win = (lua_toboolean(L, 1)) ? firstwin : curwin; /* first window? */
+! luaV_pushwindow(L, win);
+! }
+ return 1;
+ }
+
+--- 1545,1554 ----
+ int n = lua_tointeger(L, 1);
+ for (win = firstwin; win != NULL; win = win->w_next, n--)
+ if (n == 1) break;
+ }
+! else
+ win = (lua_toboolean(L, 1)) ? firstwin : curwin; /* first window? */
+! luaV_pushwindow(L, win);
+ return 1;
+ }
+
+***************
+*** 1054,1086 ****
+ }
+
+ static int
+! luaV_isbuffer(lua_State *L)
+! {
+! lua_pushboolean(L, luaV_toudata(L, 1, LUAVIM_BUFFER) != NULL);
+! return 1;
+! }
+!
+! static int
+! luaV_iswindow(lua_State *L)
+ {
+! lua_pushboolean(L, luaV_toudata(L, 1, LUAVIM_WINDOW) != NULL);
+! return 1;
+! }
+!
+! /* for freeing buffer and window objects; lightuserdata as arg */
+! static int
+! luaV_free(lua_State *L)
+! {
+! lua_pushvalue(L, 1); /* lightudata */
+! lua_rawget(L, LUA_ENVIRONINDEX);
+! if (!lua_isnil(L, -1))
+ {
+! lua_pushnil(L);
+! lua_rawset(L, LUA_ENVIRONINDEX); /* env[udata] = nil */
+! lua_pushnil(L);
+! lua_rawset(L, LUA_ENVIRONINDEX); /* env[lightudata] = nil */
+ }
+! return 0;
+ }
+
+ static const luaL_Reg luaV_module[] = {
+--- 1565,1606 ----
+ }
+
+ static int
+! luaV_type(lua_State *L)
+ {
+! luaL_checkany(L, 1);
+! if (lua_type(L, 1) == LUA_TUSERDATA) /* check vim udata? */
+ {
+! lua_settop(L, 1);
+! if (lua_getmetatable(L, 1))
+! {
+! luaV_getfield(L, LUAVIM_LIST);
+! if (lua_rawequal(L, -1, 2))
+! {
+! lua_pushstring(L, "list");
+! return 1;
+! }
+! luaV_getfield(L, LUAVIM_DICT);
+! if (lua_rawequal(L, -1, 2))
+! {
+! lua_pushstring(L, "dict");
+! return 1;
+! }
+! luaV_getfield(L, LUAVIM_BUFFER);
+! if (lua_rawequal(L, -1, 2))
+! {
+! lua_pushstring(L, "buffer");
+! return 1;
+! }
+! luaV_getfield(L, LUAVIM_WINDOW);
+! if (lua_rawequal(L, -1, 2))
+! {
+! lua_pushstring(L, "window");
+! return 1;
+! }
+! }
+ }
+! lua_pushstring(L, luaL_typename(L, 1)); /* fallback */
+! return 1;
+ }
+
+ static const luaL_Reg luaV_module[] = {
+***************
+*** 1088,1111 ****
+ {"eval", luaV_eval},
+ {"beep", luaV_beep},
+ {"line", luaV_line},
+ {"buffer", luaV_buffer},
+ {"window", luaV_window},
+ {"open", luaV_open},
+! {"isbuffer", luaV_isbuffer},
+! {"iswindow", luaV_iswindow},
+ {NULL, NULL}
+ };
+
+ static int
+ luaopen_vim(lua_State *L)
+ {
+! /* set environment */
+ lua_newtable(L);
+ lua_newtable(L);
+! lua_pushliteral(L, "v");
+ lua_setfield(L, -2, "__mode");
+! lua_setmetatable(L, -2);
+! lua_replace(L, LUA_ENVIRONINDEX);
+ /* print */
+ lua_pushcfunction(L, luaV_print);
+ lua_setglobal(L, "print");
+--- 1608,1695 ----
+ {"eval", luaV_eval},
+ {"beep", luaV_beep},
+ {"line", luaV_line},
++ {"list", luaV_list},
++ {"dict", luaV_dict},
+ {"buffer", luaV_buffer},
+ {"window", luaV_window},
+ {"open", luaV_open},
+! {"type", luaV_type},
+ {NULL, NULL}
+ };
+
++ /* for freeing list, dict, buffer and window objects; lightuserdata as arg */
++ static int
++ luaV_free(lua_State *L)
++ {
++ lua_pushnil(L);
++ luaV_setudata(L, lua_touserdata(L, 1));
++ return 0;
++ }
++
++ static int
++ luaV_luaeval (lua_State *L)
++ {
++ luaL_Buffer b;
++ size_t l;
++ const char *str = lua_tolstring(L, 1, &l);
++ typval_T *arg = (typval_T *) lua_touserdata(L, 2);
++ typval_T *rettv = (typval_T *) lua_touserdata(L, 3);
++ luaL_buffinit(L, &b);
++ luaL_addlstring(&b, LUAVIM_EVALHEADER, sizeof(LUAVIM_EVALHEADER) - 1);
++ luaL_addlstring(&b, str, l);
++ luaL_pushresult(&b);
++ str = lua_tolstring(L, -1, &l);
++ if (luaL_loadbuffer(L, str, l, LUAVIM_EVALNAME)) /* compile error? */
++ {
++ luaV_emsg(L);
++ return 0;
++ }
++ luaV_pushtypval(L, arg);
++ if (lua_pcall(L, 1, 1, 0)) /* running error? */
++ {
++ luaV_emsg(L);
++ return 0;
++ }
++ luaV_totypval(L, -1, rettv);
++ return 0;
++ }
++
++ static int
++ luaV_setref (lua_State *L)
++ {
++ int copyID = lua_tointeger(L, 1);
++ typval_T tv;
++ luaV_getfield(L, LUAVIM_LIST);
++ luaV_getfield(L, LUAVIM_DICT);
++ lua_pushnil(L);
++ while (lua_next(L, lua_upvalueindex(1)) != 0) /* traverse cache table */
++ {
++ lua_getmetatable(L, -1);
++ if (lua_rawequal(L, -1, 2)) /* list? */
++ {
++ tv.v_type = VAR_LIST;
++ tv.vval.v_list = (list_T *) lua_touserdata(L, 4); /* key */
++ }
++ else if (lua_rawequal(L, -1, 3)) /* dict? */
++ {
++ tv.v_type = VAR_DICT;
++ tv.vval.v_dict = (dict_T *) lua_touserdata(L, 4); /* key */
++ }
++ lua_pop(L, 2); /* metatable and value */
++ set_ref_in_tv(&tv, copyID);
++ }
++ return 0;
++ }
++
+ static int
+ luaopen_vim(lua_State *L)
+ {
+! /* set cache table */
+ lua_newtable(L);
+ lua_newtable(L);
+! lua_pushstring(L, "v");
+ lua_setfield(L, -2, "__mode");
+! lua_setmetatable(L, -2); /* cache is weak-valued */
+ /* print */
+ lua_pushcfunction(L, luaV_print);
+ lua_setglobal(L, "print");
+***************
+*** 1116,1129 ****
+ lua_pop(L, 1);
+ /* free */
+ lua_pushlightuserdata(L, (void *) LUAVIM_FREE);
+! lua_pushcfunction(L, luaV_free);
+ lua_rawset(L, LUA_REGISTRYINDEX);
+ /* register */
+ luaV_newmetatable(L, LUAVIM_BUFFER);
+! luaL_register(L, NULL, luaV_Buffer_mt);
+ luaV_newmetatable(L, LUAVIM_WINDOW);
+! luaL_register(L, NULL, luaV_Window_mt);
+! luaL_register(L, LUAVIM_NAME, luaV_module);
+ return 0;
+ }
+
+--- 1700,1735 ----
+ lua_pop(L, 1);
+ /* free */
+ lua_pushlightuserdata(L, (void *) LUAVIM_FREE);
+! lua_pushvalue(L, 1); /* cache table */
+! lua_pushcclosure(L, luaV_free, 1);
+! lua_rawset(L, LUA_REGISTRYINDEX);
+! /* luaeval */
+! lua_pushlightuserdata(L, (void *) LUAVIM_LUAEVAL);
+! lua_pushvalue(L, 1); /* cache table */
+! lua_pushcclosure(L, luaV_luaeval, 1);
+! lua_rawset(L, LUA_REGISTRYINDEX);
+! /* setref */
+! lua_pushlightuserdata(L, (void *) LUAVIM_SETREF);
+! lua_pushvalue(L, 1); /* cache table */
+! lua_pushcclosure(L, luaV_setref, 1);
+ lua_rawset(L, LUA_REGISTRYINDEX);
+ /* register */
++ luaV_newmetatable(L, LUAVIM_LIST);
++ lua_pushvalue(L, 1);
++ luaV_openlib(L, luaV_List_mt, 1);
++ luaV_newmetatable(L, LUAVIM_DICT);
++ lua_pushvalue(L, 1);
++ luaV_openlib(L, luaV_Dict_mt, 1);
+ luaV_newmetatable(L, LUAVIM_BUFFER);
+! lua_pushvalue(L, 1); /* cache table */
+! luaV_openlib(L, luaV_Buffer_mt, 1);
+ luaV_newmetatable(L, LUAVIM_WINDOW);
+! lua_pushvalue(L, 1); /* cache table */
+! luaV_openlib(L, luaV_Window_mt, 1);
+! lua_newtable(L); /* vim table */
+! lua_pushvalue(L, 1); /* cache table */
+! luaV_openlib(L, luaV_module, 1);
+! lua_setglobal(L, LUAVIM_NAME);
+ return 0;
+ }
+
+***************
+*** 1154,1160 ****
+ static lua_State *L = NULL;
+
+ static int
+! lua_is_open(void)
+ {
+ return L != NULL;
+ }
+--- 1760,1766 ----
+ static lua_State *L = NULL;
+
+ static int
+! lua_isopen(void)
+ {
+ return L != NULL;
+ }
+***************
+*** 1162,1168 ****
+ static int
+ lua_init(void)
+ {
+! if (L == NULL)
+ {
+ #ifdef DYNAMIC_LUA
+ if (!lua_enabled(TRUE))
+--- 1768,1774 ----
+ static int
+ lua_init(void)
+ {
+! if (!lua_isopen())
+ {
+ #ifdef DYNAMIC_LUA
+ if (!lua_enabled(TRUE))
+***************
+*** 1179,1185 ****
+ void
+ lua_end(void)
+ {
+! if (L != NULL)
+ {
+ lua_close(L);
+ L = NULL;
+--- 1785,1791 ----
+ void
+ lua_end(void)
+ {
+! if (lua_isopen())
+ {
+ lua_close(L);
+ L = NULL;
+***************
+*** 1273,1295 ****
+ }
+ }
+
+! /* buffer */
+ void
+! lua_buffer_free(buf_T *buf)
+ {
+! if (!lua_is_open()) return;
+! luaV_getfield(L, LUAVIM_FREE);
+! lua_pushlightuserdata(L, (void *) buf);
+! lua_call(L, 1, 0);
+ }
+
+- /* window */
+ void
+! lua_window_free(win_T *win)
+ {
+! if (!lua_is_open()) return;
+! luaV_getfield(L, LUAVIM_FREE);
+! lua_pushlightuserdata(L, (void *) win);
+ lua_call(L, 1, 0);
+ }
+
+--- 1879,1914 ----
+ }
+ }
+
+! #define luaV_freetype(typ,tname) \
+! void \
+! lua_##tname##_free(typ *o) \
+! { \
+! if (!lua_isopen()) return; \
+! luaV_getfield(L, LUAVIM_FREE); \
+! lua_pushlightuserdata(L, (void *) o); \
+! lua_call(L, 1, 0); \
+! }
+!
+! luaV_freetype(buf_T, buffer)
+! luaV_freetype(win_T, window)
+!
+ void
+! do_luaeval (char_u *str, typval_T *arg, typval_T *rettv)
+ {
+! lua_init();
+! luaV_getfield(L, LUAVIM_LUAEVAL);
+! lua_pushstring(L, (char *) str);
+! lua_pushlightuserdata(L, (void *) arg);
+! lua_pushlightuserdata(L, (void *) rettv);
+! lua_call(L, 3, 0);
+ }
+
+ void
+! set_ref_in_lua (int copyID)
+ {
+! if (!lua_isopen()) return;
+! luaV_getfield(L, LUAVIM_SETREF);
+! lua_pushinteger(L, copyID);
+ lua_call(L, 1, 0);
+ }
+
+*** ../vim-7.3.489/src/proto/if_lua.pro 2010-08-15 21:57:28.000000000 +0200
+--- src/proto/if_lua.pro 2012-04-05 16:41:35.000000000 +0200
+***************
+*** 6,9 ****
+--- 6,11 ----
+ void ex_luafile __ARGS((exarg_T *eap));
+ void lua_buffer_free __ARGS((buf_T *buf));
+ void lua_window_free __ARGS((win_T *win));
++ void do_luaeval __ARGS((char_u *str, typval_T *arg, typval_T *rettv));
++ void set_ref_in_lua __ARGS((int copyID));
+ /* vim: set ft=c : */
+*** ../vim-7.3.489/src/version.c 2012-04-05 16:07:01.000000000 +0200
+--- src/version.c 2012-04-05 16:52:08.000000000 +0200
+***************
+*** 716,717 ****
+--- 716,719 ----
+ { /* Add new patch number below this line */
++ /**/
++ 490,
+ /**/
+
+--
+Even got a Datapoint 3600(?) with a DD50 connector instead of the
+usual DB25... what a nightmare trying to figure out the pinout
+for *that* with no spex...
+
+ /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\
+/// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
+\\\ an exciting new programming language -- http://www.Zimbu.org ///
+ \\\ help me help AIDS victims -- http://ICCF-Holland.org ///