Compare commits

...

14 Commits

Author SHA1 Message Date
Bram Moolenaar
a1d5c154db patch 8.0.1396: memory leak when CTRL-G in search command line fails
Problem:    Memory leak when CTRL-G in search command line fails.
Solution:   Move restore_last_search_pattern to after "if".
2017-12-16 19:05:22 +01:00
Bram Moolenaar
200d0e36bc patch 8.0.1395: it is not easy to see if a colorscheme is well written
Problem:    It is not easy to see if a colorscheme is well written.
Solution:   Add a script that checks for common mistakes. (Christian Brabandt)
2017-12-16 18:53:35 +01:00
Bram Moolenaar
7e1652c63c patch 8.0.1394: cannot intercept a yank command
Problem:    Cannot intercept a yank command.
Solution:   Add the TextYankPost autocommand event. (Philippe Vaucher et al.,
            closes #2333)
2017-12-16 18:27:02 +01:00
Bram Moolenaar
6621605eb9 patch 8.0.1393: too much highlighting with 'hlsearch' and 'incsearch' set
Problem:    Too much highlighting with 'hlsearch' and 'incsearch' set.
Solution:   Do not highlight matches when the pattern matches everything.
2017-12-16 16:33:44 +01:00
Bram Moolenaar
8b42328cef patch 8.0.1392: build fails with --with-features=huge --disable-channel
Problem:    Build fails with --with-features=huge --disable-channel.
Solution:   Don't enable the terminal feature when the channel feature is
            missing. (Dominique Pelle, closes #2453)
2017-12-16 14:37:06 +01:00
Bram Moolenaar
b29d328eb4 patch 8.0.1391: encoding empty string to JSON sometimes gives "null"
Problem:    Encoding empty string to JSON sometimes gives "null".
Solution:   Handle NULL string as empty string. (closes #2446)
2017-12-15 21:25:01 +01:00
Bram Moolenaar
4697399e8c move netrw back to the previous version 2017-12-14 19:56:46 +01:00
Bram Moolenaar
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
Bram Moolenaar
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
Bram Moolenaar
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
Bram Moolenaar
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
Bram Moolenaar
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
Bram Moolenaar
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
Bram Moolenaar
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
42 changed files with 1593 additions and 1165 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -1,7 +1,7 @@
" netrwSettings.vim: makes netrw settings simpler " netrwSettings.vim: makes netrw settings simpler
" Date: Nov 09, 2016 " Date: Dec 30, 2014
" Maintainer: Charles E Campbell <drchipNOSPAM at campbellfamily dot biz> " Maintainer: Charles E Campbell <drchipNOSPAM at campbellfamily dot biz>
" Version: 16 " Version: 15
" Copyright: Copyright (C) 1999-2007 Charles E. Campbell {{{1 " Copyright: Copyright (C) 1999-2007 Charles E. Campbell {{{1
" Permission is hereby granted to use and distribute this code, " Permission is hereby granted to use and distribute this code,
" with or without modifications, provided that this copyright " with or without modifications, provided that this copyright
@@ -19,7 +19,7 @@
if exists("g:loaded_netrwSettings") || &cp if exists("g:loaded_netrwSettings") || &cp
finish finish
endif endif
let g:loaded_netrwSettings = "v16" let g:loaded_netrwSettings = "v15"
if v:version < 700 if v:version < 700
echohl WarningMsg echohl WarningMsg
echo "***warning*** this version of netrwSettings needs vim 7.0" echo "***warning*** this version of netrwSettings needs vim 7.0"
@@ -154,13 +154,9 @@ fun! netrwSettings#NetrwSettings()
put = 'let g:netrw_list_hide = '.g:netrw_list_hide put = 'let g:netrw_list_hide = '.g:netrw_list_hide
put = 'let g:netrw_liststyle = '.g:netrw_liststyle put = 'let g:netrw_liststyle = '.g:netrw_liststyle
put = 'let g:netrw_localcopycmd = '.g:netrw_localcopycmd put = 'let g:netrw_localcopycmd = '.g:netrw_localcopycmd
put = 'let g:netrw_localcopycmdopt = '.g:netrw_localcopycmdopt
put = 'let g:netrw_localmkdir = '.g:netrw_localmkdir put = 'let g:netrw_localmkdir = '.g:netrw_localmkdir
put = 'let g:netrw_localmkdiropt = '.g:netrw_localmkdiropt
put = 'let g:netrw_localmovecmd = '.g:netrw_localmovecmd put = 'let g:netrw_localmovecmd = '.g:netrw_localmovecmd
put = 'let g:netrw_localmovecmdopt = '.g:netrw_localmovecmdopt
put = 'let g:netrw_localrmdir = '.g:netrw_localrmdir put = 'let g:netrw_localrmdir = '.g:netrw_localrmdir
put = 'let g:netrw_localrmdiropt = '.g:netrw_localrmdiropt
put = 'let g:netrw_maxfilenamelen = '.g:netrw_maxfilenamelen put = 'let g:netrw_maxfilenamelen = '.g:netrw_maxfilenamelen
put = 'let g:netrw_menu = '.g:netrw_menu put = 'let g:netrw_menu = '.g:netrw_menu
put = 'let g:netrw_mousemaps = '.g:netrw_mousemaps put = 'let g:netrw_mousemaps = '.g:netrw_mousemaps

View File

@@ -64,6 +64,7 @@ Search for "highlight_init".
If you think you have a color scheme that is good enough to be used by others, If you think you have a color scheme that is good enough to be used by others,
please check the following items: please check the following items:
- Source the check_colors.vim script to check for common mistakes.
- Does it work in a color terminal as well as in the GUI? - Does it work in a color terminal as well as in the GUI?
- Is "g:colors_name" set to a meaningful value? In case of doubt you can do - Is "g:colors_name" set to a meaningful value? In case of doubt you can do
it this way: it this way:

View File

@@ -0,0 +1,136 @@
" This script tests a color scheme for some errors. Load the scheme and source
" this script. e.g. :e colors/desert.vim | :so test_colors.vim
" Will output possible errors.
let s:save_cpo= &cpo
set cpo&vim
func! Test_check_colors()
call cursor(1,1)
let err={}
" 1) Check g:colors_name is existing
if !search('\<\%(g:\)\?colors_name\>', 'cnW')
let err['colors_name'] = 'g:colors_name not set'
else
let err['colors_name'] = 'OK'
endif
" 2) Check for some well-defined highlighting groups
" Some items, check several groups, e.g. Diff, Spell
let hi_groups = ['ColorColumn', 'Diff', 'ErrorMsg', 'Folded',
\ 'FoldColumn', 'IncSearch', 'LineNr', 'ModeMsg', 'MoreMsg', 'NonText',
\ 'Normal', 'Pmenu', 'Todo', 'Search', 'Spell', 'StatusLine', 'TabLine',
\ 'Title', 'Visual', 'WarningMsg', 'WildMenu']
let groups={}
for group in hi_groups
if search('\c@suppress\s\+'.group, 'cnW')
" skip check, if the script contains a line like
" @suppress Visual:
let groups[group] = 'Ignoring '.group
continue
endif
if !search('hi\%[ghlight] \+'.group, 'cnW')
let groups[group] = 'No highlight definition for '.group
continue
endif
if !search('hi\%[ghlight] \+'.group. '.*fg=', 'cnW')
let groups[group] = 'Missing foreground color for '.group
continue
endif
if search('hi\%[ghlight] \+'.group. '.*guibg=', 'cnW') &&
\ !search('hi\%[ghlight] \+'.group. '.*ctermbg=', 'cnW')
let groups[group] = 'Missing bg terminal color for '.group
continue
endif
call search('hi\%[ghlight] \+'.group, 'cW')
" only check in the current line
if !search('guifg', 'cnW', line('.')) || !search('ctermfg', 'cnW', line('.'))
" do not check for background colors, they could be intentionally left out
let groups[group] = 'Missing fg definition for '.group
endif
call cursor(1,1)
endfor
let err['highlight'] = groups
" 3) Check, that it does not set background highlighting
" Doesn't ':hi Normal ctermfg=253 ctermfg=233' also set the background sometimes?
let bg_set='\(set\?\|setl\(ocal\)\?\) .*\(background\|bg\)=\(dark\|light\)'
let bg_let='let \%([&]\%([lg]:\)\?\)\%(background\|bg\)\s*=\s*\([''"]\?\)\w\+\1'
let bg_pat='\%('.bg_set. '\|'.bg_let.'\)'
let line=search(bg_pat, 'cnW')
if search(bg_pat, 'cnW')
exe line
if search('hi \U\w\+\s\+\S', 'cbnW')
let err['background'] = 'Should not set background option after :hi statement'
endif
else
let err['background'] = 'OK'
endif
call cursor(1,1)
" 4) Check, that t_Co is checked
let pat = '[&]t_Co\s*[<>=]=\?\s*\d\+'
if !search(pat, 'ncW')
let err['t_Co'] = 'Does not check terminal for capable colors'
endif
" 5) Initializes correctly, e.g. should have a section like
" hi clear
" if exists("syntax_on")
" syntax reset
" endif
let pat='hi\%[ghlight]\s*clear\n\s*if\s*exists(\([''"]\)syntax_on\1)\n\s*syn\%[tax]\s*reset\n\s*endif'
if !search(pat, 'cnW')
let err['init'] = 'No initialization'
endif
" 6) Does not use :syn on
if search('syn\%[tax]\s\+on', 'cnW')
let err['background'] = 'Should not issue :syn on'
endif
" 7) Does not define filetype specfic groups like vimCommand, htmlTag,
let hi_groups = ['vim', 'html', 'python', 'sh', 'ruby']
for group in hi_groups
let pat='\Chi\%[ghlight]\s*\zs'.group.'\w\+\>'
if search(pat, 'cnW')
let line = search(pat, 'cW')
let err['filetype'] = get(err, 'filetype', 'Should not define: ') . matchstr(getline('.'), pat). ' '
endif
call cursor(1,1)
endfor
let g:err = err
" print Result
call Result(err)
endfu
fu! Result(err)
let do_roups = 0
echohl Title|echomsg "---------------"|echohl Normal
for key in sort(keys(a:err))
if key is# 'highlight'
let do_groups = 1
continue
else
if a:err[key] !~ 'OK'
echohl Title
endif
echomsg printf("%15s: %s", key, a:err[key])
echohl Normal
endif
endfor
echohl Title|echomsg "---------------"|echohl Normal
if do_groups
echohl Title | echomsg "Groups" | echohl Normal
for v1 in sort(keys(a:err['highlight']))
echomsg printf("%25s: %s", v1, a:err['highlight'][v1])
endfor
endif
endfu
call Test_check_colors()
let &cpo = s:save_cpo
unlet s:save_cpo

View File

@@ -330,6 +330,7 @@ Name triggered by ~
|TextChanged| after a change was made to the text in Normal mode |TextChanged| after a change was made to the text in Normal mode
|TextChangedI| after a change was made to the text in Insert mode |TextChangedI| after a change was made to the text in Insert mode
|TextYankPost| after text is yanked or deleted
|ColorScheme| after loading a color scheme |ColorScheme| after loading a color scheme
@@ -956,6 +957,26 @@ TextChangedI After a change was made to the text in the
current buffer in Insert mode. current buffer in Insert mode.
Not triggered when the popup menu is visible. Not triggered when the popup menu is visible.
Otherwise the same as TextChanged. Otherwise the same as TextChanged.
|TextYankPost|
TextYankPost After text has been yanked or deleted in the
current buffer. The following values of
|v:event| can be used to determine the operation
that triggered this autocmd:
operator The operation performed.
regcontents Text that was stored in the
register, as a list of lines,
like with: >
getreg(r, 1, 1)
< regname Name of the |register| or
empty string for the unnamed
register.
regtype Type of the register, see
|getregtype()|.
Not triggered when |quote_| is used nor when
called recursively.
It is not allowed to change the buffer text,
see |textlock|.
*User* *User*
User Never executed automatically. To be used for User Never executed automatically. To be used for
autocommands that are only executed with autocommands that are only executed with

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
@@ -1554,6 +1554,12 @@ v:errors Errors found by assert functions, such as |assert_true()|.
< If v:errors is set to anything but a list it is made an empty < If v:errors is set to anything but a list it is made an empty
list by the assert function. list by the assert function.
*v:event* *event-variable*
v:event Dictionary containing information about the current
|autocommand|. The dictionary is emptied when the |autocommand|
finishes, please refer to |dict-identity| for how to get an
independent copy of it.
*v:exception* *exception-variable* *v:exception* *exception-variable*
v:exception The value of the exception most recently caught and not v:exception The value of the exception most recently caught and not
finished. See also |v:throwpoint| and |throw-variables|. finished. See also |v:throwpoint| and |throw-variables|.
@@ -2031,7 +2037,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 +3062,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 +4179,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 +4690,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 +4703,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 +8809,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

@@ -20,7 +20,7 @@
if &cp || exists("g:loaded_netrwPlugin") if &cp || exists("g:loaded_netrwPlugin")
finish finish
endif endif
let g:loaded_netrwPlugin = "v162" let g:loaded_netrwPlugin = "v156"
let s:keepcpo = &cpo let s:keepcpo = &cpo
set cpo&vim set cpo&vim
"DechoRemOn "DechoRemOn
@@ -42,8 +42,8 @@ augroup END
" Network Browsing Reading Writing: {{{2 " Network Browsing Reading Writing: {{{2
augroup Network augroup Network
au! au!
au BufReadCmd file://* call netrw#FileUrlEdit(expand("<amatch>")) au BufReadCmd file://* call netrw#FileUrlRead(expand("<amatch>"))
au BufReadCmd ftp://*,rcp://*,scp://*,http://*,https://*,dav://*,davs://*,rsync://*,sftp://* exe "sil doau BufReadPre ".fnameescape(expand("<amatch>"))|call netrw#Nread(2,expand("<amatch>"))|exe "sil doau BufReadPost ".fnameescape(expand("<amatch>")) au BufReadCmd ftp://*,rcp://*,scp://*,http://*,file://*,https://*,dav://*,davs://*,rsync://*,sftp://* exe "sil doau BufReadPre ".fnameescape(expand("<amatch>"))|call netrw#Nread(2,expand("<amatch>"))|exe "sil doau BufReadPost ".fnameescape(expand("<amatch>"))
au FileReadCmd ftp://*,rcp://*,scp://*,http://*,file://*,https://*,dav://*,davs://*,rsync://*,sftp://* exe "sil doau FileReadPre ".fnameescape(expand("<amatch>"))|call netrw#Nread(1,expand("<amatch>"))|exe "sil doau FileReadPost ".fnameescape(expand("<amatch>")) au FileReadCmd ftp://*,rcp://*,scp://*,http://*,file://*,https://*,dav://*,davs://*,rsync://*,sftp://* exe "sil doau FileReadPre ".fnameescape(expand("<amatch>"))|call netrw#Nread(1,expand("<amatch>"))|exe "sil doau FileReadPost ".fnameescape(expand("<amatch>"))
au BufWriteCmd ftp://*,rcp://*,scp://*,http://*,file://*,dav://*,davs://*,rsync://*,sftp://* exe "sil doau BufWritePre ".fnameescape(expand("<amatch>"))|exe 'Nwrite '.fnameescape(expand("<amatch>"))|exe "sil doau BufWritePost ".fnameescape(expand("<amatch>")) au BufWriteCmd ftp://*,rcp://*,scp://*,http://*,file://*,dav://*,davs://*,rsync://*,sftp://* exe "sil doau BufWritePre ".fnameescape(expand("<amatch>"))|exe 'Nwrite '.fnameescape(expand("<amatch>"))|exe "sil doau BufWritePost ".fnameescape(expand("<amatch>"))
au FileWriteCmd ftp://*,rcp://*,scp://*,http://*,file://*,dav://*,davs://*,rsync://*,sftp://* exe "sil doau FileWritePre ".fnameescape(expand("<amatch>"))|exe "'[,']".'Nwrite '.fnameescape(expand("<amatch>"))|exe "sil doau FileWritePost ".fnameescape(expand("<amatch>")) au FileWriteCmd ftp://*,rcp://*,scp://*,http://*,file://*,dav://*,davs://*,rsync://*,sftp://* exe "sil doau FileWritePre ".fnameescape(expand("<amatch>"))|exe "'[,']".'Nwrite '.fnameescape(expand("<amatch>"))|exe "sil doau FileWritePost ".fnameescape(expand("<amatch>"))
@@ -59,7 +59,7 @@ com! -count=1 -nargs=* Nread let s:svpos= winsaveview()<bar>call netrw#NetRead(
com! -range=% -nargs=* Nwrite let s:svpos= winsaveview()<bar><line1>,<line2>call netrw#NetWrite(<f-args>)<bar>call winrestview(s:svpos) com! -range=% -nargs=* Nwrite let s:svpos= winsaveview()<bar><line1>,<line2>call netrw#NetWrite(<f-args>)<bar>call winrestview(s:svpos)
com! -nargs=* NetUserPass call NetUserPass(<f-args>) com! -nargs=* NetUserPass call NetUserPass(<f-args>)
com! -nargs=* Nsource let s:svpos= winsaveview()<bar>call netrw#NetSource(<f-args>)<bar>call winrestview(s:svpos) com! -nargs=* Nsource let s:svpos= winsaveview()<bar>call netrw#NetSource(<f-args>)<bar>call winrestview(s:svpos)
com! -nargs=? Ntree call netrw#SetTreetop(1,<q-args>) com! -nargs=? Ntree call netrw#SetTreetop(<q-args>)
" Commands: :Explore, :Sexplore, Hexplore, Vexplore, Lexplore {{{2 " Commands: :Explore, :Sexplore, Hexplore, Vexplore, Lexplore {{{2
com! -nargs=* -bar -bang -count=0 -complete=dir Explore call netrw#Explore(<count>,0,0+<bang>0,<q-args>) com! -nargs=* -bar -bang -count=0 -complete=dir Explore call netrw#Explore(<count>,0,0+<bang>0,<q-args>)
@@ -81,7 +81,7 @@ if !exists("g:netrw_nogx")
if !hasmapto('<Plug>NetrwBrowseX') if !hasmapto('<Plug>NetrwBrowseX')
nmap <unique> gx <Plug>NetrwBrowseX nmap <unique> gx <Plug>NetrwBrowseX
endif endif
nno <silent> <Plug>NetrwBrowseX :call netrw#BrowseX(netrw#GX(),netrw#CheckIfRemote(netrw#GX()))<cr> nno <silent> <Plug>NetrwBrowseX :call netrw#BrowseX(expand((exists("g:netrw_gx")? g:netrw_gx : '<cfile>')),netrw#CheckIfRemote())<cr>
endif endif
if maparg('gx','v') == "" if maparg('gx','v') == ""
if !hasmapto('<Plug>NetrwBrowseXVis') if !hasmapto('<Plug>NetrwBrowseXVis')
@@ -129,15 +129,19 @@ fun! s:LocalBrowse(dirname)
elseif isdirectory(a:dirname) elseif isdirectory(a:dirname)
" call Decho("(LocalBrowse) dirname<".a:dirname."> ft=".&ft." (isdirectory, not amiga)") " call Decho("(LocalBrowse) dirname<".a:dirname."> ft=".&ft." (isdirectory, not amiga)")
" call Dredir("LocalBrowse ft last set: ","verbose set ft") " call Dredir("LocalBrowse ft last set: ","verbose set ft")
" call Decho("(s:LocalBrowse) COMBAK#23: buf#".bufnr("%")." file<".expand("%")."> line#".line(".")." col#".col("."))
sil! call netrw#LocalBrowseCheck(a:dirname) sil! call netrw#LocalBrowseCheck(a:dirname)
" call Decho("(s:LocalBrowse) COMBAK#24: buf#".bufnr("%")." file<".expand("%")."> line#".line(".")." col#".col("."))
if exists("w:netrw_bannercnt") && line('.') < w:netrw_bannercnt if exists("w:netrw_bannercnt") && line('.') < w:netrw_bannercnt
exe w:netrw_bannercnt exe w:netrw_bannercnt
" call Decho("(s:LocalBrowse) COMBAK#25: buf#".bufnr("%")." file<".expand("%")."> line#".line(".")." col#".col("."))
endif endif
else else
" not a directory, ignore it " not a directory, ignore it
" call Decho("(LocalBrowse) dirname<".a:dirname."> not a directory, ignoring...") " call Decho("(LocalBrowse) dirname<".a:dirname."> not a directory, ignoring...")
endif endif
" call Decho("(s:LocalBrowse) COMBAK#26: buf#".bufnr("%")." file<".expand("%")."> line#".line(".")." col#".col("."))
" call Dret("s:LocalBrowse") " call Dret("s:LocalBrowse")
endfun endfun

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

@@ -26,11 +26,14 @@
# 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]
@@ -422,6 +425,9 @@ NETBEANS_LIB = WSock32.lib
# 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 \

2
src/auto/configure vendored
View File

@@ -7514,7 +7514,7 @@ $as_echo "defaulting to no" >&6; }
$as_echo "no" >&6; } $as_echo "no" >&6; }
fi fi
fi fi
if test "$enable_terminal" = "yes"; then if test "$enable_terminal" = "yes" -a "$enable_channel" = "yes"; then
$as_echo "#define FEAT_TERMINAL 1" >>confdefs.h $as_echo "#define FEAT_TERMINAL 1" >>confdefs.h
TERM_SRC="libvterm/src/encoding.c libvterm/src/keyboard.c libvterm/src/mouse.c libvterm/src/parser.c libvterm/src/pen.c libvterm/src/screen.c libvterm/src/state.c libvterm/src/unicode.c libvterm/src/vterm.c" TERM_SRC="libvterm/src/encoding.c libvterm/src/keyboard.c libvterm/src/mouse.c libvterm/src/parser.c libvterm/src/pen.c libvterm/src/screen.c libvterm/src/state.c libvterm/src/unicode.c libvterm/src/vterm.c"

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

@@ -2059,7 +2059,7 @@ else
AC_MSG_RESULT(no) AC_MSG_RESULT(no)
fi fi
fi fi
if test "$enable_terminal" = "yes"; then if test "$enable_terminal" = "yes" -a "$enable_channel" = "yes"; then
AC_DEFINE(FEAT_TERMINAL) AC_DEFINE(FEAT_TERMINAL)
TERM_SRC="libvterm/src/encoding.c libvterm/src/keyboard.c libvterm/src/mouse.c libvterm/src/parser.c libvterm/src/pen.c libvterm/src/screen.c libvterm/src/state.c libvterm/src/unicode.c libvterm/src/vterm.c" TERM_SRC="libvterm/src/encoding.c libvterm/src/keyboard.c libvterm/src/mouse.c libvterm/src/parser.c libvterm/src/pen.c libvterm/src/screen.c libvterm/src/state.c libvterm/src/unicode.c libvterm/src/vterm.c"
AC_SUBST(TERM_SRC) AC_SUBST(TERM_SRC)

View File

@@ -47,6 +47,16 @@ dict_alloc(void)
return d; return d;
} }
dict_T *
dict_alloc_lock(int lock)
{
dict_T *d = dict_alloc();
if (d != NULL)
d->dv_lock = lock;
return d;
}
/* /*
* Allocate an empty dict for a return value. * Allocate an empty dict for a return value.
* Returns OK or FAIL. * Returns OK or FAIL.
@@ -54,13 +64,12 @@ dict_alloc(void)
int int
rettv_dict_alloc(typval_T *rettv) rettv_dict_alloc(typval_T *rettv)
{ {
dict_T *d = dict_alloc(); dict_T *d = dict_alloc_lock(0);
if (d == NULL) if (d == NULL)
return FAIL; return FAIL;
rettv_dict_set(rettv, d); rettv_dict_set(rettv, d);
rettv->v_lock = 0;
return OK; return OK;
} }
@@ -80,7 +89,7 @@ rettv_dict_set(typval_T *rettv, dict_T *d)
* Free a Dictionary, including all non-container items it contains. * Free a Dictionary, including all non-container items it contains.
* Ignores the reference count. * Ignores the reference count.
*/ */
static void void
dict_free_contents(dict_T *d) dict_free_contents(dict_T *d)
{ {
int todo; int todo;
@@ -102,6 +111,8 @@ dict_free_contents(dict_T *d)
--todo; --todo;
} }
} }
/* The hashtab is still locked, it has to be re-initialized anyway */
hash_clear(&d->dv_hashtab); hash_clear(&d->dv_hashtab);
} }
@@ -846,4 +857,23 @@ dict_list(typval_T *argvars, typval_T *rettv, int what)
} }
} }
/*
* Make each item in the dict readonly (not the value of the item).
*/
void
dict_set_items_ro(dict_T *di)
{
int todo = (int)di->dv_hashtab.ht_used;
hashitem_T *hi;
/* Set readonly */
for (hi = di->dv_hashtab.ht_array; todo > 0 ; ++hi)
{
if (HASHITEM_EMPTY(hi))
continue;
--todo;
HI2DI(hi)->di_flags |= DI_FLAGS_RO | DI_FLAGS_FIX;
}
}
#endif /* defined(FEAT_EVAL) */ #endif /* defined(FEAT_EVAL) */

