changeset 2373:f149bb1cf5be vim73

Make it possible to load Lua dynamically on Unix. (Luis Carvalho)
author Bram Moolenaar <bram@vim.org>
date Thu, 22 Jul 2010 21:32:16 +0200
parents a42d19b78c93
children f414e5a4b40e
files runtime/doc/if_lua.txt runtime/doc/todo.txt src/Makefile src/auto/configure src/config.h.in src/configure.in src/if_lua.c src/proto/if_lua.pro
diffstat 8 files changed, 114 insertions(+), 71 deletions(-) [+]
line wrap: on
line diff
--- a/runtime/doc/if_lua.txt
+++ b/runtime/doc/if_lua.txt
@@ -1,4 +1,4 @@
-*if_lua.txt*    For Vim version 7.3b.  Last change: 2008 Aug 31
+*if_lua.txt*    For Vim version 7.3b.  Last change: 2010 Jul 22
 
 
 		  VIM REFERENCE MANUAL    by Luis Carvalho
@@ -56,13 +56,13 @@ Example:
 <
 
 							*:luado*
-:[range]luado {body}	Execute Lua function$function (line)${body}$end$ for
+:[range]luado {body}	Execute Lua function "function (line) {body} end" for
 			each line in the [range], with the function argument
 			being set to the text of each line in turn, without a
 			trailing <EOL>. If the value returned by the function
 			is a string it becomes the text of the line in the
 			current turn. The default for [range] is the whole
-			file: "1,$".                  {not in Vi}
+			file: "1,$".		      {not in Vi}
 
 Examples:
 >
@@ -88,10 +88,10 @@ Examples:
 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
+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
@@ -104,36 +104,39 @@ position are restricted when the command
 2. The vim module					*lua-vim*
 
 Lua interfaces Vim through the "vim" module. The first and last line of the
-input range are stored in$vim.firstline$and$vim.lastline$respectively. The
+input range are stored in "vim.firstline" and "vim.lastline" respectively. The
 module also includes routines for buffer, window, and current line queries,
 Vim evaluation and command execution, and others.
 
-	$vim.isbuffer(value)$	Returns#true#if$value$is a buffer userdata and
-				$false$otherwise (see |lua-buffer|).
+	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$is
-				a string, returns buffer whose full or short
-				name is$arg$. In both cases, returns#nil#if
-				the buffer is not found. Otherwise, if
-				$toboolean(arg)$is#true#returns the first
-				buffer in the buffer list or else the current
-				buffer.
+	vim.buffer([arg])	If "arg" is a number, returns buffer with
+				number "arg" in the buffer list or, if "arg"
+				is a string, returns buffer whose full or short
+				name is "arg". In both cases, returns 'nil'
+				(nil value, not string) if the buffer is not
+				found. Otherwise, if "toboolean(arg)" is
+				'true' returns the first buffer in the buffer
+				list or else the current buffer.
 
-	$vim.iswindow(value)$	Returns#true#if$value$is a window userdata and
-				$false$otherwise (see |lua-window|).
+	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#if not found. Otherwise, if
-				$toboolean(arg)$is#true#returns the first
-				window or else the current 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}.
+	vim.command({cmd})	Executes the vim (ex-mode) command {cmd}.
 				Examples: >
 					:lua vim.command"set tw=60"
 					:lua vim.command"normal ddp"
 <
-	$vim.eval(${expr}$)$	Evaluates expression {expr} (see |expression|),
+	vim.eval({expr})	Evaluates expression {expr} (see |expression|),
 				converts the result to Lua, and returns it.
 				Vim strings and numbers are directly converted
 				to Lua strings and numbers respectively. Vim
@@ -143,12 +146,12 @@ Vim evaluation and command execution, an
 					:lua tw = vim.eval"&tw"
 					:lua print(vim.eval"{'a': 'one'}".a)
 <
