mirror of
https://github.com/macvim-dev/macvim.git
synced 2026-06-11 15:37:29 +02:00
Merge remote-tracking branch 'vim/master'
This commit is contained in:
@@ -412,6 +412,8 @@ SRC_DOS = \
|
||||
src/msvc2008.bat \
|
||||
src/msvc2010.bat \
|
||||
src/msvc2015.bat \
|
||||
src/msys32.bat \
|
||||
src/msys64.bat \
|
||||
src/dimm.idl \
|
||||
src/dlldata.c \
|
||||
src/dosinst.c \
|
||||
|
||||
@@ -127,7 +127,7 @@ Vim evaluation and command execution, and others.
|
||||
rules. Example: >
|
||||
:lua t = {math.pi, false, say = 'hi'}
|
||||
:echo luaeval('vim.list(t)')
|
||||
:" [3.141593, 0], 'say' is ignored
|
||||
:" [3.141593, v:false], 'say' is ignored
|
||||
<
|
||||
vim.dict([arg]) Returns an empty dictionary or, if "arg" is a
|
||||
Lua table, returns a dict d such that d[k] =
|
||||
@@ -141,8 +141,7 @@ Vim evaluation and command execution, and others.
|
||||
:" {'say': 'hi'}, numeric keys ignored
|
||||
<
|
||||
vim.funcref({name}) Returns a Funcref to function {name} (see
|
||||
|Funcref|). It is equivalent to Vim's
|
||||
"function". NOT IMPLEMENTED YET
|
||||
|Funcref|). It is equivalent to Vim's function().
|
||||
|
||||
vim.buffer([arg]) If "arg" is a number, returns buffer with
|
||||
number "arg" in the buffer list or, if "arg"
|
||||
@@ -166,7 +165,7 @@ Vim evaluation and command execution, and others.
|
||||
or window, respectively. Examples: >
|
||||
:lua l = vim.list()
|
||||
:lua print(type(l), vim.type(l))
|
||||
:" userdata list
|
||||
:" list
|
||||
<
|
||||
vim.command({cmd}) Executes the vim (ex-mode) command {cmd}.
|
||||
Examples: >
|
||||
|
||||
+112
-32
@@ -22,23 +22,24 @@ any faster, but you can edit files larger than 2 Gbyte.
|
||||
|
||||
Contents:
|
||||
1. Microsoft Visual C++
|
||||
2. Using MinGW
|
||||
3. Cygwin
|
||||
4. Borland
|
||||
5. Cross compiling for Win32 from a Linux machine
|
||||
6. Building with Python support
|
||||
7. Building with Python3 support
|
||||
8. Building with Racket or MzScheme support
|
||||
9. Building with Lua support
|
||||
10. Building with Perl support
|
||||
11. Building with Ruby support
|
||||
12. Building with Tcl support
|
||||
13. Building with Terminal support
|
||||
14. Building with DirectX (DirectWrite) support
|
||||
15. Windows 3.1
|
||||
16. MS-DOS
|
||||
2. Using MSYS2 with MinGW
|
||||
3. Using MinGW
|
||||
4. Cygwin
|
||||
5. Borland
|
||||
6. Cross compiling for Win32 from a Linux machine
|
||||
7. Building with Python support
|
||||
8. Building with Python3 support
|
||||
9. Building with Racket or MzScheme support
|
||||
10. Building with Lua support
|
||||
11. Building with Perl support
|
||||
12. Building with Ruby support
|
||||
13. Building with Tcl support
|
||||
14. Building with Terminal support
|
||||
15. Building with DirectX (DirectWrite) support
|
||||
16. Windows 3.1
|
||||
17. MS-DOS
|
||||
|
||||
17. Installing after building from sources
|
||||
18. Installing after building from sources
|
||||
|
||||
|
||||
The currently recommended way (that means it has been verified to work) is
|
||||
@@ -261,8 +262,87 @@ Instructions for integrating the Platform SDK into VC Express:
|
||||
http://msdn.microsoft.com/vstudio/express/visualc/usingpsdk/default.aspx
|
||||
|
||||
|
||||
2. MSYS2 with MinGW
|
||||
===================
|
||||
|
||||
2. MinGW
|
||||
2.1. Setup the basic msys2 environment
|
||||
|
||||
Go to the official page of MSYS2: https://www.msys2.org
|
||||
Download an installer:
|
||||
|
||||
* msys2-x86_64-YYYYMMDD.exe for 64-bit Windows
|
||||
(Even if you want to build 32-bit Vim)
|
||||
* msys2-i686-YYYYMMDD.exe for 32-bit Windows
|
||||
|
||||
Execute the installer and follow the instructions to update basic packages.
|
||||
At the end keep the checkbox checked to run msys2 now. If needed, you can
|
||||
open the window from the start menu, MSYS2 64 bit / MSYS2 MSYS
|
||||
|
||||
Execute:
|
||||
$ pacman -Syu
|
||||
|
||||
And restart MSYS2 window (select "MSYS2 MSYS" icon from the Start Menu).
|
||||
Then execute:
|
||||
$ pacman -Su
|
||||
|
||||
If pacman complains that `catgets` and `libcatgets` conflict with another
|
||||
package, select `y` to remove them.
|
||||
|
||||
|
||||
2.2. Install additional packages for building Vim
|
||||
|
||||
The following package groups are required for building Vim:
|
||||
|
||||
* base-devel
|
||||
* mingw-w64-i686-toolchain (for building 32-bit Vim)
|
||||
* mingw-w64-x86_64-toolchain (for building 64-bit Vim)
|
||||
|
||||
Use the following command to install them:
|
||||
|
||||
$ pacman -S base-devel mingw-w64-i686-toolchain mingw-w64-x86_64-toolchain
|
||||
|
||||
Or you can use the `pacboy` command to avoid long package names:
|
||||
|
||||
$ pacboy -S base-devel: toolchain:m
|
||||
|
||||
(See `pacboy help` for the help.)
|
||||
|
||||
|
||||
2.3. Keep the build environment up-to-date
|
||||
|
||||
After you have installed the build environment, you may want to keep it
|
||||
up-to-date (E.g. always use the latest GCC).
|
||||
In that case, you just need to execute the command:
|
||||
$ pacman -Syu
|
||||
|
||||
|
||||
# Build Vim
|
||||
|
||||
Select one of the following icon from the Start Menu:
|
||||
|
||||
* MSYS2 MinGW 32-bit (To build 32-bit versions of Vim)
|
||||
* MSYS2 MinGW 64-bit (To build 64-bit versions of Vim)
|
||||
|
||||
Go to the source directory of Vim, then execute the make command. E.g.:
|
||||
|
||||
make -f Make_ming.mak
|
||||
make -f Make_ming.mak GUI=no
|
||||
make -f Make_ming.mak GUI=no DEBUG=yes
|
||||
|
||||
NOTE: you can't execute the vim.exe in the MSYS console, open a normal Windows
|
||||
console for that. You need to set $PATH to be able to build there, e.g.:
|
||||
|
||||
set PATH=c:\msys64\mingw32\bin;c:\msys64\usr\bin;%PATH%
|
||||
|
||||
This command is in msys32.bat. Or or the 64 bit compiler use msys64.bat:
|
||||
|
||||
set PATH=c:\msys64\mingw64\bin;c:\msys64\usr\bin;%PATH%
|
||||
|
||||
If you have msys64 in another location you will need to adjust the paths for
|
||||
that.
|
||||
|
||||
|
||||
3. MinGW
|
||||
========
|
||||
|
||||
(written by Ron Aaron: <ronaharon@yahoo.com>)
|
||||
@@ -344,7 +424,7 @@ If you want National Language Support, read the file src/po/README_mingw.txt.
|
||||
You need to uncomment lines in Make_ming.mak to have NLS defined.
|
||||
|
||||
|
||||
3. Cygwin
|
||||
4. Cygwin
|
||||
=========
|
||||
|
||||
Use Make_cyg.mak with Cygwin's GCC. See
|
||||
@@ -356,14 +436,14 @@ running on Unix), while with Make_cyg.mak you get a Windows application (like
|
||||
with the other makefiles).
|
||||
|
||||
|
||||
4. Borland
|
||||
5. Borland
|
||||
===========
|
||||
|
||||
Use Make_bc5.mak with Borland C++ 5.x. See
|
||||
http://users.skynet.be/antoine.mechelynck/vim/compile.htm
|
||||
|
||||
|
||||
5. Cross compiling for Win32 from a Linux machine
|
||||
6. Cross compiling for Win32 from a Linux machine
|
||||
=================================================
|
||||
|
||||
[Update of 1) needs to be verified]
|
||||
@@ -383,7 +463,7 @@ your Linux (or other unix) box. To do this, you need to follow a few steps:
|
||||
Now you have created the Windows binary from your Linux box! Have fun...
|
||||
|
||||
|
||||
6. Building with Python support
|
||||
7. Building with Python support
|
||||
===============================
|
||||
|
||||
For building with MSVC 2008 the "Windows Installer" from www.python.org
|
||||
@@ -435,7 +515,7 @@ And if you use msys2 to build python support (as one line):
|
||||
You will end up with a Python-enabled, Win32 version. Enjoy!
|
||||
|
||||
|
||||
7. Building with Python3 support
|
||||
8. Building with Python3 support
|
||||
================================
|
||||
|
||||
For building with MSVC 2008 the "Windows Installer" from www.python.org
|
||||
@@ -466,7 +546,7 @@ When using msys2 and link with Python3 bundled with msys2 (as one line):
|
||||
(This is for 64-bit builds. For 32-bit builds, replace mingw64 with mingw32.)
|
||||
|
||||
|
||||
8. Building with Racket or MzScheme support
|
||||
9. Building with Racket or MzScheme support
|
||||
========================================
|
||||
|
||||
1) Building with Racket support (newest)
|
||||
@@ -556,7 +636,7 @@ After a successful build, these dlls can be freely removed, leaving them in
|
||||
|
||||
|
||||
|
||||
9. Building with Lua support
|
||||
10. Building with Lua support
|
||||
============================
|
||||
|
||||
Vim with Lua support can be built with either MSVC or MinGW (or maybe Cygwin).
|
||||
@@ -611,7 +691,7 @@ Or when using Cygwin (as one line) (untested):
|
||||
LUA=/cygdrive/c/projects/lua53 DYNAMIC_LUA=yes LUA_VER=53
|
||||
|
||||
|
||||
10. Building with Perl support
|
||||
11. Building with Perl support
|
||||
==============================
|
||||
|
||||
Vim with Perl support can be built with either MSVC or MinGW (or Cygwin).
|
||||
@@ -637,7 +717,7 @@ Or when using MinGW (as one line):
|
||||
PERL=C:/Perl DYNAMIC_PERL=yes PERL_VER=522
|
||||
|
||||
|
||||
11. Building with Ruby support
|
||||
12. Building with Ruby support
|
||||
==============================
|
||||
|
||||
Vim with Ruby support can be built with either MSVC or MinGW (or Cygwin).
|
||||
@@ -745,7 +825,7 @@ Ruby 2.1 or later. (Default is 0x501.)
|
||||
|
||||
|
||||
|
||||
12. Building with Tcl support
|
||||
13. Building with Tcl support
|
||||
=============================
|
||||
|
||||
Vim with Tcl support can be built with either MSVC or MinGW (or Cygwin).
|
||||
@@ -777,7 +857,7 @@ Or when using MinGW (as one line):
|
||||
TCL=C:/Tcl86 DYNAMIC_TCL=yes TCL_VER=86 TCL_VER_LONG=8.6
|
||||
|
||||
|
||||
13. Building with Terminal support
|
||||
14. Building with Terminal support
|
||||
==================================
|
||||
|
||||
Vim with Terminal support can be built with either MSVC, MinGW or Cygwin.
|
||||
@@ -793,7 +873,7 @@ Or when using MinGW:
|
||||
mingw32-make -f Make_ming.mak TERMINAL=yes
|
||||
|
||||
|
||||
14. Building with DirectX (DirectWrite) support
|
||||
15. Building with DirectX (DirectWrite) support
|
||||
===============================================
|
||||
|
||||
Vim with DirectX (DirectWrite) support can be built with either MSVC or MinGW.
|
||||
@@ -827,20 +907,20 @@ Just set DIRECTX to yes:
|
||||
mingw32-make -f Make_ming.mak DIRECTX=yes
|
||||
|
||||
|
||||
15. Windows 3.1x
|
||||
16. Windows 3.1x
|
||||
================
|
||||
|
||||
The Windows 3.1x support was removed in patch 7.4.1364.
|
||||
|
||||
|
||||
16. MS-DOS
|
||||
17. MS-DOS
|
||||
==========
|
||||
|
||||
The MS-DOS support was removed in patch 7.4.1399. Only very old Vim versions
|
||||
work on MS-DOS because of the limited amount of memory available.
|
||||
|
||||
|
||||
17. Installing after building from sources
|
||||
18. Installing after building from sources
|
||||
==========================================
|
||||
|
||||
[provided by Michael Soyka, updated by Ken Takata]
|
||||
|
||||
@@ -75,9 +75,10 @@ POSTSCRIPT=no
|
||||
# Set to yes to enable OLE support.
|
||||
OLE=no
|
||||
|
||||
# Set the default $(WINVER) to make it work with WinXP.
|
||||
# Set the default $(WINVER). Use 0x0501 to make it work with WinXP.
|
||||
ifndef WINVER
|
||||
WINVER = 0x0501
|
||||
# WINVER = 0x0501
|
||||
WINVER = 0x0600
|
||||
endif
|
||||
|
||||
# Set to yes to enable Cscope support.
|
||||
|
||||
+2
-1
@@ -2136,7 +2136,7 @@ test1 \
|
||||
test52 test59 \
|
||||
test64 test69 \
|
||||
test70 test72 \
|
||||
test85 test86 test87 test88 \
|
||||
test86 test87 test88 \
|
||||
test94 test95 test99 test108:
|
||||
cd testdir; rm -f $@.out; $(MAKE) -f Makefile $@.out VIMPROG=../$(VIMTESTTARGET) $(GUI_TESTARG) SCRIPTSOURCE=../$(SCRIPTSOURCE)
|
||||
|
||||
@@ -2305,6 +2305,7 @@ test_arglist \
|
||||
test_syn_attr \
|
||||
test_syntax \
|
||||
test_system \
|
||||
test_tab \
|
||||
test_tabline \
|
||||
test_tabpage \
|
||||
test_tagcase \
|
||||
|
||||
+3
-3
@@ -9387,7 +9387,7 @@ ins_bs(
|
||||
if (p_sta && in_indent)
|
||||
want_vcol = (want_vcol / curbuf->b_p_sw) * curbuf->b_p_sw;
|
||||
else
|
||||
want_vcol = tabstop_start(want_vcol, curbuf->b_p_sts,
|
||||
want_vcol = tabstop_start(want_vcol, get_sts_value(),
|
||||
curbuf->b_p_vsts_array);
|
||||
#else
|
||||
want_vcol = (want_vcol / ts) * ts;
|
||||
@@ -10236,9 +10236,9 @@ ins_tab(void)
|
||||
temp = (int)curbuf->b_p_sw;
|
||||
temp -= get_nolist_virtcol() % temp;
|
||||
}
|
||||
else if (tabstop_count(curbuf->b_p_vsts_array) > 0 || curbuf->b_p_sts > 0)
|
||||
else if (tabstop_count(curbuf->b_p_vsts_array) > 0 || curbuf->b_p_sts != 0)
|
||||
/* use 'softtabstop' when set */
|
||||
temp = tabstop_padding(get_nolist_virtcol(), curbuf->b_p_sts,
|
||||
temp = tabstop_padding(get_nolist_virtcol(), get_sts_value(),
|
||||
curbuf->b_p_vsts_array);
|
||||
else /* otherwise use 'tabstop' */
|
||||
temp = tabstop_padding(get_nolist_virtcol(), curbuf->b_p_ts,
|
||||
|
||||
+1
-1
@@ -6628,7 +6628,7 @@ f_has(typval_T *argvars, typval_T *rettv)
|
||||
#endif
|
||||
#ifdef FEAT_VTP
|
||||
else if (STRICMP(name, "vcon") == 0)
|
||||
n = has_vtp_working();
|
||||
n = is_term_win32() && has_vtp_working();
|
||||
#endif
|
||||
#ifdef FEAT_NETBEANS_INTG
|
||||
else if (STRICMP(name, "netbeans_enabled") == 0)
|
||||
|
||||
+15
-5
@@ -398,6 +398,7 @@ ex_sort(exarg_T *eap)
|
||||
colnr_T end_col;
|
||||
int sort_what = 0;
|
||||
int format_found = 0;
|
||||
int change_occurred = FALSE; // Buffer contents changed.
|
||||
|
||||
/* Sorting one line is really quick! */
|
||||
if (count <= 1)
|
||||
@@ -616,12 +617,19 @@ ex_sort(exarg_T *eap)
|
||||
lnum = eap->line2;
|
||||
for (i = 0; i < count; ++i)
|
||||
{
|
||||
s = ml_get(nrs[eap->forceit ? count - i - 1 : i].lnum);
|
||||
linenr_T get_lnum = nrs[eap->forceit ? count - i - 1 : i].lnum;
|
||||
|
||||
// If the original line number of the line being placed is not the same
|
||||
// as "lnum" (accounting for offset), we know that the buffer changed.
|
||||
if (get_lnum + ((linenr_T)count - 1) != lnum)
|
||||
change_occurred = TRUE;
|
||||
|
||||
s = ml_get(get_lnum);
|
||||
if (!unique || i == 0
|
||||
|| (sort_ic ? STRICMP(s, sortbuf1) : STRCMP(s, sortbuf1)) != 0)
|
||||
{
|
||||
/* Copy the line into a buffer, it may become invalid in
|
||||
* ml_append(). And it's needed for "unique". */
|
||||
// Copy the line into a buffer, it may become invalid in
|
||||
// ml_append(). And it's needed for "unique".
|
||||
STRCPY(sortbuf1, s);
|
||||
if (ml_append(lnum++, sortbuf1, (colnr_T)0, FALSE) == FAIL)
|
||||
break;
|
||||
@@ -644,7 +652,9 @@ ex_sort(exarg_T *eap)
|
||||
mark_adjust(eap->line2 - deleted, eap->line2, (long)MAXLNUM, -deleted);
|
||||
else if (deleted < 0)
|
||||
mark_adjust(eap->line2, MAXLNUM, -deleted, 0L);
|
||||
changed_lines(eap->line1, 0, eap->line2 + 1, -deleted);
|
||||
|
||||
if (change_occurred || deleted != 0)
|
||||
changed_lines(eap->line1, 0, eap->line2 + 1, -deleted);
|
||||
|
||||
curwin->w_cursor.lnum = eap->line1;
|
||||
beginline(BL_WHITE | BL_FIX);
|
||||
@@ -856,7 +866,6 @@ ex_retab(exarg_T *eap)
|
||||
{
|
||||
set_string_option_direct((char_u *)"vts", -1, new_ts_str,
|
||||
OPT_FREE|OPT_LOCAL, 0);
|
||||
vim_free(new_ts_str);
|
||||
curbuf->b_p_vts_array = new_vts_array;
|
||||
vim_free(old_vts_ary);
|
||||
}
|
||||
@@ -867,6 +876,7 @@ ex_retab(exarg_T *eap)
|
||||
curbuf->b_p_ts = tabstop_first(new_vts_array);
|
||||
vim_free(new_vts_array);
|
||||
}
|
||||
vim_free(new_ts_str);
|
||||
}
|
||||
#else
|
||||
curbuf->b_p_ts = new_ts;
|
||||
|
||||
+1
-1
@@ -1419,7 +1419,7 @@ check_due_timer(void)
|
||||
bevalexpr_due_set = FALSE;
|
||||
if (balloonEval == NULL)
|
||||
{
|
||||
balloonEval = (BalloonEval *)alloc(sizeof(BalloonEval));
|
||||
balloonEval = (BalloonEval *)alloc_clear(sizeof(BalloonEval));
|
||||
balloonEvalForTerm = TRUE;
|
||||
}
|
||||
if (balloonEval != NULL)
|
||||
|
||||
@@ -745,7 +745,12 @@ gui_init(void)
|
||||
/* Always create the Balloon Evaluation area, but disable it when
|
||||
* 'ballooneval' is off. */
|
||||
if (balloonEval != NULL)
|
||||
{
|
||||
# ifdef FEAT_VARTABS
|
||||
vim_free(balloonEval->vts);
|
||||
# endif
|
||||
vim_free(balloonEval);
|
||||
}
|
||||
balloonEvalForTerm = FALSE;
|
||||
# ifdef FEAT_GUI_GTK
|
||||
balloonEval = gui_mch_create_beval_area(gui.drawarea, NULL,
|
||||
|
||||
+1
-10
@@ -111,28 +111,19 @@ gui_mch_create_beval_area(
|
||||
return NULL;
|
||||
}
|
||||
|
||||
beval = (BalloonEval *)alloc(sizeof(BalloonEval));
|
||||
beval = (BalloonEval *)alloc_clear(sizeof(BalloonEval));
|
||||
if (beval != NULL)
|
||||
{
|
||||
#ifdef FEAT_GUI_GTK
|
||||
beval->target = GTK_WIDGET(target);
|
||||
beval->balloonShell = NULL;
|
||||
beval->timerID = 0;
|
||||
#else
|
||||
beval->target = (Widget)target;
|
||||
beval->balloonShell = NULL;
|
||||
beval->timerID = (XtIntervalId)NULL;
|
||||
beval->appContext = XtWidgetToApplicationContext((Widget)target);
|
||||
#endif
|
||||
beval->showState = ShS_NEUTRAL;
|
||||
beval->x = 0;
|
||||
beval->y = 0;
|
||||
beval->msg = mesg;
|
||||
beval->msgCB = mesgCB;
|
||||
beval->clientData = clientData;
|
||||
#ifdef FEAT_VARTABS
|
||||
beval->vts = NULL;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Set up event handler which will keep its eyes on the pointer,
|
||||
|
||||
+1
-8
@@ -8922,28 +8922,21 @@ gui_mch_create_beval_area(
|
||||
return NULL;
|
||||
}
|
||||
|
||||
beval = (BalloonEval *)alloc(sizeof(BalloonEval));
|
||||
beval = (BalloonEval *)alloc_clear(sizeof(BalloonEval));
|
||||
if (beval != NULL)
|
||||
{
|
||||
beval->target = s_textArea;
|
||||
beval->balloon = NULL;
|
||||
|
||||
beval->showState = ShS_NEUTRAL;
|
||||
beval->x = 0;
|
||||
beval->y = 0;
|
||||
beval->msg = mesg;
|
||||
beval->msgCB = mesgCB;
|
||||
beval->clientData = clientData;
|
||||
#ifdef FEAT_VARTABS
|
||||
beval->vts = NULL;
|
||||
#endif
|
||||
|
||||
InitCommonControls();
|
||||
cur_beval = beval;
|
||||
|
||||
if (p_beval)
|
||||
gui_mch_enable_beval_area(beval);
|
||||
|
||||
}
|
||||
return beval;
|
||||
}
|
||||
|
||||
+238
-27
@@ -28,10 +28,16 @@ typedef buf_T *luaV_Buffer;
|
||||
typedef win_T *luaV_Window;
|
||||
typedef dict_T *luaV_Dict;
|
||||
typedef list_T *luaV_List;
|
||||
typedef struct {
|
||||
typval_T tv; // funcref
|
||||
typval_T args;
|
||||
dict_T *self; // selfdict
|
||||
} luaV_Funcref;
|
||||
typedef void (*msgfunc_T)(char_u *);
|
||||
|
||||
static const char LUAVIM_DICT[] = "dict";
|
||||
static const char LUAVIM_LIST[] = "list";
|
||||
static const char LUAVIM_FUNCREF[] = "funcref";
|
||||
static const char LUAVIM_BUFFER[] = "buffer";
|
||||
static const char LUAVIM_WINDOW[] = "window";
|
||||
static const char LUAVIM_FREE[] = "luaV_free";
|
||||
@@ -55,9 +61,15 @@ static const char LUAVIM_SETREF[] = "luaV_setref";
|
||||
if (sandbox) luaL_error((L), "not allowed in sandbox")
|
||||
#define luaV_msg(L) luaV_msgfunc((L), (msgfunc_T) msg)
|
||||
#define luaV_emsg(L) luaV_msgfunc((L), (msgfunc_T) emsg)
|
||||
#define luaV_checktypval(L, a, v, msg) \
|
||||
do { \
|
||||
if (luaV_totypval(L, a, v) == FAIL) \
|
||||
luaL_error(L, msg ": cannot convert value"); \
|
||||
} while (0)
|
||||
|
||||
static luaV_List *luaV_pushlist (lua_State *L, list_T *lis);
|
||||
static luaV_Dict *luaV_pushdict (lua_State *L, dict_T *dic);
|
||||
static luaV_List *luaV_pushlist(lua_State *L, list_T *lis);
|
||||
static luaV_Dict *luaV_pushdict(lua_State *L, dict_T *dic);
|
||||
static luaV_Funcref *luaV_pushfuncref(lua_State *L, typval_T *tv);
|
||||
|
||||
#if LUA_VERSION_NUM <= 501
|
||||
#define luaV_openlib(L, l, n) luaL_openlib(L, NULL, l, n)
|
||||
@@ -506,16 +518,25 @@ luaV_pushtypval(lua_State *L, typval_T *tv)
|
||||
else
|
||||
lua_pushnil(L);
|
||||
break;
|
||||
case VAR_FUNC:
|
||||
luaV_pushfuncref(L, tv);
|
||||
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)
|
||||
/*
|
||||
* Converts lua value at 'pos' to typval 'tv'.
|
||||
* Returns OK or FAIL.
|
||||
*/
|
||||
static int
|
||||
luaV_totypval(lua_State *L, int pos, typval_T *tv)
|
||||
{
|
||||
switch(lua_type(L, pos)) {
|
||||
int status = OK;
|
||||
|
||||
switch (lua_type(L, pos))
|
||||
{
|
||||
case LUA_TBOOLEAN:
|
||||
tv->v_type = VAR_SPECIAL;
|
||||
tv->vval.v_number = (varnumber_T) lua_toboolean(L, pos);
|
||||
@@ -533,8 +554,10 @@ luaV_totypval (lua_State *L, int pos, typval_T *tv)
|
||||
tv->vval.v_number = (varnumber_T) lua_tointeger(L, pos);
|
||||
#endif
|
||||
break;
|
||||
case LUA_TUSERDATA: {
|
||||
case LUA_TUSERDATA:
|
||||
{
|
||||
void *p = lua_touserdata(L, pos);
|
||||
|
||||
if (lua_getmetatable(L, pos)) /* has metatable? */
|
||||
{
|
||||
/* check list */
|
||||
@@ -545,7 +568,7 @@ luaV_totypval (lua_State *L, int pos, typval_T *tv)
|
||||
tv->vval.v_list = *((luaV_List *) p);
|
||||
++tv->vval.v_list->lv_refcount;
|
||||
lua_pop(L, 2); /* MTs */
|
||||
return;
|
||||
break;
|
||||
}
|
||||
/* check dict */
|
||||
luaV_getfield(L, LUAVIM_DICT);
|
||||
@@ -555,16 +578,27 @@ luaV_totypval (lua_State *L, int pos, typval_T *tv)
|
||||
tv->vval.v_dict = *((luaV_Dict *) p);
|
||||
++tv->vval.v_dict->dv_refcount;
|
||||
lua_pop(L, 3); /* MTs */
|
||||
return;
|
||||
break;
|
||||
}
|
||||
lua_pop(L, 3); /* MTs */
|
||||
/* check funcref */
|
||||
luaV_getfield(L, LUAVIM_FUNCREF);
|
||||
if (lua_rawequal(L, -1, -4))
|
||||
{
|
||||
luaV_Funcref *f = (luaV_Funcref *) p;
|
||||
copy_tv(&f->tv, tv);
|
||||
lua_pop(L, 4); /* MTs */
|
||||
break;
|
||||
}
|
||||
lua_pop(L, 4); /* MTs */
|
||||
}
|
||||
break;
|
||||
}
|
||||
/* FALLTHROUGH */
|
||||
default:
|
||||
tv->v_type = VAR_NUMBER;
|
||||
tv->vval.v_number = 0;
|
||||
status = FAIL;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
/* similar to luaL_addlstring, but replaces \0 with \n if toline and
|
||||
@@ -646,7 +680,7 @@ luaV_msgfunc(lua_State *L, msgfunc_T mf)
|
||||
|
||||
#define luaV_pushtype(typ,tname,luatyp) \
|
||||
static luatyp * \
|
||||
luaV_push##tname (lua_State *L, typ *obj) \
|
||||
luaV_push##tname(lua_State *L, typ *obj) \
|
||||
{ \
|
||||
luatyp *o = NULL; \
|
||||
if (obj == NULL) \
|
||||
@@ -766,7 +800,7 @@ luaV_list_newindex (lua_State *L)
|
||||
else
|
||||
{
|
||||
typval_T v;
|
||||
luaV_totypval(L, 3, &v);
|
||||
luaV_checktypval(L, 3, &v, "setting list item");
|
||||
clear_tv(&li->li_tv);
|
||||
copy_tv(&v, &li->li_tv);
|
||||
clear_tv(&v);
|
||||
@@ -783,11 +817,11 @@ luaV_list_add (lua_State *L)
|
||||
if (l->lv_lock)
|
||||
luaL_error(L, "list is locked");
|
||||
lua_settop(L, 2);
|
||||
luaV_totypval(L, 2, &v);
|
||||
luaV_checktypval(L, 2, &v, "adding list item");
|
||||
if (list_append_tv(l, &v) == FAIL)
|
||||
{
|
||||
clear_tv(&v);
|
||||
luaL_error(L, "Failed to add item to list");
|
||||
luaL_error(L, "failed to add item to list");
|
||||
}
|
||||
clear_tv(&v);
|
||||
lua_settop(L, 1);
|
||||
@@ -811,11 +845,11 @@ luaV_list_insert (lua_State *L)
|
||||
luaL_error(L, "invalid position");
|
||||
}
|
||||
lua_settop(L, 2);
|
||||
luaV_totypval(L, 2, &v);
|
||||
luaV_checktypval(L, 2, &v, "inserting list item");
|
||||
if (list_insert_tv(l, &v, li) == FAIL)
|
||||
{
|
||||
clear_tv(&v);
|
||||
luaL_error(L, "Failed to add item to list");
|
||||
luaL_error(L, "failed to add item to list");
|
||||
}
|
||||
clear_tv(&v);
|
||||
lua_settop(L, 1);
|
||||
@@ -894,26 +928,43 @@ luaV_dict_call (lua_State *L)
|
||||
}
|
||||
|
||||
static int
|
||||
luaV_dict_index (lua_State *L)
|
||||
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);
|
||||
if (di->di_tv.v_type == VAR_FUNC) /* funcref? */
|
||||
{
|
||||
luaV_Funcref *f = (luaV_Funcref *) lua_touserdata(L, -1);
|
||||
f->self = d; /* keep "self" reference */
|
||||
d->dv_refcount++;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
luaV_dict_newindex (lua_State *L)
|
||||
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;
|
||||
typval_T v;
|
||||
if (d->dv_lock)
|
||||
luaL_error(L, "dict is locked");
|
||||
if (key != NULL && *key == NUL)
|
||||
luaL_error(L, "empty key");
|
||||
if (!lua_isnil(L, 3)) { /* read value? */
|
||||
luaV_checktypval(L, 3, &v, "setting dict item");
|
||||
if (d->dv_scope == VAR_DEF_SCOPE && v.v_type == VAR_FUNC)
|
||||
luaL_error(L, "cannot assign funcref to builtin scope");
|
||||
}
|
||||
di = dict_find(d, key, -1);
|
||||
if (di == NULL) /* non-existing key? */
|
||||
{
|
||||
@@ -934,9 +985,8 @@ luaV_dict_newindex (lua_State *L)
|
||||
hash_remove(&d->dv_hashtab, hi);
|
||||
dictitem_free(di);
|
||||
}
|
||||
else {
|
||||
typval_T v;
|
||||
luaV_totypval(L, 3, &v);
|
||||
else
|
||||
{
|
||||
copy_tv(&v, &di->di_tv);
|
||||
clear_tv(&v);
|
||||
}
|
||||
@@ -953,6 +1003,92 @@ static const luaL_Reg luaV_Dict_mt[] = {
|
||||
};
|
||||
|
||||
|
||||
/* ======= Funcref type ======= */
|
||||
|
||||
static luaV_Funcref *
|
||||
luaV_newfuncref(lua_State *L, char_u *name)
|
||||
{
|
||||
luaV_Funcref *f = (luaV_Funcref *)lua_newuserdata(L, sizeof(luaV_Funcref));
|
||||
|
||||
if (name != NULL)
|
||||
{
|
||||
func_ref(name); /* as in copy_tv */
|
||||
f->tv.vval.v_string = vim_strsave(name);
|
||||
}
|
||||
f->tv.v_type = VAR_FUNC;
|
||||
f->args.v_type = VAR_LIST;
|
||||
f->self = NULL;
|
||||
luaV_getfield(L, LUAVIM_FUNCREF);
|
||||
lua_setmetatable(L, -2);
|
||||
return f;
|
||||
}
|
||||
|
||||
static luaV_Funcref *
|
||||
luaV_pushfuncref(lua_State *L, typval_T *tv)
|
||||
{
|
||||
luaV_Funcref *f = luaV_newfuncref(L, NULL);
|
||||
copy_tv(tv, &f->tv);
|
||||
clear_tv(tv);
|
||||
return f;
|
||||
}
|
||||
|
||||
|
||||
luaV_type_tostring(funcref, LUAVIM_FUNCREF)
|
||||
|
||||
static int
|
||||
luaV_funcref_gc(lua_State *L)
|
||||
{
|
||||
luaV_Funcref *f = (luaV_Funcref *) lua_touserdata(L, 1);
|
||||
|
||||
func_unref(f->tv.vval.v_string);
|
||||
vim_free(f->tv.vval.v_string);
|
||||
dict_unref(f->self);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* equivalent to string(funcref) */
|
||||
static int
|
||||
luaV_funcref_len(lua_State *L)
|
||||
{
|
||||
luaV_Funcref *f = (luaV_Funcref *) lua_touserdata(L, 1);
|
||||
|
||||
lua_pushstring(L, (const char *) f->tv.vval.v_string);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
luaV_funcref_call(lua_State *L)
|
||||
{
|
||||
luaV_Funcref *f = (luaV_Funcref *) lua_touserdata(L, 1);
|
||||
int i, n = lua_gettop(L) - 1; /* #args */
|
||||
int status;
|
||||
typval_T v, rettv;
|
||||
|
||||
f->args.vval.v_list = list_alloc();
|
||||
rettv.v_type = VAR_UNKNOWN; /* as in clear_tv */
|
||||
for (i = 0; i < n; i++) {
|
||||
luaV_checktypval(L, i + 2, &v, "calling funcref");
|
||||
list_append_tv(f->args.vval.v_list, &v);
|
||||
}
|
||||
status = func_call(f->tv.vval.v_string, &f->args, NULL, f->self, &rettv);
|
||||
if (status == OK)
|
||||
luaV_pushtypval(L, &rettv);
|
||||
clear_tv(&f->args);
|
||||
clear_tv(&rettv);
|
||||
if (status != OK)
|
||||
luaL_error(L, "cannot call funcref");
|
||||
return 1;
|
||||
}
|
||||
|
||||
static const luaL_Reg luaV_Funcref_mt[] = {
|
||||
{"__tostring", luaV_funcref_tostring},
|
||||
{"__gc", luaV_funcref_gc},
|
||||
{"__len", luaV_funcref_len},
|
||||
{"__call", luaV_funcref_call},
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
|
||||
/* ======= Buffer type ======= */
|
||||
|
||||
luaV_newtype(buf_T, buffer, luaV_Buffer, LUAVIM_BUFFER)
|
||||
@@ -1033,7 +1169,8 @@ luaV_buffer_newindex(lua_State *L)
|
||||
curbuf = buf;
|
||||
luaL_error(L, "cannot delete line");
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
deleted_lines_mark(n, 1L);
|
||||
if (b == curwin->w_buffer) /* fix cursor in current window? */
|
||||
{
|
||||
@@ -1371,22 +1508,84 @@ luaV_line(lua_State *L)
|
||||
static int
|
||||
luaV_list(lua_State *L)
|
||||
{
|
||||
list_T *l = list_alloc();
|
||||
list_T *l;
|
||||
int initarg = !lua_isnoneornil(L, 1);
|
||||
|
||||
if (initarg && lua_type(L, 1) != LUA_TTABLE)
|
||||
luaL_error(L, "table expected, got %s", luaL_typename(L, 1));
|
||||
l = list_alloc();
|
||||
if (l == NULL)
|
||||
lua_pushnil(L);
|
||||
else
|
||||
{
|
||||
luaV_newlist(L, l);
|
||||
if (initarg) { /* traverse table to init dict */
|
||||
int notnil, i = 0;
|
||||
typval_T v;
|
||||
do {
|
||||
lua_rawgeti(L, 1, ++i);
|
||||
notnil = !lua_isnil(L, -1);
|
||||
if (notnil) {
|
||||
luaV_checktypval(L, -1, &v, "vim.list");
|
||||
list_append_tv(l, &v);
|
||||
}
|
||||
lua_pop(L, 1); /* value */
|
||||
} while (notnil);
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
luaV_dict(lua_State *L)
|
||||
{
|
||||
dict_T *d = dict_alloc();
|
||||
dict_T *d;
|
||||
int initarg = !lua_isnoneornil(L, 1);
|
||||
|
||||
if (initarg && lua_type(L, 1) != LUA_TTABLE)
|
||||
luaL_error(L, "table expected, got %s", luaL_typename(L, 1));
|
||||
d = dict_alloc();
|
||||
if (d == NULL)
|
||||
lua_pushnil(L);
|
||||
else
|
||||
{
|
||||
luaV_newdict(L, d);
|
||||
if (initarg) /* traverse table to init dict */
|
||||
{
|
||||
lua_pushnil(L);
|
||||
while (lua_next(L, 1))
|
||||
{
|
||||
char_u *key;
|
||||
dictitem_T *di;
|
||||
typval_T v;
|
||||
lua_pushvalue(L, -2); /* dup key in case it's a number */
|
||||
key = (char_u *) lua_tostring(L, -1);
|
||||
if (key != NULL && *key == NUL)
|
||||
luaL_error(L, "table has empty key");
|
||||
luaV_checktypval(L, -2, &v, "vim.dict"); /* value */
|
||||
di = dictitem_alloc(key);
|
||||
if (di == NULL || dict_add(d, di) == FAIL) {
|
||||
vim_free(di);
|
||||
lua_pushnil(L);
|
||||
return 1;
|
||||
}
|
||||
copy_tv(&v, &di->di_tv);
|
||||
clear_tv(&v);
|
||||
lua_pop(L, 2); /* key copy and value */
|
||||
}
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
luaV_funcref(lua_State *L)
|
||||
{
|
||||
const char *name = luaL_checkstring(L, 1);
|
||||
/* note: not checking if function exists (needs function_exists) */
|
||||
if (name == NULL || *name == NUL || VIM_ISDIGIT(*name))
|
||||
luaL_error(L, "invalid function name: %s", name);
|
||||
luaV_newfuncref(L, (char_u *) name);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -1402,7 +1601,8 @@ luaV_buffer(lua_State *L)
|
||||
FOR_ALL_BUFFERS(buf)
|
||||
if (buf->b_fnum == n) break;
|
||||
}
|
||||
else { /* by name */
|
||||
else // by name
|
||||
{
|
||||
size_t l;
|
||||
const char *s = lua_tolstring(L, 1, &l);
|
||||
FOR_ALL_BUFFERS(buf)
|
||||
@@ -1472,6 +1672,12 @@ luaV_type(lua_State *L)
|
||||
lua_pushstring(L, "dict");
|
||||
return 1;
|
||||
}
|
||||
luaV_getfield(L, LUAVIM_FUNCREF);
|
||||
if (lua_rawequal(L, -1, 2))
|
||||
{
|
||||
lua_pushstring(L, "funcref");
|
||||
return 1;
|
||||
}
|
||||
luaV_getfield(L, LUAVIM_BUFFER);
|
||||
if (lua_rawequal(L, -1, 2))
|
||||
{
|
||||
@@ -1497,6 +1703,7 @@ static const luaL_Reg luaV_module[] = {
|
||||
{"line", luaV_line},
|
||||
{"list", luaV_list},
|
||||
{"dict", luaV_dict},
|
||||
{"funcref", luaV_funcref},
|
||||
{"buffer", luaV_buffer},
|
||||
{"window", luaV_window},
|
||||
{"open", luaV_open},
|
||||
@@ -1537,7 +1744,8 @@ luaV_luaeval (lua_State *L)
|
||||
luaV_emsg(L);
|
||||
return 0;
|
||||
}
|
||||
luaV_totypval(L, -1, rettv);
|
||||
if (luaV_totypval(L, -1, rettv) == FAIL)
|
||||
EMSG("luaeval: cannot convert value");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1612,6 +1820,9 @@ luaopen_vim(lua_State *L)
|
||||
luaV_newmetatable(L, LUAVIM_DICT);
|
||||
lua_pushvalue(L, 1);
|
||||
luaV_openlib(L, luaV_Dict_mt, 1);
|
||||
luaV_newmetatable(L, LUAVIM_FUNCREF);
|
||||
lua_pushvalue(L, 1);
|
||||
luaV_openlib(L, luaV_Funcref_mt, 1);
|
||||
luaV_newmetatable(L, LUAVIM_BUFFER);
|
||||
lua_pushvalue(L, 1); /* cache table */
|
||||
luaV_openlib(L, luaV_Buffer_mt, 1);
|
||||
|
||||
+2
-2
@@ -14,9 +14,9 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* PCHAR(lp, c) - put character 'c' at position 'lp'
|
||||
* PBYTE(lp, c) - put byte 'c' at position 'lp'
|
||||
*/
|
||||
#define PCHAR(lp, c) (*(ml_get_buf(curbuf, (lp).lnum, TRUE) + (lp).col) = (c))
|
||||
#define PBYTE(lp, c) (*(ml_get_buf(curbuf, (lp).lnum, TRUE) + (lp).col) = (c))
|
||||
|
||||
/*
|
||||
* Position comparisons
|
||||
|
||||
@@ -399,6 +399,20 @@ smsg_attr(int attr, char_u *s, ...)
|
||||
return msg_attr(IObuff, attr);
|
||||
}
|
||||
|
||||
int
|
||||
# ifdef __BORLANDC__
|
||||
_RTLENTRYF
|
||||
# endif
|
||||
smsg_attr_keep(int attr, char_u *s, ...)
|
||||
{
|
||||
va_list arglist;
|
||||
|
||||
va_start(arglist, s);
|
||||
vim_vsnprintf((char *)IObuff, IOSIZE, (char *)s, arglist);
|
||||
va_end(arglist);
|
||||
return msg_attr_keep(IObuff, attr, TRUE);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
@@ -982,7 +996,11 @@ ex_messages(exarg_T *eap)
|
||||
{
|
||||
s = mch_getenv((char_u *)"LANG");
|
||||
if (s != NULL && *s != NUL)
|
||||
// The next comment is extracted by xgettext and put in po file for
|
||||
// translators to read.
|
||||
msg_attr((char_u *)
|
||||
// Translator: Please replace the name and email address
|
||||
// with the appropriate text for your translation.
|
||||
_("Messages maintainer: Bram Moolenaar <Bram@vim.org>"),
|
||||
HL_ATTR(HLF_T));
|
||||
}
|
||||
|
||||
+2
-2
@@ -3387,8 +3387,8 @@ same_directory(char_u *f1, char_u *f2)
|
||||
&& pathcmp((char *)ffname, (char *)f2, (int)(t1 - ffname)) == 0);
|
||||
}
|
||||
|
||||
#if defined(FEAT_SESSION) || defined(MSWIN) || defined(FEAT_GUI_MAC) \
|
||||
|| defined(FEAT_GUI_GTK) \
|
||||
#if defined(FEAT_SESSION) || defined(FEAT_AUTOCHDIR) \
|
||||
|| defined(MSWIN) || defined(FEAT_GUI_MAC) || defined(FEAT_GUI_GTK) \
|
||||
|| defined(FEAT_SUN_WORKSHOP) || defined(FEAT_NETBEANS_INTG) \
|
||||
|| defined(PROTO)
|
||||
/*
|
||||
|
||||
Executable
+6
@@ -0,0 +1,6 @@
|
||||
@echo off
|
||||
rem To be used on MS-Windows for Msys2 with the 32 bit MinGW compiler.
|
||||
rem Adjust the "c:\msys64" part to match your installation.
|
||||
@echo on
|
||||
|
||||
set PATH=c:\msys64\mingw32\bin;c:\msys64\usr\bin;%PATH%
|
||||
Executable
+6
@@ -0,0 +1,6 @@
|
||||
@echo off
|
||||
rem To be used on MS-Windows for Msys2 with the 64 bit MinGW compiler.
|
||||
rem Adjust the "c:\msys64" part to match your installation.
|
||||
@echo on
|
||||
|
||||
set PATH=c:\msys64\mingw64\bin;c:\msys64\usr\bin;%PATH%
|
||||
@@ -2146,6 +2146,25 @@ mb_adjust_opend(oparg_T *oap)
|
||||
#endif
|
||||
|
||||
#if defined(FEAT_VISUALEXTRA) || defined(PROTO)
|
||||
|
||||
# ifdef FEAT_MBYTE
|
||||
/*
|
||||
* Replace the character under the cursor with "c".
|
||||
* This takes care of multi-byte characters.
|
||||
*/
|
||||
static void
|
||||
replace_character(int c)
|
||||
{
|
||||
int n = State;
|
||||
|
||||
State = REPLACE;
|
||||
ins_char(c);
|
||||
State = n;
|
||||
/* Backup to the replaced character. */
|
||||
dec_cursor();
|
||||
}
|
||||
|
||||
# endif
|
||||
/*
|
||||
* Replace a whole area with one character.
|
||||
*/
|
||||
@@ -2331,12 +2350,7 @@ op_replace(oparg_T *oap, int c)
|
||||
* with a multi-byte and the other way around. */
|
||||
if (curwin->w_cursor.lnum == oap->end.lnum)
|
||||
oap->end.col += (*mb_char2len)(c) - (*mb_char2len)(n);
|
||||
n = State;
|
||||
State = REPLACE;
|
||||
ins_char(c);
|
||||
State = n;
|
||||
/* Backup to the replaced character. */
|
||||
dec_cursor();
|
||||
replace_character(c);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
@@ -2358,7 +2372,7 @@ op_replace(oparg_T *oap, int c)
|
||||
getvpos(&oap->end, end_vcol);
|
||||
}
|
||||
#endif
|
||||
PCHAR(curwin->w_cursor, c);
|
||||
PBYTE(curwin->w_cursor, c);
|
||||
}
|
||||
}
|
||||
#ifdef FEAT_VIRTUALEDIT
|
||||
@@ -2377,9 +2391,14 @@ op_replace(oparg_T *oap, int c)
|
||||
curwin->w_cursor.col -= (virtcols + 1);
|
||||
for (; virtcols >= 0; virtcols--)
|
||||
{
|
||||
PCHAR(curwin->w_cursor, c);
|
||||
if (inc(&curwin->w_cursor) == -1)
|
||||
break;
|
||||
#ifdef FEAT_MBYTE
|
||||
if ((*mb_char2len)(c) > 1)
|
||||
replace_character(c);
|
||||
else
|
||||
#endif
|
||||
PBYTE(curwin->w_cursor, c);
|
||||
if (inc(&curwin->w_cursor) == -1)
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -2619,7 +2638,7 @@ swapchar(int op_type, pos_T *pos)
|
||||
}
|
||||
else
|
||||
#endif
|
||||
PCHAR(*pos, nc);
|
||||
PBYTE(*pos, nc);
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
@@ -3551,9 +3570,10 @@ do_put(
|
||||
return;
|
||||
}
|
||||
|
||||
/* Autocommands may be executed when saving lines for undo, which may make
|
||||
* y_array invalid. Start undo now to avoid that. */
|
||||
u_save(curwin->w_cursor.lnum, curwin->w_cursor.lnum + 1);
|
||||
/* Autocommands may be executed when saving lines for undo. This might
|
||||
* make "y_array" invalid, so we start undo now to avoid that. */
|
||||
if (u_save(curwin->w_cursor.lnum, curwin->w_cursor.lnum + 1) == FAIL)
|
||||
goto end;
|
||||
|
||||
if (insert_string != NULL)
|
||||
{
|
||||
|
||||
+9
-4
@@ -8990,10 +8990,13 @@ set_bool_option(
|
||||
# endif
|
||||
highlight_gui_started();
|
||||
# ifdef FEAT_VTP
|
||||
control_console_color_rgb();
|
||||
/* reset t_Co */
|
||||
if (is_term_win32())
|
||||
{
|
||||
control_console_color_rgb();
|
||||
set_termname(T_NAME);
|
||||
init_highlight(TRUE, FALSE);
|
||||
}
|
||||
# endif
|
||||
}
|
||||
#endif
|
||||
@@ -13083,7 +13086,7 @@ tabstop_start(colnr_T col, int ts, int *vts)
|
||||
tabstop_fromto(
|
||||
colnr_T start_col,
|
||||
colnr_T end_col,
|
||||
int ts,
|
||||
int ts_arg,
|
||||
int *vts,
|
||||
int *ntabs,
|
||||
int *nspcs)
|
||||
@@ -13093,12 +13096,14 @@ tabstop_fromto(
|
||||
int padding = 0;
|
||||
int tabcount;
|
||||
int t;
|
||||
int ts = ts_arg == 0 ? curbuf->b_p_ts : ts_arg;
|
||||
|
||||
if (vts == NULL || vts[0] == 0)
|
||||
{
|
||||
int tabs = 0;
|
||||
int initspc = ts - (start_col % ts);
|
||||
int initspc = 0;
|
||||
|
||||
initspc = ts - (start_col % ts);
|
||||
if (spaces >= initspc)
|
||||
{
|
||||
spaces -= initspc;
|
||||
@@ -13227,7 +13232,7 @@ get_sw_value(buf_T *buf)
|
||||
|
||||
/*
|
||||
* Return the effective softtabstop value for the current buffer, using the
|
||||
* 'tabstop' value when 'softtabstop' is negative.
|
||||
* 'shiftwidth' value when 'softtabstop' is negative.
|
||||
*/
|
||||
long
|
||||
get_sts_value(void)
|
||||
|
||||
@@ -115,6 +115,12 @@ _RTLENTRYF
|
||||
# endif
|
||||
smsg_attr(int, char_u *, ...);
|
||||
|
||||
int
|
||||
# ifdef __BORLANDC__
|
||||
_RTLENTRYF
|
||||
# endif
|
||||
smsg_attr_keep(int, char_u *, ...);
|
||||
|
||||
int
|
||||
# ifdef __BORLANDC__
|
||||
_RTLENTRYF
|
||||
|
||||
+9
-4
@@ -4757,13 +4757,13 @@ win_line(
|
||||
n_extra = win_lbr_chartabsize(wp, line, p, (colnr_T)vcol,
|
||||
NULL) - 1;
|
||||
if (c == TAB && n_extra + col > wp->w_width)
|
||||
#ifdef FEAT_VARTABS
|
||||
# ifdef FEAT_VARTABS
|
||||
n_extra = tabstop_padding(vcol, wp->w_buffer->b_p_ts,
|
||||
wp->w_buffer->b_p_vts_array) - 1;
|
||||
#else
|
||||
wp->w_buffer->b_p_vts_array) - 1;
|
||||
# else
|
||||
n_extra = (int)wp->w_buffer->b_p_ts
|
||||
- vcol % (int)wp->w_buffer->b_p_ts - 1;
|
||||
#endif
|
||||
# endif
|
||||
|
||||
# ifdef FEAT_MBYTE
|
||||
c_extra = mb_off > 0 ? MB_FILLER_CHAR : ' ';
|
||||
@@ -4906,6 +4906,11 @@ win_line(
|
||||
p_extra_free = p;
|
||||
for (i = 0; i < tab_len; i++)
|
||||
{
|
||||
if (*p == NUL)
|
||||
{
|
||||
tab_len = i;
|
||||
break;
|
||||
}
|
||||
#ifdef FEAT_MBYTE
|
||||
mb_char2bytes(lcs_tab2, p);
|
||||
p += mb_char2len(lcs_tab2);
|
||||
|
||||
@@ -1345,6 +1345,7 @@ typedef struct
|
||||
garray_T uf_lines; /* function lines */
|
||||
#ifdef FEAT_PROFILE
|
||||
int uf_profiling; /* TRUE when func is being profiled */
|
||||
int uf_prof_initialized;
|
||||
/* profiling the function as a whole */
|
||||
int uf_tm_count; /* nr of calls */
|
||||
proftime_T uf_tm_total; /* time spent in function + children */
|
||||
|
||||
@@ -2595,7 +2595,6 @@ findtag_end:
|
||||
}
|
||||
|
||||
static garray_T tag_fnames = GA_EMPTY;
|
||||
static void found_tagfile_cb(char_u *fname, void *cookie);
|
||||
|
||||
/*
|
||||
* Callback function for finding all "tags" and "tags-??" files in
|
||||
@@ -2605,8 +2604,15 @@ static void found_tagfile_cb(char_u *fname, void *cookie);
|
||||
found_tagfile_cb(char_u *fname, void *cookie UNUSED)
|
||||
{
|
||||
if (ga_grow(&tag_fnames, 1) == OK)
|
||||
((char_u **)(tag_fnames.ga_data))[tag_fnames.ga_len++] =
|
||||
vim_strsave(fname);
|
||||
{
|
||||
char_u *tag_fname = vim_strsave(fname);
|
||||
|
||||
#ifdef BACKSLASH_IN_FILENAME
|
||||
slash_adjust(tag_fname);
|
||||
#endif
|
||||
simplify_filename(tag_fname);
|
||||
((char_u **)(tag_fnames.ga_data))[tag_fnames.ga_len++] = tag_fname;
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(EXITFREE) || defined(PROTO)
|
||||
@@ -2638,6 +2644,7 @@ get_tagfname(
|
||||
{
|
||||
char_u *fname = NULL;
|
||||
char_u *r_ptr;
|
||||
int i;
|
||||
|
||||
if (first)
|
||||
vim_memset(tnp, 0, sizeof(tagname_T));
|
||||
@@ -2679,6 +2686,14 @@ get_tagfname(
|
||||
++tnp->tn_hf_idx;
|
||||
STRCPY(buf, p_hf);
|
||||
STRCPY(gettail(buf), "tags");
|
||||
#ifdef BACKSLASH_IN_FILENAME
|
||||
slash_adjust(buf);
|
||||
#endif
|
||||
simplify_filename(buf);
|
||||
|
||||
for (i = 0; i < tag_fnames.ga_len; ++i)
|
||||
if (STRCMP(buf, ((char_u **)(tag_fnames.ga_data))[i]) == 0)
|
||||
return FAIL; // avoid duplicate file names
|
||||
}
|
||||
else
|
||||
vim_strncpy(buf, ((char_u **)(tag_fnames.ga_data))[
|
||||
|
||||
@@ -4696,6 +4696,11 @@ check_termcode(
|
||||
&& STRNCMP(tp + extra - 2, "0;115;0c", 8) == 0)
|
||||
is_not_xterm = TRUE;
|
||||
|
||||
// Xterm first responded to this request at patch level
|
||||
// 95, so assume anything below 95 is not xterm.
|
||||
if (version < 95)
|
||||
is_not_xterm = TRUE;
|
||||
|
||||
/* Only request the cursor style if t_SH and t_RS are
|
||||
* set. Only supported properly by xterm since version
|
||||
* 279 (otherwise it returns 0x18).
|
||||
|
||||
@@ -36,7 +36,6 @@ SCRIPTS_ALL = \
|
||||
SCRIPTS_MORE1 = \
|
||||
test11.out \
|
||||
test52.out \
|
||||
test85.out \
|
||||
test86.out \
|
||||
test87.out
|
||||
|
||||
|
||||
@@ -14,7 +14,6 @@ include Make_all.mak
|
||||
# test10 'errorformat' is different
|
||||
# test11 "cat" doesn't work properly
|
||||
# test52 only for Win32
|
||||
# test85 no Lua interface
|
||||
# test86, 87 no Python interface
|
||||
|
||||
SCRIPTS = $(SCRIPTS_ALL) $(SCRIPTS_MORE4)
|
||||
|
||||
@@ -93,7 +93,6 @@ SCRIPT = test1.out test3.out \
|
||||
#
|
||||
# test72: bug - Vim hangs at :rename (while rename works well otherwise)
|
||||
# test78: bug - Vim dies at :recover Xtest
|
||||
# test85: no Lua interface
|
||||
# test89: bug - findfile() does not work on VMS (just in the current directory)
|
||||
# test102: Just ODS-5 supports space and special chars in the filename.
|
||||
# On ODS-2 tests fail.
|
||||
@@ -119,9 +118,9 @@ SCRIPT_SPELL = test59.out
|
||||
SCRIPT_MZSCH = test70.out
|
||||
.ENDIF
|
||||
|
||||
.IFDEF HAVE_ODS5
|
||||
SCRIPT_ODS5 = test102.out
|
||||
.ENDIF
|
||||
.IFDEF HAVE_ODS5
|
||||
SCRIPT_ODS5 = test102.out
|
||||
.ENDIF
|
||||
|
||||
.IFDEF HAVE_GZIP
|
||||
SCRIPT_GZIP = test11.out
|
||||
@@ -131,10 +130,6 @@ SCRIPT_GZIP = test11.out
|
||||
SCRIPT_GDIFF = test47.out
|
||||
.ENDIF
|
||||
|
||||
.IFDEF HAVE_LUA
|
||||
SCRIPT_LUA = test85.out
|
||||
.ENDIF
|
||||
|
||||
.IFDEF HAVE_PYTHON
|
||||
SCRIPT_PYTHON = test86.out test87.out
|
||||
.ENDIF
|
||||
|
||||
@@ -1,86 +0,0 @@
|
||||
Test for Lua interface and luaeval() function
|
||||
|
||||
STARTTEST
|
||||
:so small.vim
|
||||
:set belloff=all
|
||||
:so lua.vim
|
||||
:set nocompatible viminfo+=nviminfo
|
||||
:lua l = vim.list():add"item0":add"dictionary with list OK":add"item2"
|
||||
:lua h = vim.dict(); h.list = l
|
||||
:call garbagecollect()
|
||||
/^1
|
||||
:" change buffer contents
|
||||
:lua curbuf = vim.buffer()
|
||||
:lua curline = vim.eval"line('.')"
|
||||
:lua curbuf[curline] = "1 changed line 1"
|
||||
:" scalar test
|
||||
:let tmp_string = luaeval('"string"')
|
||||
:let tmp_1000 = luaeval('1000')
|
||||
:if printf("%s%.0f", tmp_string, tmp_1000) == "string1000"
|
||||
:let scalar_res = "OK"
|
||||
:else
|
||||
:let scalar_res = "FAILED"
|
||||
:endif
|
||||
:call append(search("^1"), "scalar test " . scalar_res)
|
||||
:" dictionary containing a list
|
||||
:let tmp = luaeval("h").list[1]
|
||||
:/^2/put =tmp
|
||||
:" circular list (at the same time test lists containing lists)
|
||||
:lua l[2] = l
|
||||
:let l2 = luaeval("h").list
|
||||
:if l2[2] == l2
|
||||
:let res = "OK"
|
||||
:else
|
||||
:let res = "FAILED"
|
||||
:endif
|
||||
:call setline(search("^3"), "circular test " . res)
|
||||
|
||||
:let l = []
|
||||
:lua l = vim.eval("l")
|
||||
:lua l:add(123)
|
||||
:lua l:add("abc")
|
||||
:lua l:add(vim.eval("[1, 2, 3]"))
|
||||
:lua l:add(vim.eval("{'a':1, 'b':2, 'c':3}"))
|
||||
:lua l:insert(123)
|
||||
:lua l:insert("abc")
|
||||
:lua l:insert(vim.eval("[1, 2, 3]"))
|
||||
:lua l:insert(vim.eval("{'a':1, 'b':2, 'c':3}"))
|
||||
:lua l[0] = l[0]
|
||||
:lua l[1] = l[1]
|
||||
:lua l[2] = l[2]
|
||||
:lua l[3] = l[3]
|
||||
:lua l[0] = 123
|
||||
:lua l[1] = "abc"
|
||||
:lua l[2] = vim.eval("[1, 2, 3]")
|
||||
:lua l[3] = vim.eval("{'a':1, 'b':2, 'c':3}")
|
||||
:lua l[3] = nil
|
||||
:lua l[2] = nil
|
||||
:lua l[1] = nil
|
||||
:lua l[0] = nil
|
||||
:lua l = nil
|
||||
:$put =string(l)
|
||||
|
||||
:let d = {}
|
||||
:lua d = vim.eval("d")
|
||||
:lua d[0] = 123
|
||||
:lua d[1] = "abc"
|
||||
:lua d[2] = vim.eval("[1, 2, 3]")
|
||||
:lua d[3] = vim.eval("{'a':1, 'b':2, 'c':3}")
|
||||
:lua d[4] = d[0]
|
||||
:lua d[5] = d[1]
|
||||
:lua d[6] = d[2]
|
||||
:lua d[7] = d[3]
|
||||
:lua d[3] = nil
|
||||
:lua d[2] = nil
|
||||
:lua d[1] = nil
|
||||
:lua d[0] = nil
|
||||
:lua d = nil
|
||||
:$put =string(d)
|
||||
|
||||
:?^1?,$w! test.out
|
||||
:qa!
|
||||
ENDTEST
|
||||
|
||||
1 line 1
|
||||
2 line 2
|
||||
3 line 3
|
||||
+547
-9
@@ -1,22 +1,560 @@
|
||||
" Tests for Lua.
|
||||
" TODO: move tests from test85.in here.
|
||||
|
||||
if !has('lua')
|
||||
finish
|
||||
endif
|
||||
|
||||
func Test_luado()
|
||||
new
|
||||
call setline(1, ['one', 'two', 'three'])
|
||||
luado vim.command("%d_")
|
||||
bwipe!
|
||||
|
||||
" Check switching to another buffer does not trigger ml_get error.
|
||||
" Check that switching to another buffer does not trigger ml_get error.
|
||||
func Test_command_new_no_ml_get_error()
|
||||
new
|
||||
let wincount = winnr('$')
|
||||
call setline(1, ['one', 'two', 'three'])
|
||||
luado vim.command("new")
|
||||
call assert_equal(wincount + 1, winnr('$'))
|
||||
bwipe!
|
||||
%bwipe!
|
||||
endfunc
|
||||
|
||||
" Test vim.command()
|
||||
func Test_command()
|
||||
new
|
||||
call setline(1, ['one', 'two', 'three'])
|
||||
luado vim.command("1,2d_")
|
||||
call assert_equal(['three'], getline(1, '$'))
|
||||
bwipe!
|
||||
endfunc
|
||||
|
||||
" Test vim.eval()
|
||||
func Test_eval()
|
||||
" lua.eval with a number
|
||||
lua v = vim.eval('123')
|
||||
call assert_equal('number', luaeval('vim.type(v)'))
|
||||
call assert_equal(123.0, luaeval('v'))
|
||||
|
||||
" lua.eval with a string
|
||||
lua v = vim.eval('"abc"')
|
||||
call assert_equal('string', luaeval('vim.type(v)'))
|
||||
call assert_equal('abc', luaeval('v'))
|
||||
|
||||
" lua.eval with a list
|
||||
lua v = vim.eval("['a']")
|
||||
call assert_equal('list', luaeval('vim.type(v)'))
|
||||
call assert_equal(['a'], luaeval('v'))
|
||||
|
||||
" lua.eval with a dict
|
||||
lua v = vim.eval("{'a':'b'}")
|
||||
call assert_equal('dict', luaeval('vim.type(v)'))
|
||||
call assert_equal({'a':'b'}, luaeval('v'))
|
||||
|
||||
call assert_fails('lua v = vim.eval(nil)',
|
||||
\ "[string \"vim chunk\"]:1: bad argument #1 to 'eval' (string expected, got nil)")
|
||||
call assert_fails('lua v = vim.eval(true)',
|
||||
\ "[string \"vim chunk\"]:1: bad argument #1 to 'eval' (string expected, got boolean)")
|
||||
call assert_fails('lua v = vim.eval({})',
|
||||
\ "[string \"vim chunk\"]:1: bad argument #1 to 'eval' (string expected, got table)")
|
||||
call assert_fails('lua v = vim.eval(print)',
|
||||
\ "[string \"vim chunk\"]:1: bad argument #1 to 'eval' (string expected, got function)")
|
||||
call assert_fails('lua v = vim.eval(vim.buffer())',
|
||||
\ "[string \"vim chunk\"]:1: bad argument #1 to 'eval' (string expected, got userdata)")
|
||||
|
||||
lua v = nil
|
||||
endfunc
|
||||
|
||||
" Test vim.window()
|
||||
func Test_window()
|
||||
e Xfoo2
|
||||
new Xfoo1
|
||||
|
||||
" Window 1 (top window) contains Xfoo1
|
||||
" Window 2 (bottom window) contains Xfoo2
|
||||
call assert_equal('Xfoo1', luaeval('vim.window(1):buffer().name'))
|
||||
call assert_equal('Xfoo2', luaeval('vim.window(2):buffer().name'))
|
||||
|
||||
" Window 3 does not exist so vim.window(3) should return nil
|
||||
call assert_equal('nil', luaeval('tostring(vim.window(3))'))
|
||||
|
||||
%bwipe!
|
||||
endfunc
|
||||
|
||||
" Test vim.window().height
|
||||
func Test_window_height()
|
||||
new
|
||||
lua vim.window().height = 2
|
||||
call assert_equal(2, winheight(0))
|
||||
lua vim.window().height = vim.window().height + 1
|
||||
call assert_equal(3, winheight(0))
|
||||
bwipe!
|
||||
endfunc
|
||||
|
||||
" Test vim.window().width
|
||||
func Test_window_width()
|
||||
vert new
|
||||
lua vim.window().width = 2
|
||||
call assert_equal(2, winwidth(0))
|
||||
lua vim.window().width = vim.window().width + 1
|
||||
call assert_equal(3, winwidth(0))
|
||||
bwipe!
|
||||
endfunc
|
||||
|
||||
" Test vim.window().line and vim.window.col
|
||||
func Test_window_line_col()
|
||||
new
|
||||
call setline(1, ['line1', 'line2', 'line3'])
|
||||
lua vim.window().line = 2
|
||||
lua vim.window().col = 4
|
||||
call assert_equal([0, 2, 4, 0], getpos('.'))
|
||||
lua vim.window().line = vim.window().line + 1
|
||||
lua vim.window().col = vim.window().col - 1
|
||||
call assert_equal([0, 3, 3, 0], getpos('.'))
|
||||
|
||||
call assert_fails('lua vim.window().line = 10',
|
||||
\ '[string "vim chunk"]:1: line out of range')
|
||||
bwipe!
|
||||
endfunc
|
||||
|
||||
" Test setting the current window
|
||||
func Test_window_set_current()
|
||||
new Xfoo1
|
||||
lua w1 = vim.window()
|
||||
new Xfoo2
|
||||
lua w2 = vim.window()
|
||||
|
||||
call assert_equal('Xfoo2', bufname('%'))
|
||||
lua w1()
|
||||
call assert_equal('Xfoo1', bufname('%'))
|
||||
lua w2()
|
||||
call assert_equal('Xfoo2', bufname('%'))
|
||||
|
||||
lua w1, w2 = nil
|
||||
%bwipe!
|
||||
endfunc
|
||||
|
||||
" Test vim.window().buffer
|
||||
func Test_window_buffer()
|
||||
new Xfoo1
|
||||
lua w1 = vim.window()
|
||||
lua b1 = w1.buffer()
|
||||
new Xfoo2
|
||||
lua w2 = vim.window()
|
||||
lua b2 = w2.buffer()
|
||||
|
||||
lua b1()
|
||||
call assert_equal('Xfoo1', bufname('%'))
|
||||
lua b2()
|
||||
call assert_equal('Xfoo2', bufname('%'))
|
||||
|
||||
lua b1, b2, w1, w2 = nil
|
||||
%bwipe!
|
||||
endfunc
|
||||
|
||||
" Test vim.window():previous() and vim.window():next()
|
||||
func Test_window_next_previous()
|
||||
new Xfoo1
|
||||
new Xfoo2
|
||||
new Xfoo3
|
||||
wincmd j
|
||||
|
||||
call assert_equal('Xfoo2', luaeval('vim.window().buffer().name'))
|
||||
call assert_equal('Xfoo1', luaeval('vim.window():next():buffer().name'))
|
||||
call assert_equal('Xfoo3', luaeval('vim.window():previous():buffer().name'))
|
||||
|
||||
%bwipe!
|
||||
endfunc
|
||||
|
||||
" Test vim.window():isvalid()
|
||||
func Test_window_isvalid()
|
||||
new Xfoo
|
||||
lua w = vim.window()
|
||||
call assert_true(luaeval('w:isvalid()'))
|
||||
|
||||
" FIXME: how to test the case when isvalid() returns v:false?
|
||||
" isvalid() gives errors when the window is deleted. Is it a bug?
|
||||
|
||||
lua w = nil
|
||||
bwipe!
|
||||
endfunc
|
||||
|
||||
" Test vim.buffer() with and without argument
|
||||
func Test_buffer()
|
||||
new Xfoo1
|
||||
let bn1 = bufnr('%')
|
||||
new Xfoo2
|
||||
let bn2 = bufnr('%')
|
||||
|
||||
" Test vim.buffer() without argument.
|
||||
call assert_equal('Xfoo2', luaeval("vim.buffer().name"))
|
||||
|
||||
" Test vim.buffer() with string argument.
|
||||
call assert_equal('Xfoo1', luaeval("vim.buffer('Xfoo1').name"))
|
||||
call assert_equal('Xfoo2', luaeval("vim.buffer('Xfoo2').name"))
|
||||
|
||||
" Test vim.buffer() with integer argument.
|
||||
call assert_equal('Xfoo1', luaeval("vim.buffer(" . bn1 . ").name"))
|
||||
call assert_equal('Xfoo2', luaeval("vim.buffer(" . bn2 . ").name"))
|
||||
|
||||
lua bn1, bn2 = nil
|
||||
%bwipe!
|
||||
endfunc
|
||||
|
||||
" Test vim.buffer().name and vim.buffer().fname
|
||||
func Test_buffer_name()
|
||||
new
|
||||
" FIXME: for an unnamed buffer, I would expect
|
||||
" vim.buffer().name to give an empty string, but
|
||||
" it returns 0. Is it a bug?
|
||||
" so this assert_equal is commented out.
|
||||
" call assert_equal('', luaeval('vim.buffer().name'))
|
||||
bwipe!
|
||||
|
||||
new Xfoo
|
||||
call assert_equal('Xfoo', luaeval('vim.buffer().name'))
|
||||
call assert_equal(expand('%:p'), luaeval('vim.buffer().fname'))
|
||||
bwipe!
|
||||
endfunc
|
||||
|
||||
" Test vim.buffer().number
|
||||
func Test_buffer_number()
|
||||
" All numbers in Lua are floating points number (no integers).
|
||||
call assert_equal(bufnr('%'), float2nr(luaeval('vim.buffer().number')))
|
||||
endfunc
|
||||
|
||||
" Test inserting lines in buffer.
|
||||
func Test_buffer_insert()
|
||||
new
|
||||
lua vim.buffer()[1] = '3'
|
||||
lua vim.buffer():insert('1', 0)
|
||||
lua vim.buffer():insert('2', 1)
|
||||
lua vim.buffer():insert('4', 10)
|
||||
|
||||
call assert_equal(['1', '2', '3', '4'], getline(1, '$'))
|
||||
bwipe!
|
||||
endfunc
|
||||
|
||||
" Test deleting line in buffer
|
||||
func Test_buffer_delete()
|
||||
new
|
||||
call setline(1, ['1', '2', '3'])
|
||||
lua vim.buffer()[2] = nil
|
||||
call assert_equal(['1', '3'], getline(1, '$'))
|
||||
|
||||
call assert_fails('lua vim.buffer()[3] = nil',
|
||||
\ '[string "vim chunk"]:1: invalid line number')
|
||||
bwipe!
|
||||
endfunc
|
||||
|
||||
" Test #vim.buffer() i.e. number of lines in buffer
|
||||
func Test_buffer_number_lines()
|
||||
new
|
||||
call setline(1, ['a', 'b', 'c'])
|
||||
call assert_equal(3.0, luaeval('#vim.buffer()'))
|
||||
bwipe!
|
||||
endfunc
|
||||
|
||||
" Test vim.buffer():next() and vim.buffer():previous()
|
||||
" Note that these functions get the next or previous buffers
|
||||
" but do not switch buffer.
|
||||
func Test_buffer_next_previous()
|
||||
new Xfoo1
|
||||
new Xfoo2
|
||||
new Xfoo3
|
||||
b Xfoo2
|
||||
|
||||
lua bn = vim.buffer():next()
|
||||
lua bp = vim.buffer():previous()
|
||||
|
||||
call assert_equal('Xfoo2', luaeval('vim.buffer().name'))
|
||||
call assert_equal('Xfoo1', luaeval('bp.name'))
|
||||
call assert_equal('Xfoo3', luaeval('bn.name'))
|
||||
|
||||
call assert_equal('Xfoo2', bufname('%'))
|
||||
|
||||
lua bn()
|
||||
call assert_equal('Xfoo3', luaeval('vim.buffer().name'))
|
||||
call assert_equal('Xfoo3', bufname('%'))
|
||||
|
||||
lua bp()
|
||||
call assert_equal('Xfoo1', luaeval('vim.buffer().name'))
|
||||
call assert_equal('Xfoo1', bufname('%'))
|
||||
|
||||
lua bn, bp = nil
|
||||
%bwipe!
|
||||
endfunc
|
||||
|
||||
" Test vim.buffer():isvalid()
|
||||
func Test_buffer_isvalid()
|
||||
new Xfoo
|
||||
lua b = vim.buffer()
|
||||
call assert_true(luaeval('b:isvalid()'))
|
||||
|
||||
" FIXME: how to test the case when isvalid() returns v:false?
|
||||
" isvalid() gives errors when the buffer is wiped. Is it a bug?
|
||||
|
||||
lua b = nil
|
||||
bwipe!
|
||||
endfunc
|
||||
|
||||
func Test_list()
|
||||
call assert_equal([], luaeval('vim.list()'))
|
||||
|
||||
let l = []
|
||||
lua l = vim.eval('l')
|
||||
lua l:add(123)
|
||||
lua l:add('abc')
|
||||
lua l:add(true)
|
||||
lua l:add(false)
|
||||
lua l:add(vim.eval("[1, 2, 3]"))
|
||||
lua l:add(vim.eval("{'a':1, 'b':2, 'c':3}"))
|
||||
call assert_equal([123.0, 'abc', v:true, v:false, [1, 2, 3], {'a': 1, 'b': 2, 'c': 3}], l)
|
||||
call assert_equal(6.0, luaeval('#l'))
|
||||
call assert_match('^list: \%(0x\)\?\x\+$', luaeval('tostring(l)'))
|
||||
|
||||
lua l[0] = 124
|
||||
lua l[4] = nil
|
||||
lua l:insert('first')
|
||||
lua l:insert('xx', 3)
|
||||
call assert_equal(['first', 124.0, 'abc', 'xx', v:true, v:false, {'a': 1, 'b': 2, 'c': 3}], l)
|
||||
|
||||
lockvar 1 l
|
||||
call assert_fails('lua l:add("x")', '[string "vim chunk"]:1: list is locked')
|
||||
|
||||
lua l = nil
|
||||
endfunc
|
||||
|
||||
func Test_list_table()
|
||||
" See :help lua-vim
|
||||
" Non-numeric keys should not be used to initialize the list
|
||||
" so say = 'hi' should be ignored.
|
||||
lua t = {3.14, 'hello', false, true, say = 'hi'}
|
||||
call assert_equal([3.14, 'hello', v:false, v:true], luaeval('vim.list(t)'))
|
||||
lua t = nil
|
||||
|
||||
call assert_fails('lua vim.list(1)', '[string "vim chunk"]:1: table expected, got number')
|
||||
call assert_fails('lua vim.list("x")', '[string "vim chunk"]:1: table expected, got string')
|
||||
call assert_fails('lua vim.list(print)', '[string "vim chunk"]:1: table expected, got function')
|
||||
call assert_fails('lua vim.list(true)', '[string "vim chunk"]:1: table expected, got boolean')
|
||||
endfunc
|
||||
|
||||
" Test l() i.e. iterator on list
|
||||
func Test_list_iter()
|
||||
lua l = vim.list():add('foo'):add('bar')
|
||||
lua str = ''
|
||||
lua for v in l() do str = str .. v end
|
||||
call assert_equal('foobar', luaeval('str'))
|
||||
|
||||
lua str, l = nil
|
||||
endfunc
|
||||
|
||||
func Test_recursive_list()
|
||||
lua l = vim.list():add(1):add(2)
|
||||
lua l = l:add(l)
|
||||
|
||||
call assert_equal(1.0, luaeval('l[0]'))
|
||||
call assert_equal(2.0, luaeval('l[1]'))
|
||||
|
||||
call assert_equal(1.0, luaeval('l[2][0]'))
|
||||
call assert_equal(2.0, luaeval('l[2][1]'))
|
||||
|
||||
call assert_equal(1.0, luaeval('l[2][2][0]'))
|
||||
call assert_equal(2.0, luaeval('l[2][2][1]'))
|
||||
|
||||
call assert_equal('[1.0, 2.0, [...]]', string(luaeval('l')))
|
||||
|
||||
call assert_match('^list: \%(0x\)\?\x\+$', luaeval('tostring(l)'))
|
||||
call assert_equal(luaeval('tostring(l)'), luaeval('tostring(l[2])'))
|
||||
|
||||
call assert_equal(luaeval('l'), luaeval('l[2]'))
|
||||
call assert_equal(luaeval('l'), luaeval('l[2][2]'))
|
||||
|
||||
lua l = nil
|
||||
endfunc
|
||||
|
||||
func Test_dict()
|
||||
call assert_equal({}, luaeval('vim.dict()'))
|
||||
|
||||
let d = {}
|
||||
lua d = vim.eval('d')
|
||||
lua d[0] = 123
|
||||
lua d[1] = "abc"
|
||||
lua d[2] = true
|
||||
lua d[3] = false
|
||||
lua d[4] = vim.eval("[1, 2, 3]")
|
||||
lua d[5] = vim.eval("{'a':1, 'b':2, 'c':3}")
|
||||
call assert_equal({'0':123.0, '1':'abc', '2':v:true, '3':v:false, '4': [1, 2, 3], '5': {'a':1, 'b':2, 'c':3}}, d)
|
||||
call assert_equal(6.0, luaeval('#d'))
|
||||
call assert_match('^dict: \%(0x\)\?\x\+$', luaeval('tostring(d)'))
|
||||
|
||||
call assert_equal('abc', luaeval('d[1]'))
|
||||
|
||||
lua d[0] = 124
|
||||
lua d[4] = nil
|
||||
call assert_equal({'0':124.0, '1':'abc', '2':v:true, '3':v:false, '5': {'a':1, 'b':2, 'c':3}}, d)
|
||||
|
||||
lockvar 1 d
|
||||
call assert_fails('lua d[6] = 1', '[string "vim chunk"]:1: dict is locked')
|
||||
|
||||
lua d = nil
|
||||
endfunc
|
||||
|
||||
func Test_dict_table()
|
||||
lua t = {key1 = 'x', key2 = 3.14, key3 = true, key4 = false}
|
||||
call assert_equal({'key1': 'x', 'key2': 3.14, 'key3': v:true, 'key4': v:false},
|
||||
\ luaeval('vim.dict(t)'))
|
||||
|
||||
" Same example as in :help lua-vim.
|
||||
lua t = {math.pi, false, say = 'hi'}
|
||||
" FIXME: commented out as it currently does not work as documented:
|
||||
" Expected {'say': 'hi'}
|
||||
" but got {'1': 3.141593, '2': v:false, 'say': 'hi'}
|
||||
" Is the documentation or the code wrong?
|
||||
"call assert_equal({'say' : 'hi'}, luaeval('vim.dict(t)'))
|
||||
lua t = nil
|
||||
|
||||
call assert_fails('lua vim.dict(1)', '[string "vim chunk"]:1: table expected, got number')
|
||||
call assert_fails('lua vim.dict("x")', '[string "vim chunk"]:1: table expected, got string')
|
||||
call assert_fails('lua vim.dict(print)', '[string "vim chunk"]:1: table expected, got function')
|
||||
call assert_fails('lua vim.dict(true)', '[string "vim chunk"]:1: table expected, got boolean')
|
||||
endfunc
|
||||
|
||||
" Test d() i.e. iterator on dictionary
|
||||
func Test_dict_iter()
|
||||
let d = {'a': 1, 'b':2}
|
||||
lua d = vim.eval('d')
|
||||
lua str = ''
|
||||
lua for k,v in d() do str = str .. k ..':' .. v .. ',' end
|
||||
call assert_equal('a:1,b:2,', luaeval('str'))
|
||||
|
||||
lua str, d = nil
|
||||
endfunc
|
||||
|
||||
func Test_funcref()
|
||||
function I(x)
|
||||
return a:x
|
||||
endfunction
|
||||
let R = function('I')
|
||||
lua i1 = vim.funcref"I"
|
||||
lua i2 = vim.eval"R"
|
||||
lua msg = "funcref|test|" .. (#i2(i1) == #i1(i2) and "OK" or "FAIL")
|
||||
lua msg = vim.funcref"tr"(msg, "|", " ")
|
||||
call assert_equal("funcref test OK", luaeval('msg'))
|
||||
|
||||
" dict funcref
|
||||
function Mylen() dict
|
||||
return len(self.data)
|
||||
endfunction
|
||||
let l = [0, 1, 2, 3]
|
||||
let mydict = {'data': l}
|
||||
lua d = vim.eval"mydict"
|
||||
lua d.len = vim.funcref"Mylen" -- assign d as 'self'
|
||||
lua res = (d.len() == vim.funcref"len"(vim.eval"l")) and "OK" or "FAIL"
|
||||
call assert_equal("OK", luaeval('res'))
|
||||
|
||||
lua i1, i2, msg, d, res = nil
|
||||
endfunc
|
||||
|
||||
" Test vim.type()
|
||||
func Test_type()
|
||||
" The following values are identical to Lua's type function.
|
||||
call assert_equal('string', luaeval('vim.type("foo")'))
|
||||
call assert_equal('number', luaeval('vim.type(1)'))
|
||||
call assert_equal('number', luaeval('vim.type(1.2)'))
|
||||
call assert_equal('function', luaeval('vim.type(print)'))
|
||||
call assert_equal('table', luaeval('vim.type({})'))
|
||||
call assert_equal('boolean', luaeval('vim.type(true)'))
|
||||
call assert_equal('boolean', luaeval('vim.type(false)'))
|
||||
call assert_equal('nil', luaeval('vim.type(nil)'))
|
||||
|
||||
" The following values are specific to Vim.
|
||||
call assert_equal('window', luaeval('vim.type(vim.window())'))
|
||||
call assert_equal('buffer', luaeval('vim.type(vim.buffer())'))
|
||||
call assert_equal('list', luaeval('vim.type(vim.list())'))
|
||||
call assert_equal('dict', luaeval('vim.type(vim.dict())'))
|
||||
call assert_equal('funcref', luaeval('vim.type(vim.funcref("Test_type"))'))
|
||||
endfunc
|
||||
|
||||
" Test vim.open()
|
||||
func Test_open()
|
||||
call assert_notmatch('XOpen', execute('ls'))
|
||||
|
||||
" Open a buffer XOpen1, but do not jump to it.
|
||||
lua b = vim.open('XOpen1')
|
||||
call assert_equal('XOpen1', luaeval('b.name'))
|
||||
call assert_equal('', bufname('%'))
|
||||
|
||||
call assert_match('XOpen1', execute('ls'))
|
||||
call assert_notequal('XOpen2', bufname('%'))
|
||||
|
||||
" Open a buffer XOpen2 and jump to it.
|
||||
lua b = vim.open('XOpen2')()
|
||||
call assert_equal('XOpen2', luaeval('b.name'))
|
||||
call assert_equal('XOpen2', bufname('%'))
|
||||
|
||||
lua b = nil
|
||||
%bwipe!
|
||||
endfunc
|
||||
|
||||
" Test vim.line()
|
||||
func Test_line()
|
||||
new
|
||||
call setline(1, ['first line', 'second line'])
|
||||
1
|
||||
call assert_equal('first line', luaeval('vim.line()'))
|
||||
2
|
||||
call assert_equal('second line', luaeval('vim.line()'))
|
||||
bwipe!
|
||||
endfunc
|
||||
|
||||
" Test vim.beep()
|
||||
func Test_beep()
|
||||
call assert_beeps('lua vim.beep()')
|
||||
endfunc
|
||||
|
||||
" Test errors in luaeval()
|
||||
func Test_luaeval_error()
|
||||
" Compile error
|
||||
call assert_fails("call luaeval('-nil')",
|
||||
\ '[string "luaeval"]:1: attempt to perform arithmetic on a nil value')
|
||||
call assert_fails("call luaeval(']')",
|
||||
\ "[string \"luaeval\"]:1: unexpected symbol near ']'")
|
||||
endfunc
|
||||
|
||||
" Test :luafile foo.lua
|
||||
func Test_luafile()
|
||||
call delete('Xlua_file')
|
||||
call writefile(["str = 'hello'", "num = 123.0" ], 'Xlua_file')
|
||||
call setfperm('Xlua_file', 'r-xr-xr-x')
|
||||
|
||||
luafile Xlua_file
|
||||
call assert_equal('hello', luaeval('str'))
|
||||
call assert_equal(123.0, luaeval('num'))
|
||||
|
||||
lua str, num = nil
|
||||
call delete('Xlua_file')
|
||||
endfunc
|
||||
|
||||
" Test :luafile %
|
||||
func Test_luafile_percent()
|
||||
new Xlua_file
|
||||
append
|
||||
str, num = 'foo', 321.0
|
||||
print(string.format('str=%s, num=%d', str, num))
|
||||
.
|
||||
w!
|
||||
luafile %
|
||||
let msg = split(execute('message'), "\n")[-1]
|
||||
call assert_equal('str=foo, num=321', msg)
|
||||
|
||||
lua str, num = nil
|
||||
call delete('Xlua_file')
|
||||
bwipe!
|
||||
endfunc
|
||||
|
||||
" Test :luafile with syntax error
|
||||
func Test_luafile_error()
|
||||
new Xlua_file
|
||||
call writefile(['nil = 0' ], 'Xlua_file')
|
||||
call setfperm('Xlua_file', 'r-xr-xr-x')
|
||||
|
||||
call assert_fails('luafile Xlua_file', "Xlua_file:1: unexpected symbol near 'nil'")
|
||||
|
||||
call delete('Xlua_file')
|
||||
bwipe!
|
||||
endfunc
|
||||
|
||||
@@ -39,7 +39,7 @@ function Test_messages()
|
||||
endtry
|
||||
endfunction
|
||||
|
||||
" Patch 7.4.1696 defined the "clearmode()" command for clearing the mode
|
||||
" Patch 7.4.1696 defined the "clearmode()" function for clearing the mode
|
||||
" indicator (e.g., "-- INSERT --") when ":stopinsert" is invoked. Message
|
||||
" output could then be disturbed when 'cmdheight' was greater than one.
|
||||
" This test ensures that the bugfix for this issue remains in place.
|
||||
|
||||
@@ -5,6 +5,8 @@ endif
|
||||
|
||||
func Test_profile_func()
|
||||
let lines = [
|
||||
\ 'profile start Xprofile_func.log',
|
||||
\ 'profile func Foo*"',
|
||||
\ "func! Foo1()",
|
||||
\ "endfunc",
|
||||
\ "func! Foo2()",
|
||||
@@ -33,9 +35,7 @@ func Test_profile_func()
|
||||
|
||||
call writefile(lines, 'Xprofile_func.vim')
|
||||
call system(v:progpath
|
||||
\ . ' -es -u NONE -U NONE -i NONE --noplugin'
|
||||
\ . ' -c "profile start Xprofile_func.log"'
|
||||
\ . ' -c "profile func Foo*"'
|
||||
\ . ' -es --clean'
|
||||
\ . ' -c "so Xprofile_func.vim"'
|
||||
\ . ' -c "qall!"')
|
||||
call assert_equal(0, v:shell_error)
|
||||
@@ -97,7 +97,7 @@ func Test_profile_file()
|
||||
|
||||
call writefile(lines, 'Xprofile_file.vim')
|
||||
call system(v:progpath
|
||||
\ . ' -es -u NONE -U NONE -i NONE --noplugin'
|
||||
\ . ' -es --clean'
|
||||
\ . ' -c "profile start Xprofile_file.log"'
|
||||
\ . ' -c "profile file Xprofile_file.vim"'
|
||||
\ . ' -c "so Xprofile_file.vim"'
|
||||
@@ -152,17 +152,17 @@ func Test_profile_file_with_cont()
|
||||
let lines = readfile('Xprofile_file.log')
|
||||
call assert_equal(11, len(lines))
|
||||
|
||||
call assert_match('^SCRIPT .*Xprofile_file.vim$', lines[0])
|
||||
call assert_equal('Sourced 1 time', lines[1])
|
||||
call assert_match('^Total time:\s\+\d\+\.\d\+$', lines[2])
|
||||
call assert_match('^ Self time:\s\+\d\+\.\d\+$', lines[3])
|
||||
call assert_equal('', lines[4])
|
||||
call assert_equal('count total (s) self (s)', lines[5])
|
||||
call assert_match(' 1 0.\d\+ echo "hello', lines[6])
|
||||
call assert_equal(' \ world"', lines[7])
|
||||
call assert_match(' 1 0.\d\+ echo "foo ', lines[8])
|
||||
call assert_equal(' \bar"', lines[9])
|
||||
call assert_equal('', lines[10])
|
||||
call assert_match('^SCRIPT .*Xprofile_file.vim$', lines[0])
|
||||
call assert_equal('Sourced 1 time', lines[1])
|
||||
call assert_match('^Total time:\s\+\d\+\.\d\+$', lines[2])
|
||||
call assert_match('^ Self time:\s\+\d\+\.\d\+$', lines[3])
|
||||
call assert_equal('', lines[4])
|
||||
call assert_equal('count total (s) self (s)', lines[5])
|
||||
call assert_match(' 1 0.\d\+ echo "hello', lines[6])
|
||||
call assert_equal(' \ world"', lines[7])
|
||||
call assert_match(' 1 0.\d\+ echo "foo ', lines[8])
|
||||
call assert_equal(' \bar"', lines[9])
|
||||
call assert_equal('', lines[10])
|
||||
|
||||
call delete('Xprofile_file.vim')
|
||||
call delete('Xprofile_file.log')
|
||||
@@ -222,3 +222,73 @@ func Test_profile_truncate_mbyte()
|
||||
call delete('Xprofile_file.vim')
|
||||
call delete('Xprofile_file.log')
|
||||
endfunc
|
||||
|
||||
func Test_profdel_func()
|
||||
let lines = [
|
||||
\ 'profile start Xprofile_file.log',
|
||||
\ 'func! Foo1()',
|
||||
\ 'endfunc',
|
||||
\ 'func! Foo2()',
|
||||
\ 'endfunc',
|
||||
\ 'func! Foo3()',
|
||||
\ 'endfunc',
|
||||
\ '',
|
||||
\ 'profile func Foo1',
|
||||
\ 'profile func Foo2',
|
||||
\ 'call Foo1()',
|
||||
\ 'call Foo2()',
|
||||
\ '',
|
||||
\ 'profile func Foo3',
|
||||
\ 'profdel func Foo2',
|
||||
\ 'profdel func Foo3',
|
||||
\ 'call Foo1()',
|
||||
\ 'call Foo2()',
|
||||
\ 'call Foo3()' ]
|
||||
call writefile(lines, 'Xprofile_file.vim')
|
||||
call system(v:progpath . ' -es --clean -c "so Xprofile_file.vim" -c q')
|
||||
call assert_equal(0, v:shell_error)
|
||||
|
||||
let lines = readfile('Xprofile_file.log')
|
||||
call assert_equal(24, len(lines))
|
||||
|
||||
" Check that:
|
||||
" - Foo1() is called twice (profdel not invoked)
|
||||
" - Foo2() is called once (profdel invoked after it was called)
|
||||
" - Foo3() is not called (profdel invoked before it was called)
|
||||
call assert_equal('FUNCTION Foo1()', lines[0])
|
||||
call assert_equal('Called 2 times', lines[1])
|
||||
call assert_equal('FUNCTION Foo2()', lines[7])
|
||||
call assert_equal('Called 1 time', lines[8])
|
||||
call assert_equal('FUNCTIONS SORTED ON TOTAL TIME', lines[14])
|
||||
call assert_equal('FUNCTIONS SORTED ON SELF TIME', lines[19])
|
||||
|
||||
call delete('Xprofile_file.vim')
|
||||
call delete('Xprofile_file.log')
|
||||
endfunc
|
||||
|
||||
func Test_profdel_star()
|
||||
" Foo() is invoked once before and once after 'profdel *'.
|
||||
" So profiling should report it only once.
|
||||
let lines = [
|
||||
\ 'profile start Xprofile_file.log',
|
||||
\ 'func! Foo()',
|
||||
\ 'endfunc',
|
||||
\ 'profile func Foo',
|
||||
\ 'call Foo()',
|
||||
\ 'profdel *',
|
||||
\ 'call Foo()' ]
|
||||
call writefile(lines, 'Xprofile_file.vim')
|
||||
call system(v:progpath . ' -es --clean -c "so Xprofile_file.vim" -c q')
|
||||
call assert_equal(0, v:shell_error)
|
||||
|
||||
let lines = readfile('Xprofile_file.log')
|
||||
call assert_equal(15, len(lines))
|
||||
|
||||
call assert_equal('FUNCTION Foo()', lines[0])
|
||||
call assert_equal('Called 1 time', lines[1])
|
||||
call assert_equal('FUNCTIONS SORTED ON TOTAL TIME', lines[7])
|
||||
call assert_equal('FUNCTIONS SORTED ON SELF TIME', lines[11])
|
||||
|
||||
call delete('Xprofile_file.vim')
|
||||
call delete('Xprofile_file.log')
|
||||
endfunc
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
" Tests for put commands, e.g. ":put", "p", "gp", "P", "gP", etc.
|
||||
|
||||
func Test_put_block()
|
||||
if !has('multi_byte')
|
||||
@@ -58,3 +59,48 @@ func Test_put_expr()
|
||||
call assert_equal(['A1','A2','A3','4A','5A','6A'], getline(1,'$'))
|
||||
bw!
|
||||
endfunc
|
||||
|
||||
func Test_put_fails_when_nomodifiable()
|
||||
new
|
||||
setlocal nomodifiable
|
||||
|
||||
normal! yy
|
||||
call assert_fails(':put', 'E21')
|
||||
call assert_fails(':put!', 'E21')
|
||||
call assert_fails(':normal! p', 'E21')
|
||||
call assert_fails(':normal! gp', 'E21')
|
||||
call assert_fails(':normal! P', 'E21')
|
||||
call assert_fails(':normal! gP', 'E21')
|
||||
|
||||
if has('mouse')
|
||||
set mouse=n
|
||||
call assert_fails('execute "normal! \<MiddleMouse>"', 'E21')
|
||||
set mouse&
|
||||
endif
|
||||
|
||||
bwipeout!
|
||||
endfunc
|
||||
|
||||
" A bug was discovered where the Normal mode put commands (e.g., "p") would
|
||||
" output duplicate error messages when invoked in a non-modifiable buffer.
|
||||
func Test_put_p_errmsg_nodup()
|
||||
new
|
||||
setlocal nomodifiable
|
||||
|
||||
normal! yy
|
||||
|
||||
func Capture_p_error()
|
||||
redir => s:p_err
|
||||
normal! p
|
||||
redir END
|
||||
endfunc
|
||||
|
||||
silent! call Capture_p_error()
|
||||
|
||||
" Error message output within a function should be three lines (the function
|
||||
" name, the line number, and the error message).
|
||||
call assert_equal(3, count(s:p_err, "\n"))
|
||||
|
||||
delfunction Capture_p_error
|
||||
bwipeout!
|
||||
endfunc
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
" Test sort()
|
||||
" Tests for the "sort()" function and for the ":sort" command.
|
||||
|
||||
:func Compare1(a, b) abort
|
||||
func Compare1(a, b) abort
|
||||
call sort(range(3), 'Compare2')
|
||||
return a:a - a:b
|
||||
:endfunc
|
||||
endfunc
|
||||
|
||||
:func Compare2(a, b) abort
|
||||
func Compare2(a, b) abort
|
||||
return a:a - a:b
|
||||
:endfunc
|
||||
endfunc
|
||||
|
||||
func Test_sort_strings()
|
||||
" numbers compared as strings
|
||||
@@ -45,7 +45,7 @@ func Test_sort_default()
|
||||
call assert_fails('call sort([3.3, 1, "2"], 3)', "E474")
|
||||
endfunc
|
||||
|
||||
" Tests for the :sort command
|
||||
" Tests for the ":sort" command.
|
||||
func Test_sort_cmd()
|
||||
let tests = [
|
||||
\ {
|
||||
@@ -1167,15 +1167,54 @@ func Test_sort_cmd()
|
||||
\ '1.234',
|
||||
\ '123.456'
|
||||
\ ]
|
||||
\ }
|
||||
\ },
|
||||
\ {
|
||||
\ 'name' : 'alphabetical, sorted input',
|
||||
\ 'cmd' : 'sort',
|
||||
\ 'input' : [
|
||||
\ 'a',
|
||||
\ 'b',
|
||||
\ 'c',
|
||||
\ ],
|
||||
\ 'expected' : [
|
||||
\ 'a',
|
||||
\ 'b',
|
||||
\ 'c',
|
||||
\ ]
|
||||
\ },
|
||||
\ {
|
||||
\ 'name' : 'alphabetical, sorted input, unique at end',
|
||||
\ 'cmd' : 'sort u',
|
||||
\ 'input' : [
|
||||
\ 'aa',
|
||||
\ 'bb',
|
||||
\ 'cc',
|
||||
\ 'cc',
|
||||
\ ],
|
||||
\ 'expected' : [
|
||||
\ 'aa',
|
||||
\ 'bb',
|
||||
\ 'cc',
|
||||
\ ]
|
||||
\ },
|
||||
\ ]
|
||||
|
||||
for t in tests
|
||||
enew!
|
||||
call append(0, t.input)
|
||||
$delete _
|
||||
exe t.cmd
|
||||
setlocal nomodified
|
||||
execute t.cmd
|
||||
|
||||
call assert_equal(t.expected, getline(1, '$'), t.name)
|
||||
|
||||
" Previously, the ":sort" command would set 'modified' even if the buffer
|
||||
" contents did not change. Here, we check that this problem is fixed.
|
||||
if t.input == t.expected
|
||||
call assert_false(&modified, t.name . ': &mod is not correct')
|
||||
else
|
||||
call assert_true(&modified, t.name . ': &mod is not correct')
|
||||
endif
|
||||
endfor
|
||||
|
||||
call assert_fails('sort no', 'E474')
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
" Various tests for inserting a Tab.
|
||||
|
||||
" Tests for "r<Tab>" with 'smarttab' and 'expandtab' set/not set.
|
||||
" Also test that dv_ works correctly
|
||||
@@ -43,3 +44,38 @@ func Test_smarttab()
|
||||
enew!
|
||||
set expandtab& smartindent& copyindent& ts& sw& sts&
|
||||
endfunc
|
||||
|
||||
func Test_softtabstop()
|
||||
new
|
||||
set sts=0 sw=0
|
||||
exe "normal ix\<Tab>x\<Esc>"
|
||||
call assert_equal("x\tx", getline(1))
|
||||
|
||||
call setline(1, '')
|
||||
set sts=4
|
||||
exe "normal ix\<Tab>x\<Esc>"
|
||||
call assert_equal("x x", getline(1))
|
||||
|
||||
call setline(1, '')
|
||||
set sts=-1 sw=4
|
||||
exe "normal ix\<Tab>x\<Esc>"
|
||||
call assert_equal("x x", getline(1))
|
||||
|
||||
call setline(1, 'x ')
|
||||
set sts=0 sw=0 backspace=start
|
||||
exe "normal A\<BS>x\<Esc>"
|
||||
call assert_equal("x x", getline(1))
|
||||
|
||||
call setline(1, 'x ')
|
||||
set sts=4
|
||||
exe "normal A\<BS>x\<Esc>"
|
||||
call assert_equal("x x", getline(1))
|
||||
|
||||
call setline(1, 'x ')
|
||||
set sts=-1 sw=4
|
||||
exe "normal A\<BS>x\<Esc>"
|
||||
call assert_equal("x x", getline(1))
|
||||
|
||||
set sts=0 sw=0 backspace&
|
||||
bwipe!
|
||||
endfunc
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
" test 'taglist' function and :tags command
|
||||
" test taglist(), tagfiles() functions and :tags command
|
||||
|
||||
func Test_taglist()
|
||||
call writefile([
|
||||
@@ -61,3 +61,26 @@ func Test_tags_too_long()
|
||||
call assert_fails('tag ' . repeat('x', 1020), 'E426')
|
||||
tags
|
||||
endfunc
|
||||
|
||||
func Test_tagfiles()
|
||||
call assert_equal([], tagfiles())
|
||||
|
||||
call writefile(["FFoo\tXfoo\t1"], 'Xtags1')
|
||||
call writefile(["FBar\tXbar\t1"], 'Xtags2')
|
||||
set tags=Xtags1,Xtags2
|
||||
call assert_equal(['Xtags1', 'Xtags2'], tagfiles())
|
||||
|
||||
help
|
||||
let tf = tagfiles()
|
||||
call assert_equal(1, len(tf))
|
||||
call assert_equal(fnamemodify(expand('$VIMRUNTIME/doc/tags'), ':p:gs?\\?/?'),
|
||||
\ fnamemodify(tf[0], ':p:gs?\\?/?'))
|
||||
helpclose
|
||||
call assert_equal(['Xtags1', 'Xtags2'], tagfiles())
|
||||
set tags&
|
||||
call assert_equal([], tagfiles())
|
||||
|
||||
call delete('Xtags1')
|
||||
call delete('Xtags2')
|
||||
bd
|
||||
endfunc
|
||||
|
||||
@@ -262,21 +262,37 @@ func! Test_vartabs_breakindent()
|
||||
endfunc
|
||||
|
||||
func! Test_vartabs_linebreak()
|
||||
if winwidth(0) < 80
|
||||
if winwidth(0) < 40
|
||||
return
|
||||
endif
|
||||
new
|
||||
70vnew
|
||||
40vnew
|
||||
%d
|
||||
setl linebreak vartabstop=10,15,20,40
|
||||
setl linebreak vartabstop=10,20,30,40
|
||||
call setline(1, "\tx\tx\tx\tx")
|
||||
|
||||
let lines = ScreenLines([1, 2], winwidth(0))
|
||||
let expect = [' x x x ',
|
||||
\ ' x ']
|
||||
let expect = [' x ',
|
||||
\ 'x x ',
|
||||
\ 'x ']
|
||||
let lines = ScreenLines([1, 3], winwidth(0))
|
||||
call s:compare_lines(expect, lines)
|
||||
setl list listchars=tab:>-
|
||||
let expect = ['>---------x>------------------ ',
|
||||
\ 'x>------------------x>------------------',
|
||||
\ 'x ']
|
||||
let lines = ScreenLines([1, 3], winwidth(0))
|
||||
call s:compare_lines(expect, lines)
|
||||
setl linebreak vartabstop=40
|
||||
let expect = ['>---------------------------------------',
|
||||
\ 'x>--------------------------------------',
|
||||
\ 'x>--------------------------------------',
|
||||
\ 'x>--------------------------------------',
|
||||
\ 'x ']
|
||||
let lines = ScreenLines([1, 5], winwidth(0))
|
||||
call s:compare_lines(expect, lines)
|
||||
|
||||
" cleanup
|
||||
bw!
|
||||
bw!
|
||||
set nolist listchars&vim
|
||||
endfunc
|
||||
|
||||
@@ -42,6 +42,22 @@ func Test_paste_end_of_line()
|
||||
set virtualedit=
|
||||
endfunc
|
||||
|
||||
func Test_replace_end_of_line()
|
||||
new
|
||||
set virtualedit=all
|
||||
call setline(1, range(20))
|
||||
exe "normal! gg2jv10lr-"
|
||||
call assert_equal(["1", "-----------", "3"], getline(2,4))
|
||||
if has('multi_byte')
|
||||
call setline(1, range(20))
|
||||
exe "normal! gg2jv10lr\<c-k>hh"
|
||||
call assert_equal(["1", "───────────", "3"], getline(2,4))
|
||||
endif
|
||||
|
||||
bwipe!
|
||||
set virtualedit=
|
||||
endfunc
|
||||
|
||||
func Test_edit_CTRL_G()
|
||||
new
|
||||
set virtualedit=insert
|
||||
|
||||
+1
-1
@@ -2968,7 +2968,7 @@ u_undo_end(
|
||||
}
|
||||
#endif
|
||||
|
||||
smsg((char_u *)_("%ld %s; %s #%ld %s"),
|
||||
smsg_attr_keep(0, (char_u *)_("%ld %s; %s #%ld %s"),
|
||||
u_oldcount < 0 ? -u_oldcount : u_oldcount,
|
||||
_(msgstr),
|
||||
did_undo ? _("before") : _("after"),
|
||||
|
||||
+30
-22
@@ -293,10 +293,6 @@ get_lambda_tv(char_u **arg, typval_T *rettv, int evaluate)
|
||||
fp->uf_scoped = NULL;
|
||||
|
||||
#ifdef FEAT_PROFILE
|
||||
fp->uf_tml_count = NULL;
|
||||
fp->uf_tml_total = NULL;
|
||||
fp->uf_tml_self = NULL;
|
||||
fp->uf_profiling = FALSE;
|
||||
if (prof_def_func())
|
||||
func_do_profile(fp);
|
||||
#endif
|
||||
@@ -706,6 +702,7 @@ call_user_func(
|
||||
#ifdef FEAT_PROFILE
|
||||
proftime_T wait_start;
|
||||
proftime_T call_start;
|
||||
int started_profiling = FALSE;
|
||||
#endif
|
||||
|
||||
/* If depth of calling is getting too high, don't execute the function */
|
||||
@@ -921,7 +918,10 @@ call_user_func(
|
||||
if (do_profiling == PROF_YES)
|
||||
{
|
||||
if (!fp->uf_profiling && has_profiling(FALSE, fp->uf_name, NULL))
|
||||
{
|
||||
started_profiling = TRUE;
|
||||
func_do_profile(fp);
|
||||
}
|
||||
if (fp->uf_profiling
|
||||
|| (fc->caller != NULL && fc->caller->func->uf_profiling))
|
||||
{
|
||||
@@ -965,6 +965,9 @@ call_user_func(
|
||||
profile_add(&fc->caller->func->uf_tm_children, &call_start);
|
||||
profile_add(&fc->caller->func->uf_tml_children, &call_start);
|
||||
}
|
||||
if (started_profiling)
|
||||
// make a ":profdel func" stop profiling the function
|
||||
fp->uf_profiling = FALSE;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -2522,23 +2525,28 @@ func_do_profile(ufunc_T *fp)
|
||||
{
|
||||
int len = fp->uf_lines.ga_len;
|
||||
|
||||
if (len == 0)
|
||||
len = 1; /* avoid getting error for allocating zero bytes */
|
||||
fp->uf_tm_count = 0;
|
||||
profile_zero(&fp->uf_tm_self);
|
||||
profile_zero(&fp->uf_tm_total);
|
||||
if (fp->uf_tml_count == NULL)
|
||||
fp->uf_tml_count = (int *)alloc_clear((unsigned) (sizeof(int) * len));
|
||||
if (fp->uf_tml_total == NULL)
|
||||
fp->uf_tml_total = (proftime_T *)alloc_clear((unsigned)
|
||||
(sizeof(proftime_T) * len));
|
||||
if (fp->uf_tml_self == NULL)
|
||||
fp->uf_tml_self = (proftime_T *)alloc_clear((unsigned)
|
||||
(sizeof(proftime_T) * len));
|
||||
fp->uf_tml_idx = -1;
|
||||
if (fp->uf_tml_count == NULL || fp->uf_tml_total == NULL
|
||||
|| fp->uf_tml_self == NULL)
|
||||
return; /* out of memory */
|
||||
if (!fp->uf_prof_initialized)
|
||||
{
|
||||
if (len == 0)
|
||||
len = 1; /* avoid getting error for allocating zero bytes */
|
||||
fp->uf_tm_count = 0;
|
||||
profile_zero(&fp->uf_tm_self);
|
||||
profile_zero(&fp->uf_tm_total);
|
||||
if (fp->uf_tml_count == NULL)
|
||||
fp->uf_tml_count = (int *)alloc_clear(
|
||||
(unsigned)(sizeof(int) * len));
|
||||
if (fp->uf_tml_total == NULL)
|
||||
fp->uf_tml_total = (proftime_T *)alloc_clear(
|
||||
(unsigned)(sizeof(proftime_T) * len));
|
||||
if (fp->uf_tml_self == NULL)
|
||||
fp->uf_tml_self = (proftime_T *)alloc_clear(
|
||||
(unsigned)(sizeof(proftime_T) * len));
|
||||
fp->uf_tml_idx = -1;
|
||||
if (fp->uf_tml_count == NULL || fp->uf_tml_total == NULL
|
||||
|| fp->uf_tml_self == NULL)
|
||||
return; /* out of memory */
|
||||
fp->uf_prof_initialized = TRUE;
|
||||
}
|
||||
|
||||
fp->uf_profiling = TRUE;
|
||||
}
|
||||
@@ -2568,7 +2576,7 @@ func_dump_profile(FILE *fd)
|
||||
{
|
||||
--todo;
|
||||
fp = HI2UF(hi);
|
||||
if (fp->uf_profiling)
|
||||
if (fp->uf_prof_initialized)
|
||||
{
|
||||
if (sorttab != NULL)
|
||||
sorttab[st_len++] = fp;
|
||||
|
||||
@@ -804,6 +804,50 @@ static char *(features[]) =
|
||||
|
||||
static int included_patches[] =
|
||||
{ /* Add new patch number below this line */
|
||||
/**/
|
||||
139,
|
||||
/**/
|
||||
138,
|
||||
/**/
|
||||
137,
|
||||
/**/
|
||||
136,
|
||||
/**/
|
||||
135,
|
||||
/**/
|
||||
134,
|
||||
/**/
|
||||
133,
|
||||
/**/
|
||||
132,
|
||||
/**/
|
||||
131,
|
||||
/**/
|
||||
130,
|
||||
/**/
|
||||
129,
|
||||
/**/
|
||||
128,
|
||||
/**/
|
||||
127,
|
||||
/**/
|
||||
126,
|
||||
/**/
|
||||
125,
|
||||
/**/
|
||||
124,
|
||||
/**/
|
||||
123,
|
||||
/**/
|
||||
122,
|
||||
/**/
|
||||
121,
|
||||
/**/
|
||||
120,
|
||||
/**/
|
||||
119,
|
||||
/**/
|
||||
118,
|
||||
/**/
|
||||
117,
|
||||
/**/
|
||||
|
||||
Reference in New Issue
Block a user