View File

@@ -192,6 +192,7 @@ static struct vimvar
{VV_NAME("termu7resp", VAR_STRING), VV_RO}, {VV_NAME("termu7resp", VAR_STRING), VV_RO},
{VV_NAME("termstyleresp", VAR_STRING), VV_RO}, {VV_NAME("termstyleresp", VAR_STRING), VV_RO},
{VV_NAME("termblinkresp", VAR_STRING), VV_RO}, {VV_NAME("termblinkresp", VAR_STRING), VV_RO},
{VV_NAME("event", VAR_DICT), VV_RO},
}; };
/* shorthand */ /* shorthand */
@@ -319,8 +320,9 @@ eval_init(void)
set_vim_var_nr(VV_SEARCHFORWARD, 1L); set_vim_var_nr(VV_SEARCHFORWARD, 1L);
set_vim_var_nr(VV_HLSEARCH, 1L); set_vim_var_nr(VV_HLSEARCH, 1L);
set_vim_var_dict(VV_COMPLETED_ITEM, dict_alloc()); set_vim_var_dict(VV_COMPLETED_ITEM, dict_alloc_lock(VAR_FIXED));
set_vim_var_list(VV_ERRORS, list_alloc()); set_vim_var_list(VV_ERRORS, list_alloc());
set_vim_var_dict(VV_EVENT, dict_alloc_lock(VAR_FIXED));
set_vim_var_nr(VV_FALSE, VVAL_FALSE); set_vim_var_nr(VV_FALSE, VVAL_FALSE);
set_vim_var_nr(VV_TRUE, VVAL_TRUE); set_vim_var_nr(VV_TRUE, VVAL_TRUE);
@@ -6632,6 +6634,16 @@ get_vim_var_list(int idx)
return vimvars[idx].vv_list; return vimvars[idx].vv_list;
} }
/*
* Get Dict v: variable value. Caller must take care of reference count when
* needed.
*/
dict_T *
get_vim_var_dict(int idx)
{
return vimvars[idx].vv_dict;
}
/* /*
* Set v:char to character "c". * Set v:char to character "c".
*/ */
@@ -6706,25 +6718,13 @@ set_vim_var_list(int idx, list_T *val)
void void
set_vim_var_dict(int idx, dict_T *val) set_vim_var_dict(int idx, dict_T *val)
{ {
int todo;
hashitem_T *hi;
clear_tv(&vimvars[idx].vv_di.di_tv); clear_tv(&vimvars[idx].vv_di.di_tv);
vimvars[idx].vv_type = VAR_DICT; vimvars[idx].vv_type = VAR_DICT;
vimvars[idx].vv_dict = val; vimvars[idx].vv_dict = val;
if (val != NULL) if (val != NULL)
{ {
++val->dv_refcount; ++val->dv_refcount;
dict_set_items_ro(val);
/* Set readonly */
todo = (int)val->dv_hashtab.ht_used;
for (hi = val->dv_hashtab.ht_array; todo > 0 ; ++hi)
{
if (HASHITEM_EMPTY(hi))
continue;
--todo;
HI2DI(hi)->di_flags |= DI_FLAGS_RO | DI_FLAGS_FIX;
}
} }
} }

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

