Compare commits

...

6 Commits

Author SHA1 Message Date
7f88b65f6c patch 8.0.1390: DirectX scrolling can be slow, vertical positioning is off
Problem:    DirectX scrolling can be slow, vertical positioning is off.
Solution:   Make scroll slightly faster when using "scrlines:1". Fix y
            position of displayed text. Fix DirectX with non-utf8 encoding.
            (Ken Takata, closes #2440)
2017-12-14 13:15:19 +01:00
a6d4849c71 patch 8.0.1389: getqflist() items are missing if not set
Problem:    getqflist() items are missing if not set, that makes it more
            difficult to handle the values.
Solution:   When a value is not available return zero or another invalid
            value. (Yegappan Lakshmanan, closes #2430)
2017-12-12 22:45:31 +01:00
fae8ed1fc8 patch 8.0.1388: char not overwritten with ambiguous width char
Problem:    Char not overwritten with ambiguous width char, if the ambiguous
            char is single width but we reserve double-width space.
Solution:   First clear the screen cells. (Ozaki Kiichi, closes #2436)
2017-12-12 22:29:30 +01:00
a703aaee4d patch 8.0.1387: wordcount test is old style
Problem:    Wordcount test is old style.
Solution:   Change into a new style test. (Yegappan Lakshmanan, closes #2434)
2017-12-11 22:55:26 +01:00
8e6a31df81 patch 8.0.1386: cannot select modified buffers with getbufinfo()
Problem:    Cannot select modified buffers with getbufinfo().
Solution:   Add the "bufmodified" flag. (Yegappan Lakshmanan, closes #2431)
2017-12-10 21:06:22 +01:00
59eb016dff patch 8.0.1385: Python 3.5 is getting old
Problem:    Python 3.5 is getting old.
Solution:   Make Python 3.6 the default. (Ken Takata, closes #2429)
2017-12-10 18:17:44 +01:00
21 changed files with 443 additions and 288 deletions

View File

@ -4173,6 +4173,7 @@ getbufinfo([{dict}])
be specified in {dict}:
buflisted include only listed buffers.
bufloaded include only loaded buffers.
bufmodified include only modified buffers.
Otherwise, {expr} specifies a particular buffer to return
information for. For the use of {expr}, see |bufname()|
@ -4686,7 +4687,7 @@ getqflist([{what}]) *getqflist()*
winid get the quickfix |window-ID|
all all of the above quickfix properties
Non-string items in {what} are ignored. To get the value of a
particular item, set it to one.
particular item, set it to zero.
If "nr" is not present then the current quickfix list is used.
If both "nr" and a non-zero "id" are specified, then the list
specified by "id" is used.
@ -4696,17 +4697,21 @@ getqflist([{what}]) *getqflist()*
When "lines" is specified, all the other items except "efm"
are ignored. The returned dictionary contains the entry
"items" with the list of entries.
In case of error processing {what}, an empty dictionary is
returned.
The returned dictionary contains the following entries:
context context information stored with |setqflist()|
id quickfix list ID |quickfix-ID|
idx index of the current entry in the list
items quickfix list entries
nr quickfix list number
size number of entries in the quickfix list
title quickfix list title text
context context information stored with |setqflist()|.
If not present, set to "".
id quickfix list ID |quickfix-ID|. If not
present, set to 0.
idx index of the current entry in the list. If not
present, set to 0.
items quickfix list entries. If not present, set to
an empty list.
nr quickfix list number. If not present, set to 0
size number of entries in the quickfix list. If not
present, set to 0.
title quickfix list title text. If not present, set
to "".
winid quickfix |window-ID|. If not present, set to 0
Examples: >

View File

@ -736,8 +736,8 @@ or 'pythonthreedll' option can be also used to specify the Python DLL.
The name of the DLL should match the Python version Vim was compiled with.
Currently the name for Python 2 is "python27.dll", that is for Python 2.7.
That is the default value for 'pythondll'. For Python 3 it is python35.dll
(Python 3.5). To know for sure edit "gvim.exe" and search for
That is the default value for 'pythondll'. For Python 3 it is python36.dll
(Python 3.6). To know for sure edit "gvim.exe" and search for
"python\d*.dll\c".

View File

@ -34,10 +34,11 @@ Contents:
11. Building with Ruby support
12. Building with Tcl support
13. Building with Terminal support
14. Windows 3.1
15. MS-DOS
14. Building with DirectX (DirectWrite) support
15. Windows 3.1
16. MS-DOS
16. Installing after building from sources
17. Installing after building from sources
The currently recommended way (that means it has been verified to work) is
@ -438,18 +439,31 @@ You will end up with a Python-enabled, Win32 version. Enjoy!
================================
For building with MSVC 2008 the "Windows Installer" from www.python.org
works fine. Python 3.4 is recommended.
works fine. Python 3.6 is recommended.
When building, you need to set the following variables at least:
PYTHON3: Where Python3 is installed. E.g. C:\Python34
PYTHON3: Where Python3 is installed. E.g. C:\Python36
DYNAMIC_PYTHON3: Whether dynamic linking is used. Usually, set to yes.
PYTHON3_VER: Python3 version. E.g. 34 for Python 3.4.X.
PYTHON3_VER: Python3 version. E.g. 36 for Python 3.6.X.
E.g. When using MSVC (as one line):
nmake -f Make_mvc.mak
PYTHON3=C:\Python34 DYNAMIC_PYTHON3=yes PYTHON3_VER=34
PYTHON3=C:\Python36 DYNAMIC_PYTHON3=yes PYTHON3_VER=36
When using msys2 and link with Python3 bundled with msys2 (as one line):
mingw32-make -f Make_ming.mak PYTHON3=c:/msys64/mingw64
PYTHON3_HOME=c:/msys64/mingw64
PYTHON3INC=-Ic:/msys64/mingw64/include/python3.6m
DYNAMIC_PYTHON3=yes
PYTHON3_VER=36
DYNAMIC_PYTHON3_DLL=libpython3.6m.dll
STATIC_STDCPLUS=yes
(This is for 64-bit builds. For 32-bit builds, replace mingw64 with mingw32.)
8. Building with Racket or MzScheme support
@ -684,21 +698,33 @@ config.h and Ruby's DLL name. Here are the steps for working around them:
There is no need to build whole Ruby, just config.h is needed.
If you use 32-bit MSVC 2015, the config.h is generated in the
.ext\include\i386-mswin32_140 directory.
If you use 64-bit MSVC 2015, the config.h is generated in the
.ext\include\x64-mswin64_140 directory.
3) Install the generated config.h.
For 32-bit version:
xcopy /s .ext\include C:\Ruby24\include\ruby-2.4.0
For 64-bit version:
xcopy /s .ext\include C:\Ruby24-x64\include\ruby-2.4.0
Note that 2.4.0 is Ruby API version of Ruby 2.4.X.
You may need to close the console and reopen it to pick up the new $PATH.
4) Build Vim. Note that you need to adjust some variables (as one line):
For 32-bit version:
nmake -f Make_mvc.mak
RUBY=C:\Ruby24 DYNAMIC_RUBY=yes RUBY_VER=24 RUBY_API_VER_LONG=2.4.0
RUBY_MSVCRT_NAME=msvcrt
WINVER=0x501
For 64-bit version, replace RUBY=C:\Ruby24 with RUBY=C:\Ruby24-x64.
If you set WINVER explicitly, it must be set to >=0x500, when building
with Ruby 2.1 or later. (Default is 0x501.)
When using this trick, you also need to set RUBY_MSVCRT_NAME to msvcrt
@ -713,6 +739,7 @@ After you install RubyInstaller, just type this (as one line):
RUBY=C:/Ruby24 DYNAMIC_RUBY=yes RUBY_VER=24 RUBY_API_VER_LONG=2.4.0
WINVER=0x501
For 64-bit version, replace RUBY=C:/Ruby24 with RUBY=C:/Ruby24-x64.
If you set WINVER explicitly, it must be set to >=0x500, when building with
Ruby 2.1 or later. (Default is 0x501.)
@ -761,25 +788,59 @@ E.g. When using MSVC:
nmake -f Make_mvc.mak TERMINAL=yes
Or when using MinGW (as one line):
Or when using MinGW:
mingw32-make -f Make_ming.mak TERMINAL=yes
14. Windows 3.1x
14. Building with DirectX (DirectWrite) support
===============================================
Vim with DirectX (DirectWrite) support can be built with either MSVC or MinGW.
This requires dwrite_2.h and some other header files which come with Windows
SDK 8.1 or later (or MinGW-w64), if you want to enable color emoji support.
This also requires MBYTE=yes which is enabled by default.
A) Using MSVC
If you use MSVC 2013 or later, Windows SDK 8.1 or later is used by default.
You just need to specify DIRECTX=yes:
nmake -f Make_mvc.mak DIRECTX=yes
If you use MSVC 2012 or earlier, the required header files are not available
by default. However, you can use the header files from newer SDKs with older
compilers. E.g.:
set "INCLUDE=%INCLUDE%;C:\Program Files (x86)\Windows Kits\8.1\Include\um"
nmake -f Make_mvc.mak DIRECTX=yes
If you don't need color emoji support, only dwrite.h is required. You can use
older compilers (e.g. VC2010) without Windows SDK 8.1. E.g.:
nmake -f Make_mvc.mak DIRECTX=yes COLOR_EMOJI=no
B) Using MinGW-w64
Just set DIRECTX to yes:
mingw32-make -f Make_ming.mak DIRECTX=yes
15. Windows 3.1x
================
The Windows 3.1x support was removed in patch 7.4.1364.
15. MS-DOS
16. 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.
16. Installing after building from sources
17. Installing after building from sources
==========================================
[provided by Michael Soyka, updated by Ken Takata]

View File

@ -316,14 +316,14 @@ endif
# Python3 interface:
# PYTHON3=[Path to Python3 directory] (Set inside Make_cyg.mak or Make_ming.mak)
# DYNAMIC_PYTHON3=yes (to load the Python3 DLL dynamically)
# PYTHON3_VER=[Python3 version, eg 31, 32] (default is 35)
# PYTHON3_VER=[Python3 version, eg 31, 32] (default is 36)
ifdef PYTHON3
ifndef DYNAMIC_PYTHON3
DYNAMIC_PYTHON3=yes
endif
ifndef PYTHON3_VER
PYTHON3_VER=35
PYTHON3_VER=36
endif
ifndef DYNAMIC_PYTHON3_DLL
DYNAMIC_PYTHON3_DLL=python$(PYTHON3_VER).dll
@ -588,7 +588,7 @@ endif
ifeq ($(DIRECTX),yes)
# Only allow DirectWrite for a GUI build.
ifeq (yes, $(GUI))
DEFINES += -DFEAT_DIRECTX -DDYNAMIC_DIRECTX
DEFINES += -DFEAT_DIRECTX -DDYNAMIC_DIRECTX -DFEAT_DIRECTX_COLOR_EMOJI
endif
endif

View File

@ -25,12 +25,15 @@
#
# GUI interface: GUI=yes (default is no)
#
# GUI with DirectWrite(DirectX): DIRECTX=yes
# (default is no, requires GUI=yes)
# GUI with DirectWrite (DirectX): DIRECTX=yes
# (default is no, requires GUI=yes and MBYTE=yes)
#
# Color emoji support: COLOR_EMOJI=yes
# (default is yes if DIRECTX=yes, requires WinSDK 8.1 or later.)
#
# OLE interface: OLE=yes (usually with GUI=yes)
#
# Multibyte support: MBYTE=yes (default is no)
# Multibyte support: MBYTE=yes (default is yes for NORMAL, BIG, HUGE)
#
# IME support: IME=yes (requires GUI=yes)
# DYNAMIC_IME=[yes or no] (to load the imm32.dll dynamically, default
@ -67,7 +70,7 @@
# Python3 interface:
# PYTHON3=[Path to Python3 directory]
# DYNAMIC_PYTHON3=yes (to load the Python3 DLL dynamically)
# PYTHON3_VER=[Python3 version, eg 30, 31] (default is 35)
# PYTHON3_VER=[Python3 version, eg 30, 31] (default is 36)
#
# Ruby interface:
# RUBY=[Path to Ruby directory]
@ -419,9 +422,12 @@ NBDEBUG_SRC = nbdebug.c
NETBEANS_LIB = WSock32.lib
!endif
# DirectWrite(DirectX)
# DirectWrite (DirectX)
!if "$(DIRECTX)" == "yes"
DIRECTX_DEFS = -DFEAT_DIRECTX -DDYNAMIC_DIRECTX
!if "$(COLOR_EMOJI)" != "no"
DIRECTX_DEFS = $(DIRECTX_DEFS) -DFEAT_DIRECTX_COLOR_EMOJI
!endif
DIRECTX_INCL = gui_dwrite.h
DIRECTX_OBJ = $(OUTDIR)\gui_dwrite.obj
!endif
@ -906,7 +912,7 @@ PYTHON_LIB = $(PYTHON)\libs\python$(PYTHON_VER).lib
# PYTHON3 interface
!ifdef PYTHON3
!ifndef PYTHON3_VER
PYTHON3_VER = 35
PYTHON3_VER = 36
!endif
!message Python3 requested (version $(PYTHON3_VER)) - root dir is "$(PYTHON3)"
!if "$(DYNAMIC_PYTHON3)" == "yes"

View File

@ -2101,7 +2101,6 @@ run_message_test: $(MESSAGE_TEST_TARGET)
# These do not depend on the executable, compile it when needed.
test1 \
test_eval \
test_wordcount \
test3 test11 test14 test15 test17 \
test29 test30 test36 test37 test39 \
test42 test44 test48 test49 \
@ -2296,6 +2295,7 @@ test_arglist \
test_window_cmd \
test_window_id \
test_windows_home \
test_wordcount \
test_writefile \
test_alot_latin \
test_alot_utf8 \

View File

@ -1,5 +1,5 @@
:: command to build big Vim with OLE, Lua, Perl, Python, Racket, Ruby and Tcl
SET VCDIR="C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\bin\"
SET TOOLDIR=E:\
%VCDIR%nmake -f Make_mvc.mak GUI=yes OLE=yes LUA=%TOOLDIR%lua53 DYNAMIC_LUA=yes LUA_VER=53 PERL=%TOOLDIR%perl524 DYNAMIC_PERL=yes PERL_VER=524 PYTHON=%TOOLDIR%python27 DYNAMIC_PYTHON=yes PYTHON_VER=27 PYTHON3=%TOOLDIR%python35 DYNAMIC_PYTHON3=yes PYTHON3_VER=35 MZSCHEME=%TOOLDIR%Racket DYNAMIC_MZSCHEME=yes MZSCHEME_VER=3m_a36fs8 RUBY=%TOOLDIR%ruby24 DYNAMIC_RUBY=yes RUBY_VER=24 RUBY_API_VER_LONG=2.4.0 RUBY_MSVCRT_NAME=msvcrt TCL=%TOOLDIR%ActiveTcl TCL_VER=86 TCL_VER_LONG=8.6 DYNAMIC_TCL=yes TCL_DLL=tcl86t.dll %1 IME=yes CSCOPE=yes DIRECTX=yes
%VCDIR%nmake -f Make_mvc.mak GUI=yes OLE=yes LUA=%TOOLDIR%lua53 DYNAMIC_LUA=yes LUA_VER=53 PERL=%TOOLDIR%perl524 DYNAMIC_PERL=yes PERL_VER=524 PYTHON=%TOOLDIR%python27 DYNAMIC_PYTHON=yes PYTHON_VER=27 PYTHON3=%TOOLDIR%python36 DYNAMIC_PYTHON3=yes PYTHON3_VER=36 MZSCHEME=%TOOLDIR%Racket DYNAMIC_MZSCHEME=yes MZSCHEME_VER=3m_a36fs8 RUBY=%TOOLDIR%ruby24 DYNAMIC_RUBY=yes RUBY_VER=24 RUBY_API_VER_LONG=2.4.0 RUBY_MSVCRT_NAME=msvcrt TCL=%TOOLDIR%ActiveTcl TCL_VER=86 TCL_VER_LONG=8.6 DYNAMIC_TCL=yes TCL_DLL=tcl86t.dll %1 IME=yes CSCOPE=yes DIRECTX=yes

View File

@ -4137,6 +4137,7 @@ f_getbufinfo(typval_T *argvars, typval_T *rettv)
int filtered = FALSE;
int sel_buflisted = FALSE;
int sel_bufloaded = FALSE;
int sel_bufmodified = FALSE;
if (rettv_list_alloc(rettv) != OK)
return;
@ -4159,6 +4160,10 @@ f_getbufinfo(typval_T *argvars, typval_T *rettv)
di = dict_find(sel_d, (char_u *)"bufloaded", -1);
if (di != NULL && get_tv_number(&di->di_tv))
sel_bufloaded = TRUE;
di = dict_find(sel_d, (char_u *)"bufmodified", -1);
if (di != NULL && get_tv_number(&di->di_tv))
sel_bufmodified = TRUE;
}
}
else if (argvars[0].v_type != VAR_UNKNOWN)
@ -4178,7 +4183,8 @@ f_getbufinfo(typval_T *argvars, typval_T *rettv)
if (argbuf != NULL && argbuf != buf)
continue;
if (filtered && ((sel_bufloaded && buf->b_ml.ml_mfp == NULL)
|| (sel_buflisted && !buf->b_p_bl)))
|| (sel_buflisted && !buf->b_p_bl)
|| (sel_bufmodified && !buf->b_changed)))
continue;
d = get_buffer_info(buf);

