Patch 8.0.0360
Problem: Sometimes VimL is used, which is confusing.
Solution: Consistently use "Vim script". (Hirohito Higashi)
Files: runtime/doc/if_mzsch.txt, runtime/doc/if_pyth.txt,
runtime/doc/syntax.txt, runtime/doc/usr_02.txt,
runtime/doc/version7.txt, src/Makefile, src/eval.c,
src/ex_getln.c, src/if_py_both.h, src/if_xcmdsrv.c,
src/testdir/Make_all.mak, src/testdir/runtest.vim,
src/testdir/test49.vim, src/testdir/test_vimscript.vim,
src/testdir/test_viml.vim
*** ../vim-8.0.0359/runtime/doc/if_mzsch.txt 2016-09-12 12:45:25.000000000
+0200
--- runtime/doc/if_mzsch.txt 2017-02-23 18:49:31.945088705 +0100
***************
*** 249,255 ****
5. mzeval() Vim function *mzscheme-mzeval*
To facilitate bi-directional interface, you can use |mzeval()| function to
! evaluate MzScheme expressions and pass their values to VimL.
==============================================================================
6. Using Function references *mzscheme-funcref*
--- 249,255 ----
5. mzeval() Vim function *mzscheme-mzeval*
To facilitate bi-directional interface, you can use |mzeval()| function to
! evaluate MzScheme expressions and pass their values to Vim script.
==============================================================================
6. Using Function references *mzscheme-funcref*
*** ../vim-8.0.0359/runtime/doc/if_pyth.txt 2017-01-28 15:58:45.336197327
+0100
--- runtime/doc/if_pyth.txt 2017-02-23 18:49:31.945088705 +0100
***************
*** 676,686 ****
dictionary. Note that explicit `self` keyword used when
calling resulting object overrides this attribute.
auto_rebind Boolean. True if partial created from this Python object
! and stored in the VimL dictionary should be
automatically
! rebound to the dictionary it is stored in when this
! dictionary is indexed. Exposes Vim internal difference
! between `dict.func` (auto_rebind=True) and
! `function(dict.func,dict)` (auto_rebind=False). This
attribute makes no sense if `self` attribute is `None`.
Constructor additionally accepts `args`, `self` and `auto_rebind`
--- 676,686 ----
dictionary. Note that explicit `self` keyword used when
calling resulting object overrides this attribute.
auto_rebind Boolean. True if partial created from this Python object
! and stored in the Vim script dictionary should be
! automatically rebound to the dictionary it is stored in
! when this dictionary is indexed. Exposes Vim internal
! difference between `dict.func` (auto_rebind=True) and
! `function(dict.func,dict)` (auto_rebind=False). This
attribute makes no sense if `self` attribute is `None`.
Constructor additionally accepts `args`, `self` and `auto_rebind`
***************
*** 711,717 ****
8. pyeval() and py3eval() Vim functions *python-pyeval*
To facilitate bi-directional interface, you can use |pyeval()| and
|py3eval()|
! functions to evaluate Python expressions and pass their values to VimL.
|pyxeval()| is also available.
==============================================================================
--- 711,717 ----
8. pyeval() and py3eval() Vim functions *python-pyeval*
To facilitate bi-directional interface, you can use |pyeval()| and
|py3eval()|
! functions to evaluate Python expressions and pass their values to Vim script.
|pyxeval()| is also available.
==============================================================================
*** ../vim-8.0.0359/runtime/doc/syntax.txt 2016-09-12 13:39:47.000000000
+0200
--- runtime/doc/syntax.txt 2017-02-23 18:49:31.949088680 +0100
***************
*** 3322,3329 ****
g:vimsyn_folding =~ 't' : fold tcl script
<
*g:vimsyn_noerror*
! Not all error highlighting that syntax/vim.vim does may be correct; VimL is a
! difficult language to highlight correctly. A way to suppress error
highlighting is to put the following line in your |vimrc|: >
let g:vimsyn_noerror = 1
--- 3327,3334 ----
g:vimsyn_folding =~ 't' : fold tcl script
<
*g:vimsyn_noerror*
! Not all error highlighting that syntax/vim.vim does may be correct; Vim script
! is a difficult language to highlight correctly. A way to suppress error
highlighting is to put the following line in your |vimrc|: >
let g:vimsyn_noerror = 1
*** ../vim-8.0.0359/runtime/doc/usr_02.txt 2016-09-12 12:45:48.000000000
+0200
--- runtime/doc/usr_02.txt 2017-02-23 18:49:31.949088680 +0100
***************
*** 589,595 ****
register: >
:help quote:
! 13) Vim Script (VimL) is available at >
:help eval.txt
< Certain aspects of the language are available at :h expr-X where "X" is a
single letter. E.g. >
--- 589,595 ----
register: >
:help quote:
! 13) Vim script is available at >
:help eval.txt
< Certain aspects of the language are available at :h expr-X where "X" is a
single letter. E.g. >
***************
*** 599,608 ****
Also important is >
:help function-list
< to find a short description of all functions available. Help topics for
! VimL functions always include the "()", so: >
:help append()
! < talks about the append VimL function rather than how to append text in the
! current buffer.
14) Mappings are talked about in the help page :h |map.txt|. Use >
:help mapmode-i
--- 599,608 ----
Also important is >
:help function-list
< to find a short description of all functions available. Help topics for
! Vim script functions always include the "()", so: >
:help append()
! < talks about the append Vim script function rather than how to append text
! in the current buffer.
14) Mappings are talked about in the help page :h |map.txt|. Use >
:help mapmode-i
*** ../vim-8.0.0359/runtime/doc/version7.txt 2016-09-12 12:45:49.000000000
+0200
--- runtime/doc/version7.txt 2017-02-23 18:49:31.949088680 +0100
***************
*** 10202,10208 ****
interfaces to some extent. Extent will be improved in the future.
Added special |python-vars| objects also available for |python-buffer| and
! |python-window|. They ease access to VimL variables from Python.
Now you no longer need to alter `sys.path` to import your module: special
hooks are responsible for importing from {rtp}/python2, {rtp}/python3 and
--- 10202,10208 ----
interfaces to some extent. Extent will be improved in the future.
Added special |python-vars| objects also available for |python-buffer| and
! |python-window|. They ease access to Vim script variables from Python.
Now you no longer need to alter `sys.path` to import your module: special
hooks are responsible for importing from {rtp}/python2, {rtp}/python3 and
*** ../vim-8.0.0359/src/Makefile 2017-02-23 18:46:24.462288941 +0100
--- src/Makefile 2017-02-23 18:49:31.953088654 +0100
***************
*** 2213,2219 ****
test_usercommands \
test_utf8 \
test_viminfo \
! test_viml \
test_visual \
test_window_cmd \
test_window_id \
--- 2213,2219 ----
test_usercommands \
test_utf8 \
test_viminfo \
! test_vimscript \
test_visual \
test_window_cmd \
test_window_id \
*** ../vim-8.0.0359/src/eval.c 2017-02-23 14:25:13.210370073 +0100
--- src/eval.c 2017-02-23 18:49:31.953088654 +0100
***************
*** 950,956 ****
/*
! * Call some vimL function and return the result in "*rettv".
* Uses argv[argc] for the function arguments. Only Number and String
* arguments are currently supported.
* Returns OK or FAIL.
--- 950,956 ----
/*
! * Call some Vim script function and return the result in "*rettv".
* Uses argv[argc] for the function arguments. Only Number and String
* arguments are currently supported.
* Returns OK or FAIL.
***************
*** 1027,1033 ****
}
/*
! * Call vimL function "func" and return the result as a number.
* Returns -1 when calling the function fails.
* Uses argv[argc] for the function arguments.
*/
--- 1027,1033 ----
}
/*
! * Call Vim script function "func" and return the result as a number.
* Returns -1 when calling the function fails.
* Uses argv[argc] for the function arguments.
*/
***************
*** 1055,1061 ****
# if (defined(FEAT_USR_CMDS) && defined(FEAT_CMDL_COMPL)) || defined(PROTO)
/*
! * Call vimL function "func" and return the result as a string.
* Returns NULL when calling the function fails.
* Uses argv[argc] for the function arguments.
*/
--- 1055,1061 ----
# if (defined(FEAT_USR_CMDS) && defined(FEAT_CMDL_COMPL)) || defined(PROTO)
/*
! * Call Vim script function "func" and return the result as a string.
* Returns NULL when calling the function fails.
* Uses argv[argc] for the function arguments.
*/
***************
*** 1080,1086 ****
# endif
/*
! * Call vimL function "func" and return the result as a List.
* Uses argv[argc] for the function arguments.
* Returns NULL when there is something wrong.
*/
--- 1080,1086 ----
# endif
/*
! * Call Vim script function "func" and return the result as a List.
* Uses argv[argc] for the function arguments.
* Returns NULL when there is something wrong.
*/
*** ../vim-8.0.0359/src/ex_getln.c 2017-02-09 18:25:09.151838714 +0100
--- src/ex_getln.c 2017-02-23 18:49:31.953088654 +0100
***************
*** 5140,5147 ****
static void * call_user_expand_func(void *(*user_expand_func)(char_u *, int,
char_u **, int), expand_T *xp, int *num_file, char_u ***file);
/*
! * Call "user_expand_func()" to invoke a user defined VimL function and return
! * the result (either a string or a List).
*/
static void *
call_user_expand_func(
--- 5140,5147 ----
static void * call_user_expand_func(void *(*user_expand_func)(char_u *, int,
char_u **, int), expand_T *xp, int *num_file, char_u ***file);
/*
! * Call "user_expand_func()" to invoke a user defined Vim script function and
! * return the result (either a string or a List).
*/
static void *
call_user_expand_func(
*** ../vim-8.0.0359/src/if_py_both.h 2017-01-29 21:30:48.332627641 +0100
--- src/if_py_both.h 2017-02-23 18:49:31.953088654 +0100
***************
*** 582,590 ****
VimTryEnd(void)
{
--trylevel;
! /* Without this it stops processing all subsequent VimL commands and
! * generates strange error messages if I e.g. try calling Test() in a
! * cycle */
did_emsg = FALSE;
/* Keyboard interrupt should be preferred over anything else */
if (got_int)
--- 582,590 ----
VimTryEnd(void)
{
--trylevel;
! /* Without this it stops processing all subsequent Vim script commands and
! * generates strange error messages if I e.g. try calling Test() in a
cycle
! */
did_emsg = FALSE;
/* Keyboard interrupt should be preferred over anything else */
if (got_int)
***************
*** 625,631 ****
discard_current_exception();
return -1;
}
! /* Finally transform VimL exception to python one */
else
{
PyErr_SetVim((char *)current_exception->value);
--- 625,631 ----
discard_current_exception();
return -1;
}
! /* Finally transform Vim script exception to python one */
else
{
PyErr_SetVim((char *)current_exception->value);
*** ../vim-8.0.0359/src/if_xcmdsrv.c 2016-08-29 22:42:20.000000000 +0200
--- src/if_xcmdsrv.c 2017-02-23 18:49:31.953088654 +0100
***************
*** 1449,1456 ****
char_u *enc;
/*
! * This is a (n)otification. Sent with serverreply_send in VimL.
! * Execute any autocommand and save it for later retrieval
*/
p += 2;
gotWindow = 0;
--- 1449,1456 ----
char_u *enc;
/*
! * This is a (n)otification. Sent with serverreply_send in Vim
! * script. Execute any autocommand and save it for later retrieval
*/
p += 2;
gotWindow = 0;
*** ../vim-8.0.0359/src/testdir/Make_all.mak 2017-02-23 18:46:24.462288941
+0100
--- src/testdir/Make_all.mak 2017-02-23 18:49:31.953088654 +0100
***************
*** 199,205 ****
test_undo.res \
test_usercommands.res \
test_viminfo.res \
! test_viml.res \
test_visual.res \
test_window_id.res \
test_writefile.res \
--- 199,205 ----
test_undo.res \
test_usercommands.res \
test_viminfo.res \
! test_vimscript.res \
test_visual.res \
test_window_id.res \
test_writefile.res \
*** ../vim-8.0.0359/src/testdir/runtest.vim 2017-02-01 23:17:30.909975952
+0100
--- src/testdir/runtest.vim 2017-02-23 18:49:31.953088654 +0100
***************
*** 147,153 ****
let s:errors = []
let s:messages = []
let s:skipped = []
! if expand('%') =~ 'test_viml.vim'
" this test has intentional s:errors, don't use try/catch.
source %
else
--- 147,153 ----
let s:errors = []
let s:messages = []
let s:skipped = []
! if expand('%') =~ 'test_vimscript.vim'
" this test has intentional s:errors, don't use try/catch.
source %
else
*** ../vim-8.0.0359/src/testdir/test49.vim 2016-02-07 20:24:49.000000000
+0100
--- src/testdir/test49.vim 2017-02-23 18:49:31.957088629 +0100
***************
*** 608,614 ****
" END_OF_TEST_ENVIRONMENT - do not change or remove this line.
! " Tests 1 to 15 were moved to test_viml.vim
let Xtest = 16
"-------------------------------------------------------------------------------
--- 608,614 ----
" END_OF_TEST_ENVIRONMENT - do not change or remove this line.
! " Tests 1 to 15 were moved to test_vimscript.vim
let Xtest = 16
"-------------------------------------------------------------------------------
*** ../vim-8.0.0359/src/testdir/test_vimscript.vim 2017-02-23
18:57:49.325919004 +0100
--- src/testdir/test_vimscript.vim 2017-02-23 18:49:31.957088629 +0100
***************
*** 0 ****
--- 1,1316 ----
+ " Test various aspects of the Vim script language.
+ " Most of this was formerly in test49.
+
+
"-------------------------------------------------------------------------------
+ " Test environment {{{1
+
"-------------------------------------------------------------------------------
+
+ com! XpathINIT let g:Xpath = ''
+ com! -nargs=1 -bar Xpath let g:Xpath = g:Xpath . <args>
+
+ " Append a message to the "messages" file
+ func! Xout(text)
+ split messages
+ $put =a:text
+ wq
+ endfunc
+
+ com! -nargs=1 Xout call Xout(<args>)
+
+ " MakeScript() - Make a script file from a function. {{{2
+ "
+ " Create a script that consists of the body of the function a:funcname.
+ " Replace any ":return" by a ":finish", any argument variable by a global
+ " variable, and and every ":call" by a ":source" for the next following
argument
+ " in the variable argument list. This function is useful if similar tests are
+ " to be made for a ":return" from a function call or a ":finish" in a script
+ " file.
+ function! MakeScript(funcname, ...)
+ let script = tempname()
+ execute "redir! >" . script
+ execute "function" a:funcname
+ redir END
+ execute "edit" script
+ " Delete the "function" and the "endfunction" lines. Do not include the
+ " word "function" in the pattern since it might be translated if LANG is
+ " set. When MakeScript() is being debugged, this deletes also the
debugging
+ " output of its line 3 and 4.
+ exec '1,/.*' . a:funcname . '(.*)/d'
+ /^\d*\s*endfunction\>/,$d
+ %s/^\d*//e
+ %s/return/finish/e
+ %s/\<a:\(\h\w*\)/g:\1/ge
+ normal gg0
+ let cnt = 0
+ while search('\<call\s*\%(\u\|s:\)\w*\s*(.*)', 'W') > 0
+ let cnt = cnt + 1
+ s/\<call\s*\%(\u\|s:\)\w*\s*(.*)/\='source ' . a:{cnt}/
+ endwhile
+ g/^\s*$/d
+ write
+ bwipeout
+ return script
+ endfunction
+
+ " ExecAsScript - Source a temporary script made from a function. {{{2
+ "
+ " Make a temporary script file from the function a:funcname, ":source" it, and
+ " delete it afterwards. However, if an exception is thrown the file may
remain,
+ " the caller should call DeleteTheScript() afterwards.
+ let s:script_name = ''
+ function! ExecAsScript(funcname)
+ " Make a script from the function passed as argument.
+ let s:script_name = MakeScript(a:funcname)
+
+ " Source and delete the script.
+ exec "source" s:script_name
+ call delete(s:script_name)
+ let s:script_name = ''
+ endfunction
+
+ function! DeleteTheScript()
+ if s:script_name
+ call delete(s:script_name)
+ let s:script_name = ''
+ endif
+ endfunc
+
+ com! -nargs=1 -bar ExecAsScript call ExecAsScript(<f-args>)
+
+
+
"-------------------------------------------------------------------------------
+ " Test 1: :endwhile in function {{{1
+ "
+ " Detect if a broken loop is (incorrectly) reactivated by the
+ " :endwhile. Use a :return to prevent an endless loop, and make
+ " this test first to get a meaningful result on an error before other
+ " tests will hang.
+
"-------------------------------------------------------------------------------
+
+ function! T1_F()
+ Xpath 'a'
+ let first = 1
+ while 1
+ Xpath 'b'
+ if first
+ Xpath 'c'
+ let first = 0
+ break
+ else
+ Xpath 'd'
+ return
+ endif
+ endwhile
+ endfunction
+
+ function! T1_G()
+ Xpath 'h'
+ let first = 1
+ while 1
+ Xpath 'i'
+ if first
+ Xpath 'j'
+ let first = 0
+ break
+ else
+ Xpath 'k'
+ return
+ endif
+ if 1 " unmatched :if
+ endwhile
+ endfunction
+
+ func Test_endwhile_function()
+ XpathINIT
+ call T1_F()
+ Xpath 'F'
+
+ try
+ call T1_G()
+ catch
+ " Catch missing :endif
+ call assert_true(v:exception =~ 'E171')
+ Xpath 'x'
+ endtry
+ Xpath 'G'
+
+ call assert_equal('abcFhijxG', g:Xpath)
+ endfunc
+
+
"-------------------------------------------------------------------------------
+ " Test 2: :endwhile in script
{{{1
+ "
+ " Detect if a broken loop is (incorrectly) reactivated by the
+ " :endwhile. Use a :finish to prevent an endless loop, and place
+ " this test before others that might hang to get a meaningful result
+ " on an error.
+ "
+ " This test executes the bodies of the functions T1_F and T1_G from
+ " the previous test as script files (:return replaced by :finish).
+
"-------------------------------------------------------------------------------
+
+ func Test_endwhile_script()
+ XpathINIT
+ ExecAsScript T1_F
+ Xpath 'F'
+ call DeleteTheScript()
+
+ try
+ ExecAsScript T1_G
+ catch
+ " Catch missing :endif
+ call assert_true(v:exception =~ 'E171')
+ Xpath 'x'
+ endtry
+ Xpath 'G'
+ call DeleteTheScript()
+
+ call assert_equal('abcFhijxG', g:Xpath)
+ endfunc
+
+
"-------------------------------------------------------------------------------
+ " Test 3: :if, :elseif, :while, :continue, :break {{{1
+
"-------------------------------------------------------------------------------
+
+ function Test_if_while()
+ XpathINIT
+ if 1
+ Xpath 'a'
+ let loops = 3
+ while loops > -1 " main loop: loops == 3, 2, 1 (which breaks)
+ if loops <= 0
+ let break_err = 1
+ let loops = -1
+ else
+ Xpath 'b' . loops
+ endif
+ if (loops == 2)
+ while loops == 2 " dummy loop
+ Xpath 'c' . loops
+ let loops = loops - 1
+ continue " stop dummy loop
+ Xpath 'd' . loops
+ endwhile
+ continue " continue main loop
+ Xpath 'e' . loops
+ elseif (loops == 1)
+ let p = 1
+ while p " dummy loop
+ Xpath 'f' . loops
+ let p = 0
+ break " break dummy loop
+ Xpath 'g' . loops
+ endwhile
+ Xpath 'h' . loops
+ unlet p
+ break " break main loop
+ Xpath 'i' . loops
+ endif
+ if (loops > 0)
+ Xpath 'j' . loops
+ endif
+ while loops == 3 " dummy loop
+ let loops = loops - 1
+ endwhile " end dummy loop
+ endwhile " end main loop
+ Xpath 'k'
+ else
+ Xpath 'l'
+ endif
+ Xpath 'm'
+ if exists("break_err")
+ Xpath 'm'
+ unlet break_err
+ endif
+
+ unlet loops
+
+ call assert_equal('ab3j3b2c2b1f1h1km', g:Xpath)
+ endfunc
+
+
"-------------------------------------------------------------------------------
+ " Test 4: :return {{{1
+
"-------------------------------------------------------------------------------
+
+ function! T4_F()
+ if 1
+ Xpath 'a'
+ let loops = 3
+ while loops > 0 " 3: 2: 1:
+ Xpath 'b' . loops
+ if (loops == 2)
+ Xpath 'c' . loops
+ return
+ Xpath 'd' . loops
+ endif
+ Xpath 'e' . loops
+ let loops = loops - 1
+ endwhile
+ Xpath 'f'
+ else
+ Xpath 'g'
+ endif
+ endfunction
+
+ function Test_return()
+ XpathINIT
+ call T4_F()
+ Xpath '4'
+
+ call assert_equal('ab3e3b2c24', g:Xpath)
+ endfunction
+
+
+
"-------------------------------------------------------------------------------
+ " Test 5: :finish {{{1
+ "
+ " This test executes the body of the function T4_F from the previous
+ " test as a script file (:return replaced by :finish).
+
"-------------------------------------------------------------------------------
+
+ function Test_finish()
+ XpathINIT
+ ExecAsScript T4_F
+ Xpath '5'
+ call DeleteTheScript()
+
+ call assert_equal('ab3e3b2c25', g:Xpath)
+ endfunction
+
+
+
+
"-------------------------------------------------------------------------------
+ " Test 6: Defining functions in :while loops
{{{1
+ "
+ " Functions can be defined inside other functions. An inner function
+ " gets defined when the outer function is executed. Functions may
+ " also be defined inside while loops. Expressions in braces for
+ " defining the function name are allowed.
+ "
+ " The functions are defined when sourcing the script, only the
+ " resulting path is checked in the test function.
+
"-------------------------------------------------------------------------------
+
+ XpathINIT
+
+ " The command CALL collects the argument of all its invocations in "calls"
+ " when used from a function (that is, when the global variable "calls" needs
+ " the "g:" prefix). This is to check that the function code is skipped when
+ " the function is defined. For inner functions, do so only if the outer
+ " function is not being executed.
+ "
+ let calls = ""
+ com! -nargs=1 CALL
+ \ if !exists("calls") && !exists("outer") |
+ \ let g:calls = g:calls . <args> |
+ \ endif
+
+ let i = 0
+ while i < 3
+ let i = i + 1
+ if i == 1
+ Xpath 'a'
+ function! F1(arg)
+ CALL a:arg
+ let outer = 1
+
+ let j = 0
+ while j < 1
+ Xpath 'b'
+ let j = j + 1
+ function! G1(arg)
+ CALL a:arg
+ endfunction
+ Xpath 'c'
+ endwhile
+ endfunction
+ Xpath 'd'
+
+ continue
+ endif
+
+ Xpath 'e' . i
+ function! F{i}(i, arg)
+ CALL a:arg
+ let outer = 1
+
+ if a:i == 3
+ Xpath 'f'
+ endif
+ let k = 0
+ while k < 3
+ Xpath 'g' . k
+ let k = k + 1
+ function! G{a:i}{k}(arg)
+ CALL a:arg
+ endfunction
+ Xpath 'h' . k
+ endwhile
+ endfunction
+ Xpath 'i'
+
+ endwhile
+
+ if exists("*G1")
+ Xpath 'j'
+ endif
+ if exists("*F1")
+ call F1("F1")
+ if exists("*G1")
+ call G1("G1")
+ endif
+ endif
+
+ if exists("G21") || exists("G22") || exists("G23")
+ Xpath 'k'
+ endif
+ if exists("*F2")
+ call F2(2, "F2")
+ if exists("*G21")
+ call G21("G21")
+ endif
+ if exists("*G22")
+ call G22("G22")
+ endif
+ if exists("*G23")
+ call G23("G23")
+ endif
+ endif
+
+ if exists("G31") || exists("G32") || exists("G33")
+ Xpath 'l'
+ endif
+ if exists("*F3")
+ call F3(3, "F3")
+ if exists("*G31")
+ call G31("G31")
+ endif
+ if exists("*G32")
+ call G32("G32")
+ endif
+ if exists("*G33")
+ call G33("G33")
+ endif
+ endif
+
+ Xpath 'm'
+
+ let g:test6_result = g:Xpath
+ let g:test6_calls = calls
+
+ unlet calls
+ delfunction F1
+ delfunction G1
+ delfunction F2
+ delfunction G21
+ delfunction G22
+ delfunction G23
+ delfunction G31
+ delfunction G32
+ delfunction G33
+
+ function Test_defining_functions()
+ call assert_equal('ade2ie3ibcg0h1g1h2g2h3fg0h1g1h2g2h3m', g:test6_result)
+ call assert_equal('F1G1F2G21G22G23F3G31G32G33', g:test6_calls)
+ endfunc
+
+
"-------------------------------------------------------------------------------
+ " Test 7: Continuing on errors outside functions {{{1
+ "
+ " On an error outside a function, the script processing continues
+ " at the line following the outermost :endif or :endwhile. When not
+ " inside an :if or :while, the script processing continues at the next
+ " line.
+
"-------------------------------------------------------------------------------
+
+ XpathINIT
+
+ if 1
+ Xpath 'a'
+ while 1
+ Xpath 'b'
+ asdf
+ Xpath 'c'
+ break
+ endwhile | Xpath 'd'
+ Xpath 'e'
+ endif | Xpath 'f'
+ Xpath 'g'
+
+ while 1
+ Xpath 'h'
+ if 1
+ Xpath 'i'
+ asdf
+ Xpath 'j'
+ endif | Xpath 'k'
+ Xpath 'l'
+ break
+ endwhile | Xpath 'm'
+ Xpath 'n'
+
+ asdf
+ Xpath 'o'
+
+ asdf | Xpath 'p'
+ Xpath 'q'
+
+ let g:test7_result = g:Xpath
+
+ func Test_error_in_script()
+ call assert_equal('abghinoq', g:test7_result)
+ endfunc
+
+
"-------------------------------------------------------------------------------
+ " Test 8: Aborting and continuing on errors inside functions
{{{1
+ "
+ " On an error inside a function without the "abort" attribute, the
+ " script processing continues at the next line (unless the error was
+ " in a :return command). On an error inside a function with the
+ " "abort" attribute, the function is aborted and the script processing
+ " continues after the function call; the value -1 is returned then.
+
"-------------------------------------------------------------------------------
+
+ XpathINIT
+
+ function! T8_F()
+ if 1
+ Xpath 'a'
+ while 1
+ Xpath 'b'
+ asdf
+ Xpath 'c'
+ asdf | Xpath 'd'
+ Xpath 'e'
+ break
+ endwhile
+ Xpath 'f'
+ endif | Xpath 'g'
+ Xpath 'h'
+
+ while 1
+ Xpath 'i'
+ if 1
+ Xpath 'j'
+ asdf
+ Xpath 'k'
+ asdf | Xpath 'l'
+ Xpath 'm'
+ endif
+ Xpath 'n'
+ break
+ endwhile | Xpath 'o'
+ Xpath 'p'
+
+ return novar " returns (default return value 0)
+ Xpath 'q'
+ return 1 " not reached
+ endfunction
+
+ function! T8_G() abort
+ if 1
+ Xpath 'r'
+ while 1
+ Xpath 's'
+ asdf " returns -1
+ Xpath 't'
+ break
+ endwhile
+ Xpath 'v'
+ endif | Xpath 'w'
+ Xpath 'x'
+
+ return -4 " not reached
+ endfunction
+
+ function! T8_H() abort
+ while 1
+ Xpath 'A'
+ if 1
+ Xpath 'B'
+ asdf " returns -1
+ Xpath 'C'
+ endif
+ Xpath 'D'
+ break
+ endwhile | Xpath 'E'
+ Xpath 'F'
+
+ return -4 " not reached
+ endfunction
+
+ " Aborted functions (T8_G and T8_H) return -1.
+ let g:test8_sum = (T8_F() + 1) - 4 * T8_G() - 8 * T8_H()
+ Xpath 'X'
+ let g:test8_result = g:Xpath
+
+ func Test_error_in_function()
+ call assert_equal(13, g:test8_sum)
+ call assert_equal('abcefghijkmnoprsABX', g:test8_result)
+
+ delfunction T8_F
+ delfunction T8_G
+ delfunction T8_H
+ endfunc
+
+
+
"-------------------------------------------------------------------------------
+ " Test 9: Continuing after aborted functions
{{{1
+ "
+ " When a function with the "abort" attribute is aborted due to an
+ " error, the next function back in the call hierarchy without an
+ " "abort" attribute continues; the value -1 is returned then.
+
"-------------------------------------------------------------------------------
+
+ XpathINIT
+
+ function! F() abort
+ Xpath 'a'
+ let result = G() " not aborted
+ Xpath 'b'
+ if result != 2
+ Xpath 'c'
+ endif
+ return 1
+ endfunction
+
+ function! G() " no abort attribute
+ Xpath 'd'
+ if H() != -1 " aborted
+ Xpath 'e'
+ endif
+ Xpath 'f'
+ return 2
+ endfunction
+
+ function! H() abort
+ Xpath 'g'
+ call I() " aborted
+ Xpath 'h'
+ return 4
+ endfunction
+
+ function! I() abort
+ Xpath 'i'
+ asdf " error
+ Xpath 'j'
+ return 8
+ endfunction
+
+ if F() != 1
+ Xpath 'k'
+ endif
+
+ let g:test9_result = g:Xpath
+
+ delfunction F
+ delfunction G
+ delfunction H
+ delfunction I
+
+ func Test_func_abort()
+ call assert_equal('adgifb', g:test9_result)
+ endfunc
+
+
+
"-------------------------------------------------------------------------------
+ " Test 10: :if, :elseif, :while argument parsing {{{1
+ "
+ " A '"' or '|' in an argument expression must not be mixed up with
+ " a comment or a next command after a bar. Parsing errors should
+ " be recognized.
+
"-------------------------------------------------------------------------------
+
+ XpathINIT
+
+ function! MSG(enr, emsg)
+ let english = v:lang == "C" || v:lang =~ '^[Ee]n'
+ if a:enr == ""
+ Xout "TODO: Add message number for:" a:emsg
+ let v:errmsg = ":" . v:errmsg
+ endif
+ let match = 1
+ if v:errmsg !~ '^'.a:enr.':' || (english && v:errmsg !~ a:emsg)
+ let match = 0
+ if v:errmsg == ""
+ Xout "Message missing."
+ else
+ let v:errmsg = escape(v:errmsg, '"')
+ Xout "Unexpected message:" v:errmsg
+ endif
+ endif
+ return match
+ endfunction
+
+ if 1 || strlen("\"") | Xpath 'a'
+ Xpath 'b'
+ endif
+ Xpath 'c'
+
+ if 0
+ elseif 1 || strlen("\"") | Xpath 'd'
+ Xpath 'e'
+ endif
+ Xpath 'f'
+
+ while 1 || strlen("\"") | Xpath 'g'
+ Xpath 'h'
+ break
+ endwhile
+ Xpath 'i'
+
+ let v:errmsg = ""
+ if 1 ||| strlen("\"") | Xpath 'j'
+ Xpath 'k'
+ endif
+ Xpath 'l'
+ if !MSG('E15', "Invalid expression")
+ Xpath 'm'
+ endif
+
+ let v:errmsg = ""
+ if 0
+ elseif 1 ||| strlen("\"") | Xpath 'n'
+ Xpath 'o'
+ endif
+ Xpath 'p'
+ if !MSG('E15', "Invalid expression")
+ Xpath 'q'
+ endif
+
+ let v:errmsg = ""
+ while 1 ||| strlen("\"") | Xpath 'r'
+ Xpath 's'
+ break
+ endwhile
+ Xpath 't'
+ if !MSG('E15', "Invalid expression")
+ Xpath 'u'
+ endif
+
+ let g:test10_result = g:Xpath
+ delfunction MSG
+
+ func Test_expr_parsing()
+ call assert_equal('abcdefghilpt', g:test10_result)
+ endfunc
+
+
+
"-------------------------------------------------------------------------------
+ " Test 11: :if, :elseif, :while argument evaluation after abort {{{1
+ "
+ " When code is skipped over due to an error, the boolean argument to
+ " an :if, :elseif, or :while must not be evaluated.
+
"-------------------------------------------------------------------------------
+
+ XpathINIT
+
+ let calls = 0
+
+ function! P(num)
+ let g:calls = g:calls + a:num " side effect on call
+ return 0
+ endfunction
+
+ if 1
+ Xpath 'a'
+ asdf " error
+ Xpath 'b'
+ if P(1) " should not be called
+ Xpath 'c'
+ elseif !P(2) " should not be called
+ Xpath 'd'
+ else
+ Xpath 'e'
+ endif
+ Xpath 'f'
+ while P(4) " should not be called
+ Xpath 'g'
+ endwhile
+ Xpath 'h'
+ endif
+ Xpath 'x'
+
+ let g:test11_calls = calls
+ let g:test11_result = g:Xpath
+
+ unlet calls
+ delfunction P
+
+ func Test_arg_abort()
+ call assert_equal(0, g:test11_calls)
+ call assert_equal('ax', g:test11_result)
+ endfunc
+
+
+
"-------------------------------------------------------------------------------
+ " Test 12: Expressions in braces in skipped code {{{1
+ "
+ " In code skipped over due to an error or inactive conditional,
+ " an expression in braces as part of a variable or function name
+ " should not be evaluated.
+
"-------------------------------------------------------------------------------
+
+ XpathINIT
+
+ function! NULL()
+ Xpath 'a'
+ return 0
+ endfunction
+
+ function! ZERO()
+ Xpath 'b'
+ return 0
+ endfunction
+
+ function! F0()
+ Xpath 'c'
+ endfunction
+
+ function! F1(arg)
+ Xpath 'e'
+ endfunction
+
+ let V0 = 1
+
+ Xpath 'f'
+ echo 0 ? F{NULL() + V{ZERO()}}() : 1
+
+ Xpath 'g'
+ if 0
+ Xpath 'h'
+ call F{NULL() + V{ZERO()}}()
+ endif
+
+ Xpath 'i'
+ if 1
+ asdf " error
+ Xpath 'j'
+ call F1(F{NULL() + V{ZERO()}}())
+ endif
+
+ Xpath 'k'
+ if 1
+ asdf " error
+ Xpath 'l'
+ call F{NULL() + V{ZERO()}}()
+ endif
+
+ let g:test12_result = g:Xpath
+
+ func Test_braces_skipped()
+ call assert_equal('fgik', g:test12_result)
+ endfunc
+
+
+
"-------------------------------------------------------------------------------
+ " Test 13: Failure in argument evaluation for :while {{{1
+ "
+ " A failure in the expression evaluation for the condition of a :while
+ " causes the whole :while loop until the matching :endwhile being
+ " ignored. Continuation is at the next following line.
+
"-------------------------------------------------------------------------------
+
+ XpathINIT
+
+ Xpath 'a'
+ while asdf
+ Xpath 'b'
+ while 1
+ Xpath 'c'
+ break
+ endwhile
+ Xpath 'd'
+ break
+ endwhile
+ Xpath 'e'
+
+ while asdf | Xpath 'f' | endwhile | Xpath 'g'
+ Xpath 'h'
+ let g:test13_result = g:Xpath
+
+ func Test_while_fail()
+ call assert_equal('aeh', g:test13_result)
+ endfunc
+
+
+
"-------------------------------------------------------------------------------
+ " Test 14: Failure in argument evaluation for :if {{{1
+ "
+ " A failure in the expression evaluation for the condition of an :if
+ " does not cause the corresponding :else or :endif being matched to
+ " a previous :if/:elseif. Neither of both branches of the failed :if
+ " are executed.
+
"-------------------------------------------------------------------------------
+
+ XpathINIT
+
+ function! F()
+ Xpath 'a'
+ let x = 0
+ if x " false
+ Xpath 'b'
+ elseif !x " always true
+ Xpath 'c'
+ let x = 1
+ if g:boolvar " possibly undefined
+ Xpath 'd'
+ else
+ Xpath 'e'
+ endif
+ Xpath 'f'
+ elseif x " never executed
+ Xpath 'g'
+ endif
+ Xpath 'h'
+ endfunction
+
+ let boolvar = 1
+ call F()
+ Xpath '-'
+
+ unlet boolvar
+ call F()
+ let g:test14_result = g:Xpath
+
+ delfunction F
+
+ func Test_if_fail()
+ call assert_equal('acdfh-acfh', g:test14_result)
+ endfunc
+
+
+
"-------------------------------------------------------------------------------
+ " Test 15: Failure in argument evaluation for :if (bar) {{{1
+ "
+ " Like previous test, except that the failing :if ... | ... | :endif
+ " is in a single line.
+
"-------------------------------------------------------------------------------
+
+ XpathINIT
+
+ function! F()
+ Xpath 'a'
+ let x = 0
+ if x " false
+ Xpath 'b'
+ elseif !x " always true
+ Xpath 'c'
+ let x = 1
+ if g:boolvar | Xpath 'd' | else | Xpath 'e' | endif
+ Xpath 'f'
+ elseif x " never executed
+ Xpath 'g'
+ endif
+ Xpath 'h'
+ endfunction
+
+ let boolvar = 1
+ call F()
+ Xpath '-'
+
+ unlet boolvar
+ call F()
+ let g:test15_result = g:Xpath
+
+ delfunction F
+
+ func Test_if_bar_fail()
+ call assert_equal('acdfh-acfh', g:test15_result)
+ endfunc
+
+
"-------------------------------------------------------------------------------
+ " Test 90: Recognizing {} in variable name. {{{1
+
"-------------------------------------------------------------------------------
+
+ func Test_curlies()
+ let s:var = 66
+ let ns = 's'
+ call assert_equal(66, {ns}:var)
+
+ let g:a = {}
+ let g:b = 't'
+ let g:a[g:b] = 77
+ call assert_equal(77, g:a['t'])
+ endfunc
+
+
"-------------------------------------------------------------------------------
+ " Test 91: using type(). {{{1
+
"-------------------------------------------------------------------------------
+
+ func Test_type()
+ call assert_equal(0, type(0))
+ call assert_equal(1, type(""))
+ call assert_equal(2, type(function("tr")))
+ call assert_equal(2, type(function("tr", [8])))
+ call assert_equal(3, type([]))
+ call assert_equal(4, type({}))
+ call assert_equal(5, type(0.0))
+ call assert_equal(6, type(v:false))
+ call assert_equal(6, type(v:true))
+ call assert_equal(7, type(v:none))
+ call assert_equal(7, type(v:null))
+ call assert_equal(8, v:t_job)
+ call assert_equal(9, v:t_channel)
+ call assert_equal(v:t_number, type(0))
+ call assert_equal(v:t_string, type(""))
+ call assert_equal(v:t_func, type(function("tr")))
+ call assert_equal(v:t_func, type(function("tr", [8])))
+ call assert_equal(v:t_list, type([]))
+ call assert_equal(v:t_dict, type({}))
+ call assert_equal(v:t_float, type(0.0))
+ call assert_equal(v:t_bool, type(v:false))
+ call assert_equal(v:t_bool, type(v:true))
+ call assert_equal(v:t_none, type(v:none))
+ call assert_equal(v:t_none, type(v:null))
+
+
+ call assert_equal(0, 0 + v:false)
+ call assert_equal(1, 0 + v:true)
+ call assert_equal(0, 0 + v:none)
+ call assert_equal(0, 0 + v:null)
+
+ call assert_equal('v:false', '' . v:false)
+ call assert_equal('v:true', '' . v:true)
+ call assert_equal('v:none', '' . v:none)
+ call assert_equal('v:null', '' . v:null)
+
+ call assert_true(v:false == 0)
+ call assert_false(v:false != 0)
+ call assert_true(v:true == 1)
+ call assert_false(v:true != 1)
+ call assert_false(v:true == v:false)
+ call assert_true(v:true != v:false)
+
+ call assert_true(v:null == 0)
+ call assert_false(v:null != 0)
+ call assert_true(v:none == 0)
+ call assert_false(v:none != 0)
+
+ call assert_true(v:false is v:false)
+ call assert_true(v:true is v:true)
+ call assert_true(v:none is v:none)
+ call assert_true(v:null is v:null)
+
+ call assert_false(v:false isnot v:false)
+ call assert_false(v:true isnot v:true)
+ call assert_false(v:none isnot v:none)
+ call assert_false(v:null isnot v:null)
+
+ call assert_false(v:false is 0)
+ call assert_false(v:true is 1)
+ call assert_false(v:true is v:false)
+ call assert_false(v:none is 0)
+ call assert_false(v:null is 0)
+ call assert_false(v:null is v:none)
+
+ call assert_true(v:false isnot 0)
+ call assert_true(v:true isnot 1)
+ call assert_true(v:true isnot v:false)
+ call assert_true(v:none isnot 0)
+ call assert_true(v:null isnot 0)
+ call assert_true(v:null isnot v:none)
+
+ call assert_equal(v:false, eval(string(v:false)))
+ call assert_equal(v:true, eval(string(v:true)))
+ call assert_equal(v:none, eval(string(v:none)))
+ call assert_equal(v:null, eval(string(v:null)))
+
+ call assert_equal(v:false, copy(v:false))
+ call assert_equal(v:true, copy(v:true))
+ call assert_equal(v:none, copy(v:none))
+ call assert_equal(v:null, copy(v:null))
+
+ call assert_equal([v:false], deepcopy([v:false]))
+ call assert_equal([v:true], deepcopy([v:true]))
+ call assert_equal([v:none], deepcopy([v:none]))
+ call assert_equal([v:null], deepcopy([v:null]))
+
+ call assert_true(empty(v:false))
+ call assert_false(empty(v:true))
+ call assert_true(empty(v:null))
+ call assert_true(empty(v:none))
+
+ func ChangeYourMind()
+ try
+ return v:true
+ finally
+ return 'something else'
+ endtry
+ endfunc
+
+ call ChangeYourMind()
+ endfunc
+
+
"-------------------------------------------------------------------------------
+ " Test 92: skipping code {{{1
+
"-------------------------------------------------------------------------------
+
+ func Test_skip()
+ let Fn = function('Test_type')
+ call assert_false(0 && Fn[1])
+ call assert_false(0 && string(Fn))
+ call assert_false(0 && len(Fn))
+ let l = []
+ call assert_false(0 && l[1])
+ call assert_false(0 && string(l))
+ call assert_false(0 && len(l))
+ let f = 1.0
+ call assert_false(0 && f[1])
+ call assert_false(0 && string(f))
+ call assert_false(0 && len(f))
+ let sp = v:null
+ call assert_false(0 && sp[1])
+ call assert_false(0 && string(sp))
+ call assert_false(0 && len(sp))
+
+ endfunc
+
+
"-------------------------------------------------------------------------------
+ " Test 93: :echo and string() {{{1
+
"-------------------------------------------------------------------------------
+
+ func Test_echo_and_string()
+ " String
+ let a = 'foo bar'
+ redir => result
+ echo a
+ echo string(a)
+ redir END
+ let l = split(result, "\n")
+ call assert_equal(["foo bar",
+ \ "'foo bar'"], l)
+
+ " Float
+ if has('float')
+ let a = -1.2e0
+ redir => result
+ echo a
+ echo string(a)
+ redir END
+ let l = split(result, "\n")
+ call assert_equal(["-1.2",
+ \ "-1.2"], l)
+ endif
+
+ " Funcref
+ redir => result
+ echo function('string')
+ echo string(function('string'))
+ redir END
+ let l = split(result, "\n")
+ call assert_equal(["string",
+ \ "function('string')"], l)
+
+ " Recursive dictionary
+ let a = {}
+ let a["a"] = a
+ redir => result
+ echo a
+ echo string(a)
+ redir END
+ let l = split(result, "\n")
+ call assert_equal(["{'a': {...}}",
+ \ "{'a': {...}}"], l)
+
+ " Recursive list
+ let a = [0]
+ let a[0] = a
+ redir => result
+ echo a
+ echo string(a)
+ redir END
+ let l = split(result, "\n")
+ call assert_equal(["[[...]]",
+ \ "[[...]]"], l)
+
+ " Empty dictionaries in a list
+ let a = {}
+ redir => result
+ echo [a, a, a]
+ echo string([a, a, a])
+ redir END
+ let l = split(result, "\n")
+ call assert_equal(["[{}, {}, {}]",
+ \ "[{}, {}, {}]"], l)
+
+ " Empty dictionaries in a dictionary
+ let a = {}
+ let b = {"a": a, "b": a}
+ redir => result
+ echo b
+ echo string(b)
+ redir END
+ let l = split(result, "\n")
+ call assert_equal(["{'a': {}, 'b': {}}",
+ \ "{'a': {}, 'b': {}}"], l)
+
+ " Empty lists in a list
+ let a = []
+ redir => result
+ echo [a, a, a]
+ echo string([a, a, a])
+ redir END
+ let l = split(result, "\n")
+ call assert_equal(["[[], [], []]",
+ \ "[[], [], []]"], l)
+
+ " Empty lists in a dictionary
+ let a = []
+ let b = {"a": a, "b": a}
+ redir => result
+ echo b
+ echo string(b)
+ redir END
+ let l = split(result, "\n")
+ call assert_equal(["{'a': [], 'b': []}",
+ \ "{'a': [], 'b': []}"], l)
+
+ " Dictionaries in a list
+ let a = {"one": "yes", "two": "yes", "three": "yes"}
+ redir => result
+ echo [a, a, a]
+ echo string([a, a, a])
+ redir END
+ let l = split(result, "\n")
+ call assert_equal(["[{'one': 'yes', 'two': 'yes', 'three': 'yes'}, {...},
{...}]",
+ \ "[{'one': 'yes', 'two': 'yes', 'three': 'yes'}, {'one':
'yes', 'two': 'yes', 'three': 'yes'}, {'one': 'yes', 'two': 'yes', 'three':
'yes'}]"], l)
+
+ " Dictionaries in a dictionary
+ let a = {"one": "yes", "two": "yes", "three": "yes"}
+ let b = {"a": a, "b": a}
+ redir => result
+ echo b
+ echo string(b)
+ redir END
+ let l = split(result, "\n")
+ call assert_equal(["{'a': {'one': 'yes', 'two': 'yes', 'three': 'yes'},
'b': {...}}",
+ \ "{'a': {'one': 'yes', 'two': 'yes', 'three': 'yes'},
'b': {'one': 'yes', 'two': 'yes', 'three': 'yes'}}"], l)
+
+ " Lists in a list
+ let a = [1, 2, 3]
+ redir => result
+ echo [a, a, a]
+ echo string([a, a, a])
+ redir END
+ let l = split(result, "\n")
+ call assert_equal(["[[1, 2, 3], [...], [...]]",
+ \ "[[1, 2, 3], [1, 2, 3], [1, 2, 3]]"], l)
+
+ " Lists in a dictionary
+ let a = [1, 2, 3]
+ let b = {"a": a, "b": a}
+ redir => result
+ echo b
+ echo string(b)
+ redir END
+ let l = split(result, "\n")
+ call assert_equal(["{'a': [1, 2, 3], 'b': [...]}",
+ \ "{'a': [1, 2, 3], 'b': [1, 2, 3]}"], l)
+
+ endfunc
+
+
"-------------------------------------------------------------------------------
+ " Test 94: 64-bit Numbers {{{1
+
"-------------------------------------------------------------------------------
+
+ func Test_num64()
+ if !has('num64')
+ return
+ endif
+
+ call assert_notequal( 4294967296, 0)
+ call assert_notequal(-4294967296, 0)
+ call assert_equal( 4294967296, 0xFFFFffff + 1)
+ call assert_equal(-4294967296, -0xFFFFffff - 1)
+
+ call assert_equal( 9223372036854775807, 1 / 0)
+ call assert_equal(-9223372036854775807, -1 / 0)
+ call assert_equal(-9223372036854775807 - 1, 0 / 0)
+
+ call assert_equal( 0x7FFFffffFFFFffff, float2nr( 1.0e150))
+ call assert_equal(-0x7FFFffffFFFFffff, float2nr(-1.0e150))
+
+ let rng = range(0xFFFFffff, 0x100000001)
+ call assert_equal([0xFFFFffff, 0x100000000, 0x100000001], rng)
+ call assert_equal(0x100000001, max(rng))
+ call assert_equal(0xFFFFffff, min(rng))
+ call assert_equal(rng, sort(range(0x100000001, 0xFFFFffff, -1), 'N'))
+ endfunc
+
+
"-------------------------------------------------------------------------------
+ " Test 95: lines of :append, :change, :insert {{{1
+
"-------------------------------------------------------------------------------
+
+ function! DefineFunction(name, body)
+ let func = join(['function! ' . a:name . '()'] + a:body +
['endfunction'], "\n")
+ exec func
+ endfunction
+
+ func Test_script_lines()
+ " :append
+ try
+ call DefineFunction('T_Append', [
+ \ 'append',
+ \ 'py <<EOS',
+ \ '.',
+ \ ])
+ catch
+ call assert_false(1, "Can't define function")
+ endtry
+ try
+ call DefineFunction('T_Append', [
+ \ 'append',
+ \ 'abc',
+ \ ])
+ call assert_false(1, "Shouldn't be able to define function")
+ catch
+ call assert_exception('Vim(function):E126: Missing :endfunction')
+ endtry
+
+ " :change
+ try
+ call DefineFunction('T_Change', [
+ \ 'change',
+ \ 'py <<EOS',
+ \ '.',
+ \ ])
+ catch
+ call assert_false(1, "Can't define function")
+ endtry
+ try
+ call DefineFunction('T_Change', [
+ \ 'change',
+ \ 'abc',
+ \ ])
+ call assert_false(1, "Shouldn't be able to define function")
+ catch
+ call assert_exception('Vim(function):E126: Missing :endfunction')
+ endtry
+
+ " :insert
+ try
+ call DefineFunction('T_Insert', [
+ \ 'insert',
+ \ 'py <<EOS',
+ \ '.',
+ \ ])
+ catch
+ call assert_false(1, "Can't define function")
+ endtry
+ try
+ call DefineFunction('T_Insert', [
+ \ 'insert',
+ \ 'abc',
+ \ ])
+ call assert_false(1, "Shouldn't be able to define function")
+ catch
+ call assert_exception('Vim(function):E126: Missing :endfunction')
+ endtry
+ endfunc
+
+
"-------------------------------------------------------------------------------
+ " Modelines {{{1
+ " vim: ts=8 sw=4 tw=80 fdm=marker
+ " vim: fdt=substitute(substitute(foldtext(),\
'\\%(^+--\\)\\@<=\\(\\s*\\)\\(.\\{-}\\)\:\ \\%(\"\ \\)\\=\\(Test\
\\d*\\)\:\\s*',\ '\\3\ (\\2)\:\ \\1',\ \"\"),\
'\\(Test\\s*\\)\\(\\d\\)\\D\\@=',\ '\\1\ \\2',\ "")
+
"-------------------------------------------------------------------------------
*** ../vim-8.0.0359/src/testdir/test_viml.vim 2017-01-22 18:34:53.684030783
+0100
--- src/testdir/test_viml.vim 1970-01-01 01:00:00.000000000 +0100
***************
*** 1,1316 ****
- " Test various aspects of the Vim language.
- " Most of this was formerly in test49.
-
-
"-------------------------------------------------------------------------------
- " Test environment {{{1
-
"-------------------------------------------------------------------------------
-
- com! XpathINIT let g:Xpath = ''
- com! -nargs=1 -bar Xpath let g:Xpath = g:Xpath . <args>
-
- " Append a message to the "messages" file
- func! Xout(text)
- split messages
- $put =a:text
- wq
- endfunc
-
- com! -nargs=1 Xout call Xout(<args>)
-
- " MakeScript() - Make a script file from a function. {{{2
- "
- " Create a script that consists of the body of the function a:funcname.
- " Replace any ":return" by a ":finish", any argument variable by a global
- " variable, and and every ":call" by a ":source" for the next following
argument
- " in the variable argument list. This function is useful if similar tests are
- " to be made for a ":return" from a function call or a ":finish" in a script
- " file.
- function! MakeScript(funcname, ...)
- let script = tempname()
- execute "redir! >" . script
- execute "function" a:funcname
- redir END
- execute "edit" script
- " Delete the "function" and the "endfunction" lines. Do not include the
- " word "function" in the pattern since it might be translated if LANG is
- " set. When MakeScript() is being debugged, this deletes also the
debugging
- " output of its line 3 and 4.
- exec '1,/.*' . a:funcname . '(.*)/d'
- /^\d*\s*endfunction\>/,$d
- %s/^\d*//e
- %s/return/finish/e
- %s/\<a:\(\h\w*\)/g:\1/ge
- normal gg0
- let cnt = 0
- while search('\<call\s*\%(\u\|s:\)\w*\s*(.*)', 'W') > 0
- let cnt = cnt + 1
- s/\<call\s*\%(\u\|s:\)\w*\s*(.*)/\='source ' . a:{cnt}/
- endwhile
- g/^\s*$/d
- write
- bwipeout
- return script
- endfunction
-
- " ExecAsScript - Source a temporary script made from a function. {{{2
- "
- " Make a temporary script file from the function a:funcname, ":source" it, and
- " delete it afterwards. However, if an exception is thrown the file may
remain,
- " the caller should call DeleteTheScript() afterwards.
- let s:script_name = ''
- function! ExecAsScript(funcname)
- " Make a script from the function passed as argument.
- let s:script_name = MakeScript(a:funcname)
-
- " Source and delete the script.
- exec "source" s:script_name
- call delete(s:script_name)
- let s:script_name = ''
- endfunction
-
- function! DeleteTheScript()
- if s:script_name
- call delete(s:script_name)
- let s:script_name = ''
- endif
- endfunc
-
- com! -nargs=1 -bar ExecAsScript call ExecAsScript(<f-args>)
-
-
-
"-------------------------------------------------------------------------------
- " Test 1: :endwhile in function {{{1
- "
- " Detect if a broken loop is (incorrectly) reactivated by the
- " :endwhile. Use a :return to prevent an endless loop, and make
- " this test first to get a meaningful result on an error before other
- " tests will hang.
-
"-------------------------------------------------------------------------------
-
- function! T1_F()
- Xpath 'a'
- let first = 1
- while 1
- Xpath 'b'
- if first
- Xpath 'c'
- let first = 0
- break
- else
- Xpath 'd'
- return
- endif
- endwhile
- endfunction
-
- function! T1_G()
- Xpath 'h'
- let first = 1
- while 1
- Xpath 'i'
- if first
- Xpath 'j'
- let first = 0
- break
- else
- Xpath 'k'
- return
- endif
- if 1 " unmatched :if
- endwhile
- endfunction
-
- func Test_endwhile_function()
- XpathINIT
- call T1_F()
- Xpath 'F'
-
- try
- call T1_G()
- catch
- " Catch missing :endif
- call assert_true(v:exception =~ 'E171')
- Xpath 'x'
- endtry
- Xpath 'G'
-
- call assert_equal('abcFhijxG', g:Xpath)
- endfunc
-
-
"-------------------------------------------------------------------------------
- " Test 2: :endwhile in script
{{{1
- "
- " Detect if a broken loop is (incorrectly) reactivated by the
- " :endwhile. Use a :finish to prevent an endless loop, and place
- " this test before others that might hang to get a meaningful result
- " on an error.
- "
- " This test executes the bodies of the functions T1_F and T1_G from
- " the previous test as script files (:return replaced by :finish).
-
"-------------------------------------------------------------------------------
-
- func Test_endwhile_script()
- XpathINIT
- ExecAsScript T1_F
- Xpath 'F'
- call DeleteTheScript()
-
- try
- ExecAsScript T1_G
- catch
- " Catch missing :endif
- call assert_true(v:exception =~ 'E171')
- Xpath 'x'
- endtry
- Xpath 'G'
- call DeleteTheScript()
-
- call assert_equal('abcFhijxG', g:Xpath)
- endfunc
-
-
"-------------------------------------------------------------------------------
- " Test 3: :if, :elseif, :while, :continue, :break {{{1
-
"-------------------------------------------------------------------------------
-
- function Test_if_while()
- XpathINIT
- if 1
- Xpath 'a'
- let loops = 3
- while loops > -1 " main loop: loops == 3, 2, 1 (which breaks)
- if loops <= 0
- let break_err = 1
- let loops = -1
- else
- Xpath 'b' . loops
- endif
- if (loops == 2)
- while loops == 2 " dummy loop
- Xpath 'c' . loops
- let loops = loops - 1
- continue " stop dummy loop
- Xpath 'd' . loops
- endwhile
- continue " continue main loop
- Xpath 'e' . loops
- elseif (loops == 1)
- let p = 1
- while p " dummy loop
- Xpath 'f' . loops
- let p = 0
- break " break dummy loop
- Xpath 'g' . loops
- endwhile
- Xpath 'h' . loops
- unlet p
- break " break main loop
- Xpath 'i' . loops
- endif
- if (loops > 0)
- Xpath 'j' . loops
- endif
- while loops == 3 " dummy loop
- let loops = loops - 1
- endwhile " end dummy loop
- endwhile " end main loop
- Xpath 'k'
- else
- Xpath 'l'
- endif
- Xpath 'm'
- if exists("break_err")
- Xpath 'm'
- unlet break_err
- endif
-
- unlet loops
-
- call assert_equal('ab3j3b2c2b1f1h1km', g:Xpath)
- endfunc
-
-
"-------------------------------------------------------------------------------
- " Test 4: :return {{{1
-
"-------------------------------------------------------------------------------
-
- function! T4_F()
- if 1
- Xpath 'a'
- let loops = 3
- while loops > 0 " 3: 2: 1:
- Xpath 'b' . loops
- if (loops == 2)
- Xpath 'c' . loops
- return
- Xpath 'd' . loops
- endif
- Xpath 'e' . loops
- let loops = loops - 1
- endwhile
- Xpath 'f'
- else
- Xpath 'g'
- endif
- endfunction
-
- function Test_return()
- XpathINIT
- call T4_F()
- Xpath '4'
-
- call assert_equal('ab3e3b2c24', g:Xpath)
- endfunction
-
-
-
"-------------------------------------------------------------------------------
- " Test 5: :finish {{{1
- "
- " This test executes the body of the function T4_F from the previous
- " test as a script file (:return replaced by :finish).
-
"-------------------------------------------------------------------------------
-
- function Test_finish()
- XpathINIT
- ExecAsScript T4_F
- Xpath '5'
- call DeleteTheScript()
-
- call assert_equal('ab3e3b2c25', g:Xpath)
- endfunction
-
-
-
-
"-------------------------------------------------------------------------------
- " Test 6: Defining functions in :while loops
{{{1
- "
- " Functions can be defined inside other functions. An inner function
- " gets defined when the outer function is executed. Functions may
- " also be defined inside while loops. Expressions in braces for
- " defining the function name are allowed.
- "
- " The functions are defined when sourcing the script, only the
- " resulting path is checked in the test function.
-
"-------------------------------------------------------------------------------
-
- XpathINIT
-
- " The command CALL collects the argument of all its invocations in "calls"
- " when used from a function (that is, when the global variable "calls" needs
- " the "g:" prefix). This is to check that the function code is skipped when
- " the function is defined. For inner functions, do so only if the outer
- " function is not being executed.
- "
- let calls = ""
- com! -nargs=1 CALL
- \ if !exists("calls") && !exists("outer") |
- \ let g:calls = g:calls . <args> |
- \ endif
-
- let i = 0
- while i < 3
- let i = i + 1
- if i == 1
- Xpath 'a'
- function! F1(arg)
- CALL a:arg
- let outer = 1
-
- let j = 0
- while j < 1
- Xpath 'b'
- let j = j + 1
- function! G1(arg)
- CALL a:arg
- endfunction
- Xpath 'c'
- endwhile
- endfunction
- Xpath 'd'
-
- continue
- endif
-
- Xpath 'e' . i
- function! F{i}(i, arg)
- CALL a:arg
- let outer = 1
-
- if a:i == 3
- Xpath 'f'
- endif
- let k = 0
- while k < 3
- Xpath 'g' . k
- let k = k + 1
- function! G{a:i}{k}(arg)
- CALL a:arg
- endfunction
- Xpath 'h' . k
- endwhile
- endfunction
- Xpath 'i'
-
- endwhile
-
- if exists("*G1")
- Xpath 'j'
- endif
- if exists("*F1")
- call F1("F1")
- if exists("*G1")
- call G1("G1")
- endif
- endif
-
- if exists("G21") || exists("G22") || exists("G23")
- Xpath 'k'
- endif
- if exists("*F2")
- call F2(2, "F2")
- if exists("*G21")
- call G21("G21")
- endif
- if exists("*G22")
- call G22("G22")
- endif
- if exists("*G23")
- call G23("G23")
- endif
- endif
-
- if exists("G31") || exists("G32") || exists("G33")
- Xpath 'l'
- endif
- if exists("*F3")
- call F3(3, "F3")
- if exists("*G31")
- call G31("G31")
- endif
- if exists("*G32")
- call G32("G32")
- endif
- if exists("*G33")
- call G33("G33")
- endif
- endif
-
- Xpath 'm'
-
- let g:test6_result = g:Xpath
- let g:test6_calls = calls
-
- unlet calls
- delfunction F1
- delfunction G1
- delfunction F2
- delfunction G21
- delfunction G22
- delfunction G23
- delfunction G31
- delfunction G32
- delfunction G33
-
- function Test_defining_functions()
- call assert_equal('ade2ie3ibcg0h1g1h2g2h3fg0h1g1h2g2h3m', g:test6_result)
- call assert_equal('F1G1F2G21G22G23F3G31G32G33', g:test6_calls)
- endfunc
-
-
"-------------------------------------------------------------------------------
- " Test 7: Continuing on errors outside functions {{{1
- "
- " On an error outside a function, the script processing continues
- " at the line following the outermost :endif or :endwhile. When not
- " inside an :if or :while, the script processing continues at the next
- " line.
-
"-------------------------------------------------------------------------------
-
- XpathINIT
-
- if 1
- Xpath 'a'
- while 1
- Xpath 'b'
- asdf
- Xpath 'c'
- break
- endwhile | Xpath 'd'
- Xpath 'e'
- endif | Xpath 'f'
- Xpath 'g'
-
- while 1
- Xpath 'h'
- if 1
- Xpath 'i'
- asdf
- Xpath 'j'
- endif | Xpath 'k'
- Xpath 'l'
- break
- endwhile | Xpath 'm'
- Xpath 'n'
-
- asdf
- Xpath 'o'
-
- asdf | Xpath 'p'
- Xpath 'q'
-
- let g:test7_result = g:Xpath
-
- func Test_error_in_script()
- call assert_equal('abghinoq', g:test7_result)
- endfunc
-
-
"-------------------------------------------------------------------------------
- " Test 8: Aborting and continuing on errors inside functions
{{{1
- "
- " On an error inside a function without the "abort" attribute, the
- " script processing continues at the next line (unless the error was
- " in a :return command). On an error inside a function with the
- " "abort" attribute, the function is aborted and the script processing
- " continues after the function call; the value -1 is returned then.
-
"-------------------------------------------------------------------------------
-
- XpathINIT
-
- function! T8_F()
- if 1
- Xpath 'a'
- while 1
- Xpath 'b'
- asdf
- Xpath 'c'
- asdf | Xpath 'd'
- Xpath 'e'
- break
- endwhile
- Xpath 'f'
- endif | Xpath 'g'
- Xpath 'h'
-
- while 1
- Xpath 'i'
- if 1
- Xpath 'j'
- asdf
- Xpath 'k'
- asdf | Xpath 'l'
- Xpath 'm'
- endif
- Xpath 'n'
- break
- endwhile | Xpath 'o'
- Xpath 'p'
-
- return novar " returns (default return value 0)
- Xpath 'q'
- return 1 " not reached
- endfunction
-
- function! T8_G() abort
- if 1
- Xpath 'r'
- while 1
- Xpath 's'
- asdf " returns -1
- Xpath 't'
- break
- endwhile
- Xpath 'v'
- endif | Xpath 'w'
- Xpath 'x'
-
- return -4 " not reached
- endfunction
-
- function! T8_H() abort
- while 1
- Xpath 'A'
- if 1
- Xpath 'B'
- asdf " returns -1
- Xpath 'C'
- endif
- Xpath 'D'
- break
- endwhile | Xpath 'E'
- Xpath 'F'
-
- return -4 " not reached
- endfunction
-
- " Aborted functions (T8_G and T8_H) return -1.
- let g:test8_sum = (T8_F() + 1) - 4 * T8_G() - 8 * T8_H()
- Xpath 'X'
- let g:test8_result = g:Xpath
-
- func Test_error_in_function()
- call assert_equal(13, g:test8_sum)
- call assert_equal('abcefghijkmnoprsABX', g:test8_result)
-
- delfunction T8_F
- delfunction T8_G
- delfunction T8_H
- endfunc
-
-
-
"-------------------------------------------------------------------------------
- " Test 9: Continuing after aborted functions
{{{1
- "
- " When a function with the "abort" attribute is aborted due to an
- " error, the next function back in the call hierarchy without an
- " "abort" attribute continues; the value -1 is returned then.
-
"-------------------------------------------------------------------------------
-
- XpathINIT
-
- function! F() abort
- Xpath 'a'
- let result = G() " not aborted
- Xpath 'b'
- if result != 2
- Xpath 'c'
- endif
- return 1
- endfunction
-
- function! G() " no abort attribute
- Xpath 'd'
- if H() != -1 " aborted
- Xpath 'e'
- endif
- Xpath 'f'
- return 2
- endfunction
-
- function! H() abort
- Xpath 'g'
- call I() " aborted
- Xpath 'h'
- return 4
- endfunction
-
- function! I() abort
- Xpath 'i'
- asdf " error
- Xpath 'j'
- return 8
- endfunction
-
- if F() != 1
- Xpath 'k'
- endif
-
- let g:test9_result = g:Xpath
-
- delfunction F
- delfunction G
- delfunction H
- delfunction I
-
- func Test_func_abort()
- call assert_equal('adgifb', g:test9_result)
- endfunc
-
-
-
"-------------------------------------------------------------------------------
- " Test 10: :if, :elseif, :while argument parsing {{{1
- "
- " A '"' or '|' in an argument expression must not be mixed up with
- " a comment or a next command after a bar. Parsing errors should
- " be recognized.
-
"-------------------------------------------------------------------------------
-
- XpathINIT
-
- function! MSG(enr, emsg)
- let english = v:lang == "C" || v:lang =~ '^[Ee]n'
- if a:enr == ""
- Xout "TODO: Add message number for:" a:emsg
- let v:errmsg = ":" . v:errmsg
- endif
- let match = 1
- if v:errmsg !~ '^'.a:enr.':' || (english && v:errmsg !~ a:emsg)
- let match = 0
- if v:errmsg == ""
- Xout "Message missing."
- else
- let v:errmsg = escape(v:errmsg, '"')
- Xout "Unexpected message:" v:errmsg
- endif
- endif
- return match
- endfunction
-
- if 1 || strlen("\"") | Xpath 'a'
- Xpath 'b'
- endif
- Xpath 'c'
-
- if 0
- elseif 1 || strlen("\"") | Xpath 'd'
- Xpath 'e'
- endif
- Xpath 'f'
-
- while 1 || strlen("\"") | Xpath 'g'
- Xpath 'h'
- break
- endwhile
- Xpath 'i'
-
- let v:errmsg = ""
- if 1 ||| strlen("\"") | Xpath 'j'
- Xpath 'k'
- endif
- Xpath 'l'
- if !MSG('E15', "Invalid expression")
- Xpath 'm'
- endif
-
- let v:errmsg = ""
- if 0
- elseif 1 ||| strlen("\"") | Xpath 'n'
- Xpath 'o'
- endif
- Xpath 'p'
- if !MSG('E15', "Invalid expression")
- Xpath 'q'
- endif
-
- let v:errmsg = ""
- while 1 ||| strlen("\"") | Xpath 'r'
- Xpath 's'
- break
- endwhile
- Xpath 't'
- if !MSG('E15', "Invalid expression")
- Xpath 'u'
- endif
-
- let g:test10_result = g:Xpath
- delfunction MSG
-
- func Test_expr_parsing()
- call assert_equal('abcdefghilpt', g:test10_result)
- endfunc
-
-
-
"-------------------------------------------------------------------------------
- " Test 11: :if, :elseif, :while argument evaluation after abort {{{1
- "
- " When code is skipped over due to an error, the boolean argument to
- " an :if, :elseif, or :while must not be evaluated.
-
"-------------------------------------------------------------------------------
-
- XpathINIT
-
- let calls = 0
-
- function! P(num)
- let g:calls = g:calls + a:num " side effect on call
- return 0
- endfunction
-
- if 1
- Xpath 'a'
- asdf " error
- Xpath 'b'
- if P(1) " should not be called
- Xpath 'c'
- elseif !P(2) " should not be called
- Xpath 'd'
- else
- Xpath 'e'
- endif
- Xpath 'f'
- while P(4) " should not be called
- Xpath 'g'
- endwhile
- Xpath 'h'
- endif
- Xpath 'x'
-
- let g:test11_calls = calls
- let g:test11_result = g:Xpath
-
- unlet calls
- delfunction P
-
- func Test_arg_abort()
- call assert_equal(0, g:test11_calls)
- call assert_equal('ax', g:test11_result)
- endfunc
-
-
-
"-------------------------------------------------------------------------------
- " Test 12: Expressions in braces in skipped code {{{1
- "
- " In code skipped over due to an error or inactive conditional,
- " an expression in braces as part of a variable or function name
- " should not be evaluated.
-
"-------------------------------------------------------------------------------
-
- XpathINIT
-
- function! NULL()
- Xpath 'a'
- return 0
- endfunction
-
- function! ZERO()
- Xpath 'b'
- return 0
- endfunction
-
- function! F0()
- Xpath 'c'
- endfunction
-
- function! F1(arg)
- Xpath 'e'
- endfunction
-
- let V0 = 1
-
- Xpath 'f'
- echo 0 ? F{NULL() + V{ZERO()}}() : 1
-
- Xpath 'g'
- if 0
- Xpath 'h'
- call F{NULL() + V{ZERO()}}()
- endif
-
- Xpath 'i'
- if 1
- asdf " error
- Xpath 'j'
- call F1(F{NULL() + V{ZERO()}}())
- endif
-
- Xpath 'k'
- if 1
- asdf " error
- Xpath 'l'
- call F{NULL() + V{ZERO()}}()
- endif
-
- let g:test12_result = g:Xpath
-
- func Test_braces_skipped()
- call assert_equal('fgik', g:test12_result)
- endfunc
-
-
-
"-------------------------------------------------------------------------------
- " Test 13: Failure in argument evaluation for :while {{{1
- "
- " A failure in the expression evaluation for the condition of a :while
- " causes the whole :while loop until the matching :endwhile being
- " ignored. Continuation is at the next following line.
-
"-------------------------------------------------------------------------------
-
- XpathINIT
-
- Xpath 'a'
- while asdf
- Xpath 'b'
- while 1
- Xpath 'c'
- break
- endwhile
- Xpath 'd'
- break
- endwhile
- Xpath 'e'
-
- while asdf | Xpath 'f' | endwhile | Xpath 'g'
- Xpath 'h'
- let g:test13_result = g:Xpath
-
- func Test_while_fail()
- call assert_equal('aeh', g:test13_result)
- endfunc
-
-
-
"-------------------------------------------------------------------------------
- " Test 14: Failure in argument evaluation for :if {{{1
- "
- " A failure in the expression evaluation for the condition of an :if
- " does not cause the corresponding :else or :endif being matched to
- " a previous :if/:elseif. Neither of both branches of the failed :if
- " are executed.
-
"-------------------------------------------------------------------------------
-
- XpathINIT
-
- function! F()
- Xpath 'a'
- let x = 0
- if x " false
- Xpath 'b'
- elseif !x " always true
- Xpath 'c'
- let x = 1
- if g:boolvar " possibly undefined
- Xpath 'd'
- else
- Xpath 'e'
- endif
- Xpath 'f'
- elseif x " never executed
- Xpath 'g'
- endif
- Xpath 'h'
- endfunction
-
- let boolvar = 1
- call F()
- Xpath '-'
-
- unlet boolvar
- call F()
- let g:test14_result = g:Xpath
-
- delfunction F
-
- func Test_if_fail()
- call assert_equal('acdfh-acfh', g:test14_result)
- endfunc
-
-
-
"-------------------------------------------------------------------------------
- " Test 15: Failure in argument evaluation for :if (bar) {{{1
- "
- " Like previous test, except that the failing :if ... | ... | :endif
- " is in a single line.
-
"-------------------------------------------------------------------------------
-
- XpathINIT
-
- function! F()
- Xpath 'a'
- let x = 0
- if x " false
- Xpath 'b'
- elseif !x " always true
- Xpath 'c'
- let x = 1
- if g:boolvar | Xpath 'd' | else | Xpath 'e' | endif
- Xpath 'f'
- elseif x " never executed
- Xpath 'g'
- endif
- Xpath 'h'
- endfunction
-
- let boolvar = 1
- call F()
- Xpath '-'
-
- unlet boolvar
- call F()
- let g:test15_result = g:Xpath
-
- delfunction F
-
- func Test_if_bar_fail()
- call assert_equal('acdfh-acfh', g:test15_result)
- endfunc
-
-
"-------------------------------------------------------------------------------
- " Test 90: Recognizing {} in variable name. {{{1
-
"-------------------------------------------------------------------------------
-
- func Test_curlies()
- let s:var = 66
- let ns = 's'
- call assert_equal(66, {ns}:var)
-
- let g:a = {}
- let g:b = 't'
- let g:a[g:b] = 77
- call assert_equal(77, g:a['t'])
- endfunc
-
-
"-------------------------------------------------------------------------------
- " Test 91: using type(). {{{1
-
"-------------------------------------------------------------------------------
-
- func Test_type()
- call assert_equal(0, type(0))
- call assert_equal(1, type(""))
- call assert_equal(2, type(function("tr")))
- call assert_equal(2, type(function("tr", [8])))
- call assert_equal(3, type([]))
- call assert_equal(4, type({}))
- call assert_equal(5, type(0.0))
- call assert_equal(6, type(v:false))
- call assert_equal(6, type(v:true))
- call assert_equal(7, type(v:none))
- call assert_equal(7, type(v:null))
- call assert_equal(8, v:t_job)
- call assert_equal(9, v:t_channel)
- call assert_equal(v:t_number, type(0))
- call assert_equal(v:t_string, type(""))
- call assert_equal(v:t_func, type(function("tr")))
- call assert_equal(v:t_func, type(function("tr", [8])))
- call assert_equal(v:t_list, type([]))
- call assert_equal(v:t_dict, type({}))
- call assert_equal(v:t_float, type(0.0))
- call assert_equal(v:t_bool, type(v:false))
- call assert_equal(v:t_bool, type(v:true))
- call assert_equal(v:t_none, type(v:none))
- call assert_equal(v:t_none, type(v:null))
-
-
- call assert_equal(0, 0 + v:false)
- call assert_equal(1, 0 + v:true)
- call assert_equal(0, 0 + v:none)
- call assert_equal(0, 0 + v:null)
-
- call assert_equal('v:false', '' . v:false)
- call assert_equal('v:true', '' . v:true)
- call assert_equal('v:none', '' . v:none)
- call assert_equal('v:null', '' . v:null)
-
- call assert_true(v:false == 0)
- call assert_false(v:false != 0)
- call assert_true(v:true == 1)
- call assert_false(v:true != 1)
- call assert_false(v:true == v:false)
- call assert_true(v:true != v:false)
-
- call assert_true(v:null == 0)
- call assert_false(v:null != 0)
- call assert_true(v:none == 0)
- call assert_false(v:none != 0)
-
- call assert_true(v:false is v:false)
- call assert_true(v:true is v:true)
- call assert_true(v:none is v:none)
- call assert_true(v:null is v:null)
-
- call assert_false(v:false isnot v:false)
- call assert_false(v:true isnot v:true)
- call assert_false(v:none isnot v:none)
- call assert_false(v:null isnot v:null)
-
- call assert_false(v:false is 0)
- call assert_false(v:true is 1)
- call assert_false(v:true is v:false)
- call assert_false(v:none is 0)
- call assert_false(v:null is 0)
- call assert_false(v:null is v:none)
-
- call assert_true(v:false isnot 0)
- call assert_true(v:true isnot 1)
- call assert_true(v:true isnot v:false)
- call assert_true(v:none isnot 0)
- call assert_true(v:null isnot 0)
- call assert_true(v:null isnot v:none)
-
- call assert_equal(v:false, eval(string(v:false)))
- call assert_equal(v:true, eval(string(v:true)))
- call assert_equal(v:none, eval(string(v:none)))
- call assert_equal(v:null, eval(string(v:null)))
-
- call assert_equal(v:false, copy(v:false))
- call assert_equal(v:true, copy(v:true))
- call assert_equal(v:none, copy(v:none))
- call assert_equal(v:null, copy(v:null))
-
- call assert_equal([v:false], deepcopy([v:false]))
- call assert_equal([v:true], deepcopy([v:true]))
- call assert_equal([v:none], deepcopy([v:none]))
- call assert_equal([v:null], deepcopy([v:null]))
-
- call assert_true(empty(v:false))
- call assert_false(empty(v:true))
- call assert_true(empty(v:null))
- call assert_true(empty(v:none))
-
- func ChangeYourMind()
- try
- return v:true
- finally
- return 'something else'
- endtry
- endfunc
-
- call ChangeYourMind()
- endfunc
-
-
"-------------------------------------------------------------------------------
- " Test 92: skipping code {{{1
-
"-------------------------------------------------------------------------------
-
- func Test_skip()
- let Fn = function('Test_type')
- call assert_false(0 && Fn[1])
- call assert_false(0 && string(Fn))
- call assert_false(0 && len(Fn))
- let l = []
- call assert_false(0 && l[1])
- call assert_false(0 && string(l))
- call assert_false(0 && len(l))
- let f = 1.0
- call assert_false(0 && f[1])
- call assert_false(0 && string(f))
- call assert_false(0 && len(f))
- let sp = v:null
- call assert_false(0 && sp[1])
- call assert_false(0 && string(sp))
- call assert_false(0 && len(sp))
-
- endfunc
-
-
"-------------------------------------------------------------------------------
- " Test 93: :echo and string() {{{1
-
"-------------------------------------------------------------------------------
-
- func Test_echo_and_string()
- " String
- let a = 'foo bar'
- redir => result
- echo a
- echo string(a)
- redir END
- let l = split(result, "\n")
- call assert_equal(["foo bar",
- \ "'foo bar'"], l)
-
- " Float
- if has('float')
- let a = -1.2e0
- redir => result
- echo a
- echo string(a)
- redir END
- let l = split(result, "\n")
- call assert_equal(["-1.2",
- \ "-1.2"], l)
- endif
-
- " Funcref
- redir => result
- echo function('string')
- echo string(function('string'))
- redir END
- let l = split(result, "\n")
- call assert_equal(["string",
- \ "function('string')"], l)
-
- " Recursive dictionary
- let a = {}
- let a["a"] = a
- redir => result
- echo a
- echo string(a)
- redir END
- let l = split(result, "\n")
- call assert_equal(["{'a': {...}}",
- \ "{'a': {...}}"], l)
-
- " Recursive list
- let a = [0]
- let a[0] = a
- redir => result
- echo a
- echo string(a)
- redir END
- let l = split(result, "\n")
- call assert_equal(["[[...]]",
- \ "[[...]]"], l)
-
- " Empty dictionaries in a list
- let a = {}
- redir => result
- echo [a, a, a]
- echo string([a, a, a])
- redir END
- let l = split(result, "\n")
- call assert_equal(["[{}, {}, {}]",
- \ "[{}, {}, {}]"], l)
-
- " Empty dictionaries in a dictionary
- let a = {}
- let b = {"a": a, "b": a}
- redir => result
- echo b
- echo string(b)
- redir END
- let l = split(result, "\n")
- call assert_equal(["{'a': {}, 'b': {}}",
- \ "{'a': {}, 'b': {}}"], l)
-
- " Empty lists in a list
- let a = []
- redir => result
- echo [a, a, a]
- echo string([a, a, a])
- redir END
- let l = split(result, "\n")
- call assert_equal(["[[], [], []]",
- \ "[[], [], []]"], l)
-
- " Empty lists in a dictionary
- let a = []
- let b = {"a": a, "b": a}
- redir => result
- echo b
- echo string(b)
- redir END
- let l = split(result, "\n")
- call assert_equal(["{'a': [], 'b': []}",
- \ "{'a': [], 'b': []}"], l)
-
- " Dictionaries in a list
- let a = {"one": "yes", "two": "yes", "three": "yes"}
- redir => result
- echo [a, a, a]
- echo string([a, a, a])
- redir END
- let l = split(result, "\n")
- call assert_equal(["[{'one': 'yes', 'two': 'yes', 'three': 'yes'}, {...},
{...}]",
- \ "[{'one': 'yes', 'two': 'yes', 'three': 'yes'}, {'one':
'yes', 'two': 'yes', 'three': 'yes'}, {'one': 'yes', 'two': 'yes', 'three':
'yes'}]"], l)
-
- " Dictionaries in a dictionary
- let a = {"one": "yes", "two": "yes", "three": "yes"}
- let b = {"a": a, "b": a}
- redir => result
- echo b
- echo string(b)
- redir END
- let l = split(result, "\n")
- call assert_equal(["{'a': {'one': 'yes', 'two': 'yes', 'three': 'yes'},
'b': {...}}",
- \ "{'a': {'one': 'yes', 'two': 'yes', 'three': 'yes'},
'b': {'one': 'yes', 'two': 'yes', 'three': 'yes'}}"], l)
-
- " Lists in a list
- let a = [1, 2, 3]
- redir => result
- echo [a, a, a]
- echo string([a, a, a])
- redir END
- let l = split(result, "\n")
- call assert_equal(["[[1, 2, 3], [...], [...]]",
- \ "[[1, 2, 3], [1, 2, 3], [1, 2, 3]]"], l)
-
- " Lists in a dictionary
- let a = [1, 2, 3]
- let b = {"a": a, "b": a}
- redir => result
- echo b
- echo string(b)
- redir END
- let l = split(result, "\n")
- call assert_equal(["{'a': [1, 2, 3], 'b': [...]}",
- \ "{'a': [1, 2, 3], 'b': [1, 2, 3]}"], l)
-
- endfunc
-
-
"-------------------------------------------------------------------------------
- " Test 94: 64-bit Numbers {{{1
-
"-------------------------------------------------------------------------------
-
- func Test_num64()
- if !has('num64')
- return
- endif
-
- call assert_notequal( 4294967296, 0)
- call assert_notequal(-4294967296, 0)
- call assert_equal( 4294967296, 0xFFFFffff + 1)
- call assert_equal(-4294967296, -0xFFFFffff - 1)
-
- call assert_equal( 9223372036854775807, 1 / 0)
- call assert_equal(-9223372036854775807, -1 / 0)
- call assert_equal(-9223372036854775807 - 1, 0 / 0)
-
- call assert_equal( 0x7FFFffffFFFFffff, float2nr( 1.0e150))
- call assert_equal(-0x7FFFffffFFFFffff, float2nr(-1.0e150))
-
- let rng = range(0xFFFFffff, 0x100000001)
- call assert_equal([0xFFFFffff, 0x100000000, 0x100000001], rng)
- call assert_equal(0x100000001, max(rng))
- call assert_equal(0xFFFFffff, min(rng))
- call assert_equal(rng, sort(range(0x100000001, 0xFFFFffff, -1), 'N'))
- endfunc
-
-
"-------------------------------------------------------------------------------
- " Test 95: lines of :append, :change, :insert {{{1
-
"-------------------------------------------------------------------------------
-
- function! DefineFunction(name, body)
- let func = join(['function! ' . a:name . '()'] + a:body +
['endfunction'], "\n")
- exec func
- endfunction
-
- func Test_script_lines()
- " :append
- try
- call DefineFunction('T_Append', [
- \ 'append',
- \ 'py <<EOS',
- \ '.',
- \ ])
- catch
- call assert_false(1, "Can't define function")
- endtry
- try
- call DefineFunction('T_Append', [
- \ 'append',
- \ 'abc',
- \ ])
- call assert_false(1, "Shouldn't be able to define function")
- catch
- call assert_exception('Vim(function):E126: Missing :endfunction')
- endtry
-
- " :change
- try
- call DefineFunction('T_Change', [
- \ 'change',
- \ 'py <<EOS',
- \ '.',
- \ ])
- catch
- call assert_false(1, "Can't define function")
- endtry
- try
- call DefineFunction('T_Change', [
- \ 'change',
- \ 'abc',
- \ ])
- call assert_false(1, "Shouldn't be able to define function")
- catch
- call assert_exception('Vim(function):E126: Missing :endfunction')
- endtry
-
- " :insert
- try
- call DefineFunction('T_Insert', [
- \ 'insert',
- \ 'py <<EOS',
- \ '.',
- \ ])
- catch
- call assert_false(1, "Can't define function")
- endtry
- try
- call DefineFunction('T_Insert', [
- \ 'insert',
- \ 'abc',
- \ ])
- call assert_false(1, "Shouldn't be able to define function")
- catch
- call assert_exception('Vim(function):E126: Missing :endfunction')
- endtry
- endfunc
-
-
"-------------------------------------------------------------------------------
- " Modelines {{{1
- " vim: ts=8 sw=4 tw=80 fdm=marker
- " vim: fdt=substitute(substitute(foldtext(),\
'\\%(^+--\\)\\@<=\\(\\s*\\)\\(.\\{-}\\)\:\ \\%(\"\ \\)\\=\\(Test\
\\d*\\)\:\\s*',\ '\\3\ (\\2)\:\ \\1',\ \"\"),\
'\\(Test\\s*\\)\\(\\d\\)\\D\\@=',\ '\\1\ \\2',\ "")
-
"-------------------------------------------------------------------------------
--- 0 ----
*** ../vim-8.0.0359/src/version.c 2017-02-23 18:46:24.466288916 +0100
--- src/version.c 2017-02-23 18:50:44.848624212 +0100
***************
*** 766,767 ****
--- 766,769 ----
{ /* Add new patch number below this line */
+ /**/
+ 360,
/**/
--
Me? A skeptic? I trust you have proof.
/// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net \\\
/// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\ an exciting new programming language -- http://www.Zimbu.org ///
\\\ help me help AIDS victims -- http://ICCF-Holland.org ///
--
--
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php
---
You received this message because you are subscribed to the Google Groups
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.