-	$vim.line()$		Returns the current line (without the trailing
+	vim.line()		Returns the current line (without the trailing
 				<EOL>), a Lua string.
 
-	$vim.beep()$		Beeps.
+	vim.beep()		Beeps.
 
-	$vim.open(${fname}$)$	Opens a new buffer for file {fname} and
+	vim.open({fname})	Opens a new buffer for file {fname} and
 				returns it. Note that the buffer is not set as
 				current.
 
@@ -156,29 +159,31 @@ Vim evaluation and command execution, an
 ==============================================================================
 3. Buffer userdata					*lua-buffer*
 
-Buffer userdata represent vim buffers. A buffer userdata$b$has the following
+Buffer userdata represent vim buffers. A buffer userdata "b" has the following
 properties and methods:
 
 Properties
 ----------
-	#o#$b()$sets$b$as the current buffer.
-	#o#$#b$is the number of lines in buffer$b$.
-	#o#$b[k]$represents line number$k$:$b[k] = newline$replaces line$k$
-	    with string$newline$and$b[k] =$#nil#deletes line$k$.
-	#o#$b.name$contains the short name of buffer$b$(read-only).
-	#o#$b.fname$contains the full name of buffer$b$(read-only).
-	#o#$b.number$contains the position of buffer$b$in the buffer list
+	o "b()" sets "b" as the current buffer.
+	o "#b" is the number of lines in buffer "b".
+	o "b[k]" represents line number k: "b[k] = newline" replaces line k
+	    with string "newline" and "b[k] = nil" deletes line k.
+	o "b.name" contains the short name of buffer "b" (read-only).
+	o "b.fname" contains the full name of buffer "b" (read-only).
+	o "b.number" contains the position of buffer "b" in the buffer list
 	    (read-only).
 
 Methods
 -------
-	#o#$b:insert(newline$[, pos]$)$inserts string$newline$at position$pos$
-	    in the buffer. The default value for$pos$is$#b + 1$. If$pos == 0$
-	    then$newline$becomes the first line in the buffer.
-	#o#$b:next()$returns the buffer next to$b$in the buffer list.
-	#o#$b:previous()$returns the buffer previous to$b$in the buffer list.
-	#o#$b:isvalid()$returns#true#if buffer$b$corresponds to a "real" (not
-	    freed from memory) Vim buffer.
+	o "b:insert(newline[, pos])" inserts string "newline" at (optional)
+	    position "pos" in the buffer. The default value for "pos" is
+	    "#b + 1". If "pos == 0" then "newline" becomes the first line in
+	    the buffer.
+	o "b:next()" returns the buffer next to "b" in the buffer list.
+	o "b:previous()" returns the buffer previous to "b" in the buffer
+	    list.
+	o "b:isvalid()" returns 'true' (boolean) if buffer "b" corresponds to
+	    a "real" (not freed from memory) Vim buffer.
 
 Examples:
 >
@@ -206,24 +211,24 @@ Examples:
 ==============================================================================
 4. Window userdata					*lua-window*
 
-Window objects represent vim windows. A window userdata$w$has the following
+Window objects represent vim windows. A window userdata "w" has the following
 properties and methods:
 
 Properties
 ----------
-	#o#$w()$sets$w$as the current window.
-	#o#$w.buffer$contains the buffer of window$w$(read-only).
-	#o#$w.line$represents the cursor line position in window$w$.
-	#o#$w.col$represents the cursor column position in window$w$.
-	#o#$w.width$represents the width of window$w$.
-	#o#$w.height$represents the height of window$w$.
+	o "w()" sets "w" as the current window.
+	o "w.buffer" contains the buffer of window "w" (read-only).
+	o "w.line" represents the cursor line position in window "w".
+	o "w.col" represents the cursor column position in window "w".
+	o "w.width" represents the width of window "w".
+	o "w.height" represents the height of window "w".
 
 Methods
 -------
-	#o#$w:next()$returns the window next to$w$.
-	#o#$w:previous()$returns the window previous to$w$.
-	#o#$w:isvalid()$returns#true#if window$w$corresponds to a "real" (not
-	    freed from memory) Vim window.
+	o "w:next()" returns the window next to "w".
+	o "w:previous()" returns the window previous to "w".
+	o "w:isvalid()" returns 'true' (boolean) if window "w" corresponds to
+	    a "real" (not freed from memory) Vim window.
 
 Examples:
 >
--- a/runtime/doc/todo.txt
+++ b/runtime/doc/todo.txt
@@ -1,4 +1,4 @@
-*todo.txt*      For Vim version 7.3b.  Last change: 2010 Jul 21
+*todo.txt*      For Vim version 7.3b.  Last change: 2010 Jul 22
 
 
 		  VIM REFERENCE MANUAL	  by Bram Moolenaar
@@ -30,8 +30,14 @@ be worked on, but only if you sponsor Vi
 							*known-bugs*
 -------------------- Known bugs and current work -----------------------
 
+Conceal in help files doesn't work nice.  How about adding an 'concealcursor'
+option, when on:
+- cursorline is concealed.
+- line is redrawn on every movement
+- display function corrects cursor position.
+
 Include patch for horizontal scoll wheel? (Bjorn Winckler, 2010 Jul 20)
-Asked for a few changes.
+Additional patch Jul 21.
 
 Cursor positioning wrong with 0x200e character. (John Becket, 2010 May 6)
 
--- a/src/Makefile
+++ b/src/Makefile
@@ -370,8 +370,10 @@ CClink = $(CC)
 #CONF_OPT_DARWIN = --with-mac-arch=both
 
 # LUA
