Compare commits

...

13 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
74240d3feb patch 8.0.1384: not enough quickfix help; confusing winid
Problem:    Not enough quickfix help; confusing winid.
Solution:   Add more examples in the help. When the quickfix window is not
            present, return zero for getqflist() with 'winid'. Add more tests
            for jumping to quickfix list entries. (Yegappan Lakshmanan, closes
            #2427)
2017-12-10 15:26:15 +01:00
35c5e8155d patch 8.0.1383: local additions in help skips some files
Problem:    Local additions in help skips some files. (joshklod)
Solution:   Check the base file name length equals.
2017-12-09 21:10:13 +01:00
f405c8fe85 patch 8.0.1382: get "no write since last change" message if terminal is open
Problem:    Get "no write since last change" message if a terminal is open.
            (Fritz mehner)
Solution:   Don't consider a buffer changed if it's a terminal window.
2017-12-09 19:51:49 +01:00
620ca2da37 patch 8.0.1381: ch_readraw() waits for NL if channel mode is NL
Problem:    ch_readraw() waits for NL if channel mode is NL.
Solution:   Pass a "raw" flag to channel_read_block(). (Yasuhiro Matsumoto)
2017-12-09 19:13:13 +01:00
05684310a5 patch 8.0.1380: using "vim -r swapfile" the hit-enter prompt is misplaced.
Problem:    When recovering a file with "vim -r swapfile" the hit-enter prompt
            is at the top of the window.
Solution:   Invalidate the cursor position.
2017-12-09 15:11:24 +01:00
e4b78e2a42 patch 8.0.1379: configure check for selinux does not check for header file
Problem:    Configure check for selinux does not check for header file.
Solution:   Add an AC_CHECK_HEADER(). (Benny Siegert)
2017-12-07 22:29:11 +01:00
3388d33457 patch 8.0.1378: autoload script sources itself when defining function
Problem:    Autoload script sources itself when defining function.
Solution:   Pass TFN_NO_AUTOLOAD to trans_function_name(). (Yasuhiro
            Matsumoto, closes #2423)
2017-12-07 22:23:04 +01:00
36 changed files with 786 additions and 331 deletions

View File

@ -1,4 +1,4 @@
*eval.txt* For Vim version 8.0. Last change: 2017 Nov 24 *eval.txt* For Vim version 8.0. Last change: 2017 Dec 09
VIM REFERENCE MANUAL by Bram Moolenaar VIM REFERENCE MANUAL by Bram Moolenaar
@ -2031,7 +2031,7 @@ assert_true({actual} [, {msg}]) none assert {actual} is true
asin({expr}) Float arc sine of {expr} asin({expr}) Float arc sine of {expr}
atan({expr}) Float arc tangent of {expr} atan({expr}) Float arc tangent of {expr}
atan2({expr1}, {expr2}) Float arc tangent of {expr1} / {expr2} atan2({expr1}, {expr2}) Float arc tangent of {expr1} / {expr2}
balloon_show({msg}) none show {msg} inside the balloon balloon_show({expr}) none show {expr} inside the balloon
balloon_split({msg}) List split {msg} as used for a balloon balloon_split({msg}) List split {msg} as used for a balloon
browse({save}, {title}, {initdir}, {default}) browse({save}, {title}, {initdir}, {default})
String put up a file requester String put up a file requester
@ -3056,12 +3056,16 @@ ch_open({address} [, {options}]) *ch_open()*
ch_read({handle} [, {options}]) *ch_read()* ch_read({handle} [, {options}]) *ch_read()*
Read from {handle} and return the received message. Read from {handle} and return the received message.
{handle} can be a Channel or a Job that has a Channel. {handle} can be a Channel or a Job that has a Channel.
For a NL channel this waits for a NL to arrive, except when
there is nothing more to read (channel was closed).
See |channel-more|. See |channel-more|.
{only available when compiled with the |+channel| feature} {only available when compiled with the |+channel| feature}
ch_readraw({handle} [, {options}]) *ch_readraw()* ch_readraw({handle} [, {options}]) *ch_readraw()*
Like ch_read() but for a JS and JSON channel does not decode Like ch_read() but for a JS and JSON channel does not decode
the message. See |channel-more|. the message. For a NL channel it does not block waiting for
the NL to arrive, but otherwise works like ch_read().
See |channel-more|.
{only available when compiled with the |+channel| feature} {only available when compiled with the |+channel| feature}
ch_sendexpr({handle}, {expr} [, {options}]) *ch_sendexpr()* ch_sendexpr({handle}, {expr} [, {options}]) *ch_sendexpr()*
@ -4169,6 +4173,7 @@ getbufinfo([{dict}])
be specified in {dict}: be specified in {dict}:
buflisted include only listed buffers. buflisted include only listed buffers.
bufloaded include only loaded buffers. bufloaded include only loaded buffers.
bufmodified include only modified buffers.
Otherwise, {expr} specifies a particular buffer to return Otherwise, {expr} specifies a particular buffer to return
information for. For the use of {expr}, see |bufname()| information for. For the use of {expr}, see |bufname()|
@ -4679,9 +4684,10 @@ getqflist([{what}]) *getqflist()*
the last quickfix list the last quickfix list
size number of entries in the quickfix list size number of entries in the quickfix list
title get the list title title get the list title
winid get the |window-ID| (if opened) winid get the quickfix |window-ID|
all all of the above quickfix properties all all of the above quickfix properties
Non-string items in {what} are ignored. Non-string items in {what} are ignored. To get the value of a
particular item, set it to zero.
If "nr" is not present then the current quickfix list is used. 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 If both "nr" and a non-zero "id" are specified, then the list
specified by "id" is used. specified by "id" is used.
@ -4691,18 +4697,22 @@ getqflist([{what}]) *getqflist()*
When "lines" is specified, all the other items except "efm" When "lines" is specified, all the other items except "efm"
are ignored. The returned dictionary contains the entry are ignored. The returned dictionary contains the entry
"items" with the list of entries. "items" with the list of entries.
In case of error processing {what}, an empty dictionary is
returned.
The returned dictionary contains the following entries: The returned dictionary contains the following entries:
context context information stored with |setqflist()| context context information stored with |setqflist()|.
id quickfix list ID |quickfix-ID| If not present, set to "".
idx index of the current entry in the list id quickfix list ID |quickfix-ID|. If not
items quickfix list entries present, set to 0.
nr quickfix list number idx index of the current entry in the list. If not
size number of entries in the quickfix list present, set to 0.
title quickfix list title text items quickfix list entries. If not present, set to
winid quickfix |window-ID| (if opened) 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: > Examples: >
:echo getqflist({'all': 1}) :echo getqflist({'all': 1})
@ -8793,8 +8803,8 @@ writefile({list}, {fname} [, {flags}])
the file. This flushes the file to disk, if possible. This the file. This flushes the file to disk, if possible. This
takes more time but avoids losing the file if the system takes more time but avoids losing the file if the system
crashes. crashes.
When {flags} does not contain "S" or "s" then fsync is called When {flags} does not contain "S" or "s" then fsync() is
if the 'fsync' option is set. called if the 'fsync' option is set.
When {flags} contains "S" then fsync() is not called, even When {flags} contains "S" then fsync() is not called, even
when 'fsync' is set. when 'fsync' is set.

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. 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. 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 That is the default value for 'pythondll'. For Python 3 it is python36.dll
(Python 3.5). To know for sure edit "gvim.exe" and search for (Python 3.6). To know for sure edit "gvim.exe" and search for
"python\d*.dll\c". "python\d*.dll\c".

View File

@ -341,6 +341,50 @@ use this code: >
au QuickfixCmdPost make call QfMakeConv() au QuickfixCmdPost make call QfMakeConv()
Another option is using 'makeencoding'. Another option is using 'makeencoding'.
*quickfix-title*
Every quickfix and location list has a title. By default the title is set to
the command that created the list. The |getqflist()| and |getloclist()|
functions can be used to get the title of a quickfix and a location list
respectively. The |setqflist()| and |setloclist()| functions can be used to
modify the title of a quickfix and location list respectively. Examples: >
call setqflist([], 'a', {'title' : 'Cmd output'})
echo getqflist({'title' : 1})
call setloclist(3, [], 'a', {'title' : 'Cmd output'})
echo getloclist(3, {'title' : 1})
<
*quickfix-size*
You can get the number of entries (size) in a quickfix and a location list
using the |getqflist()| and |getloclist()| functions respectively. Examples: >
echo getqflist({'size' : 1})
echo getloclist(5, {'size' : 1})
<
*quickfix-context*
Any Vim type can be associated as a context with a quickfix or location list.
The |setqflist()| and the |setloclist()| functions can be used to associate a
context with a quickfix and a location list respectively. The |getqflist()|
and the |getloclist()| functions can be used to retrieve the context of a
quickifx and a location list respectively. This is useful for a Vim plugin
dealing with multiple quickfix/location lists.
Examples: >
let somectx = {'name' : 'Vim', 'type' : 'Editor'}
call setqflist([], 'a', {'context' : somectx})
echo getqflist({'context' : 1})
let newctx = ['red', 'green', 'blue']
call setloclist(2, [], 'a', {'id' : qfid, 'context' : newctx})
echo getloclist(2, {'id' : qfid, 'context' : 1})
<
*quickfix-parse*
You can parse a list of lines using 'erroformat' without creating or modifying
a quickfix list using the |getqflist()| function. Examples: >
echo getqflist({'lines' : ["F1:10:Line10", "F2:20:Line20"]})
echo getqflist({'lines' : systemlist('grep -Hn quickfix *')})
This returns a dictionary where the 'items' key contains the list of quickfix
entries parsed from lines. The following shows how to use a custom
'errorformat' to parse the lines without modifying the 'erroformat' option: >
echo getqflist({'efm' : '%f#%l#%m', 'lines' : ['F1#10#Line']})
<
EXECUTE A COMMAND IN ALL THE BUFFERS IN QUICKFIX OR LOCATION LIST: EXECUTE A COMMAND IN ALL THE BUFFERS IN QUICKFIX OR LOCATION LIST:
*:cdo* *:cdo*
@ -542,6 +586,13 @@ In all of the above cases, if the location list for the selected window is not
yet set, then it is set to the location list displayed in the location list yet set, then it is set to the location list displayed in the location list
window. window.
*quickfix-window-ID*
You can use the |getqflist()| and |getloclist()| functions to obtain the
window ID of the quickfix window and location list window respectively (if
present). Examples: >
echo getqflist({'winid' : 1}).winid
echo getloclist(2, {'winid' : 1}).winid
<
============================================================================= =============================================================================
3. Using more than one list of errors *quickfix-error-lists* 3. Using more than one list of errors *quickfix-error-lists*
@ -586,6 +637,14 @@ list, one newer list is overwritten. This is especially useful if you are
browsing with ":grep" |grep|. If you want to keep the more recent error browsing with ":grep" |grep|. If you want to keep the more recent error
lists, use ":cnewer 99" first. lists, use ":cnewer 99" first.
To get the number of lists in the quickfix and location list stack, you can
use the |getqflist()| and |getloclist()| functions respectively with the list
number set to the special value '$'. Examples: >
echo getqflist({'nr' : '$'}).nr
echo getloclist(3, {'nr' : '$'}).nr
To get the number of the current list in the stack: >
echo getqflist({'nr' : 0}).nr
<
============================================================================= =============================================================================
4. Using :make *:make_makeprg* 4. Using :make *:make_makeprg*

View File

@ -34,10 +34,11 @@ Contents:
11. Building with Ruby support 11. Building with Ruby support
12. Building with Tcl support 12. Building with Tcl support
13. Building with Terminal support 13. Building with Terminal support
14. Windows 3.1 14. Building with DirectX (DirectWrite) support
15. MS-DOS 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 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 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: 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. 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): E.g. When using MSVC (as one line):
nmake -f Make_mvc.mak 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 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. 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 If you use 32-bit MSVC 2015, the config.h is generated in the
.ext\include\i386-mswin32_140 directory. .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. 3) Install the generated config.h.
For 32-bit version:
xcopy /s .ext\include C:\Ruby24\include\ruby-2.4.0 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. 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. 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): 4) Build Vim. Note that you need to adjust some variables (as one line):
For 32-bit version:
nmake -f Make_mvc.mak nmake -f Make_mvc.mak
RUBY=C:\Ruby24 DYNAMIC_RUBY=yes RUBY_VER=24 RUBY_API_VER_LONG=2.4.0 RUBY=C:\Ruby24 DYNAMIC_RUBY=yes RUBY_VER=24 RUBY_API_VER_LONG=2.4.0
RUBY_MSVCRT_NAME=msvcrt RUBY_MSVCRT_NAME=msvcrt
WINVER=0x501 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 If you set WINVER explicitly, it must be set to >=0x500, when building
with Ruby 2.1 or later. (Default is 0x501.) with Ruby 2.1 or later. (Default is 0x501.)
When using this trick, you also need to set RUBY_MSVCRT_NAME to msvcrt 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 RUBY=C:/Ruby24 DYNAMIC_RUBY=yes RUBY_VER=24 RUBY_API_VER_LONG=2.4.0
WINVER=0x501 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 If you set WINVER explicitly, it must be set to >=0x500, when building with
Ruby 2.1 or later. (Default is 0x501.) Ruby 2.1 or later. (Default is 0x501.)
@ -761,25 +788,59 @@ E.g. When using MSVC:
nmake -f Make_mvc.mak TERMINAL=yes 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 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. 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 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. 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] [provided by Michael Soyka, updated by Ken Takata]