@@ -172,6 +172,22 @@ abandon_cmdline(void)
redraw_cmdline = TRUE; redraw_cmdline = TRUE;
} }
/*
* Guess that the pattern matches everything. Only finds specific cases, such
* as a trailing \|, which can happen while typing a pattern.
*/
static int
empty_pattern(char_u *p)
{
int n = STRLEN(p);
/* remove trailing \v and the like */
while (n >= 2 && p[n - 2] == '\\'
&& vim_strchr((char_u *)"mMvVcCZ", p[n - 1]) != NULL)
n -= 2;
return n == 0 || (n >= 2 && p[n - 2] == '\\' && p[n - 1] == '|');
}
/* /*
* getcmdline() - accept a command line starting with firstc. * getcmdline() - accept a command line starting with firstc.
* *
@@ -1794,11 +1810,11 @@ getcmdline(
# endif # endif
old_botline = curwin->w_botline; old_botline = curwin->w_botline;
update_screen(NOT_VALID); update_screen(NOT_VALID);
restore_last_search_pattern();
redrawcmdline(); redrawcmdline();
} }
else else
vim_beep(BO_ERROR); vim_beep(BO_ERROR);
restore_last_search_pattern();
goto cmdline_not_changed; goto cmdline_not_changed;
} }
break; break;
@@ -2023,6 +2039,11 @@ cmdline_changed:
else else
end_pos = curwin->w_cursor; /* shutup gcc 4 */ end_pos = curwin->w_cursor; /* shutup gcc 4 */
/* Disable 'hlsearch' highlighting if the pattern matches
* everything. Avoids a flash when typing "foo\|". */
if (empty_pattern(ccline.cmdbuff))
SET_NO_HLSEARCH(TRUE);
validate_cursor(); validate_cursor();
/* May redraw the status line to show the cursor position. */ /* May redraw the status line to show the cursor position. */
if (p_ru && curwin->w_status_height > 0) if (p_ru && curwin->w_status_height > 0)

