mirror of
https://github.com/macvim-dev/macvim.git
synced 2026-06-02 11:19:22 +02:00
Compare commits
48 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 220f000f59 | |||
| 9c4147192a | |||
| 1d669c233c | |||
| ee142add22 | |||
| e32abbe42c | |||
| 8b2f19536f | |||
| 872004132f | |||
| 08243d26d2 | |||
| 03c60c1573 | |||
| f446b48ff0 | |||
| caa55b65c2 | |||
| 68563937f5 | |||
| 8be81c4e3b | |||
| 6abda995a5 | |||
| 009c7b2640 | |||
| 4d0504019c | |||
| acc11d1692 | |||
| de33011ec6 | |||
| c695cec469 | |||
| 6247361101 | |||
| 2d02839050 | |||
| 453b576ee5 | |||
| a216255a4f | |||
| 31f19ce0a0 | |||
| 9d9c356517 | |||
| 04e94c7881 | |||
| 12c4492dd3 | |||
| 386ade3ae2 | |||
| 7069bf18e1 | |||
| cbd4de44e8 | |||
| c6aa475a27 | |||
| 1b14651629 | |||
| 6e450a5754 | |||
| 287266527a | |||
| 29891c4ed4 | |||
| aaeabfbca5 | |||
| 14a612fa2e | |||
| 7034a83743 | |||
| a4ce25bd98 | |||
| 294740d2ac | |||
| 9269315f63 | |||
| f845b87f2b | |||
| 4374735576 | |||
| 1e3514c02e | |||
| 8133aa23f0 | |||
| 290ed88c0b | |||
| f9ed667087 | |||
| 263115a528 |
@@ -1,4 +1,4 @@
|
||||
*develop.txt* For Vim version 8.0. Last change: 2016 Jan 31
|
||||
*develop.txt* For Vim version 8.0. Last change: 2017 Jan 05
|
||||
|
||||
|
||||
VIM REFERENCE MANUAL by Bram Moolenaar
|
||||
@@ -177,7 +177,7 @@ The basic steps to make changes to the code:
|
||||
5. Make a patch with "git diff". You can also create a pull request on
|
||||
github, but it's the diff that matters.
|
||||
6. Make a note about what changed, preferably mentioning the problem and the
|
||||
solution. Send an email to the vim-dev maillist with an explanation and
|
||||
solution. Send an email to the |vim-dev| maillist with an explanation and
|
||||
include the diff. Or create a pull request on github.
|
||||
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
*eval.txt* For Vim version 8.0. Last change: 2016 Nov 29
|
||||
*eval.txt* For Vim version 8.0. Last change: 2017 Jan 08
|
||||
|
||||
|
||||
VIM REFERENCE MANUAL by Bram Moolenaar
|
||||
@@ -5229,6 +5229,7 @@ join({list} [, {sep}]) *join()*
|
||||
js_decode({string}) *js_decode()*
|
||||
This is similar to |json_decode()| with these differences:
|
||||
- Object key names do not have to be in quotes.
|
||||
- Strings can be in single quotes.
|
||||
- Empty items in an array (between two commas) are allowed and
|
||||
result in v:none items.
|
||||
|
||||
@@ -7561,7 +7562,11 @@ system({expr} [, {input}]) *system()* *E677*
|
||||
If {input} is given and is a |List| it is written to the file
|
||||
in a way |writefile()| does with {binary} set to "b" (i.e.
|
||||
with a newline between each list item with newlines inside
|
||||
list items converted to NULs).
|
||||
list items converted to NULs).
|
||||
When {input} is given and is a number that is a valid id for
|
||||
an existing buffer then the content of the buffer is written
|
||||
to the file line by line, each line terminated by a NL and
|
||||
NULs characters where the text has a NL.
|
||||
|
||||
Pipes are not used, the 'shelltemp' option is not used.
|
||||
|
||||
@@ -7611,7 +7616,8 @@ systemlist({expr} [, {input}]) *systemlist()*
|
||||
Same as |system()|, but returns a |List| with lines (parts of
|
||||
output separated by NL) with NULs transformed into NLs. Output
|
||||
is the same as |readfile()| will output with {binary} argument
|
||||
set to "b".
|
||||
set to "b". Note that on MS-Windows you may get trailing CR
|
||||
characters.
|
||||
|
||||
Returns an empty string on error.
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
*filetype.txt* For Vim version 8.0. Last change: 2016 Sep 09
|
||||
*filetype.txt* For Vim version 8.0. Last change: 2017 Jan 04
|
||||
|
||||
|
||||
VIM REFERENCE MANUAL by Bram Moolenaar
|
||||
@@ -573,6 +573,8 @@ Man {number} {name}
|
||||
|
||||
Global mapping:
|
||||
<Leader>K Displays the manual page for the word under the cursor.
|
||||
<Plug>ManPreGetPage idem, allows for using a mapping: >
|
||||
nmap <F1> <Plug>ManPreGetPage<CR>
|
||||
|
||||
Local mappings:
|
||||
CTRL-] Jump to the manual page for the word under the cursor.
|
||||
|
||||
@@ -96,21 +96,18 @@ mention that.
|
||||
|
||||
*mail-list* *maillist*
|
||||
There are several mailing lists for Vim:
|
||||
<vim@vim.org>
|
||||
<vim@vim.org> *vim-use* *vim_use*
|
||||
For discussions about using existing versions of Vim: Useful mappings,
|
||||
questions, answers, where to get a specific version, etc. There are
|
||||
quite a few people watching this list and answering questions, also
|
||||
for beginners. Don't hesitate to ask your question here.
|
||||
<vim-dev@vim.org> *vim-dev* *vimdev*
|
||||
<vim-dev@vim.org> *vim-dev* *vim_dev* *vimdev*
|
||||
For discussions about changing Vim: New features, porting, patches,
|
||||
beta-test versions, etc.
|
||||
<vim-announce@vim.org> *vim-announce*
|
||||
<vim-announce@vim.org> *vim-announce* *vim_announce*
|
||||
Announcements about new versions of Vim; also for beta-test versions
|
||||
and ports to different systems. This is a read-only list.
|
||||
<vim-multibyte@vim.org> *vim-multibyte*
|
||||
For discussions about using and improving the multi-byte aspects of
|
||||
Vim.
|
||||
<vim-mac@vim.org> *vim-mac*
|
||||
<vim-mac@vim.org> *vim-mac* *vim_mac*
|
||||
For discussions about using and improving the Macintosh version of
|
||||
Vim.
|
||||
|
||||
|
||||
+4
-1
@@ -9220,16 +9220,19 @@ vim-dev intro.txt /*vim-dev*
|
||||
vim-mac intro.txt /*vim-mac*
|
||||
vim-modes intro.txt /*vim-modes*
|
||||
vim-modes-intro intro.txt /*vim-modes-intro*
|
||||
vim-multibyte intro.txt /*vim-multibyte*
|
||||
vim-script-intro usr_41.txt /*vim-script-intro*
|
||||
vim-use intro.txt /*vim-use*
|
||||
vim-variable eval.txt /*vim-variable*
|
||||
vim.vim syntax.txt /*vim.vim*
|
||||
vim7 version7.txt /*vim7*
|
||||
vim8 version8.txt /*vim8*
|
||||
vim: options.txt /*vim:*
|
||||
vim_announce intro.txt /*vim_announce*
|
||||
vim_dev intro.txt /*vim_dev*
|
||||
vim_did_enter-variable eval.txt /*vim_did_enter-variable*
|
||||
vim_mac gui_mac.txt /*vim_mac*
|
||||
vim_starting eval.txt /*vim_starting*
|
||||
vim_use intro.txt /*vim_use*
|
||||
vimball pi_vimball.txt /*vimball*
|
||||
vimball-contents pi_vimball.txt /*vimball-contents*
|
||||
vimball-extract pi_vimball.txt /*vimball-extract*
|
||||
|
||||
+39
-41
@@ -1,4 +1,4 @@
|
||||
*todo.txt* For Vim version 8.0. Last change: 2017 Jan 02
|
||||
*todo.txt* For Vim version 8.0. Last change: 2017 Jan 09
|
||||
|
||||
|
||||
VIM REFERENCE MANUAL by Bram Moolenaar
|
||||
@@ -29,8 +29,8 @@ be worked on, but only if you sponsor Vim development. See |sponsor|.
|
||||
|
||||
Issues can also be entered online: https://github.com/vim/vim/issues
|
||||
Only use this for bug reports, not for questions! Those belong on the
|
||||
maillist. Updates will be forwarded to the vim_dev maillist. Issues entered
|
||||
there will not be repeated below, unless there is extra information.
|
||||
maillist. Updates will be forwarded to the |vim_dev| maillist. Issues
|
||||
entered there will not be repeated below, unless there is extra information.
|
||||
|
||||
*known-bugs*
|
||||
-------------------- Known bugs and current work -----------------------
|
||||
@@ -109,11 +109,6 @@ Regexp problems:
|
||||
Make html indent file use javascript indent, now that it's not just cindent.
|
||||
#1220
|
||||
|
||||
Patch to fix completion of :filter command. (Ichizok, 2016 Dec 3, #1299)
|
||||
|
||||
Patch to use buffer id for system() and systemlist() (LemonBoy, 2016 Nov 7,
|
||||
#1240)
|
||||
|
||||
Concatenation with null string causes an error: 'a'[1:0] .. 'b'
|
||||
Might as well handle it like an empty string.
|
||||
|
||||
@@ -123,27 +118,12 @@ position in 'runtimepath'. (Dugan Chen, 2016 Nov 18)
|
||||
json_encode(): should convert to utf-8. (Nikolai Pavlov, 2016 Jan 23)
|
||||
What if there is an invalid character?
|
||||
|
||||
Putting "k" early in 'complete' does not use dictionary first?
|
||||
(RubenGZ, 2016 Dec 10, #1316)
|
||||
patch proposed by Hirohito Higashi, 2016 Dec 11.
|
||||
Include rust files. (Klabnik, #1356)
|
||||
|
||||
Patch to fix NULL pointer when sorting zero elements. (Dominique, 2016 Dec 15)
|
||||
|
||||
Patch to test float functions. (Dominique, 2016 Dec 16)
|
||||
|
||||
Patch to improve completion of :syntax command. (Dominique, 2016 Dec 12)
|
||||
|
||||
Patch to use IEMSG() in more places. (Dominique, 2016 Dec 27)
|
||||
More float tests. (Dominique, #1364)
|
||||
|
||||
Patch to avoid ubsan warning for integer overflow. (Dominique, 2016 Dec 26)
|
||||
|
||||
Bug: ":earlier 100d" doesn't work after using undo file.
|
||||
(Pavol Juhas, 2016 Nov 15, #1254)
|
||||
Fix by Christian, but lacks a test.
|
||||
Test in testdir/test_undo.vim doesn't catch the problem.
|
||||
Test by Pavol Juhas, Nov 22.
|
||||
Patch with test (Pavol Juhas,, 2016 Dec 3, #1300)
|
||||
|
||||
Bug: Json with same key should not give internal error. (Lcd, 2016 Oct 26)
|
||||
Make dict_add give a duplicate key error.
|
||||
|
||||
@@ -166,11 +146,16 @@ Patch to deal with changed configure events in GTK 3. (Jan Alexander Steffens,
|
||||
2016 Oct 23 #1193)
|
||||
Remarks from nuko8, 2016 Nov 2.
|
||||
|
||||
Multi-byte bug: dv} splits char. (Urtica Dioica, 2017 Jan 9)
|
||||
|
||||
Patch to change order of compiler flags. (Yousong Zhou, 2016 Sep 19, #1100)
|
||||
|
||||
Patch to add command line completion for :cexpr commands. (Yegappan
|
||||
Lakshmanan, 2016 Dec 13)
|
||||
|
||||
Patch for :pyx, run python commands depending on the supported version.
|
||||
(Marc Weber, update from Ken Takata, 2016 Sep 19, 2017 Jan 6)
|
||||
|
||||
Patch to avoid warnings for overflow. (Mike Williams, 2016 Dec 16)
|
||||
Update Dec 19.
|
||||
|
||||
@@ -195,6 +180,9 @@ https://github.com/neovim/neovim/pull/5737#issuecomment-266055165
|
||||
Patch for better explanation of 'compatible' side effects.
|
||||
https://github.com/vim/vim/pull/1161/files
|
||||
|
||||
Patch to add 'makeencoding', useful when the system encoding differs from
|
||||
Vim's 'encoding' setting. (Ken Takata, 2017 Jan 6)
|
||||
|
||||
Patch to adjust marks when adding a new line to the end of buffer in diff
|
||||
mode. (James McCoy, 2016 Dec 14, #1329)
|
||||
|
||||
@@ -240,6 +228,9 @@ Add tests for using number larger than number of lines in buffer.
|
||||
Patch to make v:shell_error writable. (Christian Brabandt, 2016 Sep 27)
|
||||
Useful to restore it. Is there another solution?
|
||||
|
||||
"ci[" does not look for next [ like ci" does look for next ".
|
||||
(J.F. 2017 Jan 7)
|
||||
|
||||
On MS-Windows with 'clipboard' set to "unnamed" this doesn't work to double
|
||||
lines: :g/^/normal yyp On Unix it works OK. (Bryce Orgill, 2016 Nov 5)
|
||||
|
||||
@@ -248,6 +239,10 @@ Patch for wrong cursor position on wrapped line, involving breakindent.
|
||||
|
||||
Patch for 'cursorlinenr' option. (Ozaki Kiichi, 2016 Nov 30)
|
||||
|
||||
When adding an item to a new quickfix list make ":cnext" jump to that item.
|
||||
Make a difference being at the first item and not having used :cnext at all.
|
||||
(Afanasiy Fet, 2017 Jan 3)
|
||||
|
||||
Invalid behavior with NULL list. (Nikolai Pavlov, #768)
|
||||
E.g. deepcopy(test_null_list())
|
||||
|
||||
@@ -280,6 +275,9 @@ sort() is not stable when using numeric/float sort (Nikolay Pavlov, 2016 Sep
|
||||
|
||||
Patch to add "cmdline" completion to getcompletion(). (Shougo, Oct 1, #1140)
|
||||
|
||||
Feature request: Complete members of a dictionary. (Luc Hermitte, 2017 Jan 4,
|
||||
#1350)
|
||||
|
||||
Patch for systemlist(), add empty item. (thinca, Sep 30, #1135)
|
||||
Add an argument to choose binary or non-binary (like readfile()), when omitted
|
||||
use the current behavior.
|
||||
@@ -307,9 +305,6 @@ Patch to order results from taglist(). (Duncan McDougall, 2016 Oct 25)
|
||||
patch for 'spellcamelcase' option: spellcheck each CamelCased word.
|
||||
(Ben Tucker, 2016 Dec 2)
|
||||
|
||||
Patch for :pyx, run python commands depending on the supported version.
|
||||
(Marc Weber, update from Ken Takata, 2016 Sep 19)
|
||||
|
||||
When using ":diffput" through a mapping, undo in the target buffer isn't
|
||||
synced. (Ryan Carney, 2016 Sep 14)
|
||||
|
||||
@@ -333,6 +328,19 @@ Jul 25, #948)
|
||||
Patch to fix wrong encoding of error message on Cygwin/MSYS terminal.
|
||||
(Ken Takata, 2016 Oct 4)
|
||||
|
||||
Patch to introduce 'cmdencoding'. (Ken Takata, Aug 18?)
|
||||
Better help Aug 19.
|
||||
Problem: applies to too many commands, such as :cbuffer.
|
||||
Updated patch with three options, 2016 Sep 8.
|
||||
Win32: When running ":make" and 'encoding' differs from the system locale,
|
||||
the output should be converted. Esp. when 'encoding' is "utf-8". (Yongwei
|
||||
Wu) Should we use 'termencoding' for this?
|
||||
|
||||
Patch to add 'systemencoding', convert between 'encoding' and this for file
|
||||
names, shell commands and the like. (Kikuchan, 2010 Oct 14)
|
||||
Assume the system converts between the actual encoding of the filesystem to
|
||||
the system encoding (usually utf-8).
|
||||
|
||||
'hlsearch' interferes with a Conceal match. (Rom Grk, 2016 Aug 9)
|
||||
|
||||
Patch to add context information to quickfix/location list. (Yegappan
|
||||
@@ -467,14 +475,6 @@ Should use /usr/local/share/applications or /usr/share/applications.
|
||||
Or use $XDG_DATA_DIRS.
|
||||
Also need to run update-desktop-database (Kuriyama Kazunobu, 2015 Nov 4)
|
||||
|
||||
Patch to introduce 'cmdencoding'. (Ken Takata, Aug 18?)
|
||||
Better help Aug 19.
|
||||
Problem: applies to too many commands, such as :cbuffer.
|
||||
Updated patch with three options, 2016 Sep 8.
|
||||
Win32: When running ":make" and 'encoding' differs from the system locale,
|
||||
the output should be converted. Esp. when 'encoding' is "utf-8". (Yongwei
|
||||
Wu) Should we use 'termencoding' for this?
|
||||
|
||||
Patch to have text objects defined by arbitrary single characters. (Daniel
|
||||
Thau, 2013 Nov 20, 2014 Jan 29, 2014 Jan 31)
|
||||
Added tests (James McCoy, 2016 Aug 3). Still needs more work.
|
||||
@@ -488,6 +488,9 @@ Access to uninitialized memory in match_backref() regexp_nda.c:4882
|
||||
":cd C:\Windows\System32\drivers\etc*" does not work, even though the
|
||||
directory exists. (Sergio Gallelli, 2013 Dec 29)
|
||||
|
||||
In debug mode one can inspect variables, but not the function parameters
|
||||
(starting with a:). (Luc Hermitte, 2017 Jan 4, #1352)
|
||||
|
||||
7 Add a watchpoint in the debug mode: An expression that breaks execution
|
||||
when evaluating to non-zero. Add the "watchadd expr" command, stop when
|
||||
the value of the expression changes. ":watchdel" deletes an item,
|
||||
@@ -1355,11 +1358,6 @@ Regexp engine performance:
|
||||
7.2.274. (Christian Brabandt, 2010 May 27) Generally, folding with
|
||||
'foldmethod' set to "syntax" is slow. Do profiling to find out why.
|
||||
|
||||
Patch to add 'systemencoding', convert between 'encoding' and this for file
|
||||
names, shell commands and the like. (Kikuchan, 2010 Oct 14)
|
||||
Assume the system converts between the actual encoding of the filesystem to
|
||||
the system encoding (usually utf-8).
|
||||
|
||||
Problem producing tags file when hebrew.frx is present. It has a BOM.
|
||||
Results in E670. (Tony Mechelynck, 2010 May 2)
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
" Vim support file to detect file types
|
||||
"
|
||||
" Maintainer: Bram Moolenaar <Bram@vim.org>
|
||||
" Last Change: 2016 Oct 31
|
||||
" Last Change: 2017 Jan 06
|
||||
|
||||
" Listen very carefully, I will say this only once
|
||||
if exists("did_load_filetypes")
|
||||
@@ -309,7 +309,10 @@ au BufNewFile,BufRead *.bl setf blank
|
||||
au BufNewFile,BufRead */etc/blkid.tab,*/etc/blkid.tab.old setf xml
|
||||
|
||||
" Bazel (http://bazel.io)
|
||||
autocmd BufRead,BufNewFile *.bzl,BUILD,WORKSPACE setfiletype bzl
|
||||
autocmd BufRead,BufNewFile *.bzl,WORKSPACE setfiletype bzl
|
||||
if has("fname_case")
|
||||
autocmd BufRead,BufNewFile BUILD setfiletype bzl
|
||||
endif
|
||||
|
||||
" C or lpc
|
||||
au BufNewFile,BufRead *.c call s:FTlpc()
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
" Vim filetype plugin file
|
||||
" Language: man
|
||||
" Maintainer: SungHyun Nam <goweol@gmail.com>
|
||||
" Last Change: 2016 Jun 20
|
||||
" Last Change: 2017 Jan 04
|
||||
|
||||
" To make the ":Man" command available before editing a manual page, source
|
||||
" this script from your startup vimrc file.
|
||||
@@ -47,6 +47,7 @@ endif
|
||||
if exists(":Man") != 2
|
||||
com -nargs=+ Man call s:GetPage(<f-args>)
|
||||
nmap <Leader>K :call <SID>PreGetPage(0)<CR>
|
||||
nmap <Plug>ManPreGetPage :call <SID>PreGetPage(0)<CR>
|
||||
endif
|
||||
|
||||
" Define functions only once.
|
||||
|
||||
+283
-113
@@ -2,7 +2,7 @@
|
||||
" Language: Javascript
|
||||
" Maintainer: Chris Paul ( https://github.com/bounceme )
|
||||
" URL: https://github.com/pangloss/vim-javascript
|
||||
" Last Change: August 25, 2016
|
||||
" Last Change: December 31, 2016
|
||||
|
||||
" Only load this indent file when no other was loaded.
|
||||
if exists('b:did_indent')
|
||||
@@ -12,11 +12,10 @@ let b:did_indent = 1
|
||||
|
||||
" Now, set up our indentation expression and keys that trigger it.
|
||||
setlocal indentexpr=GetJavascriptIndent()
|
||||
setlocal nolisp noautoindent nosmartindent
|
||||
setlocal indentkeys=0{,0},0),0],:,!^F,o,O,e
|
||||
setlocal cinoptions+=j1,J1
|
||||
setlocal autoindent nolisp nosmartindent
|
||||
setlocal indentkeys+=0],0)
|
||||
|
||||
let b:undo_indent = 'setlocal indentexpr< smartindent< autoindent< indentkeys< cinoptions<'
|
||||
let b:undo_indent = 'setlocal indentexpr< smartindent< autoindent< indentkeys<'
|
||||
|
||||
" Only define the function once.
|
||||
if exists('*GetJavascriptIndent')
|
||||
@@ -37,158 +36,329 @@ else
|
||||
endfunction
|
||||
endif
|
||||
|
||||
let s:line_pre = '^\s*\%(\%(\%(\/\*.\{-}\)\=\*\+\/\s*\)\=\)\@>'
|
||||
let s:expr_case = s:line_pre . '\%(\%(case\>.\+\)\|default\)\s*:'
|
||||
" searchpair() wrapper
|
||||
if has('reltime')
|
||||
function s:GetPair(start,end,flags,skip,time,...)
|
||||
return searchpair('\m'.a:start,'','\m'.a:end,a:flags,a:skip,max([prevnonblank(v:lnum) - 2000,0] + a:000),a:time)
|
||||
endfunction
|
||||
else
|
||||
function s:GetPair(start,end,flags,skip,...)
|
||||
return searchpair('\m'.a:start,'','\m'.a:end,a:flags,a:skip,max([prevnonblank(v:lnum) - 1000,get(a:000,1)]))
|
||||
endfunction
|
||||
endif
|
||||
|
||||
" Regex of syntax group names that are or delimit string or are comments.
|
||||
let s:syng_strcom = '\%(s\%(tring\|pecial\)\|comment\|regex\|doc\|template\)'
|
||||
|
||||
" Regex of syntax group names that are strings or documentation.
|
||||
let s:syng_comment = '\%(comment\|doc\)'
|
||||
|
||||
let s:syng_strcom = 'string\|comment\|regex\|special\|doc\|template'
|
||||
let s:syng_str = 'string\|template'
|
||||
let s:syng_com = 'comment\|doc'
|
||||
" Expression used to check whether we should skip a match with searchpair().
|
||||
let s:skip_expr = "synIDattr(synID(line('.'),col('.'),0),'name') =~? '".s:syng_strcom."'"
|
||||
|
||||
if has('reltime')
|
||||
function s:GetPair(start,end,flags,time)
|
||||
return searchpair(a:start,'',a:end,a:flags,s:skip_expr,max([prevnonblank(v:lnum) - 2000,0]),a:time)
|
||||
endfunction
|
||||
else
|
||||
function s:GetPair(start,end,flags,n)
|
||||
return searchpair(a:start,'',a:end,a:flags,0,max([prevnonblank(v:lnum) - 2000,0]))
|
||||
endfunction
|
||||
endif
|
||||
function s:skip_func()
|
||||
if !s:free || search('\m`\|\*\/','nW',s:looksyn)
|
||||
let s:free = !eval(s:skip_expr)
|
||||
let s:looksyn = s:free ? line('.') : s:looksyn
|
||||
return !s:free
|
||||
endif
|
||||
let s:looksyn = line('.')
|
||||
return (search('\m\/','nbW',s:looksyn) || search('\m[''"]\|\\$','nW',s:looksyn)) && eval(s:skip_expr)
|
||||
endfunction
|
||||
|
||||
let s:line_term = '\s*\%(\%(\/\%(\%(\*.\{-}\*\/\)\|\%(\*\+\)\)\)\s*\)\=$'
|
||||
function s:alternatePair(stop)
|
||||
let pos = getpos('.')[1:2]
|
||||
while search('\m[][(){}]','bW',a:stop)
|
||||
if !s:skip_func()
|
||||
let idx = stridx('])}',s:looking_at())
|
||||
if idx + 1
|
||||
if !s:GetPair(['\[','(','{'][idx], '])}'[idx],'bW','s:skip_func()',2000,a:stop)
|
||||
break
|
||||
endif
|
||||
else
|
||||
return
|
||||
endif
|
||||
endif
|
||||
endwhile
|
||||
call call('cursor',pos)
|
||||
endfunction
|
||||
|
||||
function s:save_pos(f,...)
|
||||
let l:pos = getpos('.')[1:2]
|
||||
let ret = call(a:f,a:000)
|
||||
call call('cursor',l:pos)
|
||||
return ret
|
||||
endfunction
|
||||
|
||||
function s:syn_at(l,c)
|
||||
return synIDattr(synID(a:l,a:c,0),'name')
|
||||
endfunction
|
||||
|
||||
function s:looking_at()
|
||||
return getline('.')[col('.')-1]
|
||||
endfunction
|
||||
|
||||
function s:token()
|
||||
return s:looking_at() =~ '\k' ? expand('<cword>') : s:looking_at()
|
||||
endfunction
|
||||
|
||||
function s:b_token()
|
||||
if s:looking_at() =~ '\k'
|
||||
call search('\m\<','cbW')
|
||||
endif
|
||||
return search('\m\S','bW')
|
||||
endfunction
|
||||
|
||||
function s:previous_token()
|
||||
let l:n = line('.')
|
||||
while s:b_token()
|
||||
if (s:looking_at() == '/' || line('.') != l:n && search('\m\/\/','nbW',
|
||||
\ line('.'))) && s:syn_at(line('.'),col('.')) =~? s:syng_com
|
||||
call search('\m\_[^/]\zs\/[/*]','bW')
|
||||
else
|
||||
return s:token()
|
||||
endif
|
||||
endwhile
|
||||
return ''
|
||||
endfunction
|
||||
|
||||
function s:others(p)
|
||||
return "((line2byte(line('.')) + col('.')) <= ".(line2byte(a:p[0]) + a:p[1]).") || ".s:skip_expr
|
||||
endfunction
|
||||
|
||||
function s:tern_skip(p)
|
||||
return s:GetPair('{','}','nbW',s:others(a:p),200,a:p[0]) > 0
|
||||
endfunction
|
||||
|
||||
function s:tern_col(p)
|
||||
return s:GetPair('?',':\@<!::\@!','nbW',s:others(a:p)
|
||||
\ .' || s:tern_skip('.string(a:p).')',200,a:p[0]) > 0
|
||||
endfunction
|
||||
|
||||
function s:label_col()
|
||||
let pos = getpos('.')[1:2]
|
||||
let [s:looksyn,s:free] = pos
|
||||
call s:alternatePair(0)
|
||||
if s:save_pos('s:IsBlock')
|
||||
let poss = getpos('.')[1:2]
|
||||
return call('cursor',pos) || !s:tern_col(poss)
|
||||
elseif s:looking_at() == ':'
|
||||
return !s:tern_col([0,0])
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" configurable regexes that define continuation lines, not including (, {, or [.
|
||||
if !exists('g:javascript_opfirst')
|
||||
let g:javascript_opfirst = '\%([<>,:?^%|*&]\|\/[^/*]\|\([-.+]\)\1\@!\|=>\@!\|in\%(stanceof\)\=\>\)'
|
||||
endif
|
||||
if !exists('g:javascript_continuation')
|
||||
let g:javascript_continuation = '\%([<=,.?/*:^%|&]\|+\@<!+\|-\@<!-\|=\@<!>\|\<in\%(stanceof\)\=\)'
|
||||
endif
|
||||
let s:opfirst = '^' . get(g:,'javascript_opfirst',
|
||||
\ '\%([<>=,?^%|*/&]\|\([-.:+]\)\1\@!\|!=\|in\%(stanceof\)\=\>\)')
|
||||
let s:continuation = get(g:,'javascript_continuation',
|
||||
\ '\%([<=,.~!?/*^%|&:]\|+\@<!+\|-\@<!-\|=\@<!>\|\<\%(typeof\|delete\|void\|in\|instanceof\)\)') . '$'
|
||||
|
||||
let g:javascript_opfirst = s:line_pre . g:javascript_opfirst
|
||||
let g:javascript_continuation .= s:line_term
|
||||
|
||||
function s:OneScope(lnum,text,add)
|
||||
return a:text =~# '\%(\<else\|\<do\|=>\)' . s:line_term ? 'no b' :
|
||||
\ ((a:add && a:text =~ s:line_pre . '$' && search('\%' . s:PrevCodeLine(a:lnum - 1) . 'l.)' . s:line_term)) ||
|
||||
\ cursor(a:lnum, match(a:text, ')' . s:line_term)) > -1) &&
|
||||
\ s:GetPair('(', ')', 'cbW', 100) > 0 && search('\C\l\+\_s*\%#','bW') &&
|
||||
\ (a:add || ((expand('<cword>') !=# 'while' || !s:GetPair('\C\<do\>', '\C\<while\>','nbW',100)) &&
|
||||
\ (expand('<cword>') !=# 'each' || search('\C\<for\_s\+\%#','nbW')))) ? expand('<cword>') : ''
|
||||
function s:continues(ln,con)
|
||||
return !cursor(a:ln, match(' '.a:con,s:continuation)) &&
|
||||
\ eval((['s:syn_at(line("."),col(".")) !~? "regex"'] +
|
||||
\ repeat(['s:previous_token() != "."'],5) + [1])[
|
||||
\ index(split('/ typeof in instanceof void delete'),s:token())])
|
||||
endfunction
|
||||
|
||||
" https://github.com/sweet-js/sweet.js/wiki/design#give-lookbehind-to-the-reader
|
||||
function s:IsBlock()
|
||||
return getline(line('.'))[col('.')-1] == '{' && !search(
|
||||
\ '\C\%(\<return\s*\|\%([-=~!<*+,.?^%|&\[(]\|=\@<!>\|\*\@<!\/\|\<\%(var\|const\|let\|import\|export\%(\_s\+default\)\=\|yield\|delete\|void\|t\%(ypeof\|hrow\)\|new\|in\%(stanceof\)\=\)\)\_s*\)\%#','bnW') &&
|
||||
\ (!search(':\_s*\%#','bW') || (!s:GetPair('[({[]','[])}]','bW',200) || s:IsBlock()))
|
||||
" get the line of code stripped of comments and move cursor to the last
|
||||
" non-comment char.
|
||||
function s:Trim(ln)
|
||||
let pline = substitute(getline(a:ln),'\s*$','','')
|
||||
let l:max = max([match(pline,'.*[^/]\zs\/[/*]'),0])
|
||||
while l:max && s:syn_at(a:ln, strlen(pline)) =~? s:syng_com
|
||||
let pline = substitute(strpart(pline, 0, l:max),'\s*$','','')
|
||||
let l:max = max([match(pline,'.*[^/]\zs\/[/*]'),0])
|
||||
endwhile
|
||||
return cursor(a:ln,strlen(pline)) ? pline : pline
|
||||
endfunction
|
||||
|
||||
" Auxiliary Functions {{{2
|
||||
|
||||
" Find line above 'lnum' that isn't empty, in a comment, or in a string.
|
||||
" Find line above 'lnum' that isn't empty or in a comment
|
||||
function s:PrevCodeLine(lnum)
|
||||
let l:lnum = prevnonblank(a:lnum)
|
||||
while l:lnum
|
||||
if synIDattr(synID(l:lnum,matchend(getline(l:lnum), '^\s*[^''"]'),0),'name') !~? s:syng_strcom
|
||||
return l:lnum
|
||||
let l:n = prevnonblank(a:lnum)
|
||||
while l:n
|
||||
if getline(l:n) =~ '^\s*\/[/*]'
|
||||
if (stridx(getline(l:n),'`') > 0 || getline(l:n-1)[-1:] == '\') &&
|
||||
\ s:syn_at(l:n,1) =~? s:syng_str
|
||||
return l:n
|
||||
endif
|
||||
let l:n = prevnonblank(l:n-1)
|
||||
elseif s:syn_at(l:n,1) =~? s:syng_com
|
||||
let l:n = s:save_pos('eval',
|
||||
\ 'cursor('.l:n.',1) + search(''\m\/\*'',"bW")')
|
||||
else
|
||||
return l:n
|
||||
endif
|
||||
let l:lnum = prevnonblank(l:lnum - 1)
|
||||
endwhile
|
||||
endfunction
|
||||
|
||||
" Check if line 'lnum' has a balanced amount of parentheses.
|
||||
function s:Balanced(lnum)
|
||||
let [open_0,open_2,open_4] = [0,0,0]
|
||||
let l:open = 0
|
||||
let l:line = getline(a:lnum)
|
||||
let pos = match(l:line, '[][(){}]', 0)
|
||||
while pos != -1
|
||||
if synIDattr(synID(a:lnum,pos + 1,0),'name') !~? s:syng_strcom
|
||||
let idx = stridx('(){}[]', l:line[pos])
|
||||
if idx % 2 == 0
|
||||
let open_{idx} = open_{idx} + 1
|
||||
else
|
||||
let open_{idx - 1} = open_{idx - 1} - 1
|
||||
if s:syn_at(a:lnum,pos + 1) !~? s:syng_strcom
|
||||
let l:open += match(' ' . l:line[pos],'[[({]')
|
||||
if l:open < 0
|
||||
return
|
||||
endif
|
||||
endif
|
||||
let pos = match(l:line, '[][(){}]', pos + 1)
|
||||
endwhile
|
||||
return (!open_4 + !open_2 + !open_0) - 2
|
||||
return !l:open
|
||||
endfunction
|
||||
|
||||
function s:OneScope(lnum)
|
||||
let pline = s:Trim(a:lnum)
|
||||
let kw = 'else do'
|
||||
if pline[-1:] == ')' && s:GetPair('(', ')', 'bW', s:skip_expr, 100) > 0
|
||||
call s:previous_token()
|
||||
let kw = 'for if let while with'
|
||||
if index(split('await each'),s:token()) + 1
|
||||
call s:previous_token()
|
||||
let kw = 'for'
|
||||
endif
|
||||
endif
|
||||
return pline[-2:] == '=>' || index(split(kw),s:token()) + 1 &&
|
||||
\ s:save_pos('s:previous_token') != '.'
|
||||
endfunction
|
||||
|
||||
" returns braceless levels started by 'i' and above lines * &sw. 'num' is the
|
||||
" lineNr which encloses the entire context, 'cont' if whether line 'i' + 1 is
|
||||
" a continued expression, which could have started in a braceless context
|
||||
function s:iscontOne(i,num,cont)
|
||||
let [l:i, l:num, bL] = [a:i, a:num + !a:num, 0]
|
||||
let pind = a:num ? indent(l:num) + s:W : 0
|
||||
let ind = indent(l:i) + (a:cont ? 0 : s:W)
|
||||
while l:i >= l:num && (ind > pind || l:i == l:num)
|
||||
if indent(l:i) < ind && s:OneScope(l:i)
|
||||
let bL += s:W
|
||||
let l:i = line('.')
|
||||
elseif !a:cont || bL || ind < indent(a:i)
|
||||
break
|
||||
endif
|
||||
let ind = min([ind, indent(l:i)])
|
||||
let l:i = s:PrevCodeLine(l:i - 1)
|
||||
endwhile
|
||||
return bL
|
||||
endfunction
|
||||
|
||||
" https://github.com/sweet-js/sweet.js/wiki/design#give-lookbehind-to-the-reader
|
||||
function s:IsBlock()
|
||||
if s:looking_at() == '{'
|
||||
let l:n = line('.')
|
||||
let char = s:previous_token()
|
||||
let syn = char =~ '[{>/]' ? s:syn_at(line('.'),col('.')-(char == '{')) : ''
|
||||
if syn =~? 'xml\|jsx'
|
||||
return char != '{'
|
||||
elseif char =~ '\k'
|
||||
return index(split('return const let import export yield default delete var await void typeof throw case new in instanceof')
|
||||
\ ,char) < (line('.') != l:n) || s:previous_token() == '.'
|
||||
elseif char == '>'
|
||||
return getline('.')[col('.')-2] == '=' || syn =~? '^jsflow'
|
||||
elseif char == ':'
|
||||
return getline('.')[col('.')-2] != ':' && s:label_col()
|
||||
endif
|
||||
return syn =~? 'regex' || char !~ '[-=~!<*+,/?^%|&([]'
|
||||
endif
|
||||
endfunction
|
||||
" }}}
|
||||
|
||||
function GetJavascriptIndent()
|
||||
if !exists('b:js_cache')
|
||||
let b:js_cache = [0,0,0]
|
||||
endif
|
||||
let b:js_cache = get(b:,'js_cache',[0,0,0])
|
||||
" Get the current line.
|
||||
let l:line = getline(v:lnum)
|
||||
let syns = synIDattr(synID(v:lnum, 1, 0), 'name')
|
||||
call cursor(v:lnum,1)
|
||||
let l:line = getline('.')
|
||||
let syns = s:syn_at(v:lnum, 1)
|
||||
|
||||
" start with strings,comments,etc.{{{2
|
||||
if (l:line !~ '^[''"`]' && syns =~? '\%(string\|template\)') ||
|
||||
\ (l:line !~ '^\s*[/*]' && syns =~? s:syng_comment)
|
||||
" start with strings,comments,etc.
|
||||
if syns =~? s:syng_com
|
||||
if l:line =~ '^\s*\*'
|
||||
return cindent(v:lnum)
|
||||
elseif l:line !~ '^\s*\/[/*]'
|
||||
return -1
|
||||
endif
|
||||
elseif syns =~? s:syng_str && l:line !~ '^[''"]'
|
||||
if b:js_cache[0] == v:lnum - 1 && s:Balanced(v:lnum-1)
|
||||
let b:js_cache[0] = v:lnum
|
||||
endif
|
||||
return -1
|
||||
endif
|
||||
if l:line !~ '^\%(\/\*\|\s*\/\/\)' && syns =~? s:syng_comment
|
||||
return cindent(v:lnum)
|
||||
endif
|
||||
let l:lnum = s:PrevCodeLine(v:lnum - 1)
|
||||
if l:lnum == 0
|
||||
return 0
|
||||
if !l:lnum
|
||||
return
|
||||
endif
|
||||
|
||||
if (l:line =~# s:expr_case)
|
||||
let cpo_switch = &cpo
|
||||
set cpo+=%
|
||||
let ind = cindent(v:lnum)
|
||||
let &cpo = cpo_switch
|
||||
return ind
|
||||
let l:line = substitute(l:line,'^\s*','','')
|
||||
if l:line[:1] == '/*'
|
||||
let l:line = substitute(l:line,'^\%(\/\*.\{-}\*\/\s*\)*','','')
|
||||
endif
|
||||
if l:line =~ '^\/[/*]'
|
||||
let l:line = ''
|
||||
endif
|
||||
"}}}
|
||||
|
||||
" the containing paren, bracket, curly. Memoize, last lineNr either has the
|
||||
" same scope or starts a new one, unless if it closed a scope.
|
||||
call cursor(v:lnum,1)
|
||||
if b:js_cache[0] >= l:lnum && b:js_cache[0] < v:lnum && b:js_cache[0] &&
|
||||
\ (b:js_cache[0] > l:lnum || s:Balanced(l:lnum) > 0)
|
||||
let num = b:js_cache[1]
|
||||
elseif syns != '' && l:line[0] =~ '\s'
|
||||
let pattern = syns =~? 'block' ? ['{','}'] : syns =~? 'jsparen' ? ['(',')'] :
|
||||
\ syns =~? 'jsbracket'? ['\[','\]'] : ['[({[]','[])}]']
|
||||
let num = s:GetPair(pattern[0],pattern[1],'bW',2000)
|
||||
" the containing paren, bracket, or curly. Many hacks for performance
|
||||
let idx = strlen(l:line) ? stridx('])}',l:line[0]) : -1
|
||||
if b:js_cache[0] >= l:lnum && b:js_cache[0] < v:lnum &&
|
||||
\ (b:js_cache[0] > l:lnum || s:Balanced(l:lnum))
|
||||
call call('cursor',b:js_cache[1:])
|
||||
else
|
||||
let num = s:GetPair('[({[]','[])}]','bW',2000)
|
||||
endif
|
||||
let b:js_cache = [v:lnum,num,line('.') == v:lnum ? b:js_cache[2] : col('.')]
|
||||
|
||||
if l:line =~ s:line_pre . '[])}]'
|
||||
return indent(num)
|
||||
let [s:looksyn, s:free, top] = [v:lnum - 1, 1, (!indent(l:lnum) &&
|
||||
\ s:syn_at(l:lnum,1) !~? s:syng_str) * l:lnum]
|
||||
if idx + 1
|
||||
call s:GetPair(['\[','(','{'][idx], '])}'[idx],'bW','s:skip_func()',2000,top)
|
||||
elseif indent(v:lnum) && syns =~? 'block'
|
||||
call s:GetPair('{','}','bW','s:skip_func()',2000,top)
|
||||
else
|
||||
call s:alternatePair(top)
|
||||
endif
|
||||
endif
|
||||
|
||||
call cursor(b:js_cache[1],b:js_cache[2])
|
||||
|
||||
let swcase = getline(l:lnum) =~# s:expr_case
|
||||
let pline = swcase ? getline(l:lnum) : substitute(getline(l:lnum), '\%(:\@<!\/\/.*\)$', '','')
|
||||
let inb = num == 0 || num < l:lnum && ((l:line !~ s:line_pre . ',' && pline !~ ',' . s:line_term) || s:IsBlock())
|
||||
let switch_offset = num == 0 || s:OneScope(num, strpart(getline(num),0,b:js_cache[2] - 1),1) !=# 'switch' ? 0 :
|
||||
\ &cino !~ ':' || !has('float') ? s:sw() :
|
||||
\ float2nr(str2float(matchstr(&cino,'.*:\zs[-0-9.]*')) * (&cino =~# '.*:[^,]*s' ? s:sw() : 1))
|
||||
|
||||
" most significant, find the indent amount
|
||||
if inb && !swcase && ((l:line =~# g:javascript_opfirst || pline =~# g:javascript_continuation) ||
|
||||
\ num < l:lnum && s:OneScope(l:lnum,pline,0) =~# '\<\%(for\|each\|if\|let\|no\sb\|w\%(hile\|ith\)\)\>' &&
|
||||
\ l:line !~ s:line_pre . '{')
|
||||
return (num > 0 ? indent(num) : -s:sw()) + (s:sw() * 2) + switch_offset
|
||||
elseif num > 0
|
||||
return indent(num) + s:sw() + switch_offset
|
||||
if idx + 1 || l:line[:1] == '|}'
|
||||
if idx == 2 && search('\m\S','bW',line('.')) && s:looking_at() == ')'
|
||||
call s:GetPair('(',')','bW',s:skip_expr,200)
|
||||
endif
|
||||
return indent('.')
|
||||
endif
|
||||
|
||||
let b:js_cache = [v:lnum] + (line('.') == v:lnum ? [0,0] : getpos('.')[1:2])
|
||||
let num = b:js_cache[1]
|
||||
|
||||
let [s:W, isOp, bL, switch_offset] = [s:sw(),0,0,0]
|
||||
if !num || s:IsBlock()
|
||||
let pline = s:save_pos('s:Trim',l:lnum)
|
||||
if num && s:looking_at() == ')' && s:GetPair('(', ')', 'bW', s:skip_expr, 100) > 0
|
||||
let num = line('.')
|
||||
if s:previous_token() ==# 'switch' && s:previous_token() != '.'
|
||||
if &cino !~ ':' || !has('float')
|
||||
let switch_offset = s:W
|
||||
else
|
||||
let cinc = matchlist(&cino,'.*:\(-\)\=\([0-9.]*\)\(s\)\=\C')
|
||||
let switch_offset = float2nr(str2float(cinc[1].(strlen(cinc[2]) ? cinc[2] : strlen(cinc[3])))
|
||||
\ * (strlen(cinc[3]) ? s:W : 1))
|
||||
endif
|
||||
if pline[-1:] != '.' && l:line =~# '^\%(default\|case\)\>'
|
||||
return indent(num) + switch_offset
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
if pline[-1:] !~ '[{;]'
|
||||
if pline =~# ':\@<!:$'
|
||||
call cursor(l:lnum,strlen(pline))
|
||||
let isOp = s:tern_col(b:js_cache[1:2])
|
||||
else
|
||||
let isOp = l:line =~# s:opfirst || s:continues(l:lnum,pline)
|
||||
endif
|
||||
let bL = s:iscontOne(l:lnum,num,isOp)
|
||||
let bL -= (bL && l:line[0] == '{') * s:W
|
||||
endif
|
||||
endif
|
||||
|
||||
" main return
|
||||
if isOp
|
||||
return (num ? indent(num) : -s:W) + (s:W * 2) + switch_offset + bL
|
||||
elseif num
|
||||
return indent(num) + s:W + switch_offset + bL
|
||||
endif
|
||||
return bL
|
||||
endfunction
|
||||
|
||||
|
||||
let &cpo = s:cpo_save
|
||||
unlet s:cpo_save
|
||||
|
||||
@@ -80,6 +80,9 @@ if has("gui_macvim")
|
||||
an <silent> 9998.350 Window.Select\ Previous\ Tab :tabprevious<CR>
|
||||
an 9998.360 Window.-SEP2- <Nop>
|
||||
an <silent> 9998.370 Window.Bring\ All\ To\ Front <Nop>
|
||||
an <silent> 9998.380 Window.Stay\ in\ Front <Nop>
|
||||
an <silent> 9998.390 Window.Stay\ in\ Back <Nop>
|
||||
an <silent> 9998.400 Window.Stay\ Level\ Normal <Nop>
|
||||
endif
|
||||
|
||||
" Help menu
|
||||
@@ -1255,6 +1258,9 @@ if has("gui_macvim")
|
||||
macm Window.Select\ Next\ Tab key=<D-}>
|
||||
macm Window.Select\ Previous\ Tab key=<D-{>
|
||||
macm Window.Bring\ All\ To\ Front action=arrangeInFront:
|
||||
macm Window.Stay\ in\ Front action=stayInFront:
|
||||
macm Window.Stay\ in\ Back action=stayInBack:
|
||||
macm Window.Stay\ Level\ Normal action=stayLevelNormal:
|
||||
|
||||
macm Help.MacVim\ Help key=<D-?>
|
||||
macm Help.MacVim\ Website action=openWebsite:
|
||||
|
||||
@@ -2,7 +2,8 @@
|
||||
" Language: HTML
|
||||
" Maintainer: Jorge Maldonado Ventura <jorgesumle@freakspot.net>
|
||||
" Previous Maintainer: Claudio Fleiner <claudio@fleiner.com>
|
||||
" Last Change: 2016 Dec 29
|
||||
" Repository: https://notabug.org/jorgesumle/vim-html-syntax
|
||||
" Last Change: 2017 Jan 04
|
||||
" included patch from Jorge Maldonado Ventura
|
||||
|
||||
" Please check :help html.vim for some comments and a description of the options
|
||||
@@ -95,6 +96,10 @@ syn keyword htmlArg contained multiple nohref nowrap object profile readonly
|
||||
syn keyword htmlArg contained rules scheme scope span standby style
|
||||
syn keyword htmlArg contained summary tabindex valuetype version
|
||||
|
||||
" html 5 arg names
|
||||
syn keyword htmlArg contained contenteditable contextmenu draggable dropzone
|
||||
syn keyword htmlArg contained hidden spellcheck title translate
|
||||
|
||||
" special characters
|
||||
syn match htmlSpecialChar "&#\=[0-9A-Za-z]\{1,8};"
|
||||
|
||||
|
||||
@@ -72,5 +72,11 @@
|
||||
<string></string>
|
||||
<key>zoomAll:</key>
|
||||
<string></string>
|
||||
<key>stayInFront:</key>
|
||||
<string></string>
|
||||
<key>stayInBack:</key>
|
||||
<string></string>
|
||||
<key>stayLevelNormal:</key>
|
||||
<string></string>
|
||||
</dict>
|
||||
</plist>
|
||||
|
||||
@@ -1255,7 +1255,7 @@
|
||||
</dict>
|
||||
</array>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>120</string>
|
||||
<string>121</string>
|
||||
<key>NSAppTransportSecurity</key>
|
||||
<dict>
|
||||
<key>NSAllowsArbitraryLoads</key>
|
||||
|
||||
@@ -53,5 +53,8 @@
|
||||
- (IBAction)openWebsite:(id)sender;
|
||||
- (IBAction)showVimHelp:(id)sender;
|
||||
- (IBAction)zoomAll:(id)sender;
|
||||
- (IBAction)stayInFront:(id)sender;
|
||||
- (IBAction)stayInBack:(id)sender;
|
||||
- (IBAction)stayLevelNormal:(id)sender;
|
||||
|
||||
@end
|
||||
|
||||
@@ -1196,6 +1196,27 @@ fsEventCallback(ConstFSEventStreamRef streamRef,
|
||||
[NSApp makeWindowsPerform:@selector(performZoom:) inOrder:YES];
|
||||
}
|
||||
|
||||
- (IBAction)stayInFront:(id)sender
|
||||
{
|
||||
ASLogDebug(@"Stay in Front");
|
||||
NSWindow *keyWindow = [NSApp keyWindow];
|
||||
[keyWindow setLevel:NSFloatingWindowLevel];
|
||||
}
|
||||
|
||||
- (IBAction)stayInBack:(id)sender
|
||||
{
|
||||
ASLogDebug(@"Stay in Back");
|
||||
NSWindow *keyWindow = [NSApp keyWindow];
|
||||
[keyWindow setLevel:kCGDesktopIconWindowLevel +1];
|
||||
}
|
||||
|
||||
- (IBAction)stayLevelNormal:(id)sender
|
||||
{
|
||||
ASLogDebug(@"Stay level normal");
|
||||
NSWindow *keyWindow = [NSApp keyWindow];
|
||||
[keyWindow setLevel:NSNormalWindowLevel];
|
||||
}
|
||||
|
||||
- (IBAction)coreTextButtonClicked:(id)sender
|
||||
{
|
||||
ASLogDebug(@"Toggle CoreText renderer");
|
||||
|
||||
@@ -1123,9 +1123,6 @@ clean:
|
||||
cd GvimExt
|
||||
$(MAKE) /NOLOGO -f Makefile clean
|
||||
cd ..
|
||||
cd GvimExt
|
||||
$(MAKE) /NOLOGO -f Makefile clean
|
||||
cd ..
|
||||
- if exist testdir\*.out del testdir\*.out
|
||||
|
||||
test:
|
||||
|
||||
@@ -2108,6 +2108,7 @@ test_arglist \
|
||||
test_delete \
|
||||
test_diffmode \
|
||||
test_digraph \
|
||||
test_functions \
|
||||
test_display \
|
||||
test_ex_undo \
|
||||
test_execute_func \
|
||||
@@ -2121,6 +2122,7 @@ test_arglist \
|
||||
test_fileformat \
|
||||
test_filter_cmd \
|
||||
test_filter_map \
|
||||
test_float_func \
|
||||
test_fnameescape \
|
||||
test_fnamemodify \
|
||||
test_fold \
|
||||
@@ -2181,6 +2183,7 @@ test_arglist \
|
||||
test_substitute \
|
||||
test_syn_attr \
|
||||
test_syntax \
|
||||
test_system \
|
||||
test_tabline \
|
||||
test_tabpage \
|
||||
test_tagcase \
|
||||
|
||||
Vendored
+7
-1
@@ -7233,6 +7233,12 @@ $as_echo "$rubyhdrdir" >&6; }
|
||||
rubyarchdir=`$vi_cv_path_ruby -r rbconfig -e "print ($ruby_rbconfig::CONFIG.has_key? 'rubyarchhdrdir') ? $ruby_rbconfig::CONFIG['rubyarchhdrdir'] : '$rubyhdrdir/'+$ruby_rbconfig::CONFIG['arch']"`
|
||||
if test -d "$rubyarchdir"; then
|
||||
RUBY_CFLAGS="$RUBY_CFLAGS -I$rubyarchdir"
|
||||
else
|
||||
dnl rbconfig says darwin15 but 10.12 SDK has darwin16
|
||||
rubyarchdir=${rubyarchdir/darwin15/darwin16}
|
||||
if test -d "$rubyarchdir"; then
|
||||
RUBY_CFLAGS="$RUBY_CFLAGS -I$rubyarchdir"
|
||||
fi
|
||||
fi
|
||||
rubyversion=`$vi_cv_path_ruby -r rbconfig -e "print $ruby_rbconfig::CONFIG['ruby_version'].gsub(/\./, '')[0,2]"`
|
||||
if test "X$rubyversion" = "X"; then
|
||||
@@ -7251,7 +7257,7 @@ $as_echo "$rubyhdrdir" >&6; }
|
||||
RUBY_LIBS="$RUBY_LIBS -L$rubylibdir"
|
||||
elif test -d "/System/Library/Frameworks/Ruby.framework"; then
|
||||
RUBY_LIBS="-framework Ruby"
|
||||
RUBY_CFLAGS="-DRUBY_VERSION=$rubyversion"
|
||||
RUBY_CFLAGS="$RUBY_CFLAGS -DRUBY_VERSION=$rubyversion"
|
||||
librubyarg=
|
||||
fi
|
||||
|
||||
|
||||
+5
-2
@@ -1588,7 +1588,7 @@ invoke_callback(channel_T *channel, char_u *callback, partial_T *partial,
|
||||
int dummy;
|
||||
|
||||
if (safe_to_invoke_callback == 0)
|
||||
EMSG("INTERNAL: Invoking callback when it is not safe");
|
||||
IEMSG("INTERNAL: Invoking callback when it is not safe");
|
||||
|
||||
argv[0].v_type = VAR_CHANNEL;
|
||||
argv[0].vval.v_channel = channel;
|
||||
@@ -1917,9 +1917,12 @@ channel_parse_json(channel_T *channel, ch_part_T part)
|
||||
|
||||
/* When a message is incomplete we wait for a short while for more to
|
||||
* arrive. After the delay drop the input, otherwise a truncated string
|
||||
* or list will make us hang. */
|
||||
* or list will make us hang.
|
||||
* Do not generate error messages, they will be written in a channel log. */
|
||||
++emsg_silent;
|
||||
status = json_decode(&reader, &listtv,
|
||||
chanpart->ch_mode == MODE_JS ? JSON_JS : 0);
|
||||
--emsg_silent;
|
||||
if (status == OK)
|
||||
{
|
||||
/* Only accept the response when it is a list with at least two
|
||||
|
||||
+1
-1
@@ -887,7 +887,7 @@ vim_isIDc(int c)
|
||||
|
||||
/*
|
||||
* return TRUE if 'c' is a keyword character: Letters and characters from
|
||||
* 'iskeyword' option for current buffer.
|
||||
* 'iskeyword' option for the current buffer.
|
||||
* For multi-byte characters mb_get_class() is used (builtin rules).
|
||||
*/
|
||||
int
|
||||
|
||||
+7
-1
@@ -1904,6 +1904,12 @@ if test "$enable_rubyinterp" = "yes" -o "$enable_rubyinterp" = "dynamic"; then
|
||||
rubyarchdir=`$vi_cv_path_ruby -r rbconfig -e "print ($ruby_rbconfig::CONFIG.has_key? 'rubyarchhdrdir') ? $ruby_rbconfig::CONFIG[['rubyarchhdrdir']] : '$rubyhdrdir/'+$ruby_rbconfig::CONFIG[['arch']]"`
|
||||
if test -d "$rubyarchdir"; then
|
||||
RUBY_CFLAGS="$RUBY_CFLAGS -I$rubyarchdir"
|
||||
else
|
||||
dnl rbconfig says darwin15 but 10.12 SDK has darwin16
|
||||
rubyarchdir=${rubyarchdir/darwin15/darwin16}
|
||||
if test -d "$rubyarchdir"; then
|
||||
RUBY_CFLAGS="$RUBY_CFLAGS -I$rubyarchdir"
|
||||
fi
|
||||
fi
|
||||
rubyversion=`$vi_cv_path_ruby -r rbconfig -e "print $ruby_rbconfig::CONFIG[['ruby_version']].gsub(/\./, '')[[0,2]]"`
|
||||
if test "X$rubyversion" = "X"; then
|
||||
@@ -1924,7 +1930,7 @@ if test "$enable_rubyinterp" = "yes" -o "$enable_rubyinterp" = "dynamic"; then
|
||||
dnl On Mac OS X it is safer to just use the -framework flag
|
||||
RUBY_LIBS="-framework Ruby"
|
||||
dnl Don't include the -I flag when -framework is set
|
||||
RUBY_CFLAGS="-DRUBY_VERSION=$rubyversion"
|
||||
RUBY_CFLAGS="$RUBY_CFLAGS -DRUBY_VERSION=$rubyversion"
|
||||
librubyarg=
|
||||
fi
|
||||
|
||||
|
||||
+17
-1
@@ -270,7 +270,7 @@ eval_init(void)
|
||||
p = &vimvars[i];
|
||||
if (STRLEN(p->vv_name) > 16)
|
||||
{
|
||||
EMSG("INTERNAL: name too long, increase size of dictitem16_T");
|
||||
IEMSG("INTERNAL: name too long, increase size of dictitem16_T");
|
||||
getout(1);
|
||||
}
|
||||
STRCPY(p->vv_di.di_key, p->vv_name);
|
||||
@@ -5971,6 +5971,22 @@ string2float(
|
||||
char *s = (char *)text;
|
||||
float_T f;
|
||||
|
||||
/* MS-Windows does not deal with "inf" and "nan" properly. */
|
||||
if (STRNICMP(text, "inf", 3) == 0)
|
||||
{
|
||||
*value = INFINITY;
|
||||
return 3;
|
||||
}
|
||||
if (STRNICMP(text, "-inf", 3) == 0)
|
||||
{
|
||||
*value = -INFINITY;
|
||||
return 4;
|
||||
}
|
||||
if (STRNICMP(text, "nan", 3) == 0)
|
||||
{
|
||||
*value = NAN;
|
||||
return 3;
|
||||
}
|
||||
f = strtod(s, &s);
|
||||
*value = f;
|
||||
return (int)((char_u *)s - text);
|
||||
|
||||
+50
-14
@@ -3973,7 +3973,8 @@ get_buffer_info(buf_T *buf)
|
||||
dict_add_nr_str(dict, "bufnr", buf->b_fnum, NULL);
|
||||
dict_add_nr_str(dict, "name", 0L,
|
||||
buf->b_ffname != NULL ? buf->b_ffname : (char_u *)"");
|
||||
dict_add_nr_str(dict, "lnum", buflist_findlnum(buf), NULL);
|
||||
dict_add_nr_str(dict, "lnum", buf == curbuf ? curwin->w_cursor.lnum
|
||||
: buflist_findlnum(buf), NULL);
|
||||
dict_add_nr_str(dict, "loaded", buf->b_ml.ml_mfp != NULL, NULL);
|
||||
dict_add_nr_str(dict, "listed", buf->b_p_bl, NULL);
|
||||
dict_add_nr_str(dict, "changed", bufIsChanged(buf), NULL);
|
||||
@@ -6836,8 +6837,7 @@ f_json_decode(typval_T *argvars, typval_T *rettv)
|
||||
reader.js_buf = get_tv_string(&argvars[0]);
|
||||
reader.js_fill = NULL;
|
||||
reader.js_used = 0;
|
||||
if (json_decode_all(&reader, rettv, 0) != OK)
|
||||
EMSG(_(e_invarg));
|
||||
json_decode_all(&reader, rettv, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -9535,15 +9535,15 @@ do_searchpair(
|
||||
|
||||
/* Make two search patterns: start/end (pat2, for in nested pairs) and
|
||||
* start/middle/end (pat3, for the top pair). */
|
||||
pat2 = alloc((unsigned)(STRLEN(spat) + STRLEN(epat) + 15));
|
||||
pat3 = alloc((unsigned)(STRLEN(spat) + STRLEN(mpat) + STRLEN(epat) + 23));
|
||||
pat2 = alloc((unsigned)(STRLEN(spat) + STRLEN(epat) + 17));
|
||||
pat3 = alloc((unsigned)(STRLEN(spat) + STRLEN(mpat) + STRLEN(epat) + 25));
|
||||
if (pat2 == NULL || pat3 == NULL)
|
||||
goto theend;
|
||||
sprintf((char *)pat2, "\\(%s\\m\\)\\|\\(%s\\m\\)", spat, epat);
|
||||
sprintf((char *)pat2, "\\m\\(%s\\m\\)\\|\\(%s\\m\\)", spat, epat);
|
||||
if (*mpat == NUL)
|
||||
STRCPY(pat3, pat2);
|
||||
else
|
||||
sprintf((char *)pat3, "\\(%s\\m\\)\\|\\(%s\\m\\)\\|\\(%s\\m\\)",
|
||||
sprintf((char *)pat3, "\\m\\(%s\\m\\)\\|\\(%s\\m\\)\\|\\(%s\\m\\)",
|
||||
spat, epat, mpat);
|
||||
if (flags & SP_START)
|
||||
options |= SEARCH_START;
|
||||
@@ -11093,10 +11093,13 @@ f_sqrt(typval_T *argvars, typval_T *rettv)
|
||||
f_str2float(typval_T *argvars, typval_T *rettv)
|
||||
{
|
||||
char_u *p = skipwhite(get_tv_string(&argvars[0]));
|
||||
int isneg = (*p == '-');
|
||||
|
||||
if (*p == '+')
|
||||
if (*p == '+' || *p == '-')
|
||||
p = skipwhite(p + 1);
|
||||
(void)string2float(p, &rettv->vval.v_float);
|
||||
if (isneg)
|
||||
rettv->vval.v_float *= -1;
|
||||
rettv->v_type = VAR_FLOAT;
|
||||
}
|
||||
#endif
|
||||
@@ -11111,6 +11114,7 @@ f_str2nr(typval_T *argvars, typval_T *rettv)
|
||||
char_u *p;
|
||||
varnumber_T n;
|
||||
int what;
|
||||
int isneg;
|
||||
|
||||
if (argvars[1].v_type != VAR_UNKNOWN)
|
||||
{
|
||||
@@ -11123,7 +11127,8 @@ f_str2nr(typval_T *argvars, typval_T *rettv)
|
||||
}
|
||||
|
||||
p = skipwhite(get_tv_string(&argvars[0]));
|
||||
if (*p == '+')
|
||||
isneg = (*p == '-');
|
||||
if (*p == '+' || *p == '-')
|
||||
p = skipwhite(p + 1);
|
||||
switch (base)
|
||||
{
|
||||
@@ -11133,7 +11138,11 @@ f_str2nr(typval_T *argvars, typval_T *rettv)
|
||||
default: what = 0;
|
||||
}
|
||||
vim_str2nr(p, NULL, NULL, what, &n, NULL, 0);
|
||||
rettv->vval.v_number = n;
|
||||
if (isneg)
|
||||
rettv->vval.v_number = -n;
|
||||
else
|
||||
rettv->vval.v_number = n;
|
||||
|
||||
}
|
||||
|
||||
#ifdef HAVE_STRFTIME
|
||||
@@ -11843,7 +11852,6 @@ get_cmd_output_as_rettv(
|
||||
char_u *res = NULL;
|
||||
char_u *p;
|
||||
char_u *infile = NULL;
|
||||
char_u buf[NUMBUFLEN];
|
||||
int err = FALSE;
|
||||
FILE *fd;
|
||||
list_T *list = NULL;
|
||||
@@ -11857,7 +11865,7 @@ get_cmd_output_as_rettv(
|
||||
if (argvars[1].v_type != VAR_UNKNOWN)
|
||||
{
|
||||
/*
|
||||
* Write the string to a temp file, to be used for input of the shell
|
||||
* Write the text to a temp file, to be used for input of the shell
|
||||
* command.
|
||||
*/
|
||||
if ((infile = vim_tempname('i', TRUE)) == NULL)
|
||||
@@ -11872,14 +11880,42 @@ get_cmd_output_as_rettv(
|
||||
EMSG2(_(e_notopen), infile);
|
||||
goto errret;
|
||||
}
|
||||
if (argvars[1].v_type == VAR_LIST)
|
||||
if (argvars[1].v_type == VAR_NUMBER)
|
||||
{
|
||||
linenr_T lnum;
|
||||
buf_T *buf;
|
||||
|
||||
buf = buflist_findnr(argvars[1].vval.v_number);
|
||||
if (buf == NULL)
|
||||
{
|
||||
EMSGN(_(e_nobufnr), argvars[1].vval.v_number);
|
||||
goto errret;
|
||||
}
|
||||
|
||||
for (lnum = 1; lnum <= buf->b_ml.ml_line_count; lnum++)
|
||||
{
|
||||
for (p = ml_get_buf(buf, lnum, FALSE); *p != NUL; ++p)
|
||||
if (putc(*p == '\n' ? NUL : *p, fd) == EOF)
|
||||
{
|
||||
err = TRUE;
|
||||
break;
|
||||
}
|
||||
if (putc(NL, fd) == EOF)
|
||||
{
|
||||
err = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (argvars[1].v_type == VAR_LIST)
|
||||
{
|
||||
if (write_list(fd, argvars[1].vval.v_list, TRUE) == FAIL)
|
||||
err = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
size_t len;
|
||||
size_t len;
|
||||
char_u buf[NUMBUFLEN];
|
||||
|
||||
p = get_tv_string_buf_chk(&argvars[1], buf);
|
||||
if (p == NULL)
|
||||
|
||||
+10
-1
@@ -3878,7 +3878,6 @@ set_one_cmd_context(
|
||||
case CMD_cfdo:
|
||||
case CMD_confirm:
|
||||
case CMD_debug:
|
||||
case CMD_filter:
|
||||
case CMD_folddoclosed:
|
||||
case CMD_folddoopen:
|
||||
case CMD_hide:
|
||||
@@ -3903,6 +3902,16 @@ set_one_cmd_context(
|
||||
case CMD_windo:
|
||||
return arg;
|
||||
|
||||
case CMD_filter:
|
||||
if (*arg != NUL)
|
||||
arg = skip_vimgrep_pat(arg, NULL, NULL);
|
||||
if (arg == NULL || *arg == NUL)
|
||||
{
|
||||
xp->xp_context = EXPAND_NOTHING;
|
||||
return NULL;
|
||||
}
|
||||
return skipwhite(arg);
|
||||
|
||||
#ifdef FEAT_CMDL_COMPL
|
||||
# ifdef FEAT_SEARCH_EXTRA
|
||||
case CMD_match:
|
||||
|
||||
+4
-5
@@ -212,7 +212,8 @@ getcmdline(
|
||||
#endif
|
||||
expand_T xpc;
|
||||
long *b_im_ptr = NULL;
|
||||
#if defined(FEAT_WILDMENU) || defined(FEAT_EVAL) || defined(FEAT_SEARCH_EXTRA)
|
||||
#if defined(FEAT_WILDMENU) || defined(FEAT_EVAL) \
|
||||
|| defined(FEAT_SEARCH_EXTRA) || defined(FEAT_CMDWIN)
|
||||
/* Everything that may work recursively should save and restore the
|
||||
* current command line in save_ccline. That includes update_screen(), a
|
||||
* custom status line may invoke ":normal". */
|
||||
@@ -6915,9 +6916,7 @@ ex_window(void)
|
||||
redraw_later(SOME_VALID);
|
||||
|
||||
/* Save the command line info, can be used recursively. */
|
||||
save_ccline = ccline;
|
||||
ccline.cmdbuff = NULL;
|
||||
ccline.cmdprompt = NULL;
|
||||
save_cmdline(&save_ccline);
|
||||
|
||||
/* No Ex mode here! */
|
||||
exmode_active = 0;
|
||||
@@ -6964,7 +6963,7 @@ ex_window(void)
|
||||
# endif
|
||||
|
||||
/* Restore the command line info. */
|
||||
ccline = save_ccline;
|
||||
restore_cmdline(&save_ccline);
|
||||
cmdwin_type = 0;
|
||||
|
||||
exmode_active = save_exmode;
|
||||
|
||||
+10
-11
@@ -978,23 +978,22 @@ ins_typebuf(
|
||||
|
||||
addlen = (int)STRLEN(str);
|
||||
|
||||
/*
|
||||
* Easy case: there is room in front of typebuf.tb_buf[typebuf.tb_off]
|
||||
*/
|
||||
if (offset == 0 && addlen <= typebuf.tb_off)
|
||||
{
|
||||
/*
|
||||
* Easy case: there is room in front of typebuf.tb_buf[typebuf.tb_off]
|
||||
*/
|
||||
typebuf.tb_off -= addlen;
|
||||
mch_memmove(typebuf.tb_buf + typebuf.tb_off, str, (size_t)addlen);
|
||||
}
|
||||
|
||||
/*
|
||||
* Need to allocate a new buffer.
|
||||
* In typebuf.tb_buf there must always be room for 3 * MAXMAPLEN + 4
|
||||
* characters. We add some extra room to avoid having to allocate too
|
||||
* often.
|
||||
*/
|
||||
else
|
||||
{
|
||||
/*
|
||||
* Need to allocate a new buffer.
|
||||
* In typebuf.tb_buf there must always be room for 3 * MAXMAPLEN + 4
|
||||
* characters. We add some extra room to avoid having to allocate too
|
||||
* often.
|
||||
*/
|
||||
newoff = MAXMAPLEN + 4;
|
||||
newlen = typebuf.tb_len + addlen + newoff + 4 * (MAXMAPLEN + 4);
|
||||
if (newlen < 0) /* string is getting too long */
|
||||
@@ -2009,7 +2008,7 @@ vgetorpeek(int advance)
|
||||
{
|
||||
/* KeyTyped = FALSE; When the command that stuffed something
|
||||
* was typed, behave like the stuffed command was typed.
|
||||
* needed for CTRL-W CTRl-] to open a fold, for example. */
|
||||
* needed for CTRL-W CTRL-] to open a fold, for example. */
|
||||
KeyStuffed = TRUE;
|
||||
}
|
||||
if (typebuf.tb_no_abbr_cnt == 0)
|
||||
|
||||
@@ -51,6 +51,9 @@
|
||||
# ifdef _
|
||||
# undef _
|
||||
# endif
|
||||
# ifdef ngettext
|
||||
# undef ngettext
|
||||
# endif
|
||||
# ifdef N_
|
||||
# undef N_
|
||||
# endif
|
||||
|
||||
@@ -35,6 +35,9 @@
|
||||
# ifdef _
|
||||
# undef _
|
||||
# endif
|
||||
# ifdef ngettext
|
||||
# undef ngettext
|
||||
# endif
|
||||
# ifdef N_
|
||||
# undef N_
|
||||
# endif
|
||||
|
||||
+2
-1
@@ -523,9 +523,10 @@ static struct
|
||||
{
|
||||
{"rb_assoc_new", (RUBY_PROC*)&dll_rb_assoc_new},
|
||||
{"rb_cFalseClass", (RUBY_PROC*)&dll_rb_cFalseClass},
|
||||
{"rb_cFixnum", (RUBY_PROC*)&dll_rb_cFixnum},
|
||||
# if defined(USE_RUBY_INTEGER)
|
||||
{"rb_cInteger", (RUBY_PROC*)&dll_rb_cInteger},
|
||||
# else
|
||||
{"rb_cFixnum", (RUBY_PROC*)&dll_rb_cFixnum},
|
||||
# endif
|
||||
# if defined(DYNAMIC_RUBY_VER) && DYNAMIC_RUBY_VER >= 20
|
||||
{"rb_cFloat", (RUBY_PROC*)&dll_rb_cFloat},
|
||||
|
||||
+431
-292
@@ -378,176 +378,7 @@ json_skip_white(js_read_T *reader)
|
||||
}
|
||||
|
||||
static int
|
||||
json_decode_array(js_read_T *reader, typval_T *res, int options)
|
||||
{
|
||||
char_u *p;
|
||||
typval_T item;
|
||||
listitem_T *li;
|
||||
int ret;
|
||||
|
||||
if (res != NULL && rettv_list_alloc(res) == FAIL)
|
||||
{
|
||||
res->v_type = VAR_SPECIAL;
|
||||
res->vval.v_number = VVAL_NONE;
|
||||
return FAIL;
|
||||
}
|
||||
++reader->js_used; /* consume the '[' */
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
json_skip_white(reader);
|
||||
p = reader->js_buf + reader->js_used;
|
||||
if (*p == NUL)
|
||||
return MAYBE;
|
||||
if (*p == ']')
|
||||
{
|
||||
++reader->js_used; /* consume the ']' */
|
||||
break;
|
||||
}
|
||||
|
||||
ret = json_decode_item(reader, res == NULL ? NULL : &item, options);
|
||||
if (ret != OK)
|
||||
return ret;
|
||||
if (res != NULL)
|
||||
{
|
||||
li = listitem_alloc();
|
||||
if (li == NULL)
|
||||
{
|
||||
clear_tv(&item);
|
||||
return FAIL;
|
||||
}
|
||||
li->li_tv = item;
|
||||
list_append(res->vval.v_list, li);
|
||||
}
|
||||
|
||||
json_skip_white(reader);
|
||||
p = reader->js_buf + reader->js_used;
|
||||
if (*p == ',')
|
||||
++reader->js_used;
|
||||
else if (*p != ']')
|
||||
{
|
||||
if (*p == NUL)
|
||||
return MAYBE;
|
||||
return FAIL;
|
||||
}
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
static int
|
||||
json_decode_object(js_read_T *reader, typval_T *res, int options)
|
||||
{
|
||||
char_u *p;
|
||||
typval_T tvkey;
|
||||
typval_T item;
|
||||
dictitem_T *di;
|
||||
char_u buf[NUMBUFLEN];
|
||||
char_u *key = NULL;
|
||||
int ret;
|
||||
|
||||
if (res != NULL && rettv_dict_alloc(res) == FAIL)
|
||||
{
|
||||
res->v_type = VAR_SPECIAL;
|
||||
res->vval.v_number = VVAL_NONE;
|
||||
return FAIL;
|
||||
}
|
||||
++reader->js_used; /* consume the '{' */
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
json_skip_white(reader);
|
||||
p = reader->js_buf + reader->js_used;
|
||||
if (*p == NUL)
|
||||
return MAYBE;
|
||||
if (*p == '}')
|
||||
{
|
||||
++reader->js_used; /* consume the '}' */
|
||||
break;
|
||||
}
|
||||
|
||||
if ((options & JSON_JS) && reader->js_buf[reader->js_used] != '"')
|
||||
{
|
||||
/* accept a key that is not in quotes */
|
||||
key = p = reader->js_buf + reader->js_used;
|
||||
while (*p != NUL && *p != ':' && *p > ' ')
|
||||
++p;
|
||||
tvkey.v_type = VAR_STRING;
|
||||
tvkey.vval.v_string = vim_strnsave(key, (int)(p - key));
|
||||
reader->js_used += (int)(p - key);
|
||||
key = tvkey.vval.v_string;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = json_decode_item(reader, res == NULL ? NULL : &tvkey,
|
||||
options);
|
||||
if (ret != OK)
|
||||
return ret;
|
||||
if (res != NULL)
|
||||
{
|
||||
key = get_tv_string_buf_chk(&tvkey, buf);
|
||||
if (key == NULL || *key == NUL)
|
||||
{
|
||||
clear_tv(&tvkey);
|
||||
return FAIL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
json_skip_white(reader);
|
||||
p = reader->js_buf + reader->js_used;
|
||||
if (*p != ':')
|
||||
{
|
||||
if (res != NULL)
|
||||
clear_tv(&tvkey);
|
||||
if (*p == NUL)
|
||||
return MAYBE;
|
||||
return FAIL;
|
||||
}
|
||||
++reader->js_used;
|
||||
json_skip_white(reader);
|
||||
|
||||
ret = json_decode_item(reader, res == NULL ? NULL : &item, options);
|
||||
if (ret != OK)
|
||||
{
|
||||
if (res != NULL)
|
||||
clear_tv(&tvkey);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (res != NULL)
|
||||
{
|
||||
di = dictitem_alloc(key);
|
||||
clear_tv(&tvkey);
|
||||
if (di == NULL)
|
||||
{
|
||||
clear_tv(&item);
|
||||
return FAIL;
|
||||
}
|
||||
di->di_tv = item;
|
||||
di->di_tv.v_lock = 0;
|
||||
if (dict_add(res->vval.v_dict, di) == FAIL)
|
||||
{
|
||||
dictitem_free(di);
|
||||
return FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
json_skip_white(reader);
|
||||
p = reader->js_buf + reader->js_used;
|
||||
if (*p == ',')
|
||||
++reader->js_used;
|
||||
else if (*p != '}')
|
||||
{
|
||||
if (*p == NUL)
|
||||
return MAYBE;
|
||||
return FAIL;
|
||||
}
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
static int
|
||||
json_decode_string(js_read_T *reader, typval_T *res)
|
||||
json_decode_string(js_read_T *reader, typval_T *res, int quote)
|
||||
{
|
||||
garray_T ga;
|
||||
int len;
|
||||
@@ -558,8 +389,8 @@ json_decode_string(js_read_T *reader, typval_T *res)
|
||||
if (res != NULL)
|
||||
ga_init2(&ga, 1, 200);
|
||||
|
||||
p = reader->js_buf + reader->js_used + 1; /* skip over " */
|
||||
while (*p != '"')
|
||||
p = reader->js_buf + reader->js_used + 1; /* skip over " or ' */
|
||||
while (*p != quote)
|
||||
{
|
||||
/* The JSON is always expected to be utf-8, thus use utf functions
|
||||
* here. The string is converted below if needed. */
|
||||
@@ -673,7 +504,7 @@ json_decode_string(js_read_T *reader, typval_T *res)
|
||||
}
|
||||
|
||||
reader->js_used = (int)(p - reader->js_buf);
|
||||
if (*p == '"')
|
||||
if (*p == quote)
|
||||
{
|
||||
++reader->js_used;
|
||||
if (res != NULL)
|
||||
@@ -711,11 +542,24 @@ json_decode_string(js_read_T *reader, typval_T *res)
|
||||
return MAYBE;
|
||||
}
|
||||
|
||||
typedef enum {
|
||||
JSON_ARRAY, /* parsing items in an array */
|
||||
JSON_OBJECT_KEY, /* parsing key of an object */
|
||||
JSON_OBJECT /* parsing item in an object, after the key */
|
||||
} json_decode_T;
|
||||
|
||||
typedef struct {
|
||||
json_decode_T jd_type;
|
||||
typval_T jd_tv; /* the list or dict */
|
||||
typval_T jd_key_tv;
|
||||
char_u *jd_key;
|
||||
} json_dec_item_T;
|
||||
|
||||
/*
|
||||
* Decode one item and put it in "res". If "res" is NULL only advance.
|
||||
* Must already have skipped white space.
|
||||
*
|
||||
* Return FAIL for a decoding error.
|
||||
* Return FAIL for a decoding error (and give an error).
|
||||
* Return MAYBE for an incomplete message.
|
||||
*/
|
||||
static int
|
||||
@@ -723,150 +567,438 @@ json_decode_item(js_read_T *reader, typval_T *res, int options)
|
||||
{
|
||||
char_u *p;
|
||||
int len;
|
||||
int retval;
|
||||
garray_T stack;
|
||||
typval_T item;
|
||||
typval_T *cur_item;
|
||||
json_dec_item_T *top_item;
|
||||
char_u key_buf[NUMBUFLEN];
|
||||
|
||||
ga_init2(&stack, sizeof(json_dec_item_T), 100);
|
||||
cur_item = res;
|
||||
init_tv(&item);
|
||||
if (res != NULL)
|
||||
init_tv(res);
|
||||
|
||||
fill_numbuflen(reader);
|
||||
p = reader->js_buf + reader->js_used;
|
||||
switch (*p)
|
||||
for (;;)
|
||||
{
|
||||
case '[': /* array */
|
||||
return json_decode_array(reader, res, options);
|
||||
|
||||
case '{': /* object */
|
||||
return json_decode_object(reader, res, options);
|
||||
|
||||
case '"': /* string */
|
||||
return json_decode_string(reader, res);
|
||||
|
||||
case ',': /* comma: empty item */
|
||||
if ((options & JSON_JS) == 0)
|
||||
return FAIL;
|
||||
/* FALLTHROUGH */
|
||||
case NUL: /* empty */
|
||||
if (res != NULL)
|
||||
top_item = NULL;
|
||||
if (stack.ga_len > 0)
|
||||
{
|
||||
top_item = ((json_dec_item_T *)stack.ga_data) + stack.ga_len - 1;
|
||||
json_skip_white(reader);
|
||||
p = reader->js_buf + reader->js_used;
|
||||
if (*p == NUL)
|
||||
{
|
||||
res->v_type = VAR_SPECIAL;
|
||||
res->vval.v_number = VVAL_NONE;
|
||||
retval = MAYBE;
|
||||
if (top_item->jd_type == JSON_OBJECT)
|
||||
/* did get the key, clear it */
|
||||
clear_tv(&top_item->jd_key_tv);
|
||||
goto theend;
|
||||
}
|
||||
return OK;
|
||||
|
||||
default:
|
||||
if (VIM_ISDIGIT(*p) || *p == '-')
|
||||
if (top_item->jd_type == JSON_OBJECT_KEY
|
||||
|| top_item->jd_type == JSON_ARRAY)
|
||||
{
|
||||
#ifdef FEAT_FLOAT
|
||||
char_u *sp = p;
|
||||
|
||||
if (*sp == '-')
|
||||
/* Check for end of object or array. */
|
||||
if (*p == (top_item->jd_type == JSON_ARRAY ? ']' : '}'))
|
||||
{
|
||||
++sp;
|
||||
if (*sp == NUL)
|
||||
return MAYBE;
|
||||
if (!VIM_ISDIGIT(*sp))
|
||||
return FAIL;
|
||||
}
|
||||
sp = skipdigits(sp);
|
||||
if (*sp == '.' || *sp == 'e' || *sp == 'E')
|
||||
{
|
||||
if (res == NULL)
|
||||
++reader->js_used; /* consume the ']' or '}' */
|
||||
--stack.ga_len;
|
||||
if (stack.ga_len == 0)
|
||||
{
|
||||
float_T f;
|
||||
|
||||
len = string2float(p, &f);
|
||||
retval = OK;
|
||||
goto theend;
|
||||
}
|
||||
if (cur_item != NULL)
|
||||
cur_item = &top_item->jd_tv;
|
||||
goto item_end;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (top_item != NULL && top_item->jd_type == JSON_OBJECT_KEY
|
||||
&& (options & JSON_JS)
|
||||
&& reader->js_buf[reader->js_used] != '"'
|
||||
&& reader->js_buf[reader->js_used] != '\'')
|
||||
{
|
||||
char_u *key;
|
||||
|
||||
/* accept an object key that is not in quotes */
|
||||
key = p = reader->js_buf + reader->js_used;
|
||||
while (*p != NUL && *p != ':' && *p > ' ')
|
||||
++p;
|
||||
cur_item->v_type = VAR_STRING;
|
||||
cur_item->vval.v_string = vim_strnsave(key, (int)(p - key));
|
||||
reader->js_used += (int)(p - key);
|
||||
top_item->jd_key = cur_item->vval.v_string;
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (*p)
|
||||
{
|
||||
case '[': /* start of array */
|
||||
if (ga_grow(&stack, 1) == FAIL)
|
||||
{
|
||||
retval = FAIL;
|
||||
break;
|
||||
}
|
||||
if (cur_item != NULL && rettv_list_alloc(cur_item) == FAIL)
|
||||
{
|
||||
cur_item->v_type = VAR_SPECIAL;
|
||||
cur_item->vval.v_number = VVAL_NONE;
|
||||
retval = FAIL;
|
||||
break;
|
||||
}
|
||||
|
||||
++reader->js_used; /* consume the '[' */
|
||||
top_item = ((json_dec_item_T *)stack.ga_data)
|
||||
+ stack.ga_len;
|
||||
top_item->jd_type = JSON_ARRAY;
|
||||
++stack.ga_len;
|
||||
if (cur_item != NULL)
|
||||
{
|
||||
top_item->jd_tv = *cur_item;
|
||||
cur_item = &item;
|
||||
}
|
||||
continue;
|
||||
|
||||
case '{': /* start of object */
|
||||
if (ga_grow(&stack, 1) == FAIL)
|
||||
{
|
||||
retval = FAIL;
|
||||
break;
|
||||
}
|
||||
if (cur_item != NULL && rettv_dict_alloc(cur_item) == FAIL)
|
||||
{
|
||||
cur_item->v_type = VAR_SPECIAL;
|
||||
cur_item->vval.v_number = VVAL_NONE;
|
||||
retval = FAIL;
|
||||
break;
|
||||
}
|
||||
|
||||
++reader->js_used; /* consume the '{' */
|
||||
top_item = ((json_dec_item_T *)stack.ga_data)
|
||||
+ stack.ga_len;
|
||||
top_item->jd_type = JSON_OBJECT_KEY;
|
||||
++stack.ga_len;
|
||||
if (cur_item != NULL)
|
||||
{
|
||||
top_item->jd_tv = *cur_item;
|
||||
cur_item = &top_item->jd_key_tv;
|
||||
}
|
||||
continue;
|
||||
|
||||
case '"': /* string */
|
||||
retval = json_decode_string(reader, cur_item, *p);
|
||||
break;
|
||||
|
||||
case '\'':
|
||||
if (options & JSON_JS)
|
||||
retval = json_decode_string(reader, cur_item, *p);
|
||||
else
|
||||
{
|
||||
res->v_type = VAR_FLOAT;
|
||||
len = string2float(p, &res->vval.v_float);
|
||||
EMSG(_(e_invarg));
|
||||
retval = FAIL;
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
varnumber_T nr;
|
||||
break;
|
||||
|
||||
vim_str2nr(reader->js_buf + reader->js_used,
|
||||
NULL, &len, 0, /* what */
|
||||
&nr, NULL, 0);
|
||||
if (res != NULL)
|
||||
case ',': /* comma: empty item */
|
||||
if ((options & JSON_JS) == 0)
|
||||
{
|
||||
res->v_type = VAR_NUMBER;
|
||||
res->vval.v_number = nr;
|
||||
EMSG(_(e_invarg));
|
||||
retval = FAIL;
|
||||
break;
|
||||
}
|
||||
/* FALLTHROUGH */
|
||||
case NUL: /* empty */
|
||||
if (cur_item != NULL)
|
||||
{
|
||||
cur_item->v_type = VAR_SPECIAL;
|
||||
cur_item->vval.v_number = VVAL_NONE;
|
||||
}
|
||||
retval = OK;
|
||||
break;
|
||||
|
||||
default:
|
||||
if (VIM_ISDIGIT(*p) || *p == '-')
|
||||
{
|
||||
#ifdef FEAT_FLOAT
|
||||
char_u *sp = p;
|
||||
|
||||
if (*sp == '-')
|
||||
{
|
||||
++sp;
|
||||
if (*sp == NUL)
|
||||
{
|
||||
retval = MAYBE;
|
||||
break;
|
||||
}
|
||||
if (!VIM_ISDIGIT(*sp))
|
||||
{
|
||||
EMSG(_(e_invarg));
|
||||
retval = FAIL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
sp = skipdigits(sp);
|
||||
if (*sp == '.' || *sp == 'e' || *sp == 'E')
|
||||
{
|
||||
if (cur_item == NULL)
|
||||
{
|
||||
float_T f;
|
||||
|
||||
len = string2float(p, &f);
|
||||
}
|
||||
else
|
||||
{
|
||||
cur_item->v_type = VAR_FLOAT;
|
||||
len = string2float(p, &cur_item->vval.v_float);
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
varnumber_T nr;
|
||||
|
||||
vim_str2nr(reader->js_buf + reader->js_used,
|
||||
NULL, &len, 0, /* what */
|
||||
&nr, NULL, 0);
|
||||
if (cur_item != NULL)
|
||||
{
|
||||
cur_item->v_type = VAR_NUMBER;
|
||||
cur_item->vval.v_number = nr;
|
||||
}
|
||||
}
|
||||
reader->js_used += len;
|
||||
retval = OK;
|
||||
break;
|
||||
}
|
||||
if (STRNICMP((char *)p, "false", 5) == 0)
|
||||
{
|
||||
reader->js_used += 5;
|
||||
if (cur_item != NULL)
|
||||
{
|
||||
cur_item->v_type = VAR_SPECIAL;
|
||||
cur_item->vval.v_number = VVAL_FALSE;
|
||||
}
|
||||
retval = OK;
|
||||
break;
|
||||
}
|
||||
if (STRNICMP((char *)p, "true", 4) == 0)
|
||||
{
|
||||
reader->js_used += 4;
|
||||
if (cur_item != NULL)
|
||||
{
|
||||
cur_item->v_type = VAR_SPECIAL;
|
||||
cur_item->vval.v_number = VVAL_TRUE;
|
||||
}
|
||||
retval = OK;
|
||||
break;
|
||||
}
|
||||
if (STRNICMP((char *)p, "null", 4) == 0)
|
||||
{
|
||||
reader->js_used += 4;
|
||||
if (cur_item != NULL)
|
||||
{
|
||||
cur_item->v_type = VAR_SPECIAL;
|
||||
cur_item->vval.v_number = VVAL_NULL;
|
||||
}
|
||||
retval = OK;
|
||||
break;
|
||||
}
|
||||
#ifdef FEAT_FLOAT
|
||||
if (STRNICMP((char *)p, "NaN", 3) == 0)
|
||||
{
|
||||
reader->js_used += 3;
|
||||
if (cur_item != NULL)
|
||||
{
|
||||
cur_item->v_type = VAR_FLOAT;
|
||||
cur_item->vval.v_float = NAN;
|
||||
}
|
||||
retval = OK;
|
||||
break;
|
||||
}
|
||||
if (STRNICMP((char *)p, "Infinity", 8) == 0)
|
||||
{
|
||||
reader->js_used += 8;
|
||||
if (cur_item != NULL)
|
||||
{
|
||||
cur_item->v_type = VAR_FLOAT;
|
||||
cur_item->vval.v_float = INFINITY;
|
||||
}
|
||||
retval = OK;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
/* check for truncated name */
|
||||
len = (int)(reader->js_end - (reader->js_buf + reader->js_used));
|
||||
if (
|
||||
(len < 5 && STRNICMP((char *)p, "false", len) == 0)
|
||||
#ifdef FEAT_FLOAT
|
||||
|| (len < 8 && STRNICMP((char *)p, "Infinity", len) == 0)
|
||||
|| (len < 3 && STRNICMP((char *)p, "NaN", len) == 0)
|
||||
#endif
|
||||
|| (len < 4 && (STRNICMP((char *)p, "true", len) == 0
|
||||
|| STRNICMP((char *)p, "null", len) == 0)))
|
||||
|
||||
retval = MAYBE;
|
||||
else
|
||||
retval = FAIL;
|
||||
break;
|
||||
}
|
||||
|
||||
/* We are finished when retval is FAIL or MAYBE and when at the
|
||||
* toplevel. */
|
||||
if (retval == FAIL)
|
||||
break;
|
||||
if (retval == MAYBE || stack.ga_len == 0)
|
||||
goto theend;
|
||||
|
||||
if (top_item != NULL && top_item->jd_type == JSON_OBJECT_KEY
|
||||
&& cur_item != NULL)
|
||||
{
|
||||
top_item->jd_key = get_tv_string_buf_chk(cur_item, key_buf);
|
||||
if (top_item->jd_key == NULL || *top_item->jd_key == NUL)
|
||||
{
|
||||
clear_tv(cur_item);
|
||||
EMSG(_(e_invarg));
|
||||
retval = FAIL;
|
||||
goto theend;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
item_end:
|
||||
top_item = ((json_dec_item_T *)stack.ga_data) + stack.ga_len - 1;
|
||||
switch (top_item->jd_type)
|
||||
{
|
||||
case JSON_ARRAY:
|
||||
if (res != NULL)
|
||||
{
|
||||
listitem_T *li = listitem_alloc();
|
||||
|
||||
if (li == NULL)
|
||||
{
|
||||
clear_tv(cur_item);
|
||||
retval = FAIL;
|
||||
goto theend;
|
||||
}
|
||||
li->li_tv = *cur_item;
|
||||
list_append(top_item->jd_tv.vval.v_list, li);
|
||||
}
|
||||
if (cur_item != NULL)
|
||||
cur_item = &item;
|
||||
|
||||
json_skip_white(reader);
|
||||
p = reader->js_buf + reader->js_used;
|
||||
if (*p == ',')
|
||||
++reader->js_used;
|
||||
else if (*p != ']')
|
||||
{
|
||||
if (*p == NUL)
|
||||
retval = MAYBE;
|
||||
else
|
||||
{
|
||||
EMSG(_(e_invarg));
|
||||
retval = FAIL;
|
||||
}
|
||||
goto theend;
|
||||
}
|
||||
break;
|
||||
|
||||
case JSON_OBJECT_KEY:
|
||||
json_skip_white(reader);
|
||||
p = reader->js_buf + reader->js_used;
|
||||
if (*p != ':')
|
||||
{
|
||||
if (cur_item != NULL)
|
||||
clear_tv(cur_item);
|
||||
if (*p == NUL)
|
||||
retval = MAYBE;
|
||||
else
|
||||
{
|
||||
EMSG(_(e_invarg));
|
||||
retval = FAIL;
|
||||
}
|
||||
goto theend;
|
||||
}
|
||||
++reader->js_used;
|
||||
json_skip_white(reader);
|
||||
top_item->jd_type = JSON_OBJECT;
|
||||
if (cur_item != NULL)
|
||||
cur_item = &item;
|
||||
break;
|
||||
|
||||
case JSON_OBJECT:
|
||||
if (cur_item != NULL
|
||||
&& dict_find(top_item->jd_tv.vval.v_dict,
|
||||
top_item->jd_key, -1) != NULL)
|
||||
{
|
||||
EMSG2(_("E937: Duplicate key in JSON: \"%s\""),
|
||||
top_item->jd_key);
|
||||
clear_tv(&top_item->jd_key_tv);
|
||||
clear_tv(cur_item);
|
||||
retval = FAIL;
|
||||
goto theend;
|
||||
}
|
||||
|
||||
if (cur_item != NULL)
|
||||
{
|
||||
dictitem_T *di = dictitem_alloc(top_item->jd_key);
|
||||
|
||||
clear_tv(&top_item->jd_key_tv);
|
||||
if (di == NULL)
|
||||
{
|
||||
clear_tv(cur_item);
|
||||
retval = FAIL;
|
||||
goto theend;
|
||||
}
|
||||
di->di_tv = *cur_item;
|
||||
di->di_tv.v_lock = 0;
|
||||
if (dict_add(top_item->jd_tv.vval.v_dict, di) == FAIL)
|
||||
{
|
||||
dictitem_free(di);
|
||||
retval = FAIL;
|
||||
goto theend;
|
||||
}
|
||||
}
|
||||
reader->js_used += len;
|
||||
return OK;
|
||||
}
|
||||
if (STRNICMP((char *)p, "false", 5) == 0)
|
||||
{
|
||||
reader->js_used += 5;
|
||||
if (res != NULL)
|
||||
|
||||
json_skip_white(reader);
|
||||
p = reader->js_buf + reader->js_used;
|
||||
if (*p == ',')
|
||||
++reader->js_used;
|
||||
else if (*p != '}')
|
||||
{
|
||||
res->v_type = VAR_SPECIAL;
|
||||
res->vval.v_number = VVAL_FALSE;
|
||||
if (*p == NUL)
|
||||
retval = MAYBE;
|
||||
else
|
||||
{
|
||||
EMSG(_(e_invarg));
|
||||
retval = FAIL;
|
||||
}
|
||||
goto theend;
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
if (STRNICMP((char *)p, "true", 4) == 0)
|
||||
{
|
||||
reader->js_used += 4;
|
||||
if (res != NULL)
|
||||
{
|
||||
res->v_type = VAR_SPECIAL;
|
||||
res->vval.v_number = VVAL_TRUE;
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
if (STRNICMP((char *)p, "null", 4) == 0)
|
||||
{
|
||||
reader->js_used += 4;
|
||||
if (res != NULL)
|
||||
{
|
||||
res->v_type = VAR_SPECIAL;
|
||||
res->vval.v_number = VVAL_NULL;
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
#ifdef FEAT_FLOAT
|
||||
if (STRNICMP((char *)p, "NaN", 3) == 0)
|
||||
{
|
||||
reader->js_used += 3;
|
||||
if (res != NULL)
|
||||
{
|
||||
res->v_type = VAR_FLOAT;
|
||||
res->vval.v_float = NAN;
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
if (STRNICMP((char *)p, "Infinity", 8) == 0)
|
||||
{
|
||||
reader->js_used += 8;
|
||||
if (res != NULL)
|
||||
{
|
||||
res->v_type = VAR_FLOAT;
|
||||
res->vval.v_float = INFINITY;
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
#endif
|
||||
/* check for truncated name */
|
||||
len = (int)(reader->js_end - (reader->js_buf + reader->js_used));
|
||||
if (
|
||||
(len < 5 && STRNICMP((char *)p, "false", len) == 0)
|
||||
#ifdef FEAT_FLOAT
|
||||
|| (len < 8 && STRNICMP((char *)p, "Infinity", len) == 0)
|
||||
|| (len < 3 && STRNICMP((char *)p, "NaN", len) == 0)
|
||||
#endif
|
||||
|| (len < 4 && (STRNICMP((char *)p, "true", len) == 0
|
||||
|| STRNICMP((char *)p, "null", len) == 0)))
|
||||
return MAYBE;
|
||||
break;
|
||||
top_item->jd_type = JSON_OBJECT_KEY;
|
||||
if (cur_item != NULL)
|
||||
cur_item = &top_item->jd_key_tv;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Get here when parsing failed. */
|
||||
if (res != NULL)
|
||||
{
|
||||
clear_tv(res);
|
||||
res->v_type = VAR_SPECIAL;
|
||||
res->vval.v_number = VVAL_NONE;
|
||||
}
|
||||
return FAIL;
|
||||
EMSG(_(e_invarg));
|
||||
|
||||
theend:
|
||||
ga_clear(&stack);
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -884,10 +1016,17 @@ json_decode_all(js_read_T *reader, typval_T *res, int options)
|
||||
json_skip_white(reader);
|
||||
ret = json_decode_item(reader, res, options);
|
||||
if (ret != OK)
|
||||
{
|
||||
if (ret == MAYBE)
|
||||
EMSG(_(e_invarg));
|
||||
return FAIL;
|
||||
}
|
||||
json_skip_white(reader);
|
||||
if (reader->js_buf[reader->js_used] != NUL)
|
||||
{
|
||||
EMSG(_(e_trailing));
|
||||
return FAIL;
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -181,7 +181,7 @@ test_fill_called_on_string(void)
|
||||
reader.js_buf = (char_u *)" \"foo";
|
||||
reader.js_end = reader.js_buf + STRLEN(reader.js_buf);
|
||||
reader.js_cookie = " \"foobar\" ";
|
||||
assert(json_decode_string(&reader, NULL) == OK);
|
||||
assert(json_decode_string(&reader, NULL, '"') == OK);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
+1
-1
@@ -885,7 +885,7 @@ failret:
|
||||
}
|
||||
|
||||
/*
|
||||
* Write list of strings to file
|
||||
* Write "list" of strings to file "fd".
|
||||
*/
|
||||
int
|
||||
write_list(FILE *fd, list_T *list, int binary)
|
||||
|
||||
+19
-11
@@ -5428,7 +5428,6 @@ static int skip_label(linenr_T, char_u **pp);
|
||||
static int cin_first_id_amount(void);
|
||||
static int cin_get_equal_amount(linenr_T lnum);
|
||||
static int cin_ispreproc(char_u *);
|
||||
static int cin_ispreproc_cont(char_u **pp, linenr_T *lnump);
|
||||
static int cin_iscomment(char_u *);
|
||||
static int cin_islinecomment(char_u *);
|
||||
static int cin_isterminated(char_u *, int, int);
|
||||
@@ -6008,13 +6007,18 @@ cin_ispreproc(char_u *s)
|
||||
* Return TRUE if line "*pp" at "*lnump" is a preprocessor statement or a
|
||||
* continuation line of a preprocessor statement. Decrease "*lnump" to the
|
||||
* start and return the line in "*pp".
|
||||
* Put the amount of indent in "*amount".
|
||||
*/
|
||||
static int
|
||||
cin_ispreproc_cont(char_u **pp, linenr_T *lnump)
|
||||
cin_ispreproc_cont(char_u **pp, linenr_T *lnump, int *amount)
|
||||
{
|
||||
char_u *line = *pp;
|
||||
linenr_T lnum = *lnump;
|
||||
int retval = FALSE;
|
||||
int candidate_amount = *amount;
|
||||
|
||||
if (*line != NUL && line[STRLEN(line) - 1] == '\\')
|
||||
candidate_amount = get_indent_lnum(lnum);
|
||||
|
||||
for (;;)
|
||||
{
|
||||
@@ -6033,6 +6037,8 @@ cin_ispreproc_cont(char_u **pp, linenr_T *lnump)
|
||||
|
||||
if (lnum != *lnump)
|
||||
*pp = ml_get(*lnump);
|
||||
if (retval)
|
||||
*amount = candidate_amount;
|
||||
return retval;
|
||||
}
|
||||
|
||||
@@ -7396,7 +7402,7 @@ get_c_indent(void)
|
||||
l = skipwhite(ml_get(lnum));
|
||||
if (cin_nocode(l)) /* skip comment lines */
|
||||
continue;
|
||||
if (cin_ispreproc_cont(&l, &lnum))
|
||||
if (cin_ispreproc_cont(&l, &lnum, &amount))
|
||||
continue; /* ignore #define, #if, etc. */
|
||||
curwin->w_cursor.lnum = lnum;
|
||||
|
||||
@@ -7809,10 +7815,10 @@ get_c_indent(void)
|
||||
*/
|
||||
if (curwin->w_cursor.lnum <= ourscope)
|
||||
{
|
||||
/* we reached end of scope:
|
||||
* if looking for a enum or structure initialization
|
||||
/* We reached end of scope:
|
||||
* If looking for a enum or structure initialization
|
||||
* go further back:
|
||||
* if it is an initializer (enum xxx or xxx =), then
|
||||
* If it is an initializer (enum xxx or xxx =), then
|
||||
* don't add ind_continuation, otherwise it is a variable
|
||||
* declaration:
|
||||
* int x,
|
||||
@@ -7851,7 +7857,8 @@ get_c_indent(void)
|
||||
/*
|
||||
* Skip preprocessor directives and blank lines.
|
||||
*/
|
||||
if (cin_ispreproc_cont(&l, &curwin->w_cursor.lnum))
|
||||
if (cin_ispreproc_cont(&l, &curwin->w_cursor.lnum,
|
||||
&amount))
|
||||
continue;
|
||||
|
||||
if (cin_nocode(l))
|
||||
@@ -7968,7 +7975,8 @@ get_c_indent(void)
|
||||
}
|
||||
|
||||
/* Skip preprocessor directives and blank lines. */
|
||||
if (cin_ispreproc_cont(&l, &curwin->w_cursor.lnum))
|
||||
if (cin_ispreproc_cont(&l, &curwin->w_cursor.lnum,
|
||||
&amount))
|
||||
continue;
|
||||
|
||||
/* Finally the actual check for "namespace". */
|
||||
@@ -8144,7 +8152,7 @@ get_c_indent(void)
|
||||
* unlocked it)
|
||||
*/
|
||||
l = ml_get_curline();
|
||||
if (cin_ispreproc_cont(&l, &curwin->w_cursor.lnum)
|
||||
if (cin_ispreproc_cont(&l, &curwin->w_cursor.lnum, &amount)
|
||||
|| cin_nocode(l))
|
||||
continue;
|
||||
|
||||
@@ -8865,7 +8873,7 @@ term_again:
|
||||
/*
|
||||
* Skip preprocessor directives and blank lines.
|
||||
*/
|
||||
if (cin_ispreproc_cont(&l, &curwin->w_cursor.lnum))
|
||||
if (cin_ispreproc_cont(&l, &curwin->w_cursor.lnum, &amount))
|
||||
continue;
|
||||
|
||||
if (cin_nocode(l))
|
||||
@@ -8966,7 +8974,7 @@ term_again:
|
||||
{
|
||||
look = ml_get(--curwin->w_cursor.lnum);
|
||||
if (!(cin_nocode(look) || cin_ispreproc_cont(
|
||||
&look, &curwin->w_cursor.lnum)))
|
||||
&look, &curwin->w_cursor.lnum, &amount)))
|
||||
break;
|
||||
}
|
||||
if (curwin->w_cursor.lnum > 0
|
||||
|
||||
+1
-1
@@ -403,7 +403,7 @@ incl(pos_T *lp)
|
||||
int
|
||||
dec_cursor(void)
|
||||
{
|
||||
return dec(&curwin->w_cursor);
|
||||
return dec(&curwin->w_cursor);
|
||||
}
|
||||
|
||||
int
|
||||
|
||||
+6
-6
@@ -50,7 +50,7 @@ enum
|
||||
NFA_CONCAT, /* concatenate two previous items (postfix
|
||||
* only) */
|
||||
NFA_OR, /* \| (postfix only) */
|
||||
NFA_STAR, /* greedy * (posfix only) */
|
||||
NFA_STAR, /* greedy * (postfix only) */
|
||||
NFA_STAR_NONGREEDY, /* non-greedy * (postfix only) */
|
||||
NFA_QUEST, /* greedy \? (postfix only) */
|
||||
NFA_QUEST_NONGREEDY, /* non-greedy \? (postfix only) */
|
||||
@@ -1359,7 +1359,7 @@ nfa_regatom(void)
|
||||
rc_did_emsg = TRUE;
|
||||
return FAIL;
|
||||
}
|
||||
EMSGN("INTERNAL: Unknown character class char: %ld", c);
|
||||
IEMSGN("INTERNAL: Unknown character class char: %ld", c);
|
||||
return FAIL;
|
||||
}
|
||||
#ifdef FEAT_MBYTE
|
||||
@@ -2169,7 +2169,7 @@ nfa_regpiece(void)
|
||||
* maximum is much larger than the minimum and when the maximum is
|
||||
* large. Bail out if we can use the other engine. */
|
||||
if ((nfa_re_flags & RE_AUTO)
|
||||
&& (maxval > minval + 200 || maxval > 500))
|
||||
&& (maxval > 500 || maxval > minval + 200))
|
||||
return FAIL;
|
||||
|
||||
/* Ignore previous call to nfa_regatom() */
|
||||
@@ -4925,7 +4925,7 @@ check_char_class(int class, int c)
|
||||
|
||||
default:
|
||||
/* should not be here :P */
|
||||
EMSGN(_(e_ill_char_class), class);
|
||||
IEMSGN(_(e_ill_char_class), class);
|
||||
return FAIL;
|
||||
}
|
||||
return FAIL;
|
||||
@@ -6688,7 +6688,7 @@ nfa_regmatch(
|
||||
|
||||
#ifdef DEBUG
|
||||
if (c < 0)
|
||||
EMSGN("INTERNAL: Negative state char: %ld", c);
|
||||
IEMSGN("INTERNAL: Negative state char: %ld", c);
|
||||
#endif
|
||||
result = (c == curc);
|
||||
|
||||
@@ -7216,7 +7216,7 @@ nfa_regcomp(char_u *expr, int re_flags)
|
||||
{
|
||||
/* TODO: only give this error for debugging? */
|
||||
if (post_ptr >= post_end)
|
||||
EMSGN("Internal error: estimated max number of states insufficient: %ld", post_end - post_start);
|
||||
IEMSGN("Internal error: estimated max number of states insufficient: %ld", post_end - post_start);
|
||||
goto fail; /* Cascaded (syntax?) error */
|
||||
}
|
||||
|
||||
|
||||
+3
-1
@@ -3650,7 +3650,7 @@ win_line(
|
||||
if (fdc > 0)
|
||||
{
|
||||
/* Draw the 'foldcolumn'. Allocate a buffer, "extra" may
|
||||
* already be in used. */
|
||||
* already be in use. */
|
||||
p_extra_free = alloc(12 + 1);
|
||||
|
||||
if (p_extra_free != NULL)
|
||||
@@ -10373,6 +10373,8 @@ draw_tabline(void)
|
||||
#endif
|
||||
);
|
||||
|
||||
if (ScreenLines == NULL)
|
||||
return;
|
||||
redraw_tabline = FALSE;
|
||||
|
||||
#ifdef FEAT_GUI_TABLINE
|
||||
|
||||
+36
-8
@@ -6383,7 +6383,9 @@ syntax_present(win_T *win)
|
||||
static enum
|
||||
{
|
||||
EXP_SUBCMD, /* expand ":syn" sub-commands */
|
||||
EXP_CASE /* expand ":syn case" arguments */
|
||||
EXP_CASE, /* expand ":syn case" arguments */
|
||||
EXP_SPELL, /* expand ":syn spell" arguments */
|
||||
EXP_SYNC /* expand ":syn sync" arguments */
|
||||
} expand_what;
|
||||
|
||||
/*
|
||||
@@ -6434,6 +6436,10 @@ set_context_in_syntax_cmd(expand_T *xp, char_u *arg)
|
||||
xp->xp_context = EXPAND_NOTHING;
|
||||
else if (STRNICMP(arg, "case", p - arg) == 0)
|
||||
expand_what = EXP_CASE;
|
||||
else if (STRNICMP(arg, "spell", p - arg) == 0)
|
||||
expand_what = EXP_SPELL;
|
||||
else if (STRNICMP(arg, "sync", p - arg) == 0)
|
||||
expand_what = EXP_SYNC;
|
||||
else if ( STRNICMP(arg, "keyword", p - arg) == 0
|
||||
|| STRNICMP(arg, "region", p - arg) == 0
|
||||
|| STRNICMP(arg, "match", p - arg) == 0
|
||||
@@ -6445,8 +6451,6 @@ set_context_in_syntax_cmd(expand_T *xp, char_u *arg)
|
||||
}
|
||||
}
|
||||
|
||||
static char *(case_args[]) = {"match", "ignore", NULL};
|
||||
|
||||
/*
|
||||
* Function given to ExpandGeneric() to obtain the list syntax names for
|
||||
* expansion.
|
||||
@@ -6454,9 +6458,31 @@ static char *(case_args[]) = {"match", "ignore", NULL};
|
||||
char_u *
|
||||
get_syntax_name(expand_T *xp UNUSED, int idx)
|
||||
{
|
||||
if (expand_what == EXP_SUBCMD)
|
||||
return (char_u *)subcommands[idx].name;
|
||||
return (char_u *)case_args[idx];
|
||||
switch (expand_what)
|
||||
{
|
||||
case EXP_SUBCMD:
|
||||
return (char_u *)subcommands[idx].name;
|
||||
case EXP_CASE:
|
||||
{
|
||||
static char *case_args[] = {"match", "ignore", NULL};
|
||||
return (char_u *)case_args[idx];
|
||||
}
|
||||
case EXP_SPELL:
|
||||
{
|
||||
static char *spell_args[] =
|
||||
{"toplevel", "notoplevel", "default", NULL};
|
||||
return (char_u *)spell_args[idx];
|
||||
}
|
||||
case EXP_SYNC:
|
||||
{
|
||||
static char *sync_args[] =
|
||||
{"ccomment", "clear", "fromstart",
|
||||
"linebreaks=", "linecont", "lines=", "match",
|
||||
"maxlines=", "minlines=", "region", NULL};
|
||||
return (char_u *)sync_args[idx];
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#endif /* FEAT_CMDL_COMPL */
|
||||
@@ -6704,8 +6730,10 @@ syntime_report(void)
|
||||
}
|
||||
}
|
||||
|
||||
/* sort on total time */
|
||||
qsort(ga.ga_data, (size_t)ga.ga_len, sizeof(time_entry_T),
|
||||
/* Sort on total time. Skip if there are no items to avoid passing NULL
|
||||
* pointer to qsort(). */
|
||||
if (ga.ga_len > 1)
|
||||
qsort(ga.ga_data, (size_t)ga.ga_len, sizeof(time_entry_T),
|
||||
syn_compare_syntime);
|
||||
|
||||
MSG_PUTS_TITLE(_(" TOTAL COUNT MATCH SLOWEST AVERAGE NAME PATTERN"));
|
||||
|
||||
+6
-2
@@ -6075,8 +6075,12 @@ hex_digit(int c)
|
||||
guicolor_T
|
||||
gui_get_color_cmn(char_u *name)
|
||||
{
|
||||
/* On MS-Windows an RGB macro is available and it's different from ours,
|
||||
* but does what is needed. */
|
||||
/* On MS-Windows an RGB macro is available and it produces 0x00bbggrr color
|
||||
* values as used by the MS-Windows GDI api. It should be used only for
|
||||
* MS-Windows GDI builds. */
|
||||
# if defined(RGB) && defined(WIN32) && !defined(FEAT_GUI)
|
||||
# undef RGB
|
||||
# endif
|
||||
# ifndef RGB
|
||||
# define RGB(r, g, b) ((r<<16) | (g<<8) | (b))
|
||||
# endif
|
||||
|
||||
@@ -184,6 +184,7 @@ NEW_TESTS = test_arglist.res \
|
||||
test_stat.res \
|
||||
test_substitute.res \
|
||||
test_syntax.res \
|
||||
test_system.res \
|
||||
test_textobjects.res \
|
||||
test_undo.res \
|
||||
test_usercommands.res \
|
||||
|
||||
@@ -44,12 +44,12 @@ $(DOSTMP_INFILES): $(*B).in
|
||||
# This moves test99.in to test99.in.bak temporarily.
|
||||
$(TEST_OUTFILES): $(DOSTMP)\$(*B).in
|
||||
-@if exist test.out DEL test.out
|
||||
move $(*B).in $(*B).in.bak
|
||||
copy $(DOSTMP)\$(*B).in $(*B).in
|
||||
copy $(*B).ok test.ok
|
||||
move $(*B).in $(*B).in.bak > nul
|
||||
copy $(DOSTMP)\$(*B).in $(*B).in > nul
|
||||
copy $(*B).ok test.ok > nul
|
||||
$(VIMPROG) -u dos.vim $(NO_PLUGIN) -s dotest.in $(*B).in
|
||||
-@if exist test.out MOVE /y test.out $(DOSTMP)\$(*B).out
|
||||
-@if exist $(*B).in.bak move /y $(*B).in.bak $(*B).in
|
||||
-@if exist test.out MOVE /y test.out $(DOSTMP)\$(*B).out > nul
|
||||
-@if exist $(*B).in.bak move /y $(*B).in.bak $(*B).in > nul
|
||||
-@if exist test.ok del test.ok
|
||||
-@if exist Xdir1 rd /s /q Xdir1
|
||||
-@if exist Xfind rd /s /q Xfind
|
||||
@@ -58,10 +58,10 @@ $(TEST_OUTFILES): $(DOSTMP)\$(*B).in
|
||||
$(VIMPROG) -u dos.vim $(NO_PLUGIN) "+set ff=unix|f test.out|wq" \
|
||||
$(DOSTMP)\$(*B).out
|
||||
@diff test.out $*.ok & if errorlevel 1 \
|
||||
( move /y test.out $*.failed \
|
||||
( move /y test.out $*.failed > nul \
|
||||
& del $(DOSTMP)\$(*B).out \
|
||||
& echo $* FAILED >> test.log ) \
|
||||
else ( move /y test.out $*.out )
|
||||
else ( move /y test.out $*.out > nul )
|
||||
|
||||
# Must run test1 first to create small.vim.
|
||||
# This rule must come after the one that copies the input files to dostmp to
|
||||
|
||||
@@ -14,10 +14,10 @@ can. Use an old style test when it needs to run without the +eval feature.
|
||||
TO ADD A NEW STYLE TEST:
|
||||
|
||||
1) Create a test_<subject>.vim file.
|
||||
2) Add test_<subject>.vim to NEW_TESTS in Make_all.mak in alphabetical order.
|
||||
3) Use make test_<subject>.res to run a single test in src/testdir/.
|
||||
2) Add test_<subject>.res to NEW_TESTS in Make_all.mak in alphabetical order.
|
||||
3) Also add an entry in src/Makefile.
|
||||
4) Use make test_<subject>.res to run a single test in src/testdir/.
|
||||
Use make test_<subject> to run a single test in src/.
|
||||
4) Also add an entry in src/Makefile.
|
||||
|
||||
What you can use (see test_assert.vim for an example):
|
||||
- Call assert_equal(), assert_true(), assert_false(), etc.
|
||||
|
||||
@@ -2317,6 +2317,25 @@ h,
|
||||
i;
|
||||
JSEND
|
||||
|
||||
STARTTEST
|
||||
:set cin cino&
|
||||
/start of define
|
||||
=/end of define
|
||||
ENDTEST
|
||||
|
||||
/* start of define */
|
||||
{
|
||||
}
|
||||
#define AAA \
|
||||
BBB\
|
||||
CCC
|
||||
|
||||
#define CNT \
|
||||
1 + \
|
||||
2 + \
|
||||
4
|
||||
/* end of define */
|
||||
|
||||
STARTTEST
|
||||
:g/^STARTTEST/.,/^ENDTEST/d
|
||||
:1;/start of AUTO/,$wq! test.out
|
||||
|
||||
@@ -2080,3 +2080,17 @@ var a,
|
||||
i;
|
||||
JSEND
|
||||
|
||||
|
||||
/* start of define */
|
||||
{
|
||||
}
|
||||
#define AAA \
|
||||
BBB\
|
||||
CCC
|
||||
|
||||
#define CNT \
|
||||
1 + \
|
||||
2 + \
|
||||
4
|
||||
/* end of define */
|
||||
|
||||
|
||||
@@ -16,7 +16,9 @@ source test_file_perm.vim
|
||||
source test_fileformat.vim
|
||||
source test_filter_cmd.vim
|
||||
source test_filter_map.vim
|
||||
source test_float_func.vim
|
||||
source test_fnamemodify.vim
|
||||
source test_functions.vim
|
||||
source test_glob2regpat.vim
|
||||
source test_goto.vim
|
||||
source test_help_tagjump.vim
|
||||
|
||||
@@ -279,7 +279,6 @@ func Ch_channel_handler(port)
|
||||
endfunc
|
||||
|
||||
func Test_channel_handler()
|
||||
call ch_logfile('channellog', 'w')
|
||||
call ch_log('Test_channel_handler()')
|
||||
let g:Ch_reply = ""
|
||||
let s:chopt.callback = 'Ch_handler'
|
||||
|
||||
@@ -52,3 +52,25 @@ func Test_filter_fails()
|
||||
call assert_fails('filter! /pat/', 'E476:')
|
||||
call assert_fails('filter! /pat/ asdf', 'E492:')
|
||||
endfunc
|
||||
|
||||
function s:complete_filter_cmd(filtcmd)
|
||||
let keystroke = "\<TAB>\<C-R>=execute('let cmdline = getcmdline()')\<CR>\<C-C>"
|
||||
let cmdline = ''
|
||||
call feedkeys(':' . a:filtcmd . keystroke, 'ntx')
|
||||
return cmdline
|
||||
endfunction
|
||||
|
||||
func Test_filter_cmd_completion()
|
||||
" Do not complete pattern
|
||||
call assert_equal("filter \t", s:complete_filter_cmd('filter '))
|
||||
call assert_equal("filter pat\t", s:complete_filter_cmd('filter pat'))
|
||||
call assert_equal("filter /pat\t", s:complete_filter_cmd('filter /pat'))
|
||||
call assert_equal("filter /pat/\t", s:complete_filter_cmd('filter /pat/'))
|
||||
|
||||
" Complete after string pattern
|
||||
call assert_equal('filter pat print', s:complete_filter_cmd('filter pat pri'))
|
||||
|
||||
" Complete after regexp pattern
|
||||
call assert_equal('filter /pat/ print', s:complete_filter_cmd('filter /pat/ pri'))
|
||||
call assert_equal('filter #pat# print', s:complete_filter_cmd('filter #pat# pri'))
|
||||
endfunc
|
||||
|
||||
@@ -0,0 +1,284 @@
|
||||
" test float functions
|
||||
|
||||
if !has('float')
|
||||
finish
|
||||
end
|
||||
|
||||
func Test_abs()
|
||||
call assert_equal('1.23', string(abs(1.23)))
|
||||
call assert_equal('1.23', string(abs(-1.23)))
|
||||
call assert_equal('0.0', string(abs(0.0)))
|
||||
call assert_equal('0.0', string(abs(1.0/(1.0/0.0))))
|
||||
call assert_equal('0.0', string(abs(-1.0/(1.0/0.0))))
|
||||
call assert_equal('inf', string(abs(1.0/0.0)))
|
||||
call assert_equal('inf', string(abs(-1.0/0.0)))
|
||||
call assert_equal('nan', string(abs(0.0/0.0)))
|
||||
call assert_equal('12', string(abs('-12abc')))
|
||||
call assert_fails("call abs([])", 'E745:')
|
||||
call assert_fails("call abs({})", 'E728:')
|
||||
call assert_fails("call abs(function('string'))", 'E703:')
|
||||
endfunc
|
||||
|
||||
func Test_sqrt()
|
||||
call assert_equal('0.0', string(sqrt(0.0)))
|
||||
call assert_equal('1.414214', string(sqrt(2.0)))
|
||||
call assert_equal('inf', string(sqrt(1.0/0.0)))
|
||||
call assert_equal('nan', string(sqrt(-1.0)))
|
||||
call assert_equal('nan', string(sqrt(0.0/0.0)))
|
||||
call assert_fails('call sqrt("")', 'E808:')
|
||||
endfunc
|
||||
|
||||
func Test_log()
|
||||
call assert_equal('0.0', string(log(1.0)))
|
||||
call assert_equal('-0.693147', string(log(0.5)))
|
||||
call assert_equal('-inf', string(log(0.0)))
|
||||
call assert_equal('nan', string(log(-1.0)))
|
||||
call assert_equal('inf', string(log(1.0/0.0)))
|
||||
call assert_equal('nan', string(log(0.0/0.0)))
|
||||
call assert_fails('call log("")', 'E808:')
|
||||
endfunc
|
||||
|
||||
func Test_log10()
|
||||
call assert_equal('0.0', string(log10(1.0)))
|
||||
call assert_equal('2.0', string(log10(100.0)))
|
||||
call assert_equal('2.079181', string(log10(120.0)))
|
||||
call assert_equal('-inf', string(log10(0.0)))
|
||||
call assert_equal('nan', string(log10(-1.0)))
|
||||
call assert_equal('inf', string(log10(1.0/0.0)))
|
||||
call assert_equal('nan', string(log10(0.0/0.0)))
|
||||
call assert_fails('call log10("")', 'E808:')
|
||||
endfunc
|
||||
|
||||
func Test_exp()
|
||||
call assert_equal('1.0', string(exp(0.0)))
|
||||
call assert_equal('7.389056', string(exp(2.0)))
|
||||
call assert_equal('0.367879', string(exp(-1.0)))
|
||||
call assert_equal('inf', string(exp(1.0/0.0)))
|
||||
call assert_equal('0.0', string(exp(-1.0/0.0)))
|
||||
call assert_equal('nan', string(exp(0.0/0.0)))
|
||||
call assert_fails('call exp("")', 'E808:')
|
||||
endfunc
|
||||
|
||||
func Test_sin()
|
||||
call assert_equal('0.0', string(sin(0.0)))
|
||||
call assert_equal('0.841471', string(sin(1.0)))
|
||||
call assert_equal('-0.479426', string(sin(-0.5)))
|
||||
call assert_equal('nan', string(sin(0.0/0.0)))
|
||||
call assert_equal('nan', string(sin(1.0/0.0)))
|
||||
call assert_equal('0.0', string(sin(1.0/(1.0/0.0))))
|
||||
call assert_equal('-0.0', string(sin(-1.0/(1.0/0.0))))
|
||||
call assert_fails('call sin("")', 'E808:')
|
||||
endfunc
|
||||
|
||||
func Test_asin()
|
||||
call assert_equal('0.0', string(asin(0.0)))
|
||||
call assert_equal('1.570796', string(asin(1.0)))
|
||||
call assert_equal('-0.523599', string(asin(-0.5)))
|
||||
call assert_equal('nan', string(asin(1.1)))
|
||||
call assert_equal('nan', string(asin(1.0/0.0)))
|
||||
call assert_equal('nan', string(asin(0.0/0.0)))
|
||||
call assert_fails('call asin("")', 'E808:')
|
||||
endfunc
|
||||
|
||||
func Test_sinh()
|
||||
call assert_equal('0.0', string(sinh(0.0)))
|
||||
call assert_equal('0.521095', string(sinh(0.5)))
|
||||
call assert_equal('-1.026517', string(sinh(-0.9)))
|
||||
call assert_equal('inf', string(sinh(1.0/0.0)))
|
||||
call assert_equal('-inf', string(sinh(-1.0/0.0)))
|
||||
call assert_equal('nan', string(sinh(0.0/0.0)))
|
||||
call assert_fails('call sinh("")', 'E808:')
|
||||
endfunc
|
||||
|
||||
func Test_cos()
|
||||
call assert_equal('1.0', string(cos(0.0)))
|
||||
call assert_equal('0.540302', string(cos(1.0)))
|
||||
call assert_equal('0.877583', string(cos(-0.5)))
|
||||
call assert_equal('nan', string(cos(0.0/0.0)))
|
||||
call assert_equal('nan', string(cos(1.0/0.0)))
|
||||
call assert_fails('call cos("")', 'E808:')
|
||||
endfunc
|
||||
|
||||
func Test_acos()
|
||||
call assert_equal('1.570796', string(acos(0.0)))
|
||||
call assert_equal('0.0', string(acos(1.0)))
|
||||
call assert_equal('3.141593', string(acos(-1.0)))
|
||||
call assert_equal('2.094395', string(acos(-0.5)))
|
||||
call assert_equal('nan', string(acos(1.1)))
|
||||
call assert_equal('nan', string(acos(1.0/0.0)))
|
||||
call assert_equal('nan', string(acos(0.0/0.0)))
|
||||
call assert_fails('call acos("")', 'E808:')
|
||||
endfunc
|
||||
|
||||
func Test_cosh()
|
||||
call assert_equal('1.0', string(cosh(0.0)))
|
||||
call assert_equal('1.127626', string(cosh(0.5)))
|
||||
call assert_equal('inf', string(cosh(1.0/0.0)))
|
||||
call assert_equal('inf', string(cosh(-1.0/0.0)))
|
||||
call assert_equal('nan', string(cosh(0.0/0.0)))
|
||||
call assert_fails('call cosh("")', 'E808:')
|
||||
endfunc
|
||||
|
||||
func Test_tan()
|
||||
call assert_equal('0.0', string(tan(0.0)))
|
||||
call assert_equal('0.546302', string(tan(0.5)))
|
||||
call assert_equal('-0.546302', string(tan(-0.5)))
|
||||
call assert_equal('nan', string(tan(1.0/0.0)))
|
||||
call assert_equal('nan', string(cos(0.0/0.0)))
|
||||
call assert_equal('0.0', string(tan(1.0/(1.0/0.0))))
|
||||
call assert_equal('-0.0', string(tan(-1.0/(1.0/0.0))))
|
||||
call assert_fails('call tan("")', 'E808:')
|
||||
endfunc
|
||||
|
||||
func Test_atan()
|
||||
call assert_equal('0.0', string(atan(0.0)))
|
||||
call assert_equal('0.463648', string(atan(0.5)))
|
||||
call assert_equal('-0.785398', string(atan(-1.0)))
|
||||
call assert_equal('1.570796', string(atan(1.0/0.0)))
|
||||
call assert_equal('-1.570796', string(atan(-1.0/0.0)))
|
||||
call assert_equal('nan', string(atan(0.0/0.0)))
|
||||
call assert_fails('call atan("")', 'E808:')
|
||||
endfunc
|
||||
|
||||
func Test_atan2()
|
||||
call assert_equal('-2.356194', string(atan2(-1, -1)))
|
||||
call assert_equal('2.356194', string(atan2(1, -1)))
|
||||
call assert_equal('0.0', string(atan2(1.0, 1.0/0.0)))
|
||||
call assert_equal('1.570796', string(atan2(1.0/0.0, 1.0)))
|
||||
call assert_equal('nan', string(atan2(0.0/0.0, 1.0)))
|
||||
call assert_fails('call atan2("", -1)', 'E808:')
|
||||
call assert_fails('call atan2(-1, "")', 'E808:')
|
||||
endfunc
|
||||
|
||||
func Test_tanh()
|
||||
call assert_equal('0.0', string(tanh(0.0)))
|
||||
call assert_equal('0.462117', string(tanh(0.5)))
|
||||
call assert_equal('-0.761594', string(tanh(-1.0)))
|
||||
call assert_equal('1.0', string(tanh(1.0/0.0)))
|
||||
call assert_equal('-1.0', string(tanh(-1.0/0.0)))
|
||||
call assert_equal('nan', string(tanh(0.0/0.0)))
|
||||
call assert_fails('call tanh("")', 'E808:')
|
||||
endfunc
|
||||
|
||||
func Test_fmod()
|
||||
call assert_equal('0.13', string(fmod(12.33, 1.22)))
|
||||
call assert_equal('-0.13', string(fmod(-12.33, 1.22)))
|
||||
call assert_equal('nan', string(fmod(1.0/0.0, 1.0)))
|
||||
" On Windows we get "nan" instead of 1.0, accept both.
|
||||
let res = string(fmod(1.0, 1.0/0.0))
|
||||
if res != 'nan'
|
||||
call assert_equal('1.0', res)
|
||||
endif
|
||||
call assert_equal('nan', string(fmod(1.0, 0.0)))
|
||||
call assert_fails("call fmod('', 1.22)", 'E808:')
|
||||
call assert_fails("call fmod(12.33, '')", 'E808:')
|
||||
endfunc
|
||||
|
||||
func Test_pow()
|
||||
call assert_equal('1.0', string(pow(0.0, 0.0)))
|
||||
call assert_equal('8.0', string(pow(2.0, 3.0)))
|
||||
call assert_equal('nan', string(pow(2.0, 0.0/0.0)))
|
||||
call assert_equal('nan', string(pow(0.0/0.0, 3.0)))
|
||||
call assert_equal('nan', string(pow(0.0/0.0, 3.0)))
|
||||
call assert_equal('inf', string(pow(2.0, 1.0/0.0)))
|
||||
call assert_equal('inf', string(pow(1.0/0.0, 3.0)))
|
||||
call assert_fails("call pow('', 2.0)", 'E808:')
|
||||
call assert_fails("call pow(2.0, '')", 'E808:')
|
||||
endfunc
|
||||
|
||||
func Test_str2float()
|
||||
call assert_equal('1.0', string(str2float('1')))
|
||||
call assert_equal('1.0', string(str2float(' 1 ')))
|
||||
call assert_equal('1.0', string(str2float(' 1.0 ')))
|
||||
call assert_equal('1.23', string(str2float('1.23')))
|
||||
call assert_equal('1.23', string(str2float('1.23abc')))
|
||||
call assert_equal('1.0e40', string(str2float('1e40')))
|
||||
call assert_equal('-1.23', string(str2float('-1.23')))
|
||||
call assert_equal('1.23', string(str2float(' + 1.23 ')))
|
||||
|
||||
call assert_equal('1.0', string(str2float('+1')))
|
||||
call assert_equal('1.0', string(str2float('+1')))
|
||||
call assert_equal('1.0', string(str2float(' +1 ')))
|
||||
call assert_equal('1.0', string(str2float(' + 1 ')))
|
||||
|
||||
call assert_equal('-1.0', string(str2float('-1')))
|
||||
call assert_equal('-1.0', string(str2float('-1')))
|
||||
call assert_equal('-1.0', string(str2float(' -1 ')))
|
||||
call assert_equal('-1.0', string(str2float(' - 1 ')))
|
||||
|
||||
call assert_equal('0.0', string(str2float('+0.0')))
|
||||
call assert_equal('-0.0', string(str2float('-0.0')))
|
||||
call assert_equal('inf', string(str2float('1e1000')))
|
||||
call assert_equal('inf', string(str2float('inf')))
|
||||
call assert_equal('-inf', string(str2float('-inf')))
|
||||
call assert_equal('inf', string(str2float('+inf')))
|
||||
call assert_equal('inf', string(str2float('Inf')))
|
||||
call assert_equal('inf', string(str2float(' +inf ')))
|
||||
call assert_equal('nan', string(str2float('nan')))
|
||||
call assert_equal('nan', string(str2float('NaN')))
|
||||
call assert_equal('nan', string(str2float(' nan ')))
|
||||
|
||||
call assert_fails("call str2float(1.2)", 'E806:')
|
||||
call assert_fails("call str2float([])", 'E730:')
|
||||
call assert_fails("call str2float({})", 'E731:')
|
||||
call assert_fails("call str2float(function('string'))", 'E729:')
|
||||
endfunc
|
||||
|
||||
func Test_floor()
|
||||
call assert_equal('2.0', string(floor(2.0)))
|
||||
call assert_equal('2.0', string(floor(2.11)))
|
||||
call assert_equal('2.0', string(floor(2.99)))
|
||||
call assert_equal('-3.0', string(floor(-2.11)))
|
||||
call assert_equal('-3.0', string(floor(-2.99)))
|
||||
call assert_equal('nan', string(floor(0.0/0.0)))
|
||||
call assert_equal('inf', string(floor(1.0/0.0)))
|
||||
call assert_equal('-inf', string(floor(-1.0/0.0)))
|
||||
call assert_fails("call floor('')", 'E808:')
|
||||
endfunc
|
||||
|
||||
func Test_ceil()
|
||||
call assert_equal('2.0', string(ceil(2.0)))
|
||||
call assert_equal('3.0', string(ceil(2.11)))
|
||||
call assert_equal('3.0', string(ceil(2.99)))
|
||||
call assert_equal('-2.0', string(ceil(-2.11)))
|
||||
call assert_equal('-2.0', string(ceil(-2.99)))
|
||||
call assert_equal('nan', string(ceil(0.0/0.0)))
|
||||
call assert_equal('inf', string(ceil(1.0/0.0)))
|
||||
call assert_equal('-inf', string(ceil(-1.0/0.0)))
|
||||
call assert_fails("call ceil('')", 'E808:')
|
||||
endfunc
|
||||
|
||||
func Test_round()
|
||||
call assert_equal('2.0', string(round(2.1)))
|
||||
call assert_equal('3.0', string(round(2.5)))
|
||||
call assert_equal('3.0', string(round(2.9)))
|
||||
call assert_equal('-2.0', string(round(-2.1)))
|
||||
call assert_equal('-3.0', string(round(-2.5)))
|
||||
call assert_equal('-3.0', string(round(-2.9)))
|
||||
call assert_equal('nan', string(round(0.0/0.0)))
|
||||
call assert_equal('inf', string(round(1.0/0.0)))
|
||||
call assert_equal('-inf', string(round(-1.0/0.0)))
|
||||
call assert_fails("call round('')", 'E808:')
|
||||
endfunc
|
||||
|
||||
func Test_trunc()
|
||||
call assert_equal('2.0', string(trunc(2.1)))
|
||||
call assert_equal('2.0', string(trunc(2.5)))
|
||||
call assert_equal('2.0', string(trunc(2.9)))
|
||||
call assert_equal('-2.0', string(trunc(-2.1)))
|
||||
call assert_equal('-2.0', string(trunc(-2.5)))
|
||||
call assert_equal('-2.0', string(trunc(-2.9)))
|
||||
call assert_equal('nan', string(trunc(0.0/0.0)))
|
||||
call assert_equal('inf', string(trunc(1.0/0.0)))
|
||||
call assert_equal('-inf', string(trunc(-1.0/0.0)))
|
||||
call assert_fails("call trunc('')", 'E808:')
|
||||
endfunc
|
||||
|
||||
func Test_isnan()
|
||||
call assert_equal(0, isnan(1.0))
|
||||
call assert_equal(1, isnan(0.0/0.0))
|
||||
call assert_equal(0, isnan(1.0/0.0))
|
||||
call assert_equal(0, isnan('a'))
|
||||
call assert_equal(0, isnan([]))
|
||||
call assert_equal(0, isnan({}))
|
||||
endfunc
|
||||
@@ -0,0 +1,18 @@
|
||||
" Tests for various functions.
|
||||
|
||||
func Test_str2nr()
|
||||
call assert_equal(0, str2nr(''))
|
||||
call assert_equal(1, str2nr('1'))
|
||||
call assert_equal(1, str2nr(' 1 '))
|
||||
|
||||
call assert_equal(1, str2nr('+1'))
|
||||
call assert_equal(1, str2nr('+ 1'))
|
||||
call assert_equal(1, str2nr(' + 1 '))
|
||||
|
||||
call assert_equal(-1, str2nr('-1'))
|
||||
call assert_equal(-1, str2nr('- 1'))
|
||||
call assert_equal(-1, str2nr(' - 1 '))
|
||||
|
||||
call assert_equal(123456789, str2nr('123456789'))
|
||||
call assert_equal(-123456789, str2nr('-123456789'))
|
||||
endfunc
|
||||
@@ -87,3 +87,20 @@ function Test_History()
|
||||
call assert_equal(-1, histnr('abc'))
|
||||
call assert_fails('call histnr([])', 'E730:')
|
||||
endfunction
|
||||
|
||||
function Test_Search_history_window()
|
||||
new
|
||||
call setline(1, ['a', 'b', 'a', 'b'])
|
||||
1
|
||||
call feedkeys("/a\<CR>", 'xt')
|
||||
call assert_equal('a', getline('.'))
|
||||
1
|
||||
call feedkeys("/b\<CR>", 'xt')
|
||||
call assert_equal('b', getline('.'))
|
||||
1
|
||||
" select the previous /a command
|
||||
call feedkeys("q/kk\<CR>", 'x!')
|
||||
call assert_equal('a', getline('.'))
|
||||
call assert_equal('a', @/)
|
||||
bwipe!
|
||||
endfunc
|
||||
|
||||
@@ -145,11 +145,14 @@ func Test_json_decode()
|
||||
call assert_equal("", json_decode('""'))
|
||||
|
||||
call assert_equal({'n': 1}, json_decode('{"n":1,}'))
|
||||
call assert_fails("call json_decode(\"{'n':'1',}\")", 'E474:')
|
||||
call assert_fails("call json_decode(\"'n'\")", 'E474:')
|
||||
|
||||
call assert_fails('call json_decode("\"")', "E474:")
|
||||
call assert_fails('call json_decode("blah")', "E474:")
|
||||
call assert_fails('call json_decode("true blah")', "E474:")
|
||||
call assert_fails('call json_decode("true blah")', "E488:")
|
||||
call assert_fails('call json_decode("<foobar>")', "E474:")
|
||||
call assert_fails('call json_decode("{\"a\":1,\"a\":2}")', "E937:")
|
||||
|
||||
call assert_fails('call json_decode("{")', "E474:")
|
||||
call assert_fails('call json_decode("{foobar}")', "E474:")
|
||||
@@ -254,8 +257,11 @@ func Test_js_decode()
|
||||
call assert_equal(v:none, js_decode(''))
|
||||
call assert_equal(type(v:none), type(js_decode('')))
|
||||
call assert_equal("", js_decode('""'))
|
||||
call assert_equal("", js_decode("''"))
|
||||
|
||||
call assert_equal('n', js_decode("'n'"))
|
||||
call assert_equal({'n': 1}, js_decode('{"n":1,}'))
|
||||
call assert_equal({'n': '1'}, js_decode("{'n':'1',}"))
|
||||
|
||||
call assert_fails('call js_decode("\"")', "E474:")
|
||||
call assert_fails('call js_decode("blah")', "E474:")
|
||||
|
||||
@@ -279,3 +279,18 @@ func Test_use_sub_pat()
|
||||
call X()
|
||||
bwipe!
|
||||
endfunc
|
||||
|
||||
func Test_searchpair()
|
||||
new
|
||||
call setline(1, ['other code here', '', '[', '" cursor here', ']'])
|
||||
4
|
||||
let a=searchpair('\[','',']','bW')
|
||||
call assert_equal(3, a)
|
||||
set nomagic
|
||||
4
|
||||
let a=searchpair('\[','',']','bW')
|
||||
call assert_equal(3, a)
|
||||
set magic
|
||||
q!
|
||||
endfunc
|
||||
|
||||
|
||||
@@ -150,6 +150,12 @@ func Test_syntax_completion()
|
||||
call feedkeys(":syn case \<C-A>\<C-B>\"\<CR>", 'tx')
|
||||
call assert_equal('"syn case ignore match', @:)
|
||||
|
||||
call feedkeys(":syn spell \<C-A>\<C-B>\"\<CR>", 'tx')
|
||||
call assert_equal('"syn spell default notoplevel toplevel', @:)
|
||||
|
||||
call feedkeys(":syn sync \<C-A>\<C-B>\"\<CR>", 'tx')
|
||||
call assert_equal('"syn sync ccomment clear fromstart linebreaks= linecont lines= match maxlines= minlines= region', @:)
|
||||
|
||||
call feedkeys(":syn list \<C-A>\<C-B>\"\<CR>", 'tx')
|
||||
call assert_match('^"syn list Boolean Character ', @:)
|
||||
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
" Tests for system() and systemlist()
|
||||
|
||||
function! Test_System()
|
||||
if !executable('echo') || !executable('cat') || !executable('wc')
|
||||
return
|
||||
endif
|
||||
let out = system('echo 123')
|
||||
" On Windows we may get a trailing space.
|
||||
if out != "123 \n"
|
||||
call assert_equal("123\n", out)
|
||||
endif
|
||||
|
||||
let out = systemlist('echo 123')
|
||||
" On Windows we may get a trailing space and CR.
|
||||
if out != ["123 \r"]
|
||||
call assert_equal(['123'], out)
|
||||
endif
|
||||
|
||||
call assert_equal('123', system('cat', '123'))
|
||||
call assert_equal(['123'], systemlist('cat', '123'))
|
||||
call assert_equal(["as\<NL>df"], systemlist('cat', ["as\<NL>df"]))
|
||||
|
||||
new Xdummy
|
||||
call setline(1, ['asdf', "pw\<NL>er", 'xxxx'])
|
||||
let out = system('wc -l', bufnr('%'))
|
||||
" On OS/X we get leading spaces
|
||||
let out = substitute(out, '^ *', '', '')
|
||||
call assert_equal("3\n", out)
|
||||
|
||||
let out = systemlist('wc -l', bufnr('%'))
|
||||
" On Windows we may get a trailing CR.
|
||||
if out != ["3\r"]
|
||||
" On OS/X we get leading spaces
|
||||
if type(out) == v:t_list
|
||||
let out[0] = substitute(out[0], '^ *', '', '')
|
||||
endif
|
||||
call assert_equal(['3'], out)
|
||||
endif
|
||||
|
||||
let out = systemlist('cat', bufnr('%'))
|
||||
" On Windows we may get a trailing CR.
|
||||
if out != ["asdf\r", "pw\<NL>er\r", "xxxx\r"]
|
||||
call assert_equal(['asdf', "pw\<NL>er", 'xxxx'], out)
|
||||
endif
|
||||
bwipe!
|
||||
|
||||
call assert_fails('call system("wc -l", 99999)', 'E86:')
|
||||
endfunction
|
||||
@@ -235,3 +235,31 @@ func Test_insert_expr()
|
||||
|
||||
close!
|
||||
endfunc
|
||||
|
||||
func Test_undofile_earlier()
|
||||
" Issue #1254
|
||||
" create undofile with timestamps older than Vim startup time.
|
||||
let t0 = localtime() - 43200
|
||||
call test_settime(t0)
|
||||
new Xfile
|
||||
call feedkeys("ione\<Esc>", 'xt')
|
||||
set ul=100
|
||||
call test_settime(t0 + 1)
|
||||
call feedkeys("otwo\<Esc>", 'xt')
|
||||
set ul=100
|
||||
call test_settime(t0 + 2)
|
||||
call feedkeys("othree\<Esc>", 'xt')
|
||||
set ul=100
|
||||
w
|
||||
wundo Xundofile
|
||||
bwipe!
|
||||
" restore normal timestamps.
|
||||
call test_settime(0)
|
||||
new Xfile
|
||||
rundo Xundofile
|
||||
earlier 1d
|
||||
call assert_equal('', getline(1))
|
||||
bwipe!
|
||||
call delete('Xfile')
|
||||
call delete('Xundofile')
|
||||
endfunc
|
||||
|
||||
+3
-5
@@ -2298,10 +2298,8 @@ undo_time(
|
||||
}
|
||||
else
|
||||
{
|
||||
/* When doing computations with time_t subtract starttime, because
|
||||
* time_t converted to a long may result in a wrong number. */
|
||||
if (dosec)
|
||||
target = (long)(curbuf->b_u_time_cur - starttime) + step;
|
||||
target = (long)(curbuf->b_u_time_cur) + step;
|
||||
else if (dofile)
|
||||
{
|
||||
if (step < 0)
|
||||
@@ -2350,7 +2348,7 @@ undo_time(
|
||||
else
|
||||
{
|
||||
if (dosec)
|
||||
closest = (long)(vim_time() - starttime + 1);
|
||||
closest = (long)(vim_time() + 1);
|
||||
else if (dofile)
|
||||
closest = curbuf->b_u_save_nr_last + 2;
|
||||
else
|
||||
@@ -2388,7 +2386,7 @@ undo_time(
|
||||
{
|
||||
uhp->uh_walk = mark;
|
||||
if (dosec)
|
||||
val = (long)(uhp->uh_time - starttime);
|
||||
val = (long)(uhp->uh_time);
|
||||
else if (dofile)
|
||||
val = uhp->uh_save_nr;
|
||||
else
|
||||
|
||||
@@ -779,6 +779,66 @@ static char *(features[]) =
|
||||
|
||||
static int included_patches[] =
|
||||
{ /* Add new patch number below this line */
|
||||
/**/
|
||||
172,
|
||||
/**/
|
||||
171,
|
||||
/**/
|
||||
170,
|
||||
/**/
|
||||
169,
|
||||
/**/
|
||||
168,
|
||||
/**/
|
||||
167,
|
||||
/**/
|
||||
166,
|
||||
/**/
|
||||
165,
|
||||
/**/
|
||||
164,
|
||||
/**/
|
||||
163,
|
||||
/**/
|
||||
162,
|
||||
/**/
|
||||
161,
|
||||
/**/
|
||||
160,
|
||||
/**/
|
||||
159,
|
||||
/**/
|
||||
158,
|
||||
/**/
|
||||
157,
|
||||
/**/
|
||||
156,
|
||||
/**/
|
||||
155,
|
||||
/**/
|
||||
154,
|
||||
/**/
|
||||
153,
|
||||
/**/
|
||||
152,
|
||||
/**/
|
||||
151,
|
||||
/**/
|
||||
150,
|
||||
/**/
|
||||
149,
|
||||
/**/
|
||||
148,
|
||||
/**/
|
||||
147,
|
||||
/**/
|
||||
146,
|
||||
/**/
|
||||
145,
|
||||
/**/
|
||||
144,
|
||||
/**/
|
||||
143,
|
||||
/**/
|
||||
142,
|
||||
/**/
|
||||
|
||||
Reference in New Issue
Block a user