-# Uncomment this when you want to include the Lua interface.
+# Uncomment one of these when you want to include the Lua interface.
+# First one is for static linking, second one for dynamic loading.
 #CONF_OPT_LUA = --enable-luainterp
+#CONF_OPT_LUA = --enable-luainterp=dynamic
 # Lua installation dir (when not set uses $LUA_PREFIX or defaults to /usr)
 #CONF_OPT_LUA_PREFIX = --with-lua-prefix=/usr/local
 
@@ -1314,7 +1316,7 @@ SHELL = /bin/sh
 .SUFFIXES: .c .o .pro
 
 PRE_DEFS = -Iproto $(DEFS) $(GUI_DEFS) $(GUI_IPATH) $(CPPFLAGS) $(EXTRA_IPATHS)
-POST_DEFS = $(X_CFLAGS) $(LUA_CFLAGS) $(MZSCHEME_CFLAGS) $(TCL_CFLAGS) $(RUBY_CFLAGS) $(EXTRA_DEFS)
+POST_DEFS = $(X_CFLAGS) $(MZSCHEME_CFLAGS) $(TCL_CFLAGS) $(RUBY_CFLAGS) $(EXTRA_DEFS)
 
 ALL_CFLAGS = $(PRE_DEFS) $(CFLAGS) $(PROFILE_CFLAGS) $(POST_DEFS)
 
@@ -1322,7 +1324,7 @@ ALL_CFLAGS = $(PRE_DEFS) $(CFLAGS) $(PRO
 # with "-E".
 OSDEF_CFLAGS = $(PRE_DEFS) $(POST_DEFS)
 
-LINT_CFLAGS = -DLINT -I. $(PRE_DEFS) $(POST_DEFS) $(PYTHON_CFLAGS) -Dinline= -D__extension__= -Dalloca=alloca
+LINT_CFLAGS = -DLINT -I. $(PRE_DEFS) $(POST_DEFS) $(LUA_CFLAGS) $(PERL_CFLAGS) $(PYTHON_CFLAGS) -Dinline= -D__extension__= -Dalloca=alloca
 
 LINT_EXTRA = -DUSE_SNIFF -DHANGUL_INPUT -D"__attribute__(x)="
 
@@ -2488,7 +2490,7 @@ objects/if_xcmdsrv.o: if_xcmdsrv.c
 	$(CCC) -o $@ if_xcmdsrv.c
 
 objects/if_lua.o: if_lua.c
-	$(CCC) -o $@ if_lua.c
+	$(CCC) $(LUA_CFLAGS) -o $@ if_lua.c
 
 objects/if_mzsch.o: if_mzsch.c $(MZSCHEME_EXTRA)
 	$(CCC) -o $@ $(MZSCHEME_CFLAGS_EXTRA) if_mzsch.c
--- a/src/auto/configure
+++ b/src/auto/configure
@@ -1421,7 +1421,7 @@ Optional Features:
   --disable-selinux	  Don't check for SELinux support.
   --disable-xsmp          Disable XSMP session management
   --disable-xsmp-interact Disable XSMP interaction
-  --enable-luainterp      Include Lua interpreter.
+  --enable-luainterp=OPTS     Include Lua interpreter.  default=no OPTS=no/yes/dynamic
   --enable-mzschemeinterp   Include MzScheme interpreter.
   --enable-perlinterp=OPTS     Include Perl interpreter.  default=no OPTS=no/yes/dynamic
   --enable-pythoninterp   Include Python interpreter.
@@ -4594,7 +4594,7 @@ fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_luainterp" >&5
 $as_echo "$enable_luainterp" >&6; }
 
-if test "$enable_luainterp" = "yes"; then
+if test "$enable_luainterp" = "yes" -o "$enable_luainterp" = "dynamic"; then
 
 
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking --with-lua-prefix argument" >&5
@@ -4713,6 +4713,12 @@ fi
     LUA_PRO="if_lua.pro"
     $as_echo "#define FEAT_LUA 1" >>confdefs.h
 
+    if test "$enable_luainterp" = "dynamic"; then
+      $as_echo "#define DYNAMIC_LUA 1" >>confdefs.h
+
+      LUA_LIBS=""
+      LUA_CFLAGS="-DDYNAMIC_LUA_DLL=\\\"liblua${vi_cv_version_lua}.so\\\" $LUA_CFLAGS"
+    fi
   fi
 
 
--- a/src/config.h.in
+++ b/src/config.h.in
@@ -319,6 +319,9 @@
 /* Define if you want to include the Lua interpreter. */
 #undef FEAT_LUA
 