View File

@@ -6478,6 +6478,7 @@ buf_modname(
/* /*
* Like fgets(), but if the file line is too long, it is truncated and the * Like fgets(), but if the file line is too long, it is truncated and the
* rest of the line is thrown away. Returns TRUE for end-of-file. * rest of the line is thrown away. Returns TRUE for end-of-file.
* If the line is truncated then buf[size - 2] will not be NUL.
*/ */
int int
vim_fgets(char_u *buf, int size, FILE *fp) vim_fgets(char_u *buf, int size, FILE *fp)
@@ -7856,6 +7857,7 @@ static struct event_name
{"WinEnter", EVENT_WINENTER}, {"WinEnter", EVENT_WINENTER},
{"WinLeave", EVENT_WINLEAVE}, {"WinLeave", EVENT_WINLEAVE},
{"VimResized", EVENT_VIMRESIZED}, {"VimResized", EVENT_VIMRESIZED},
{"TextYankPost", EVENT_TEXTYANKPOST},
{NULL, (event_T)0} {NULL, (event_T)0}
}; };
@@ -9399,6 +9401,15 @@ has_funcundefined(void)
return (first_autopat[(int)EVENT_FUNCUNDEFINED] != NULL); return (first_autopat[(int)EVENT_FUNCUNDEFINED] != NULL);
} }
/*
* Return TRUE when there is a TextYankPost autocommand defined.
*/
int
has_textyankpost(void)
{
return (first_autopat[(int)EVENT_TEXTYANKPOST] != NULL);
}
/* /*
* Execute autocommands for "event" and file name "fname". * Execute autocommands for "event" and file name "fname".
* Return TRUE if some commands were executed. * Return TRUE if some commands were executed.

View File

@@ -38,7 +38,11 @@
# define _Outptr_ # define _Outptr_
#endif #endif
#ifdef FEAT_DIRECTX_COLOR_EMOJI
# include <dwrite_2.h> # 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
@@ -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,9 +3209,8 @@ 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);
@@ -6405,7 +6409,7 @@ gui_mch_draw_string(
/* 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

View File

@@ -92,7 +92,7 @@ write_string(garray_T *gap, char_u *str)
char_u numbuf[NUMBUFLEN]; char_u numbuf[NUMBUFLEN];
if (res == NULL) if (res == NULL)
ga_concat(gap, (char_u *)"null"); ga_concat(gap, (char_u *)"\"\"");
else else
{ {
#if defined(FEAT_MBYTE) && defined(USE_ICONV) #if defined(FEAT_MBYTE) && defined(USE_ICONV)
@@ -237,7 +237,7 @@ json_encode_item(garray_T *gap, typval_T *val, int copyID, int options)
case VAR_LIST: case VAR_LIST:
l = val->vval.v_list; l = val->vval.v_list;
if (l == NULL) if (l == NULL)
ga_concat(gap, (char_u *)"null"); ga_concat(gap, (char_u *)"[]");
else else
{ {
if (l->lv_copyID == copyID) if (l->lv_copyID == copyID)
@@ -272,7 +272,7 @@ json_encode_item(garray_T *gap, typval_T *val, int copyID, int options)
case VAR_DICT: case VAR_DICT:
d = val->vval.v_dict; d = val->vval.v_dict;
if (d == NULL) if (d == NULL)
ga_concat(gap, (char_u *)"null"); ga_concat(gap, (char_u *)"{}");
else else
{ {
if (d->dv_copyID == copyID) if (d->dv_copyID == copyID)

View File

@@ -1645,6 +1645,63 @@ shift_delete_registers()
y_regs[1].y_array = NULL; /* set register one to empty */ y_regs[1].y_array = NULL; /* set register one to empty */
} }
static void
yank_do_autocmd(oparg_T *oap, yankreg_T *reg)
{
static int recursive = FALSE;
dict_T *v_event;
list_T *list;
int n;
char_u buf[NUMBUFLEN + 2];
long reglen = 0;
if (recursive)
return;
v_event = get_vim_var_dict(VV_EVENT);
list = list_alloc();
for (n = 0; n < reg->y_size; n++)
list_append_string(list, reg->y_array[n], -1);
list->lv_lock = VAR_FIXED;
dict_add_list(v_event, "regcontents", list);
buf[0] = (char_u)oap->regname;
buf[1] = NUL;
dict_add_nr_str(v_event, "regname", 0, buf);
buf[0] = get_op_char(oap->op_type);
buf[1] = get_extra_op_char(oap->op_type);
buf[2] = NUL;
dict_add_nr_str(v_event, "operator", 0, buf);
buf[0] = NUL;
buf[1] = NUL;
switch (get_reg_type(oap->regname, &reglen))
{
case MLINE: buf[0] = 'V'; break;
case MCHAR: buf[0] = 'v'; break;
case MBLOCK:
vim_snprintf((char *)buf, sizeof(buf), "%c%ld", Ctrl_V,
reglen + 1);
break;
}
dict_add_nr_str(v_event, "regtype", 0, buf);
/* Lock the dictionary and its keys */
dict_set_items_ro(v_event);
recursive = TRUE;
textlock++;
apply_autocmds(EVENT_TEXTYANKPOST, NULL, NULL, FALSE, curbuf);
textlock--;
recursive = FALSE;
/* Empty the dictionary, v:event is still valid */
dict_free_contents(v_event);
hash_init(&v_event->dv_hashtab);
}
/* /*
* Handle a delete operation. * Handle a delete operation.
* *
@@ -1798,6 +1855,11 @@ op_delete(oparg_T *oap)
return FAIL; return FAIL;
} }
} }
#ifdef FEAT_AUTOCMD
if (did_yank && has_textyankpost())
yank_do_autocmd(oap, y_current);
#endif
} }
/* /*
@@ -3270,6 +3332,11 @@ op_yank(oparg_T *oap, int deleting, int mess)
# endif # endif
#endif #endif
#ifdef FEAT_AUTOCMD
if (!deleting && has_textyankpost())
yank_do_autocmd(oap, y_current);
#endif
return OK; return OK;
fail: /* free the allocated lines */ fail: /* free the allocated lines */