View File

@ -38,7 +38,11 @@
# define _Outptr_
#endif
#include <dwrite_2.h>
#ifdef FEAT_DIRECTX_COLOR_EMOJI
# include <dwrite_2.h>
#else
# include <dwrite.h>
#endif
#include "gui_dwrite.h"
@ -284,7 +288,9 @@ struct DWriteContext {
ID2D1SolidColorBrush *mBrush;
IDWriteFactory *mDWriteFactory;
#ifdef FEAT_DIRECTX_COLOR_EMOJI
IDWriteFactory2 *mDWriteFactory2;
#endif
IDWriteGdiInterop *mGdiInterop;
IDWriteRenderingParams *mRenderingParams;
@ -481,6 +487,7 @@ public:
AdjustedGlyphRun adjustedGlyphRun(glyphRun, context->cellWidth,
context->offsetX);
#ifdef FEAT_DIRECTX_COLOR_EMOJI
if (pDWC_->mDWriteFactory2 != NULL)
{
IDWriteColorGlyphRunEnumerator *enumerator = NULL;
@ -517,6 +524,7 @@ public:
return S_OK;
}
}
#endif
// Draw by IDWriteFactory (without color emoji)
pDWC_->mRT->DrawGlyphRun(
@ -589,7 +597,9 @@ DWriteContext::DWriteContext() :
mGDIRT(NULL),
mBrush(NULL),
mDWriteFactory(NULL),
#ifdef FEAT_DIRECTX_COLOR_EMOJI
mDWriteFactory2(NULL),
#endif
mGdiInterop(NULL),
mRenderingParams(NULL),
mFontCache(8),
@ -618,6 +628,7 @@ DWriteContext::DWriteContext() :
mDWriteFactory);
}
#ifdef FEAT_DIRECTX_COLOR_EMOJI
if (SUCCEEDED(hr))
{
DWriteCreateFactory(
@ -626,6 +637,7 @@ DWriteContext::DWriteContext() :
reinterpret_cast<IUnknown**>(&mDWriteFactory2));
_RPT1(_CRT_WARN, "IDWriteFactory2: %s\n", SUCCEEDED(hr) ? "available" : "not available");
}
#endif
if (SUCCEEDED(hr))
{
@ -647,7 +659,9 @@ DWriteContext::~DWriteContext()
SafeRelease(&mRenderingParams);
SafeRelease(&mGdiInterop);
SafeRelease(&mDWriteFactory);
#ifdef FEAT_DIRECTX_COLOR_EMOJI
SafeRelease(&mDWriteFactory2);
#endif
SafeRelease(&mBrush);
SafeRelease(&mGDIRT);
SafeRelease(&mRT);
@ -995,7 +1009,7 @@ DWriteContext::DrawText(const WCHAR *text, int len,
TextRenderer renderer(this);
TextRendererContext context = { color, FLOAT(cellWidth), 0.0f };
textLayout->Draw(&context, &renderer, FLOAT(x), FLOAT(y));
textLayout->Draw(&context, &renderer, FLOAT(x), FLOAT(y) - 0.5f);
}
SafeRelease(&textLayout);

View File

@ -30,11 +30,14 @@
#endif
#if defined(FEAT_DIRECTX)
# ifndef FEAT_MBYTE
# error FEAT_MBYTE is required for FEAT_DIRECTX.
# endif
static DWriteContext *s_dwc = NULL;
static int s_directx_enabled = 0;
static int s_directx_load_attempted = 0;
static int s_directx_scrlines = 0;
# define IS_ENABLE_DIRECTX() (s_directx_enabled && s_dwc != NULL)
# define IS_ENABLE_DIRECTX() (s_directx_enabled && s_dwc != NULL && enc_utf8)
static int directx_enabled(void);
static void directx_binddc(void);
#endif
@ -47,7 +50,7 @@ static int gui_mswin_get_menu_height(int fix_window);
int
gui_mch_set_rendering_options(char_u *s)
{
#ifdef FEAT_DIRECTX
# ifdef FEAT_DIRECTX
char_u *p, *q;
int dx_enable = 0;
@ -159,9 +162,9 @@ gui_mch_set_rendering_options(char_u *s)
s_directx_scrlines = dx_scrlines;
return OK;
#else
# else
return FAIL;
#endif
# endif
}
#endif
@ -3140,7 +3143,8 @@ gui_mch_delete_lines(
{
if (s_directx_scrlines > 0 && s_directx_scrlines <= num_lines)
{
RedrawWindow(s_textArea, &rc, NULL, RDW_INVALIDATE);
gui_redraw(rc.left, rc.top,
rc.right - rc.left + 1, rc.bottom - rc.top + 1);
use_redraw = 1;
}
else
@ -3152,9 +3156,9 @@ gui_mch_delete_lines(
intel_gpu_workaround();
ScrollWindowEx(s_textArea, 0, -num_lines * gui.char_height,
&rc, &rc, NULL, NULL, get_scroll_flags());
UpdateWindow(s_textArea);
}
UpdateWindow(s_textArea);
/* This seems to be required to avoid the cursor disappearing when
* scrolling such that the cursor ends up in the top-left character on
* the screen... But why? (Webb) */
@ -3190,7 +3194,8 @@ gui_mch_insert_lines(
{
if (s_directx_scrlines > 0 && s_directx_scrlines <= num_lines)
{
RedrawWindow(s_textArea, &rc, NULL, RDW_INVALIDATE);
gui_redraw(rc.left, rc.top,
rc.right - rc.left + 1, rc.bottom - rc.top + 1);
use_redraw = 1;
}
else
@ -3204,10 +3209,9 @@ gui_mch_insert_lines(
* off-screen. How do we avoid it when it's not needed? */
ScrollWindowEx(s_textArea, 0, num_lines * gui.char_height,
&rc, &rc, NULL, NULL, get_scroll_flags());
UpdateWindow(s_textArea);
}
UpdateWindow(s_textArea);
gui_clear_block(row, gui.scroll_region_left,
row + num_lines - 1, gui.scroll_region_right);
}
@ -6401,13 +6405,13 @@ gui_mch_draw_string(
if (text[n] >= 0x80)
break;
#if defined(FEAT_DIRECTX)
# if defined(FEAT_DIRECTX)
/* Quick hack to enable DirectWrite. To use DirectWrite (antialias), it is
* required that unicode drawing routine, currently. So this forces it
* enabled. */
if (enc_utf8 && IS_ENABLE_DIRECTX())
if (IS_ENABLE_DIRECTX())
n = 0; /* Keep n < len, to enter block for unicode. */
#endif
# endif
/* Check if the Unicode buffer exists and is big enough. Create it
* with the same length as the multi-byte string, the number of wide
@ -6480,7 +6484,7 @@ gui_mch_draw_string(
i += utf_ptr2len_len(text + i, len - i);
++clen;
}
#if defined(FEAT_DIRECTX)
# if defined(FEAT_DIRECTX)
if (IS_ENABLE_DIRECTX())
{
/* Add one to "cells" for italics. */
@ -6490,7 +6494,7 @@ gui_mch_draw_string(
foptions, pcliprect, unicodepdy);
}
else
#endif
# endif
ExtTextOutW(s_hdc, TEXT_X(col), TEXT_Y(row),
foptions, pcliprect, unicodebuf, wlen, unicodepdy);
len = cells; /* used for underlining */

View File

@ -4863,70 +4863,24 @@ qf_get_properties(win_T *wp, dict_T *what, dict_T *retdict)
if (wp != NULL)
qi = GET_LOC_LIST(wp);
/* List is not present or is empty */
if (qi == NULL || qi->qf_listcount == 0)
{
/* If querying for the size of the list, return 0 */
if (((di = dict_find(what, (char_u *)"nr", -1)) != NULL)
&& (di->di_tv.v_type == VAR_STRING)
&& (STRCMP(di->di_tv.vval.v_string, "$") == 0))
return dict_add_nr_str(retdict, "nr", 0, NULL);
return FAIL;
}
qf_idx = qi->qf_curlist; /* default is the current list */
if ((di = dict_find(what, (char_u *)"nr", -1)) != NULL)
{
/* Use the specified quickfix/location list */
if (di->di_tv.v_type == VAR_NUMBER)
{
/* for zero use the current list */
if (di->di_tv.vval.v_number != 0)
{
qf_idx = di->di_tv.vval.v_number - 1;
if (qf_idx < 0 || qf_idx >= qi->qf_listcount)
return FAIL;
}
}
else if ((di->di_tv.v_type == VAR_STRING)
&& (STRCMP(di->di_tv.vval.v_string, "$") == 0))
/* Get the last quickfix list number */
qf_idx = qi->qf_listcount - 1;
else
return FAIL;
flags |= QF_GETLIST_NR;
}
if ((di = dict_find(what, (char_u *)"id", -1)) != NULL)
{
/* Look for a list with the specified id */
if (di->di_tv.v_type == VAR_NUMBER)
{
/* For zero, use the current list or the list specifed by 'nr' */
if (di->di_tv.vval.v_number != 0)
{
qf_idx = qf_id2nr(qi, di->di_tv.vval.v_number);
if (qf_idx == -1)
return FAIL; /* List not found */
}
flags |= QF_GETLIST_ID;
}
else
return FAIL;
}
if (dict_find(what, (char_u *)"all", -1) != NULL)
flags |= QF_GETLIST_ALL;
if (dict_find(what, (char_u *)"title", -1) != NULL)
flags |= QF_GETLIST_TITLE;
if (dict_find(what, (char_u *)"nr", -1) != NULL)
flags |= QF_GETLIST_NR;
if (dict_find(what, (char_u *)"winid", -1) != NULL)
flags |= QF_GETLIST_WINID;
if (dict_find(what, (char_u *)"context", -1) != NULL)
flags |= QF_GETLIST_CONTEXT;
if (dict_find(what, (char_u *)"id", -1) != NULL)
flags |= QF_GETLIST_ID;
if (dict_find(what, (char_u *)"items", -1) != NULL)
flags |= QF_GETLIST_ITEMS;
@ -4936,6 +4890,77 @@ qf_get_properties(win_T *wp, dict_T *what, dict_T *retdict)
if (dict_find(what, (char_u *)"size", -1) != NULL)
flags |= QF_GETLIST_SIZE;
if (qi != NULL && qi->qf_listcount != 0)
{
qf_idx = qi->qf_curlist; /* default is the current list */
if ((di = dict_find(what, (char_u *)"nr", -1)) != NULL)
{
/* Use the specified quickfix/location list */
if (di->di_tv.v_type == VAR_NUMBER)
{
/* for zero use the current list */
if (di->di_tv.vval.v_number != 0)
{
qf_idx = di->di_tv.vval.v_number - 1;
if (qf_idx < 0 || qf_idx >= qi->qf_listcount)
qf_idx = -1;
}
}
else if ((di->di_tv.v_type == VAR_STRING)
&& (STRCMP(di->di_tv.vval.v_string, "$") == 0))
/* Get the last quickfix list number */
qf_idx = qi->qf_listcount - 1;
else
qf_idx = -1;
flags |= QF_GETLIST_NR;
}
if ((di = dict_find(what, (char_u *)"id", -1)) != NULL)
{
/* Look for a list with the specified id */
if (di->di_tv.v_type == VAR_NUMBER)
{
/*
* For zero, use the current list or the list specifed by 'nr'
*/
if (di->di_tv.vval.v_number != 0)
qf_idx = qf_id2nr(qi, di->di_tv.vval.v_number);
flags |= QF_GETLIST_ID;
}
else
qf_idx = -1;
}
}
/* List is not present or is empty */
if (qi == NULL || qi->qf_listcount == 0 || qf_idx == -1)
{
if (flags & QF_GETLIST_TITLE)
status = dict_add_nr_str(retdict, "title", 0L, (char_u *)"");
if ((status == OK) && (flags & QF_GETLIST_ITEMS))
{
list_T *l = list_alloc();
if (l != NULL)
status = dict_add_list(retdict, "items", l);
else
status = FAIL;
}
if ((status == OK) && (flags & QF_GETLIST_NR))
status = dict_add_nr_str(retdict, "nr", 0L, NULL);
if ((status == OK) && (flags & QF_GETLIST_WINID))
status = dict_add_nr_str(retdict, "winid", 0L, NULL);
if ((status == OK) && (flags & QF_GETLIST_CONTEXT))
status = dict_add_nr_str(retdict, "context", 0L, (char_u *)"");
if ((status == OK) && (flags & QF_GETLIST_ID))
status = dict_add_nr_str(retdict, "id", 0L, NULL);
if ((status == OK) && (flags & QF_GETLIST_IDX))
status = dict_add_nr_str(retdict, "idx", 0L, NULL);
if ((status == OK) && (flags & QF_GETLIST_SIZE))
status = dict_add_nr_str(retdict, "size", 0L, NULL);
return status;
}
if (flags & QF_GETLIST_TITLE)
{
char_u *t;

View File

@ -8317,15 +8317,29 @@ screen_char(unsigned off, int row, int col)
{
char_u buf[MB_MAXBYTES + 1];
/* Convert UTF-8 character to bytes and write it. */
buf[utfc_char2bytes(off, buf)] = NUL;
out_str(buf);
if (utf_ambiguous_width(ScreenLinesUC[off]))
{
if (*p_ambw == 'd'
# ifdef FEAT_GUI
&& !gui.in_use
# endif
)
{
/* Clear the two screen cells. If the character is actually
* single width it won't change the second cell. */
out_str((char_u *)" ");
term_windgoto(row, col);
}
/* not sure where the cursor is after drawing the ambiguous width
* character */
screen_cur_col = 9999;
}
else if (utf_char2cells(ScreenLinesUC[off]) > 1)
++screen_cur_col;
/* Convert the UTF-8 character to bytes and write it. */
buf[utfc_char2bytes(off, buf)] = NUL;
out_str(buf);
}
else
#endif

View File

@ -31,8 +31,7 @@ SCRIPTS_ALL = \
test95.out \
test99.out \
test108.out \
test_eval.out \
test_wordcount.out
test_eval.out
# Tests that run on most systems, but not on Amiga.
@ -183,6 +182,7 @@ NEW_TESTS = test_arabic.res \
test_winbuf_close.res \
test_window_id.res \
test_windows_home.res \
test_wordcount.res \
test_writefile.res \
test_alot_latin.res \
test_alot_utf8.res \

View File

@ -63,7 +63,7 @@ win32: fixff nolog $(SCRIPTS_FIRST) $(SCRIPTS) $(SCRIPTS_WIN32) newtests
fixff:
-$(VIMPROG) -u dos.vim $(NO_INITS) "+argdo set ff=dos|upd" +q *.in *.ok
-$(VIMPROG) -u dos.vim $(NO_INITS) "+argdo set ff=unix|upd" +q \
dotest.in test_wordcount.ok
dotest.in
clean:
-@if exist *.out $(DEL) *.out

View File

@ -81,13 +81,7 @@ SCRIPT = test1.out test3.out \
test64.out test69.out \
test72.out test77a.out test88.out \
test94.out test95.out test99.out test108.out \
test_autocmd_option.out \
test_breakindent.out \
test_eval.out \
test_listlbr.out \
test_listlbr_utf8.out \
test_utf8.out \
test_wordcount.out
test_eval.out
# Known problems:
# test17: ?

View File

@ -20,6 +20,13 @@ function Test_getbufwintabinfo()
call assert_equal('vim', l[0].variables.editor)
call assert_notequal(-1, index(l[0].windows, bufwinid('%')))
" Test for getbufinfo() with 'bufmodified'
call assert_equal(0, len(getbufinfo({'bufmodified' : 1})))
call setbufline('Xtestfile1', 1, ["Line1"])
let l = getbufinfo({'bufmodified' : 1})
call assert_equal(1, len(l))
call assert_equal(bufnr('Xtestfile1'), l[0].bufnr)
if has('signs')
call append(0, ['Linux', 'Windows', 'Mac'])
sign define Mark text=>> texthl=Search

View File

@ -1833,8 +1833,8 @@ func Xproperty_tests(cchar)
call assert_equal(-1, s)
call assert_equal({}, g:Xgetlist({'abc':1}))
call assert_equal({}, g:Xgetlist({'nr':99, 'title':1}))
call assert_equal({}, g:Xgetlist({'nr':[], 'title':1}))
call assert_equal('', g:Xgetlist({'nr':99, 'title':1}).title)
call assert_equal('', g:Xgetlist({'nr':[], 'title':1}).title)
if a:cchar == 'l'
call assert_equal({}, getloclist(99, {'title': 1}))
@ -1870,7 +1870,7 @@ func Xproperty_tests(cchar)
call assert_equal([1, 2], getloclist(w2_id, {'context':1}).context)
only
call setloclist(0, [], 'f')
call assert_equal({}, getloclist(0, {'context':1}))
call assert_equal('', getloclist(0, {'context':1}).context)
endif
" Test for changing the context of previous quickfix lists
@ -2383,8 +2383,8 @@ func XsizeTests(cchar)
call g:Xsetlist([], 'f')
call assert_equal(0, g:Xgetlist({'nr':'$'}).nr)
call assert_equal(1, len(g:Xgetlist({'nr':'$', 'all':1})))
call assert_equal(0, len(g:Xgetlist({'nr':0})))
call assert_equal('', g:Xgetlist({'nr':'$', 'all':1}).title)
call assert_equal(0, g:Xgetlist({'nr':0}).nr)
Xexpr "File1:10:Line1"
Xexpr "File2:20:Line2"
@ -2754,7 +2754,7 @@ func Xqfid_tests(cchar)
call s:setup_commands(a:cchar)
call g:Xsetlist([], 'f')
call assert_equal({}, g:Xgetlist({'id':0}))
call assert_equal(0, g:Xgetlist({'id':0}).id)
Xexpr ''
let start_id = g:Xgetlist({'id' : 0}).id
Xexpr '' | Xexpr ''
@ -2762,10 +2762,10 @@ func Xqfid_tests(cchar)
call assert_equal(start_id, g:Xgetlist({'id':0, 'nr':1}).id)
call assert_equal(start_id + 1, g:Xgetlist({'id':0, 'nr':0}).id)
call assert_equal(start_id + 2, g:Xgetlist({'id':0, 'nr':'$'}).id)
call assert_equal({}, g:Xgetlist({'id':0, 'nr':99}))
call assert_equal(0, g:Xgetlist({'id':0, 'nr':99}).id)
call assert_equal(2, g:Xgetlist({'id':start_id + 1, 'nr':0}).nr)
call assert_equal({}, g:Xgetlist({'id':99, 'nr':0}))
call assert_equal({}, g:Xgetlist({'id':"abc", 'nr':0}))
call assert_equal(0, g:Xgetlist({'id':99, 'nr':0}).id)
call assert_equal(0, g:Xgetlist({'id':"abc", 'nr':0}).id)
call g:Xsetlist([], 'a', {'id':start_id, 'context':[1,2]})
call assert_equal([1,2], g:Xgetlist({'nr':1, 'context':1}).context)
@ -2776,7 +2776,7 @@ func Xqfid_tests(cchar)
let qfid = g:Xgetlist({'id':0, 'nr':0})
call g:Xsetlist([], 'f')
call assert_equal({}, g:Xgetlist({'id':qfid, 'nr':0}))
call assert_equal(0, g:Xgetlist({'id':qfid, 'nr':0}).id)
endfunc
func Test_qf_id()
@ -2880,3 +2880,62 @@ func Test_qfjump()
call Xqfjump_tests('c')
call Xqfjump_tests('l')
endfunc
" Tests for the getqflist() and getloclist() functions when the list is not
" present or is empty
func Xgetlist_empty_tests(cchar)
call s:setup_commands(a:cchar)
" Empty quickfix stack
call g:Xsetlist([], 'f')
call assert_equal('', g:Xgetlist({'context' : 0}).context)
call assert_equal(0, g:Xgetlist({'id' : 0}).id)
call assert_equal(0, g:Xgetlist({'idx' : 0}).idx)
call assert_equal([], g:Xgetlist({'items' : 0}).items)
call assert_equal(0, g:Xgetlist({'nr' : 0}).nr)
call assert_equal(0, g:Xgetlist({'size' : 0}).size)
call assert_equal('', g:Xgetlist({'title' : 0}).title)
call assert_equal(0, g:Xgetlist({'winid' : 0}).winid)
call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 'items' : [], 'nr' : 0, 'size' : 0, 'title' : '', 'winid' : 0}, g:Xgetlist({'all' : 0}))
" Empty quickfix list
Xexpr ""
call assert_equal('', g:Xgetlist({'context' : 0}).context)
call assert_notequal(0, g:Xgetlist({'id' : 0}).id)
call assert_equal(0, g:Xgetlist({'idx' : 0}).idx)
call assert_equal([], g:Xgetlist({'items' : 0}).items)
call assert_notequal(0, g:Xgetlist({'nr' : 0}).nr)
call assert_equal(0, g:Xgetlist({'size' : 0}).size)
call assert_notequal('', g:Xgetlist({'title' : 0}).title)
call assert_equal(0, g:Xgetlist({'winid' : 0}).winid)
let qfid = g:Xgetlist({'id' : 0}).id
call g:Xsetlist([], 'f')
" Non-existing quickfix identifier
call assert_equal('', g:Xgetlist({'id' : qfid, 'context' : 0}).context)
call assert_equal(0, g:Xgetlist({'id' : qfid}).id)
call assert_equal(0, g:Xgetlist({'id' : qfid, 'idx' : 0}).idx)
call assert_equal([], g:Xgetlist({'id' : qfid, 'items' : 0}).items)
call assert_equal(0, g:Xgetlist({'id' : qfid, 'nr' : 0}).nr)
call assert_equal(0, g:Xgetlist({'id' : qfid, 'size' : 0}).size)
call assert_equal('', g:Xgetlist({'id' : qfid, 'title' : 0}).title)
call assert_equal(0, g:Xgetlist({'id' : qfid, 'winid' : 0}).winid)
call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 'items' : [], 'nr' : 0, 'size' : 0, 'title' : '', 'winid' : 0}, g:Xgetlist({'id' : qfid, 'all' : 0}))
" Non-existing quickfix list number
call assert_equal('', g:Xgetlist({'nr' : 5, 'context' : 0}).context)
call assert_equal(0, g:Xgetlist({'nr' : 5}).nr)
call assert_equal(0, g:Xgetlist({'nr' : 5, 'idx' : 0}).idx)
call assert_equal([], g:Xgetlist({'nr' : 5, 'items' : 0}).items)
call assert_equal(0, g:Xgetlist({'nr' : 5, 'id' : 0}).id)
call assert_equal(0, g:Xgetlist({'nr' : 5, 'size' : 0}).size)
call assert_equal('', g:Xgetlist({'nr' : 5, 'title' : 0}).title)
call assert_equal(0, g:Xgetlist({'nr' : 5, 'winid' : 0}).winid)
call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 'items' : [], 'nr' : 0, 'size' : 0, 'title' : '', 'winid' : 0}, g:Xgetlist({'nr' : 5, 'all' : 0}))
endfunc
func Test_getqflist()
call Xgetlist_empty_tests('c')
call Xgetlist_empty_tests('l')
endfunc