View File

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

View File

@ -25,12 +25,15 @@
# #
# GUI interface: GUI=yes (default is no) # GUI interface: GUI=yes (default is no)
# #
# GUI with DirectWrite(DirectX): DIRECTX=yes # GUI with DirectWrite (DirectX): DIRECTX=yes
# (default is no, requires GUI=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) # 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) # IME support: IME=yes (requires GUI=yes)
# DYNAMIC_IME=[yes or no] (to load the imm32.dll dynamically, default # DYNAMIC_IME=[yes or no] (to load the imm32.dll dynamically, default
@ -67,7 +70,7 @@
# Python3 interface: # Python3 interface:
# PYTHON3=[Path to Python3 directory] # PYTHON3=[Path to Python3 directory]
# DYNAMIC_PYTHON3=yes (to load the Python3 DLL dynamically) # 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 interface:
# RUBY=[Path to Ruby directory] # RUBY=[Path to Ruby directory]
@ -419,9 +422,12 @@ NBDEBUG_SRC = nbdebug.c
NETBEANS_LIB = WSock32.lib NETBEANS_LIB = WSock32.lib
!endif !endif
# DirectWrite(DirectX) # DirectWrite (DirectX)
!if "$(DIRECTX)" == "yes" !if "$(DIRECTX)" == "yes"
DIRECTX_DEFS = -DFEAT_DIRECTX -DDYNAMIC_DIRECTX 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_INCL = gui_dwrite.h
DIRECTX_OBJ = $(OUTDIR)\gui_dwrite.obj DIRECTX_OBJ = $(OUTDIR)\gui_dwrite.obj
!endif !endif
@ -906,7 +912,7 @@ PYTHON_LIB = $(PYTHON)\libs\python$(PYTHON_VER).lib
# PYTHON3 interface # PYTHON3 interface
!ifdef PYTHON3 !ifdef PYTHON3
!ifndef PYTHON3_VER !ifndef PYTHON3_VER
PYTHON3_VER = 35 PYTHON3_VER = 36
!endif !endif
!message Python3 requested (version $(PYTHON3_VER)) - root dir is "$(PYTHON3)" !message Python3 requested (version $(PYTHON3_VER)) - root dir is "$(PYTHON3)"
!if "$(DYNAMIC_PYTHON3)" == "yes" !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. # These do not depend on the executable, compile it when needed.
test1 \ test1 \
test_eval \ test_eval \
test_wordcount \
test3 test11 test14 test15 test17 \ test3 test11 test14 test15 test17 \
test29 test30 test36 test37 test39 \ test29 test30 test36 test37 test39 \
test42 test44 test48 test49 \ test42 test44 test48 test49 \
@ -2296,6 +2295,7 @@ test_arglist \
test_window_cmd \ test_window_cmd \
test_window_id \ test_window_id \
test_windows_home \ test_windows_home \
test_wordcount \
test_writefile \ test_writefile \
test_alot_latin \ test_alot_latin \
test_alot_utf8 \ test_alot_utf8 \