View File

@@ -1,7 +1,9 @@
/* dict.c */ /* dict.c */
dict_T *dict_alloc(void); dict_T *dict_alloc(void);
dict_T *dict_alloc_lock(int lock);
int rettv_dict_alloc(typval_T *rettv); int rettv_dict_alloc(typval_T *rettv);
void rettv_dict_set(typval_T *rettv, dict_T *d); void rettv_dict_set(typval_T *rettv, dict_T *d);
void dict_free_contents(dict_T *d);
void dict_unref(dict_T *d); void dict_unref(dict_T *d);
int dict_free_nonref(int copyID); int dict_free_nonref(int copyID);
void dict_free_items(int copyID); void dict_free_items(int copyID);
@@ -23,4 +25,5 @@ void dict_extend(dict_T *d1, dict_T *d2, char_u *action);
dictitem_T *dict_lookup(hashitem_T *hi); dictitem_T *dict_lookup(hashitem_T *hi);
int dict_equal(dict_T *d1, dict_T *d2, int ic, int recursive); int dict_equal(dict_T *d1, dict_T *d2, int ic, int recursive);
void dict_list(typval_T *argvars, typval_T *rettv, int what); void dict_list(typval_T *argvars, typval_T *rettv, int what);
void dict_set_items_ro(dict_T *di);
/* vim: set ft=c : */ /* vim: set ft=c : */