View File

@ -1,126 +0,0 @@
Test for wordcount() function
STARTTEST
:so small.vim
:so mbyte.vim
:set enc=utf8
:set selection=inclusive fileformat=unix fileformats=unix
:new
:fu DoRecordWin(...)
: wincmd k
: if exists("a:1")
: call cursor(a:1)
: endif
: let result=[]
: call add(result, g:test)
: call add(result, getline(1, '$'))
: call add(result, wordcount())
: wincmd j
: return result
:endfu
:fu PutInWindow(args)
: wincmd k
: %d _
: call append(1, a:args)
: wincmd j
:endfu
:fu Log()
: $put ='----'
: $put =remove(g:log,0)
: $put =string(g:log)
:endfu
:fu! STL()
: if mode() =~? 'V'
: let g:visual_stat=wordcount()
: endif
: return string(wordcount())
:endfu
:let g:test="Test 1: empty window"
:let log=DoRecordWin()
:call Log()
:"
:let g:test="Test 2: some words, cursor at start"
:call PutInWindow('one two three')
:let log=DoRecordWin([1,1,0])
:call Log()
:"
:let g:test="Test 3: some words, cursor at end"
:call PutInWindow('one two three')
:let log=DoRecordWin([2,99,0])
:call Log()
:"
:let g:test="Test 4: some words, cursor at end, ve=all"
:set ve=all
:call PutInWindow('one two three')
:let log=DoRecordWin([2,99,0])
:call Log()
:set ve=
:"
:let g:test="Test 5: several lines with words"
:call PutInWindow(['one two three', 'one two three', 'one two three'])
:let log=DoRecordWin([4,99,0])
:call Log()
:"
:let g:test="Test 6: one line with BOM set"
:call PutInWindow('one two three')
:wincmd k
:set bomb
:w! Xtest
:wincmd j
:let log=DoRecordWin([2,99,0])
:call Log()
:wincmd k
:set nobomb
:w!
:wincmd j
:"
:let g:test="Test 7: one line with multibyte words"
:call PutInWindow(['Äne M¤ne Müh'])
:let log=DoRecordWin([2,99,0])
:call Log()
:"
:let g:test="Test 8: several lines with multibyte words"
:call PutInWindow(['Äne M¤ne Müh', 'und raus bist dü!'])
:let log=DoRecordWin([3,99,0])
:call Log()
:"
:let g:test="Test 9: visual mode, complete buffer"
:call PutInWindow(['Äne M¤ne Müh', 'und raus bist dü!'])
:wincmd k
:set ls=2 stl=%{STL()}
:" start visual mode quickly and select complete buffer
:0
V2jy
:set stl= ls=1
:let log=DoRecordWin([3,99,0])
:let log[2]=g:visual_stat
:call Log()
:"
:let g:test="Test 10: visual mode (empty)"
:call PutInWindow(['Äne M¤ne Müh', 'und raus bist dü!'])
:wincmd k
:set ls=2 stl=%{STL()}
:" start visual mode quickly and select complete buffer
:0
v$y
:set stl= ls=1
:let log=DoRecordWin([3,99,0])
:let log[2]=g:visual_stat
:call Log()
:"
:let g:test="Test 11: visual mode, single line"
:call PutInWindow(['Äne M¤ne Müh', 'und raus bist dü!'])
:wincmd k
:set ls=2 stl=%{STL()}
:" start visual mode quickly and select complete buffer
:2
0v$y
:set stl= ls=1
:let log=DoRecordWin([3,99,0])
:let log[2]=g:visual_stat
:call Log()
:"
:/^RESULT test/,$w! test.out
:qa!
ENDTEST
RESULT test:

View File

@ -1,34 +0,0 @@
RESULT test:
----
Test 1: empty window
[[''], {'chars': 0, 'cursor_chars': 0, 'words': 0, 'cursor_words': 0, 'bytes': 0, 'cursor_bytes': 0}]
----
Test 2: some words, cursor at start
[['', 'one two three'], {'chars': 15, 'cursor_chars': 1, 'words': 3, 'cursor_words': 0, 'bytes': 15, 'cursor_bytes': 1}]
----
Test 3: some words, cursor at end
[['', 'one two three'], {'chars': 15, 'cursor_chars': 14, 'words': 3, 'cursor_words': 3, 'bytes': 15, 'cursor_bytes': 14}]
----
Test 4: some words, cursor at end, ve=all
[['', 'one two three'], {'chars': 15, 'cursor_chars': 15, 'words': 3, 'cursor_words': 3, 'bytes': 15, 'cursor_bytes': 15}]
----
Test 5: several lines with words
[['', 'one two three', 'one two three', 'one two three'], {'chars': 43, 'cursor_chars': 42, 'words': 9, 'cursor_words': 9, 'bytes': 43, 'cursor_bytes': 42}]
----
Test 6: one line with BOM set
[['', 'one two three'], {'chars': 15, 'cursor_chars': 14, 'words': 3, 'cursor_words': 3, 'bytes': 18, 'cursor_bytes': 14}]
----
Test 7: one line with multibyte words
[['', 'Äne M¤ne Müh'], {'chars': 14, 'cursor_chars': 13, 'words': 3, 'cursor_words': 3, 'bytes': 17, 'cursor_bytes': 16}]
----
Test 8: several lines with multibyte words
[['', 'Äne M¤ne Müh', 'und raus bist dü!'], {'chars': 32, 'cursor_chars': 31, 'words': 7, 'cursor_words': 7, 'bytes': 36, 'cursor_bytes': 35}]
----
Test 9: visual mode, complete buffer
[['', 'Äne M¤ne Müh', 'und raus bist dü!'], {'chars': 32, 'words': 7, 'bytes': 36, 'visual_chars': 32, 'visual_words': 7, 'visual_bytes': 36}]
----
Test 10: visual mode (empty)
[['', 'Äne M¤ne Müh', 'und raus bist dü!'], {'chars': 32, 'words': 7, 'bytes': 36, 'visual_chars': 1, 'visual_words': 0, 'visual_bytes': 1}]
----
Test 11: visual mode, single line
[['', 'Äne M¤ne Müh', 'und raus bist dü!'], {'chars': 32, 'words': 7, 'bytes': 36, 'visual_chars': 13, 'visual_words': 3, 'visual_bytes': 16}]