+/* Define for linking via dlopen() or LoadLibrary() */
+#undef DYNAMIC_LUA
+
 /* Define if you want to include the MzScheme interpreter. */
 #undef FEAT_MZSCHEME
 
--- a/src/configure.in
+++ b/src/configure.in
@@ -413,11 +413,11 @@ fi
 dnl Check for Lua feature.
 AC_MSG_CHECKING(--enable-luainterp argument)
 AC_ARG_ENABLE(luainterp,
-	[  --enable-luainterp      Include Lua interpreter.], ,
+	[  --enable-luainterp[=OPTS]     Include Lua interpreter.  [default=no] [OPTS=no/yes/dynamic]], ,
 	[enable_luainterp="no"])
 AC_MSG_RESULT($enable_luainterp)
 
-if test "$enable_luainterp" = "yes"; then
+if test "$enable_luainterp" = "yes" -o "$enable_luainterp" = "dynamic"; then
   dnl -- find the lua executable
   AC_SUBST(vi_cv_path_lua)
 
@@ -477,6 +477,11 @@ if test "$enable_luainterp" = "yes"; the
     LUA_OBJ="objects/if_lua.o"
     LUA_PRO="if_lua.pro"
     AC_DEFINE(FEAT_LUA)
+    if test "$enable_luainterp" = "dynamic"; then
+      AC_DEFINE(DYNAMIC_LUA)
+      LUA_LIBS=""
+      LUA_CFLAGS="-DDYNAMIC_LUA_DLL=\\\"liblua${vi_cv_version_lua}.so\\\" $LUA_CFLAGS"
+    fi
   fi
   AC_SUBST(LUA_SRC)
   AC_SUBST(LUA_OBJ)
--- a/src/if_lua.c
+++ b/src/if_lua.c
@@ -41,6 +41,19 @@ static const char LUAVIM_FREE[] = "luaV_
 
 
 #ifdef DYNAMIC_LUA
+
+#ifndef WIN3264
+# include <dlfcn.h>
+# define HANDLE void*
+# define load_dll(n) dlopen((n), RTLD_LAZY|RTLD_GLOBAL)
+# define symbol_from_dll dlsym
+# define close_dll dlclose
+#else
+# define load_dll LoadLibrary
+# define symbol_from_dll GetProcAddress
+# define close_dll FreeLibrary
+#endif
+
 /* lauxlib */
 #define luaL_register dll_luaL_register
 #define luaL_typerror dll_luaL_typerror
@@ -227,14 +240,14 @@ static const luaV_Reg luaV_dll[] = {
     {NULL, NULL}
 };
 
-static HINSTANCE hinstLua = 0;
+static HANDLE hinstLua = NULL;
 
     static void
 end_dynamic_lua(void)
 {
     if (hinstLua)
     {
-	FreeLibrary(hinstLua);
+	close_dll(hinstLua);
 	hinstLua = 0;
     }
 }
@@ -244,7 +257,7 @@ lua_link_init(char *libname, int verbose
 {
     const luaV_Reg *reg;
     if (hinstLua) return OK;
-    hinstLua = LoadLibrary(libname);
+    hinstLua = load_dll(libname);
     if (!hinstLua)
     {
 	if (verbose)
@@ -253,8 +266,9 @@ lua_link_init(char *libname, int verbose
     }
     for (reg = luaV_dll; reg->func; reg++)
     {
-	if ((*reg->func = GetProcAddress(hinstLua, reg->name)) == NULL) {
-	    FreeLibrary(hinstLua);
+	if ((*reg->func = symbol_from_dll(hinstLua, reg->name)) == NULL)
+	{
+	    close_dll(hinstLua);
 	    hinstLua = 0;
 	    if (verbose)
 		EMSG2(_(e_loadfunc), reg->name);
@@ -364,7 +378,8 @@ luaV_pushtypval(lua_State *L, typval_T *
 		/* check cache */
 		lua_pushlightuserdata(L, (void *) d);
 		lua_rawget(L, LUA_ENVIRONINDEX);
-		if (lua_isnil(L, -1)) { /* not interned? */
+		if (lua_isnil(L, -1)) /* not interned? */
+		{
 		    hashtab_T *ht = &d->dv_hashtab;
 		    hashitem_T *hi;
 		    int n = ht->ht_used; /* remaining items */
--- a/src/proto/if_lua.pro
+++ b/src/proto/if_lua.pro
@@ -1,4 +1,5 @@
 /* if_lua.c */
+int lua_enabled __ARGS((int verbose));
 void lua_end __ARGS((void));
 void ex_lua __ARGS((exarg_T *eap));
 void ex_luado __ARGS((exarg_T *eap));