View File

@@ -64,6 +64,7 @@ void set_vim_var_nr(int idx, varnumber_T val);
varnumber_T get_vim_var_nr(int idx); varnumber_T get_vim_var_nr(int idx);
char_u *get_vim_var_str(int idx); char_u *get_vim_var_str(int idx);
list_T *get_vim_var_list(int idx); list_T *get_vim_var_list(int idx);
dict_T * get_vim_var_dict(int idx);
void set_vim_var_char(int c); void set_vim_var_char(int c);
void set_vcount(long count, long count1, int set_prevcount); void set_vcount(long count, long count1, int set_prevcount);
void set_vim_var_string(int idx, char_u *val, int len); void set_vim_var_string(int idx, char_u *val, int len);

View File

@@ -51,6 +51,7 @@ int has_textchangedI(void);
int has_insertcharpre(void); int has_insertcharpre(void);
int has_cmdundefined(void); int has_cmdundefined(void);
int has_funcundefined(void); int has_funcundefined(void);
int has_textyankpost(void);
void block_autocmds(void); void block_autocmds(void);
void unblock_autocmds(void); void unblock_autocmds(void);
int is_autocmd_blocked(void); int is_autocmd_blocked(void);

View File

@@ -4863,17 +4863,35 @@ 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 (dict_find(what, (char_u *)"all", -1) != NULL)
if (qi == NULL || qi->qf_listcount == 0) flags |= QF_GETLIST_ALL;
{
/* 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;
}
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;
if (dict_find(what, (char_u *)"idx", -1) != NULL)
flags |= QF_GETLIST_IDX;
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 */ qf_idx = qi->qf_curlist; /* default is the current list */
if ((di = dict_find(what, (char_u *)"nr", -1)) != NULL) if ((di = dict_find(what, (char_u *)"nr", -1)) != NULL)
{ {
@@ -4885,7 +4903,7 @@ qf_get_properties(win_T *wp, dict_T *what, dict_T *retdict)
{ {
qf_idx = di->di_tv.vval.v_number - 1; qf_idx = di->di_tv.vval.v_number - 1;
if (qf_idx < 0 || qf_idx >= qi->qf_listcount) if (qf_idx < 0 || qf_idx >= qi->qf_listcount)
return FAIL; qf_idx = -1;
} }
} }
else if ((di->di_tv.v_type == VAR_STRING) else if ((di->di_tv.v_type == VAR_STRING)
@@ -4893,7 +4911,7 @@ qf_get_properties(win_T *wp, dict_T *what, dict_T *retdict)
/* Get the last quickfix list number */ /* Get the last quickfix list number */
qf_idx = qi->qf_listcount - 1; qf_idx = qi->qf_listcount - 1;
else else
return FAIL; qf_idx = -1;
flags |= QF_GETLIST_NR; flags |= QF_GETLIST_NR;
} }
@@ -4902,39 +4920,46 @@ qf_get_properties(win_T *wp, dict_T *what, dict_T *retdict)
/* Look for a list with the specified id */ /* Look for a list with the specified id */
if (di->di_tv.v_type == VAR_NUMBER) if (di->di_tv.v_type == VAR_NUMBER)
{ {
/* For zero, use the current list or the list specifed by 'nr' */ /*
* For zero, use the current list or the list specifed by 'nr'
*/
if (di->di_tv.vval.v_number != 0) if (di->di_tv.vval.v_number != 0)
{
qf_idx = qf_id2nr(qi, di->di_tv.vval.v_number); qf_idx = qf_id2nr(qi, di->di_tv.vval.v_number);
if (qf_idx == -1)
return FAIL; /* List not found */
}
flags |= QF_GETLIST_ID; flags |= QF_GETLIST_ID;
} }
else else
return FAIL; qf_idx = -1;
}
} }
if (dict_find(what, (char_u *)"all", -1) != NULL) /* List is not present or is empty */
flags |= QF_GETLIST_ALL; 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);
if (dict_find(what, (char_u *)"title", -1) != NULL) return status;
flags |= QF_GETLIST_TITLE; }
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 *)"items", -1) != NULL)
flags |= QF_GETLIST_ITEMS;
if (dict_find(what, (char_u *)"idx", -1) != NULL)
flags |= QF_GETLIST_IDX;
if (dict_find(what, (char_u *)"size", -1) != NULL)
flags |= QF_GETLIST_SIZE;
if (flags & QF_GETLIST_TITLE) if (flags & QF_GETLIST_TITLE)
{ {
@@ -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

@@ -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

@@ -1124,3 +1124,42 @@ func Test_Filter_noshelltemp()
let &shelltemp = shelltemp let &shelltemp = shelltemp
bwipe! bwipe!
endfunc endfunc
func Test_TextYankPost()
enew!
call setline(1, ['foo'])
let g:event = []
au TextYankPost * let g:event = copy(v:event)
call assert_equal({}, v:event)
call assert_fails('let v:event = {}', 'E46:')
call assert_fails('let v:event.mykey = 0', 'E742:')
norm "ayiw
call assert_equal(
\{'regcontents': ['foo'], 'regname': 'a', 'operator': 'y', 'regtype': 'v'},
\g:event)
norm y_
call assert_equal(
\{'regcontents': ['foo'], 'regname': '', 'operator': 'y', 'regtype': 'V'},
\g:event)
call feedkeys("\<C-V>y", 'x')
call assert_equal(
\{'regcontents': ['f'], 'regname': '', 'operator': 'y', 'regtype': "\x161"},
\g:event)
norm "xciwbar
call assert_equal(
\{'regcontents': ['foo'], 'regname': 'x', 'operator': 'c', 'regtype': 'v'},
\g:event)
norm "bdiw
call assert_equal(
\{'regcontents': ['bar'], 'regname': 'b', 'operator': 'd', 'regtype': 'v'},
\g:event)
call assert_equal({}, v:event)
au! TextYankPost
unlet g:event
bwipe!
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

@@ -103,6 +103,10 @@ func Test_json_encode()
call assert_fails('echo json_encode(function("tr"))', 'E474:') call assert_fails('echo json_encode(function("tr"))', 'E474:')
call assert_fails('echo json_encode([function("tr")])', 'E474:') call assert_fails('echo json_encode([function("tr")])', 'E474:')
call assert_equal('{"a":""}', json_encode({'a': test_null_string()}))
call assert_equal('{"a":[]}', json_encode({"a": test_null_list()}))
call assert_equal('{"a":{}}', json_encode({"a": test_null_dict()}))
silent! let res = json_encode(function("tr")) silent! let res = json_encode(function("tr"))
call assert_equal("", res) call assert_equal("", res)
endfunc 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

@@ -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 */
/**/
1396,
/**/
1395,
/**/
1394,
/**/
1393,
/**/
1392,
/**/
1391,
/**/
1390,
/**/
1389,
/**/
1388,
/**/
1387,
/**/
1386,
/**/
1385,
/**/
1384,
/**/ /**/
1383, 1383,
/**/ /**/

View File

@@ -1339,6 +1339,7 @@ enum auto_event
EVENT_TEXTCHANGEDI, /* text was modified in Insert mode*/ EVENT_TEXTCHANGEDI, /* text was modified in Insert mode*/
EVENT_CMDUNDEFINED, /* command undefined */ EVENT_CMDUNDEFINED, /* command undefined */
EVENT_OPTIONSET, /* option was set */ EVENT_OPTIONSET, /* option was set */
EVENT_TEXTYANKPOST, /* after some text was yanked */
NUM_EVENTS /* MUST be the last one */ NUM_EVENTS /* MUST be the last one */
}; };
@@ -1988,7 +1989,8 @@ typedef int sock_T;
#define VV_TERMU7RESP 83 #define VV_TERMU7RESP 83
#define VV_TERMSTYLERESP 84 #define VV_TERMSTYLERESP 84
#define VV_TERMBLINKRESP 85 #define VV_TERMBLINKRESP 85
#define VV_LEN 86 /* number of v: vars */ #define VV_EVENT 86
#define VV_LEN 87 /* number of v: vars */
/* used for v_number in VAR_SPECIAL */ /* used for v_number in VAR_SPECIAL */
#define VVAL_FALSE 0L #define VVAL_FALSE 0L