7
src/auto/configure vendored
View File

@ -4781,8 +4781,13 @@ fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_selinux_is_selinux_enabled" >&5 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_selinux_is_selinux_enabled" >&5
$as_echo "$ac_cv_lib_selinux_is_selinux_enabled" >&6; } $as_echo "$ac_cv_lib_selinux_is_selinux_enabled" >&6; }
if test "x$ac_cv_lib_selinux_is_selinux_enabled" = xyes; then : if test "x$ac_cv_lib_selinux_is_selinux_enabled" = xyes; then :
ac_fn_c_check_header_mongrel "$LINENO" "selinux/selinux.h" "ac_cv_header_selinux_selinux_h" "$ac_includes_default"
if test "x$ac_cv_header_selinux_selinux_h" = xyes; then :
LIBS="$LIBS -lselinux" LIBS="$LIBS -lselinux"
$as_echo "#define HAVE_SELINUX 1" >>confdefs.h $as_echo "#define HAVE_SELINUX 1" >>confdefs.h
fi
fi fi

View File

@ -1,5 +1,5 @@
:: command to build big Vim with OLE, Lua, Perl, Python, Racket, Ruby and Tcl :: 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 VCDIR="C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\bin\"
SET TOOLDIR=E:\ 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

@ -3313,11 +3313,12 @@ channel_read(channel_T *channel, ch_part_T part, char *func)
/* /*
* Read from RAW or NL "channel"/"part". Blocks until there is something to * Read from RAW or NL "channel"/"part". Blocks until there is something to
* read or the timeout expires. * read or the timeout expires.
* When "raw" is TRUE don't block waiting on a NL.
* Returns what was read in allocated memory. * Returns what was read in allocated memory.
* Returns NULL in case of error or timeout. * Returns NULL in case of error or timeout.
*/ */
char_u * static char_u *
channel_read_block(channel_T *channel, ch_part_T part, int timeout) channel_read_block(channel_T *channel, ch_part_T part, int timeout, int raw)
{ {
char_u *buf; char_u *buf;
char_u *msg; char_u *msg;
@ -3327,7 +3328,7 @@ channel_read_block(channel_T *channel, ch_part_T part, int timeout)
readq_T *node; readq_T *node;
ch_log(channel, "Blocking %s read, timeout: %d msec", ch_log(channel, "Blocking %s read, timeout: %d msec",
mode == MODE_RAW ? "RAW" : "NL", timeout); mode == MODE_RAW ? "RAW" : "NL", timeout);
while (TRUE) while (TRUE)
{ {
@ -3340,6 +3341,10 @@ channel_read_block(channel_T *channel, ch_part_T part, int timeout)
break; break;
if (channel_collapse(channel, part, mode == MODE_NL) == OK) if (channel_collapse(channel, part, mode == MODE_NL) == OK)
continue; continue;
/* If not blocking or nothing more is coming then return what we
* have. */
if (raw || fd == INVALID_FD)
break;
} }
/* Wait for up to the channel timeout. */ /* Wait for up to the channel timeout. */
@ -3366,11 +3371,16 @@ channel_read_block(channel_T *channel, ch_part_T part, int timeout)
nl = channel_first_nl(node); nl = channel_first_nl(node);
/* Convert NUL to NL, the internal representation. */ /* Convert NUL to NL, the internal representation. */
for (p = buf; p < nl && p < buf + node->rq_buflen; ++p) for (p = buf; (nl == NULL || p < nl) && p < buf + node->rq_buflen; ++p)
if (*p == NUL) if (*p == NUL)
*p = NL; *p = NL;
if (nl + 1 == buf + node->rq_buflen) if (nl == NULL)
{
/* must be a closed channel with missing NL */
msg = channel_get(channel, part);
}
else if (nl + 1 == buf + node->rq_buflen)
{ {
/* get the whole buffer */ /* get the whole buffer */
msg = channel_get(channel, part); msg = channel_get(channel, part);
@ -3513,7 +3523,8 @@ common_channel_read(typval_T *argvars, typval_T *rettv, int raw)
timeout = opt.jo_timeout; timeout = opt.jo_timeout;
if (raw || mode == MODE_RAW || mode == MODE_NL) if (raw || mode == MODE_RAW || mode == MODE_NL)
rettv->vval.v_string = channel_read_block(channel, part, timeout); rettv->vval.v_string = channel_read_block(channel, part,
timeout, raw);
else else
{ {
if (opt.jo_set & JO_ID) if (opt.jo_set & JO_ID)
@ -3955,7 +3966,8 @@ ch_raw_common(typval_T *argvars, typval_T *rettv, int eval)
timeout = opt.jo_timeout; timeout = opt.jo_timeout;
else else
timeout = channel_get_timeout(channel, part_read); timeout = channel_get_timeout(channel, part_read);
rettv->vval.v_string = channel_read_block(channel, part_read, timeout); rettv->vval.v_string = channel_read_block(channel, part_read,
timeout, TRUE);
} }
free_job_options(&opt); free_job_options(&opt);
} }

View File

@ -433,8 +433,9 @@ if test "x$found_smack" = "x"; then
if test "$enable_selinux" = "yes"; then if test "$enable_selinux" = "yes"; then
AC_MSG_RESULT(no) AC_MSG_RESULT(no)
AC_CHECK_LIB(selinux, is_selinux_enabled, AC_CHECK_LIB(selinux, is_selinux_enabled,
[AC_CHECK_HEADER(selinux/selinux.h,
[LIBS="$LIBS -lselinux" [LIBS="$LIBS -lselinux"
AC_DEFINE(HAVE_SELINUX)]) AC_DEFINE(HAVE_SELINUX)])])
else else
AC_MSG_RESULT(yes) AC_MSG_RESULT(yes)
fi fi

View File

@ -4137,6 +4137,7 @@ f_getbufinfo(typval_T *argvars, typval_T *rettv)
int filtered = FALSE; int filtered = FALSE;
int sel_buflisted = FALSE; int sel_buflisted = FALSE;
int sel_bufloaded = FALSE; int sel_bufloaded = FALSE;
int sel_bufmodified = FALSE;
if (rettv_list_alloc(rettv) != OK) if (rettv_list_alloc(rettv) != OK)
return; return;
@ -4159,6 +4160,10 @@ f_getbufinfo(typval_T *argvars, typval_T *rettv)
di = dict_find(sel_d, (char_u *)"bufloaded", -1); di = dict_find(sel_d, (char_u *)"bufloaded", -1);
if (di != NULL && get_tv_number(&di->di_tv)) if (di != NULL && get_tv_number(&di->di_tv))
sel_bufloaded = TRUE; 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) 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) if (argbuf != NULL && argbuf != buf)
continue; continue;
if (filtered && ((sel_bufloaded && buf->b_ml.ml_mfp == NULL) 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; continue;
d = get_buffer_info(buf); d = get_buffer_info(buf);

View File

@ -1482,7 +1482,7 @@ do_shell(
#endif #endif
&& msg_silent == 0) && msg_silent == 0)
FOR_ALL_BUFFERS(buf) FOR_ALL_BUFFERS(buf)
if (bufIsChanged(buf)) if (bufIsChangedNotTerm(buf))
{ {
#ifdef FEAT_GUI_MSWIN #ifdef FEAT_GUI_MSWIN
if (!winstart) if (!winstart)
@ -6934,13 +6934,10 @@ fix_help_buffer(void)
&& fcount > 0) && fcount > 0)
{ {
#ifdef FEAT_MULTI_LANG #ifdef FEAT_MULTI_LANG
int i1; int i1, i2;
int i2; char_u *f1, *f2;
char_u *f1; char_u *t1, *t2;
char_u *f2; char_u *e1, *e2;
char_u *t1;
char_u *e1;
char_u *e2;
/* If foo.abx is found use it instead of foo.txt in /* If foo.abx is found use it instead of foo.txt in
* the same directory. */ * the same directory. */
@ -6955,10 +6952,9 @@ fix_help_buffer(void)
f1 = fnames[i1]; f1 = fnames[i1];
f2 = fnames[i2]; f2 = fnames[i2];
t1 = gettail(f1); t1 = gettail(f1);
if (fnamencmp(f1, f2, t1 - f1) != 0) t2 = gettail(f2);
continue;
e1 = vim_strrchr(t1, '.'); e1 = vim_strrchr(t1, '.');
e2 = vim_strrchr(gettail(f2), '.'); e2 = vim_strrchr(t2, '.');
if (e1 == NULL || e2 == NULL) if (e1 == NULL || e2 == NULL)
continue; continue;
if (fnamecmp(e1, ".txt") != 0 if (fnamecmp(e1, ".txt") != 0
@ -6969,7 +6965,8 @@ fix_help_buffer(void)
fnames[i1] = NULL; fnames[i1] = NULL;
continue; continue;
} }
if (fnamencmp(f1, f2, e1 - f1) != 0) if (e1 - f1 != e2 - f2
|| fnamencmp(f1, f2, e1 - f1) != 0)
continue; continue;
if (fnamecmp(e1, ".txt") == 0 if (fnamecmp(e1, ".txt") == 0
&& fnamecmp(e2, fname + 4) == 0) && fnamecmp(e2, fname + 4) == 0)

View File

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

View File

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

View File

@ -31,7 +31,6 @@ void channel_close(channel_T *channel, int invoke_close_cb);
void channel_close_in(channel_T *channel); void channel_close_in(channel_T *channel);
void channel_clear(channel_T *channel); void channel_clear(channel_T *channel);
void channel_free_all(void); void channel_free_all(void);
char_u *channel_read_block(channel_T *channel, ch_part_T part, int timeout);
void common_channel_read(typval_T *argvars, typval_T *rettv, int raw); void common_channel_read(typval_T *argvars, typval_T *rettv, int raw);
channel_T *channel_fd2channel(sock_T fd, ch_part_T *partp); channel_T *channel_fd2channel(sock_T fd, ch_part_T *partp);
void channel_handle_events(int only_keep_open); void channel_handle_events(int only_keep_open);

View File

@ -25,6 +25,7 @@ void u_clearline(void);
void u_undoline(void); void u_undoline(void);
void u_blockfree(buf_T *buf); void u_blockfree(buf_T *buf);
int bufIsChanged(buf_T *buf); int bufIsChanged(buf_T *buf);
int bufIsChangedNotTerm(buf_T *buf);
int curbufIsChanged(void); int curbufIsChanged(void);
void u_eval_tree(u_header_T *first_uhp, list_T *list); void u_eval_tree(u_header_T *first_uhp, list_T *list);
/* vim: set ft=c : */ /* vim: set ft=c : */

View File

@ -4863,70 +4863,24 @@ qf_get_properties(win_T *wp, dict_T *what, dict_T *retdict)
if (wp != NULL) if (wp != NULL)
qi = GET_LOC_LIST(wp); 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) if (dict_find(what, (char_u *)"all", -1) != NULL)
flags |= QF_GETLIST_ALL; flags |= QF_GETLIST_ALL;
if (dict_find(what, (char_u *)"title", -1) != NULL) if (dict_find(what, (char_u *)"title", -1) != NULL)
flags |= QF_GETLIST_TITLE; 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) if (dict_find(what, (char_u *)"winid", -1) != NULL)
flags |= QF_GETLIST_WINID; flags |= QF_GETLIST_WINID;
if (dict_find(what, (char_u *)"context", -1) != NULL) if (dict_find(what, (char_u *)"context", -1) != NULL)
flags |= QF_GETLIST_CONTEXT; 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) if (dict_find(what, (char_u *)"items", -1) != NULL)
flags |= QF_GETLIST_ITEMS; 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) if (dict_find(what, (char_u *)"size", -1) != NULL)
flags |= QF_GETLIST_SIZE; 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) if (flags & QF_GETLIST_TITLE)
{ {
char_u *t; char_u *t;
@ -4949,9 +4974,12 @@ qf_get_properties(win_T *wp, dict_T *what, dict_T *retdict)
if ((status == OK) && (flags & QF_GETLIST_WINID)) if ((status == OK) && (flags & QF_GETLIST_WINID))
{ {
win_T *win; win_T *win;
int win_id = 0;
win = qf_find_win(qi); win = qf_find_win(qi);
if (win != NULL) if (win != NULL)
status = dict_add_nr_str(retdict, "winid", win->w_id, NULL); win_id = win->w_id;
status = dict_add_nr_str(retdict, "winid", win_id, NULL);
} }
if ((status == OK) && (flags & QF_GETLIST_ITEMS)) if ((status == OK) && (flags & QF_GETLIST_ITEMS))
{ {

View File

@ -8317,15 +8317,29 @@ screen_char(unsigned off, int row, int col)
{ {
char_u buf[MB_MAXBYTES + 1]; 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 (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; screen_cur_col = 9999;
}
else if (utf_char2cells(ScreenLinesUC[off]) > 1) else if (utf_char2cells(ScreenLinesUC[off]) > 1)
++screen_cur_col; ++screen_cur_col;
/* Convert the UTF-8 character to bytes and write it. */
buf[utfc_char2bytes(off, buf)] = NUL;
out_str(buf);
} }
else else
#endif #endif

View File

@ -3510,6 +3510,9 @@ may_req_ambiguous_char_width(void)
out_str((char_u *)" "); out_str((char_u *)" ");
term_windgoto(0, 0); term_windgoto(0, 0);
/* Need to reset the known cursor position. */
screen_start();
/* check for the characters now, otherwise they might be eaten by /* check for the characters now, otherwise they might be eaten by
* get_keystroke() */ * get_keystroke() */
out_flush(); out_flush();
@ -4585,7 +4588,7 @@ check_termcode(
is_mac_terminal = TRUE; is_mac_terminal = TRUE;
} }
# ifdef FEAT_MOUSE_SGR # ifdef FEAT_MOUSE_SGR
/* Iterm2 sends 0;95;0 */ /* iTerm2 sends 0;95;0 */
if (STRNCMP(tp + extra - 2, "0;95;0c", 7) == 0) if (STRNCMP(tp + extra - 2, "0;95;0c", 7) == 0)
is_iterm2 = TRUE; is_iterm2 = TRUE;
# endif # endif
@ -4597,7 +4600,7 @@ check_termcode(
{ {
# ifdef FEAT_MOUSE_SGR # ifdef FEAT_MOUSE_SGR
/* Xterm version 277 supports SGR. Also support /* Xterm version 277 supports SGR. Also support
* Terminal.app and iterm2. */ * Terminal.app and iTerm2. */
if (version >= 277 || is_iterm2 || is_mac_terminal) if (version >= 277 || is_iterm2 || is_mac_terminal)
set_option_value((char_u *)"ttym", 0L, set_option_value((char_u *)"ttym", 0L,
(char_u *)"sgr", 0); (char_u *)"sgr", 0);

View File

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

View File

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

View File

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

View File

@ -0,0 +1,3 @@
let g:loaded_sourced_vim += 1
func! sourced#something()
endfunc

View File

@ -2,10 +2,16 @@
set runtimepath=./sautest set runtimepath=./sautest
func! Test_autoload_dict_func() func Test_autoload_dict_func()
let g:loaded_foo_vim = 0 let g:loaded_foo_vim = 0
let g:called_foo_bar_echo = 0 let g:called_foo_bar_echo = 0
call g:foo#bar.echo() call g:foo#bar.echo()
call assert_equal(1, g:loaded_foo_vim) call assert_equal(1, g:loaded_foo_vim)
call assert_equal(1, g:called_foo_bar_echo) call assert_equal(1, g:called_foo_bar_echo)
endfunc endfunc
func Test_source_autoload()
let g:loaded_sourced_vim = 0
source sautest/autoload/sourced.vim
call assert_equal(1, g:loaded_sourced_vim)
endfunc

View File

@ -20,6 +20,13 @@ function Test_getbufwintabinfo()
call assert_equal('vim', l[0].variables.editor) call assert_equal('vim', l[0].variables.editor)
call assert_notequal(-1, index(l[0].windows, bufwinid('%'))) 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') if has('signs')
call append(0, ['Linux', 'Windows', 'Mac']) call append(0, ['Linux', 'Windows', 'Mac'])
sign define Mark text=>> texthl=Search sign define Mark text=>> texthl=Search

View File

@ -515,7 +515,7 @@ func Test_nl_pipe()
call assert_equal("AND this", ch_readraw(handle)) call assert_equal("AND this", ch_readraw(handle))
call ch_sendraw(handle, "split this line\n") call ch_sendraw(handle, "split this line\n")
call assert_equal("this linethis linethis line", ch_readraw(handle)) call assert_equal("this linethis linethis line", ch_read(handle))
let reply = ch_evalraw(handle, "quit\n") let reply = ch_evalraw(handle, "quit\n")
call assert_equal("Goodbye!", reply) call assert_equal("Goodbye!", reply)
@ -1266,6 +1266,31 @@ func Test_read_in_close_cb()
endtry endtry
endfunc endfunc
" Use channel in NL mode but received text does not end in NL.
func Test_read_in_close_cb_incomplete()
if !has('job')
return
endif
call ch_log('Test_read_in_close_cb_incomplete()')
let g:Ch_received = ''
func! CloseHandler(chan)
while ch_status(a:chan, {'part': 'out'}) == 'buffered'
let g:Ch_received .= ch_read(a:chan)
endwhile
endfunc
let job = job_start(s:python . " test_channel_pipe.py incomplete",
\ {'close_cb': 'CloseHandler'})
call assert_equal("run", job_status(job))
try
call WaitFor('g:Ch_received != ""')
call assert_equal('incomplete', g:Ch_received)
finally
call job_stop(job)
delfunc CloseHandler
endtry
endfunc
func Test_out_cb_lambda() func Test_out_cb_lambda()
if !has('job') if !has('job')
return return

View File

@ -14,6 +14,10 @@ if __name__ == "__main__":
if sys.argv[1].startswith("err"): if sys.argv[1].startswith("err"):
print(sys.argv[1], file=sys.stderr) print(sys.argv[1], file=sys.stderr)
sys.stderr.flush() sys.stderr.flush()
elif sys.argv[1].startswith("incomplete"):
print(sys.argv[1], end='')
sys.stdout.flush()
sys.exit(0)
else: else:
print(sys.argv[1]) print(sys.argv[1])
sys.stdout.flush() sys.stdout.flush()

View File

@ -30,3 +30,22 @@ func Test_help_keyword()
close close
bwipe! bwipe!
endfunc endfunc
func Test_help_local_additions()
call mkdir('Xruntime/doc', 'p')
call writefile(['*mydoc.txt* my awesome doc'], 'Xruntime/doc/mydoc.txt')
call writefile(['*mydoc-ext.txt* my extended awesome doc'], 'Xruntime/doc/mydoc-ext.txt')
let rtp_save = &rtp
set rtp+=./Xruntime
help
1
call search('mydoc.txt')
call assert_equal('|mydoc.txt| my awesome doc', getline('.'))
1
call search('mydoc-ext.txt')
call assert_equal('|mydoc-ext.txt| my extended awesome doc', getline('.'))
close
call delete('Xruntime', 'rf')
let &rtp = rtp_save
endfunc

View File

@ -28,7 +28,7 @@ func s:setup_commands(cchar)
command! -count -nargs=* -bang Xprev <mods><count>cprev<bang> <args> command! -count -nargs=* -bang Xprev <mods><count>cprev<bang> <args>
command! -nargs=* -bang Xfirst <mods>cfirst<bang> <args> command! -nargs=* -bang Xfirst <mods>cfirst<bang> <args>
command! -nargs=* -bang Xlast <mods>clast<bang> <args> command! -nargs=* -bang Xlast <mods>clast<bang> <args>
command! -nargs=* -bang Xnfile <mods>cnfile<bang> <args> command! -nargs=* -bang -range Xnfile <mods><count>cnfile<bang> <args>
command! -nargs=* -bang Xpfile <mods>cpfile<bang> <args> command! -nargs=* -bang Xpfile <mods>cpfile<bang> <args>
command! -nargs=* Xexpr <mods>cexpr <args> command! -nargs=* Xexpr <mods>cexpr <args>
command! -range -nargs=* Xvimgrep <mods><count>vimgrep <args> command! -range -nargs=* Xvimgrep <mods><count>vimgrep <args>
@ -36,6 +36,7 @@ func s:setup_commands(cchar)
command! -nargs=* Xgrep <mods> grep <args> command! -nargs=* Xgrep <mods> grep <args>
command! -nargs=* Xgrepadd <mods> grepadd <args> command! -nargs=* Xgrepadd <mods> grepadd <args>
command! -nargs=* Xhelpgrep helpgrep <args> command! -nargs=* Xhelpgrep helpgrep <args>
command! -nargs=0 -count Xcc <count>cc
let g:Xgetlist = function('getqflist') let g:Xgetlist = function('getqflist')
let g:Xsetlist = function('setqflist') let g:Xsetlist = function('setqflist')
call setqflist([], 'f') call setqflist([], 'f')
@ -60,7 +61,7 @@ func s:setup_commands(cchar)
command! -count -nargs=* -bang Xprev <mods><count>lprev<bang> <args> command! -count -nargs=* -bang Xprev <mods><count>lprev<bang> <args>
command! -nargs=* -bang Xfirst <mods>lfirst<bang> <args> command! -nargs=* -bang Xfirst <mods>lfirst<bang> <args>
command! -nargs=* -bang Xlast <mods>llast<bang> <args> command! -nargs=* -bang Xlast <mods>llast<bang> <args>
command! -nargs=* -bang Xnfile <mods>lnfile<bang> <args> command! -nargs=* -bang -range Xnfile <mods><count>lnfile<bang> <args>
command! -nargs=* -bang Xpfile <mods>lpfile<bang> <args> command! -nargs=* -bang Xpfile <mods>lpfile<bang> <args>
command! -nargs=* Xexpr <mods>lexpr <args> command! -nargs=* Xexpr <mods>lexpr <args>
command! -range -nargs=* Xvimgrep <mods><count>lvimgrep <args> command! -range -nargs=* Xvimgrep <mods><count>lvimgrep <args>
@ -68,6 +69,7 @@ func s:setup_commands(cchar)
command! -nargs=* Xgrep <mods> lgrep <args> command! -nargs=* Xgrep <mods> lgrep <args>
command! -nargs=* Xgrepadd <mods> lgrepadd <args> command! -nargs=* Xgrepadd <mods> lgrepadd <args>
command! -nargs=* Xhelpgrep lhelpgrep <args> command! -nargs=* Xhelpgrep lhelpgrep <args>
command! -nargs=0 -count Xcc <count>ll
let g:Xgetlist = function('getloclist', [0]) let g:Xgetlist = function('getloclist', [0])
let g:Xsetlist = function('setloclist', [0]) let g:Xsetlist = function('setloclist', [0])
call setloclist(0, [], 'f') call setloclist(0, [], 'f')
@ -382,12 +384,18 @@ endfunc
func Xtest_browse(cchar) func Xtest_browse(cchar)
call s:setup_commands(a:cchar) call s:setup_commands(a:cchar)
call g:Xsetlist([], 'f')
" Jumping to first or next location list entry without any error should " Jumping to first or next location list entry without any error should
" result in failure " result in failure
if a:cchar == 'l' if a:cchar == 'c'
call assert_fails('lfirst', 'E776:') let err = 'E42:'
call assert_fails('lnext', 'E776:') else
let err = 'E776:'
endif endif
call assert_fails('Xnext', err)
call assert_fails('Xprev', err)
call assert_fails('Xnfile', err)
call assert_fails('Xpfile', err)
call s:create_test_file('Xqftestfile1') call s:create_test_file('Xqftestfile1')
call s:create_test_file('Xqftestfile2') call s:create_test_file('Xqftestfile2')
@ -408,6 +416,12 @@ func Xtest_browse(cchar)
Xpfile Xpfile
call assert_equal('Xqftestfile1', bufname('%')) call assert_equal('Xqftestfile1', bufname('%'))
call assert_equal(6, line('.')) call assert_equal(6, line('.'))
5Xcc
call assert_equal(5, g:Xgetlist({'idx':0}).idx)
2Xcc
call assert_equal(2, g:Xgetlist({'idx':0}).idx)
10Xcc
call assert_equal(6, g:Xgetlist({'idx':0}).idx)
Xlast Xlast
Xprev Xprev
call assert_equal('Xqftestfile2', bufname('%')) call assert_equal('Xqftestfile2', bufname('%'))
@ -425,6 +439,23 @@ func Xtest_browse(cchar)
call assert_equal('Xqftestfile1', bufname('%')) call assert_equal('Xqftestfile1', bufname('%'))
call assert_equal(5, line('.')) call assert_equal(5, line('.'))
" Jumping to an error from the error window using cc command
Xgetexpr ['Xqftestfile1:5:Line5',
\ 'Xqftestfile1:6:Line6',
\ 'Xqftestfile2:10:Line10',
\ 'Xqftestfile2:11:Line11']
Xopen
10Xcc
call assert_equal(11, line('.'))
call assert_equal('Xqftestfile2', bufname('%'))
" Jumping to an error from the error window (when only the error window is
" present)
Xopen | only
Xlast 1
call assert_equal(5, line('.'))
call assert_equal('Xqftestfile1', bufname('%'))
Xexpr "" Xexpr ""
call assert_fails('Xnext', 'E42:') call assert_fails('Xnext', 'E42:')
@ -1497,13 +1528,18 @@ func Test_switchbuf()
set switchbuf=usetab set switchbuf=usetab
tabedit Xqftestfile1 tabedit Xqftestfile1
tabedit Xqftestfile2 tabedit Xqftestfile2
tabedit Xqftestfile3
tabfirst tabfirst
cfirst | cnext cfirst | cnext
call assert_equal(2, tabpagenr()) call assert_equal(2, tabpagenr())
2cnext 2cnext
call assert_equal(3, tabpagenr()) call assert_equal(3, tabpagenr())
2cnext 6cnext
call assert_equal(3, tabpagenr()) call assert_equal(4, tabpagenr())
2cpfile
call assert_equal(2, tabpagenr())
2cnfile
call assert_equal(4, tabpagenr())
tabfirst | tabonly | enew tabfirst | tabonly | enew
set switchbuf=split set switchbuf=split
@ -1797,8 +1833,8 @@ func Xproperty_tests(cchar)
call assert_equal(-1, s) call assert_equal(-1, s)
call assert_equal({}, g:Xgetlist({'abc':1})) call assert_equal({}, g:Xgetlist({'abc':1}))
call assert_equal({}, g:Xgetlist({'nr':99, 'title':1})) call assert_equal('', g:Xgetlist({'nr':99, 'title':1}).title)
call assert_equal({}, g:Xgetlist({'nr':[], 'title':1})) call assert_equal('', g:Xgetlist({'nr':[], 'title':1}).title)
if a:cchar == 'l' if a:cchar == 'l'
call assert_equal({}, getloclist(99, {'title': 1})) call assert_equal({}, getloclist(99, {'title': 1}))
@ -1834,7 +1870,7 @@ func Xproperty_tests(cchar)
call assert_equal([1, 2], getloclist(w2_id, {'context':1}).context) call assert_equal([1, 2], getloclist(w2_id, {'context':1}).context)
only only
call setloclist(0, [], 'f') call setloclist(0, [], 'f')
call assert_equal({}, getloclist(0, {'context':1})) call assert_equal('', getloclist(0, {'context':1}).context)
endif endif
" Test for changing the context of previous quickfix lists " Test for changing the context of previous quickfix lists
@ -2320,7 +2356,7 @@ func XfreeTests(cchar)
Xclose Xclose
endfunc endfunc
" Tests for the quickifx free functionality " Tests for the quickfix free functionality
func Test_qf_free() func Test_qf_free()
call XfreeTests('c') call XfreeTests('c')
call XfreeTests('l') call XfreeTests('l')
@ -2347,8 +2383,8 @@ func XsizeTests(cchar)
call g:Xsetlist([], 'f') call g:Xsetlist([], 'f')
call assert_equal(0, g:Xgetlist({'nr':'$'}).nr) call assert_equal(0, g:Xgetlist({'nr':'$'}).nr)
call assert_equal(1, len(g:Xgetlist({'nr':'$', 'all':1}))) call assert_equal('', g:Xgetlist({'nr':'$', 'all':1}).title)
call assert_equal(0, len(g:Xgetlist({'nr':0}))) call assert_equal(0, g:Xgetlist({'nr':0}).nr)
Xexpr "File1:10:Line1" Xexpr "File1:10:Line1"
Xexpr "File2:20:Line2" Xexpr "File2:20:Line2"
@ -2718,7 +2754,7 @@ func Xqfid_tests(cchar)
call s:setup_commands(a:cchar) call s:setup_commands(a:cchar)
call g:Xsetlist([], 'f') call g:Xsetlist([], 'f')
call assert_equal({}, g:Xgetlist({'id':0})) call assert_equal(0, g:Xgetlist({'id':0}).id)
Xexpr '' Xexpr ''
let start_id = g:Xgetlist({'id' : 0}).id let start_id = g:Xgetlist({'id' : 0}).id
Xexpr '' | Xexpr '' Xexpr '' | Xexpr ''
@ -2726,10 +2762,10 @@ func Xqfid_tests(cchar)
call assert_equal(start_id, g:Xgetlist({'id':0, 'nr':1}).id) 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 + 1, g:Xgetlist({'id':0, 'nr':0}).id)
call assert_equal(start_id + 2, g:Xgetlist({'id':0, 'nr':'$'}).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(2, g:Xgetlist({'id':start_id + 1, 'nr':0}).nr)
call assert_equal({}, g:Xgetlist({'id':99, 'nr':0})) call assert_equal(0, g:Xgetlist({'id':99, 'nr':0}).id)
call assert_equal({}, g:Xgetlist({'id':"abc", 'nr':0})) call assert_equal(0, g:Xgetlist({'id':"abc", 'nr':0}).id)
call g:Xsetlist([], 'a', {'id':start_id, 'context':[1,2]}) call g:Xsetlist([], 'a', {'id':start_id, 'context':[1,2]})
call assert_equal([1,2], g:Xgetlist({'nr':1, 'context':1}).context) call assert_equal([1,2], g:Xgetlist({'nr':1, 'context':1}).context)
@ -2740,10 +2776,166 @@ func Xqfid_tests(cchar)
let qfid = g:Xgetlist({'id':0, 'nr':0}) let qfid = g:Xgetlist({'id':0, 'nr':0})
call g:Xsetlist([], 'f') 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 endfunc
func Test_qf_id() func Test_qf_id()
call Xqfid_tests('c') call Xqfid_tests('c')
call Xqfid_tests('l') call Xqfid_tests('l')
endfunc endfunc
func Xqfjump_tests(cchar)
call s:setup_commands(a:cchar)
call writefile(["Line1\tFoo", "Line2"], 'F1')
call writefile(["Line1\tBar", "Line2"], 'F2')
call writefile(["Line1\tBaz", "Line2"], 'F3')
call g:Xsetlist([], 'f')
" Tests for
" Jumping to a line using a pattern
" Jumping to a column greater than the last column in a line
" Jumping to a line greater than the last line in the file
let l = []
for i in range(1, 7)
call add(l, {})
endfor
let l[0].filename='F1'
let l[0].pattern='Line1'
let l[1].filename='F2'
let l[1].pattern='Line1'
let l[2].filename='F3'
let l[2].pattern='Line1'
let l[3].filename='F3'
let l[3].lnum=1
let l[3].col=9
let l[3].vcol=1
let l[4].filename='F3'
let l[4].lnum=99
let l[5].filename='F3'
let l[5].lnum=1
let l[5].col=99
let l[5].vcol=1
let l[6].filename='F3'
let l[6].pattern='abcxyz'
call g:Xsetlist([], ' ', {'items' : l})
Xopen | only
2Xnext
call assert_equal(3, g:Xgetlist({'idx' : 0}).idx)
call assert_equal('F3', bufname('%'))
Xnext
call assert_equal(7, col('.'))
Xnext
call assert_equal(2, line('.'))
Xnext
call assert_equal(9, col('.'))
2
Xnext
call assert_equal(2, line('.'))
if a:cchar == 'l'
" When jumping to a location list entry in the location list window and
" no usable windows are available, then a new window should be opened.
enew! | new | only
call g:Xsetlist([], 'f')
setlocal buftype=nofile
new
call g:Xsetlist([], ' ', {'lines' : ['F1:1:1:Line1', 'F1:2:2:Line2', 'F2:1:1:Line1', 'F2:2:2:Line2', 'F3:1:1:Line1', 'F3:2:2:Line2']})
Xopen
let winid = win_getid()
wincmd p
close
call win_gotoid(winid)
Xnext
call assert_equal(3, winnr('$'))
call assert_equal(1, winnr())
call assert_equal(2, line('.'))
" When jumping to an entry in the location list window and the window
" associated with the location list is not present and a window containing
" the file is already present, then that window should be used.
close
belowright new
call g:Xsetlist([], 'f')
edit F3
call win_gotoid(winid)
Xlast
call assert_equal(3, winnr())
call assert_equal(6, g:Xgetlist({'size' : 1}).size)
call assert_equal(winid, g:Xgetlist({'winid' : 1}).winid)
endif
" Cleanup
enew!
new | only
call delete('F1')
call delete('F2')
call delete('F3')
endfunc
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

@ -3523,6 +3523,8 @@ u_save_line(linenr_T lnum)
* Check if the 'modified' flag is set, or 'ff' has changed (only need to * Check if the 'modified' flag is set, or 'ff' has changed (only need to
* check the first character, because it can only be "dos", "unix" or "mac"). * check the first character, because it can only be "dos", "unix" or "mac").
* "nofile" and "scratch" type buffers are considered to always be unchanged. * "nofile" and "scratch" type buffers are considered to always be unchanged.
* Also considers a buffer changed when a terminal window contains a running
* job.
*/ */
int int
bufIsChanged(buf_T *buf) bufIsChanged(buf_T *buf)
@ -3531,6 +3533,15 @@ bufIsChanged(buf_T *buf)
if (term_job_running(buf->b_term)) if (term_job_running(buf->b_term))
return TRUE; return TRUE;
#endif #endif
return bufIsChangedNotTerm(buf);
}
/*
* Like bufIsChanged() but ignoring a terminal window.
*/
int
bufIsChangedNotTerm(buf_T *buf)
{
return !bt_dontwrite(buf) return !bt_dontwrite(buf)
&& (buf->b_changed || file_ff_differs(buf, TRUE)); && (buf->b_changed || file_ff_differs(buf, TRUE));
} }

View File

@ -1886,7 +1886,7 @@ ex_function(exarg_T *eap)
* g:func global function name, same as "func" * g:func global function name, same as "func"
*/ */
p = eap->arg; p = eap->arg;
name = trans_function_name(&p, eap->skip, 0, &fudi, NULL); name = trans_function_name(&p, eap->skip, TFN_NO_AUTOLOAD, &fudi, NULL);
paren = (vim_strchr(p, '(') != NULL); paren = (vim_strchr(p, '(') != NULL);
if (name == NULL && (fudi.fd_dict == NULL || !paren) && !eap->skip) if (name == NULL && (fudi.fd_dict == NULL || !paren) && !eap->skip)
{ {

View File

@ -771,6 +771,32 @@ static char *(features[]) =
static int included_patches[] = static int included_patches[] =
{ /* Add new patch number below this line */ { /* Add new patch number below this line */
/**/
1390,
/**/
1389,
/**/
1388,
/**/
1387,
/**/
1386,
/**/
1385,
/**/
1384,
/**/
1383,
/**/
1382,
/**/
1381,
/**/
1380,
/**/
1379,
/**/
1378,
/**/ /**/
1377, 1377,
/**/ /**/