changeset 10942:e05695e59f6d v8.0.0360

patch 8.0.0360: sometimes VimL is used instead of "Vim script" commit https://github.com/vim/vim/commit/b544f3c81f1e6a50322855681ac266ffaa8e313c Author: Bram Moolenaar <Bram@vim.org> Date: Thu Feb 23 19:03:28 2017 +0100 patch 8.0.0360: sometimes VimL is used instead of "Vim script" Problem: Sometimes VimL is used, which is confusing. Solution: Consistently use "Vim script". (Hirohito Higashi)
author Christian Brabandt <cb@256bit.org>
date Thu, 23 Feb 2017 19:15:05 +0100
parents 56b3c9414c82
children 02654bf3c3f6
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_viml.vim src/testdir/test_vimscript.vim src/version.c
diffstat 16 files changed, 1348 insertions(+), 1346 deletions(-) [+]
line wrap: on
line diff
--- a/runtime/doc/if_mzsch.txt
+++ b/runtime/doc/if_mzsch.txt
@@ -249,7 +249,7 @@ Windows							    *mzscheme-window*
 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.
+evaluate MzScheme expressions and pass their values to Vim script.
 
 ==============================================================================
 6. Using Function references				    *mzscheme-funcref*
--- a/runtime/doc/if_pyth.txt
+++ b/runtime/doc/if_pyth.txt
@@ -676,11 +676,11 @@ vim.Function object				*python-Function*
                      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 
+                     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,7 +711,7 @@ vim.Function object				*python-Function*
 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.
+functions to evaluate Python expressions and pass their values to Vim script.
 |pyxeval()| is also available.
 
 ==============================================================================
--- a/runtime/doc/syntax.txt
+++ b/runtime/doc/syntax.txt
@@ -3327,8 +3327,8 @@ Some folding is now supported with synta
    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
+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
--- a/runtime/doc/usr_02.txt
+++ b/runtime/doc/usr_02.txt
@@ -589,7 +589,7 @@ 12) Registers always start with "quote".
     register: >
    	:help quote:
 
-13) Vim Script (VimL) is available at >
+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,10 +599,10 @@ 13) Vim Script (VimL) is available at >
    Also important is >
    	:help function-list
 <   to find a short description of all functions available.  Help topics for
-   VimL functions always include the "()", so: >
+   Vim script functions always include the "()", so: >
    	:help append()
-<   talks about the append VimL function rather than how to append text in the
-   current buffer.
+<   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
--- a/runtime/doc/version7.txt
+++ b/runtime/doc/version7.txt
@@ -10202,7 +10202,7 @@ objects in place of `str()` ones avoidin
 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.
+|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 
--- a/src/Makefile
+++ b/src/Makefile
@@ -2213,7 +2213,7 @@ test_arglist \
 	test_usercommands \
 	test_utf8 \
 	test_viminfo \
-	test_viml \
+	test_vimscript \
 	test_visual \
 	test_window_cmd \
 	test_window_id \
--- a/src/eval.c
+++ b/src/eval.c
@@ -950,7 +950,7 @@ eval_expr(char_u *arg, char_u **nextcmd)
 
 
 /*
- * Call some vimL function and return the result in "*rettv".
+ * 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,7 +1027,7 @@ call_vim_function(
 }
 
 /*
- * Call vimL function "func" and return the result as a number.
+ * 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,7 +1055,7 @@ call_func_retnr(
 
 # if (defined(FEAT_USR_CMDS) && defined(FEAT_CMDL_COMPL)) || defined(PROTO)
 /*
- * Call vimL function "func" and return the result as a string.
+ * 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,7 +1080,7 @@ call_func_retstr(
 # endif
 
 /*
- * Call vimL function "func" and return the result as a List.
+ * 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.
  */
--- a/src/ex_getln.c
+++ b/src/ex_getln.c
@@ -5140,8 +5140,8 @@ expand_shellcmd(
 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).
+ * 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(
--- a/src/if_py_both.h
+++ b/src/if_py_both.h
@@ -582,9 +582,9 @@ VimTryStart(void)
 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 */
+    /* 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,7 +625,7 @@ VimTryEnd(void)
 	discard_current_exception();
 	return -1;
     }
-    /* Finally transform VimL exception to python one */
+    /* Finally transform Vim script exception to python one */
     else
     {
 	PyErr_SetVim((char *)current_exception->value);
--- a/src/if_xcmdsrv.c
+++ b/src/if_xcmdsrv.c
@@ -1449,8 +1449,8 @@ server_parse_message(
 	    char_u	*enc;
 
 	    /*
-	     * This is a (n)otification.  Sent with serverreply_send in VimL.
-	     * Execute any autocommand and save it for later retrieval
+	     * 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;
--- a/src/testdir/Make_all.mak
+++ b/src/testdir/Make_all.mak
@@ -199,7 +199,7 @@ NEW_TESTS = test_arglist.res \
 	    test_undo.res \
 	    test_usercommands.res \
 	    test_viminfo.res \
-	    test_viml.res \
+	    test_vimscript.res \
 	    test_visual.res \
 	    test_window_id.res \
 	    test_writefile.res \
--- a/src/testdir/runtest.vim
+++ b/src/testdir/runtest.vim
@@ -147,7 +147,7 @@ let s:fail = 0
 let s:errors = []
 let s:messages = []
 let s:skipped = []
-if expand('%') =~ 'test_viml.vim'
+if expand('%') =~ 'test_vimscript.vim'
   " this test has intentional s:errors, don't use try/catch.
   source %
 else
--- a/src/testdir/test49.vim
+++ b/src/testdir/test49.vim
@@ -608,7 +608,7 @@ com! -nargs=1 -bar ExecAsScript call Exe
 " END_OF_TEST_ENVIRONMENT - do not change or remove this line.
 
 
-" Tests 1 to 15 were moved to test_viml.vim
+" Tests 1 to 15 were moved to test_vimscript.vim
 let Xtest = 16
 
 "-------------------------------------------------------------------------------
deleted file mode 100644
--- a/src/testdir/test_viml.vim
+++ /dev/null
@@ -1,1316 +0,0 @@
-" 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',\ "")
-"-------------------------------------------------------------------------------
new file mode 100644
--- /dev/null
+++ b/src/testdir/test_vimscript.vim
@@ -0,0 +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',\ "")
+"-------------------------------------------------------------------------------
--- a/src/version.c
+++ b/src/version.c
@@ -765,6 +765,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    360,
+/**/
     359,
 /**/
     358,