View File

@ -0,0 +1,108 @@
" Test for wordcount() function
if !has('multi_byte')
finish
endif
func Test_wordcount()
let save_enc = &enc
set encoding=utf-8
set selection=inclusive fileformat=unix fileformats=unix
new
" Test 1: empty window
call assert_equal({'chars': 0, 'cursor_chars': 0, 'words': 0, 'cursor_words': 0,
\ 'bytes': 0, 'cursor_bytes': 0}, wordcount())
" Test 2: some words, cursor at start
call append(1, 'one two three')
call cursor([1, 1, 0])
call assert_equal({'chars': 15, 'cursor_chars': 1, 'words': 3, 'cursor_words': 0,
\ 'bytes': 15, 'cursor_bytes': 1}, wordcount())
" Test 3: some words, cursor at end
%d _
call append(1, 'one two three')
call cursor([2, 99, 0])
call assert_equal({'chars': 15, 'cursor_chars': 14, 'words': 3, 'cursor_words': 3,
\ 'bytes': 15, 'cursor_bytes': 14}, wordcount())
" Test 4: some words, cursor at end, ve=all
set ve=all
%d _
call append(1, 'one two three')
call cursor([2, 99, 0])
call assert_equal({'chars': 15, 'cursor_chars': 15, 'words': 3, 'cursor_words': 3,
\ 'bytes': 15, 'cursor_bytes': 15}, wordcount())
set ve=
" Test 5: several lines with words
%d _
call append(1, ['one two three', 'one two three', 'one two three'])
call cursor([4, 99, 0])
call assert_equal({'chars': 43, 'cursor_chars': 42, 'words': 9, 'cursor_words': 9,
\ 'bytes': 43, 'cursor_bytes': 42}, wordcount())
" Test 6: one line with BOM set
%d _
call append(1, 'one two three')
set bomb
w! Xtest
call cursor([2, 99, 0])
call assert_equal({'chars': 15, 'cursor_chars': 14, 'words': 3, 'cursor_words': 3,
\ 'bytes': 18, 'cursor_bytes': 14}, wordcount())
set nobomb
w!
call delete('Xtest')
" Test 7: one line with multibyte words
%d _
call append(1, ['Äne M¤ne Müh'])
call cursor([2, 99, 0])
call assert_equal({'chars': 14, 'cursor_chars': 13, 'words': 3, 'cursor_words': 3,
\ 'bytes': 17, 'cursor_bytes': 16}, wordcount())
" Test 8: several lines with multibyte words
%d _
call append(1, ['Äne M¤ne Müh', 'und raus bist dü!'])
call cursor([3, 99, 0])
call assert_equal({'chars': 32, 'cursor_chars': 31, 'words': 7, 'cursor_words': 7,
\ 'bytes': 36, 'cursor_bytes': 35}, wordcount())
" Visual map to capture wordcount() in visual mode
vnoremap <expr> <F2> execute("let g:visual_stat = wordcount()")
" Test 9: visual mode, complete buffer
let g:visual_stat = {}
%d _
call append(1, ['Äne M¤ne Müh', 'und raus bist dü!'])
" start visual mode and select the complete buffer
0
exe "normal V2j\<F2>y"
call assert_equal({'chars': 32, 'words': 7, 'bytes': 36, 'visual_chars': 32,
\ 'visual_words': 7, 'visual_bytes': 36}, g:visual_stat)
" Test 10: visual mode (empty)
%d _
call append(1, ['Äne M¤ne Müh', 'und raus bist dü!'])
" start visual mode and select the complete buffer
0
exe "normal v$\<F2>y"
call assert_equal({'chars': 32, 'words': 7, 'bytes': 36, 'visual_chars': 1,
\ 'visual_words': 0, 'visual_bytes': 1}, g:visual_stat)
" Test 11: visual mode, single line
%d _
call append(1, ['Äne M¤ne Müh', 'und raus bist dü!'])
" start visual mode and select the complete buffer
2
exe "normal 0v$\<F2>y"
call assert_equal({'chars': 32, 'words': 7, 'bytes': 36, 'visual_chars': 13,
\ 'visual_words': 3, 'visual_bytes': 16}, g:visual_stat)
set selection& fileformat& fileformats&
let &enc = save_enc
enew!
close
endfunc

View File

@ -771,6 +771,18 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
1390,
/**/
1389,
/**/
1388,
/**/
1387,
/**/
1386,
/**/
1385,
/**/
1384,
/**/