diff runtime/doc/eval.txt @ 32670:695b50472e85

Fix line endings issue
author Christian Brabandt <cb@256bit.org>
date Mon, 26 Jun 2023 13:13:12 +0200
parents 448aef880252
children c517845bd10e
line wrap: on
line diff
--- a/runtime/doc/eval.txt
+++ b/runtime/doc/eval.txt
@@ -1,4782 +1,4782 @@
-*eval.txt*	For Vim version 9.0.  Last change: 2023 Jun 01
-
-
-		  VIM REFERENCE MANUAL	  by Bram Moolenaar
-
-
-Expression evaluation			*expression* *expr* *E15* *eval*
-							*E1002*
-Using expressions is introduced in chapter 41 of the user manual |usr_41.txt|.
-
-Note: Expression evaluation can be disabled at compile time.  If this has been
-done, the features in this document are not available.  See |+eval| and
-|no-eval-feature|.
-
-This file is mainly about the backwards compatible (legacy) Vim script.  For
-specifics of Vim9 script, which can execute much faster, supports type
-checking and much more, see |vim9.txt|.  Where the syntax or semantics differ
-a remark is given.
-
-1.  Variables			|variables|
-    1.1 Variable types
-    1.2 Function references		|Funcref|
-    1.3 Lists				|Lists|
-    1.4 Dictionaries			|Dictionaries|
-    1.5 Blobs				|Blobs|
-    1.6 More about variables		|more-variables|
-2.  Expression syntax		|expression-syntax|
-3.  Internal variable		|internal-variables|
-4.  Builtin Functions		|functions|
-5.  Defining functions		|user-functions|
-6.  Curly braces names		|curly-braces-names|
-7.  Commands			|expression-commands|
-8.  Exception handling		|exception-handling|
-9.  Examples			|eval-examples|
-10. Vim script version		|vimscript-version|
-11. No +eval feature		|no-eval-feature|
-12. The sandbox			|eval-sandbox|
-13. Textlock			|textlock|
-
-Testing support is documented in |testing.txt|.
-Profiling is documented at |profiling|.
-
-==============================================================================
-1. Variables						*variables*
-
-1.1 Variable types ~
-					*E712* *E896* *E897* *E899* *E1098*
-					*E1107* *E1135* *E1138*
-There are ten types of variables:
-
-							*Number* *Integer*
-Number		A 32 or 64 bit signed number.  |expr-number|
-		The number of bits is available in |v:numbersize|.
-		Examples:  -123  0x10  0177  0o177 0b1011
-
-Float		A floating point number. |floating-point-format| *Float*
-		Examples: 123.456  1.15e-6  -1.1e3
-
-String		A NUL terminated string of 8-bit unsigned characters (bytes).
-		|expr-string| Examples: "ab\txx\"--"  'x-z''a,c'
-
-List		An ordered sequence of items, see |List| for details.
-		Example: [1, 2, ['a', 'b']]
-
-Dictionary	An associative, unordered array: Each entry has a key and a
-		value. |Dictionary|
-		Examples:
-			{'blue': "#0000ff", 'red': "#ff0000"}
-			#{blue: "#0000ff", red: "#ff0000"}
-
-Funcref		A reference to a function |Funcref|.
-		Example: function("strlen")
-		It can be bound to a dictionary and arguments, it then works
-		like a Partial.
-		Example: function("Callback", [arg], myDict)
-
-Special		|v:false|, |v:true|, |v:none| and |v:null|.  *Special*
-
-Job		Used for a job, see |job_start()|. *Job* *Jobs*
-
-Channel		Used for a channel, see |ch_open()|. *Channel* *Channels*
-
-Blob		Binary Large Object. Stores any sequence of bytes.  See |Blob|
-		for details
-		Example: 0zFF00ED015DAF
-		0z is an empty Blob.
-
-The Number and String types are converted automatically, depending on how they
-are used.
-
-Conversion from a Number to a String is by making the ASCII representation of
-the Number.  Examples:
-	Number 123	-->	String "123" ~
-	Number 0	-->	String "0" ~
-	Number -1	-->	String "-1" ~
-							*octal*
-Conversion from a String to a Number only happens in legacy Vim script, not in
-Vim9 script.  It is done by converting the first digits to a number.
-Hexadecimal "0xf9", Octal "017" or "0o17", and Binary "0b10"
-numbers are recognized
-NOTE: when using |Vim9| script or |scriptversion-4| octal with a leading "0"
-is not recognized.  The 0o notation requires patch 8.2.0886.
-If the String doesn't start with digits, the result is zero.
-Examples:
-	String "456"	-->	Number 456 ~
-	String "6bar"	-->	Number 6 ~
-	String "foo"	-->	Number 0 ~
-	String "0xf1"	-->	Number 241 ~
-	String "0100"	-->	Number 64 ~
-	String "0o100"	-->	Number 64 ~
-	String "0b101"	-->	Number 5 ~
-	String "-8"	-->	Number -8 ~
-	String "+8"	-->	Number 0 ~
-
-To force conversion from String to Number, add zero to it: >
-	:echo "0100" + 0
-<	64 ~
-
-To avoid a leading zero to cause octal conversion, or for using a different
-base, use |str2nr()|.
-
-						*TRUE* *FALSE* *Boolean*
-For boolean operators Numbers are used.  Zero is FALSE, non-zero is TRUE.
-You can also use |v:false| and |v:true|, in Vim9 script |false| and |true|.
-When TRUE is returned from a function it is the Number one, FALSE is the
-number zero.
-
-Note that in the command: >
-	:if "foo"
-	:" NOT executed
-"foo" is converted to 0, which means FALSE.  If the string starts with a
-non-zero number it means TRUE: >
-	:if "8foo"
-	:" executed
-To test for a non-empty string, use empty(): >
-	:if !empty("foo")
-
-<						*falsy* *truthy*
-An expression can be used as a condition, ignoring the type and only using
-whether the value is "sort of true" or "sort of false".  Falsy is:
-	the number zero
-	empty string, blob, list or dictionary
-Other values are truthy.  Examples:
-	0	falsy
-	1	truthy
-	-1	truthy
-	0.0	falsy
-	0.1	truthy
-	''	falsy
-	'x'	truthy
-	[]	falsy
-	[0]	truthy
-	{}	falsy
-	#{x: 1} truthy
-	0z	falsy
-	0z00	truthy
-
-							*non-zero-arg*
-Function arguments often behave slightly different from |TRUE|: If the
-argument is present and it evaluates to a non-zero Number, |v:true| or a
-non-empty String, then the value is considered to be TRUE.
-Note that " " and "0" are also non-empty strings, thus considered to be TRUE.
-A List, Dictionary or Float is not a Number or String, thus evaluate to FALSE.
-
-		*E611* *E745* *E728* *E703* *E729* *E730* *E731* *E908* *E910*
-		*E913* *E974* *E975* *E976* *E1319* *E1320* *E1321* *E1322*
-		*E1323* *E1324*
-|List|, |Dictionary|, |Funcref|, |Job|, |Channel|, |Blob|, |Class| and
-|object| types are not automatically converted.
-
-							*E805* *E806* *E808*
-When mixing Number and Float the Number is converted to Float.  Otherwise
-there is no automatic conversion of Float.  You can use str2float() for String
-to Float, printf() for Float to String and float2nr() for Float to Number.
-
-			*E362* *E891* *E892* *E893* *E894* *E907* *E911* *E914*
-When expecting a Float a Number can also be used, but nothing else.
-
-						*no-type-checking*
-You will not get an error if you try to change the type of a variable.
-
-
-1.2 Function references ~
-					*Funcref* *E695* *E718* *E1192*
-A Funcref variable is obtained with the |function()| function, the |funcref()|
-function, (in |Vim9| script) the name of a function, or created with the
-lambda expression |expr-lambda|.  It can be used in an expression in the place
-of a function name, before the parenthesis around the arguments, to invoke the
-function it refers to.  Example in |Vim9| script: >
-
-	:var Fn = MyFunc
-	:echo Fn()
-
-Legacy script: >
-	:let Fn = function("MyFunc")
-	:echo Fn()
-<							*E704* *E705* *E707*
-A Funcref variable must start with a capital, "s:", "w:", "t:" or "b:".  You
-can use "g:" but the following name must still start with a capital.  You
-cannot have both a Funcref variable and a function with the same name.
-
-A special case is defining a function and directly assigning its Funcref to a
-Dictionary entry.  Example: >
-	:function dict.init() dict
-	:   let self.val = 0
-	:endfunction
-
-The key of the Dictionary can start with a lower case letter.  The actual
-function name is not used here.  Also see |numbered-function|.
-
-A Funcref can also be used with the |:call| command: >
-	:call Fn()
-	:call dict.init()
-
-The name of the referenced function can be obtained with |string()|. >
-	:let func = string(Fn)
-
-You can use |call()| to invoke a Funcref and use a list variable for the
-arguments: >
-	:let r = call(Fn, mylist)
-<
-								*Partial*
-A Funcref optionally binds a Dictionary and/or arguments.  This is also called
-a Partial.  This is created by passing the Dictionary and/or arguments to
-function() or funcref().  When calling the function the Dictionary and/or
-arguments will be passed to the function.  Example: >
-
-	let Cb = function('Callback', ['foo'], myDict)
-	call Cb('bar')
-
-This will invoke the function as if using: >
-	call myDict.Callback('foo', 'bar')
-
-This is very useful when passing a function around, e.g. in the arguments of
-|ch_open()|.
-
-Note that binding a function to a Dictionary also happens when the function is
-a member of the Dictionary: >
-
-	let myDict.myFunction = MyFunction
-	call myDict.myFunction()
-
-Here MyFunction() will get myDict passed as "self".  This happens when the
-"myFunction" member is accessed.  When making assigning "myFunction" to
-otherDict and calling it, it will be bound to otherDict: >
-
-	let otherDict.myFunction = myDict.myFunction
-	call otherDict.myFunction()
-
-Now "self" will be "otherDict".  But when the dictionary was bound explicitly
-this won't happen: >
-
-	let myDict.myFunction = function(MyFunction, myDict)
-	let otherDict.myFunction = myDict.myFunction
-	call otherDict.myFunction()
-
-Here "self" will be "myDict", because it was bound explicitly.
-
-
-1.3 Lists ~
-						*list* *List* *Lists* *E686*
-A List is an ordered sequence of items.  An item can be of any type.  Items
-can be accessed by their index number.  Items can be added and removed at any
-position in the sequence.
-
-
-List creation ~
-							*E696* *E697*
-A List is created with a comma-separated list of items in square brackets.
-Examples: >
-	:let mylist = [1, two, 3, "four"]
-	:let emptylist = []
-
-An item can be any expression.  Using a List for an item creates a
-List of Lists: >
-	:let nestlist = [[11, 12], [21, 22], [31, 32]]
-
-An extra comma after the last item is ignored.
-
-
-List index ~
-							*list-index* *E684*
-An item in the List can be accessed by putting the index in square brackets
-after the List.  Indexes are zero-based, thus the first item has index zero. >
-	:let item = mylist[0]		" get the first item: 1
-	:let item = mylist[2]		" get the third item: 3
-
-When the resulting item is a list this can be repeated: >
-	:let item = nestlist[0][1]	" get the first list, second item: 12
-<
-A negative index is counted from the end.  Index -1 refers to the last item in
-the List, -2 to the last but one item, etc. >
-	:let last = mylist[-1]		" get the last item: "four"
-
-To avoid an error for an invalid index use the |get()| function.  When an item
-is not available it returns zero or the default value you specify: >
-	:echo get(mylist, idx)
-	:echo get(mylist, idx, "NONE")
-
-
-List concatenation ~
-							*list-concatenation*
-Two lists can be concatenated with the "+" operator: >
-	:let longlist = mylist + [5, 6]
-	:let mylist += [7, 8]
-
-To prepend or append an item, turn the item into a list by putting [] around
-it.  To change a list in-place, refer to |list-modification| below.
-
-
-Sublist ~
-							*sublist*
-A part of the List can be obtained by specifying the first and last index,
-separated by a colon in square brackets: >
-	:let shortlist = mylist[2:-1]	" get List [3, "four"]
-
-Omitting the first index is similar to zero.  Omitting the last index is
-similar to -1. >
-	:let endlist = mylist[2:]	" from item 2 to the end: [3, "four"]
-	:let shortlist = mylist[2:2]	" List with one item: [3]
-	:let otherlist = mylist[:]	" make a copy of the List
-
-Notice that the last index is inclusive.  If you prefer using an exclusive
-index use the |slice()| method.
-
-If the first index is beyond the last item of the List or the second item is
-before the first item, the result is an empty list.  There is no error
-message.
-
-If the second index is equal to or greater than the length of the list the
-length minus one is used: >
-	:let mylist = [0, 1, 2, 3]
-	:echo mylist[2:8]		" result: [2, 3]
-
-NOTE: mylist[s:e] means using the variable "s:e" as index.  Watch out for
-using a single letter variable before the ":".  Insert a space when needed:
-mylist[s : e].
-
-
-List identity ~
-							*list-identity*
-When variable "aa" is a list and you assign it to another variable "bb", both
-variables refer to the same list.  Thus changing the list "aa" will also
-change "bb": >
-	:let aa = [1, 2, 3]
-	:let bb = aa
-	:call add(aa, 4)
-	:echo bb
-<	[1, 2, 3, 4]
-
-Making a copy of a list is done with the |copy()| function.  Using [:] also
-works, as explained above.  This creates a shallow copy of the list: Changing
-a list item in the list will also change the item in the copied list: >
-	:let aa = [[1, 'a'], 2, 3]
-	:let bb = copy(aa)
-	:call add(aa, 4)
-	:let aa[0][1] = 'aaa'
-	:echo aa
-<	[[1, aaa], 2, 3, 4] >
-	:echo bb
-<	[[1, aaa], 2, 3]
-
-To make a completely independent list use |deepcopy()|.  This also makes a
-copy of the values in the list, recursively.  Up to a hundred levels deep.
-
-The operator "is" can be used to check if two variables refer to the same
-List.  "isnot" does the opposite.  In contrast "==" compares if two lists have
-the same value. >
-	:let alist = [1, 2, 3]
-	:let blist = [1, 2, 3]
-	:echo alist is blist
-<	0 >
-	:echo alist == blist
-<	1
-
-Note about comparing lists: Two lists are considered equal if they have the
-same length and all items compare equal, as with using "==".  There is one
-exception: When comparing a number with a string they are considered
-different.  There is no automatic type conversion, as with using "==" on
-variables.  Example: >
-	echo 4 == "4"
-<	1 >
-	echo [4] == ["4"]
-<	0
-
-Thus comparing Lists is more strict than comparing numbers and strings.  You
-can compare simple values this way too by putting them in a list: >
-
-	:let a = 5
-	:let b = "5"
-	:echo a == b
-<	1 >
-	:echo [a] == [b]
-<	0
-
-
-List unpack ~
-
-To unpack the items in a list to individual variables, put the variables in
-square brackets, like list items: >
-	:let [var1, var2] = mylist
-
-When the number of variables does not match the number of items in the list
-this produces an error.  To handle any extra items from the list append ";"
-and a variable name: >
-	:let [var1, var2; rest] = mylist
-
-This works like: >
-	:let var1 = mylist[0]
-	:let var2 = mylist[1]
-	:let rest = mylist[2:]
-
-Except that there is no error if there are only two items.  "rest" will be an
-empty list then.
-
-
-List modification ~
-							*list-modification*
-To change a specific item of a list use |:let| this way: >
-	:let list[4] = "four"
-	:let listlist[0][3] = item
-
-To change part of a list you can specify the first and last item to be
-modified.  The value must at least have the number of items in the range: >
-	:let list[3:5] = [3, 4, 5]
-
-Adding and removing items from a list is done with functions.  Here are a few
-examples: >
-	:call insert(list, 'a')		" prepend item 'a'
-	:call insert(list, 'a', 3)	" insert item 'a' before list[3]
-	:call add(list, "new")		" append String item
-	:call add(list, [1, 2])		" append a List as one new item
-	:call extend(list, [1, 2])	" extend the list with two more items
-	:let i = remove(list, 3)	" remove item 3
-	:unlet list[3]			" idem
-	:let l = remove(list, 3, -1)	" remove items 3 to last item
-	:unlet list[3 : ]		" idem
-	:call filter(list, 'v:val !~ "x"')  " remove items with an 'x'
-
-Changing the order of items in a list: >
-	:call sort(list)		" sort a list alphabetically
-	:call reverse(list)		" reverse the order of items
-	:call uniq(sort(list))		" sort and remove duplicates
-
-
-For loop ~
-
-The |:for| loop executes commands for each item in a List, String or Blob.
-A variable is set to each item in sequence.  Example with a List: >
-	:for item in mylist
-	:   call Doit(item)
-	:endfor
-
-This works like: >
-	:let index = 0
-	:while index < len(mylist)
-	:   let item = mylist[index]
-	:   :call Doit(item)
-	:   let index = index + 1
-	:endwhile
-
-If all you want to do is modify each item in the list then the |map()|
-function will be a simpler method than a for loop.
-
-Just like the |:let| command, |:for| also accepts a list of variables.  This
-requires the argument to be a List of Lists. >
-	:for [lnum, col] in [[1, 3], [2, 8], [3, 0]]
-	:   call Doit(lnum, col)
-	:endfor
-
-This works like a |:let| command is done for each list item.  Again, the types
-must remain the same to avoid an error.
-
-It is also possible to put remaining items in a List variable: >
-	:for [i, j; rest] in listlist
-	:   call Doit(i, j)
-	:   if !empty(rest)
-	:      echo "remainder: " .. string(rest)
-	:   endif
-	:endfor
-
-For a Blob one byte at a time is used.
-
-For a String one character, including any composing characters, is used as a
-String.  Example: >
-	for c in text
-	  echo 'This character is ' .. c
-	endfor
-
-
-List functions ~
-						*E714*
-Functions that are useful with a List: >
-	:let r = call(funcname, list)	" call a function with an argument list
-	:if empty(list)			" check if list is empty
-	:let l = len(list)		" number of items in list
-	:let big = max(list)		" maximum value in list
-	:let small = min(list)		" minimum value in list
-	:let xs = count(list, 'x')	" count nr of times 'x' appears in list
-	:let i = index(list, 'x')	" index of first 'x' in list
-	:let lines = getline(1, 10)	" get ten text lines from buffer
-	:call append('$', lines)	" append text lines in buffer
-	:let list = split("a b c")	" create list from items in a string
-	:let string = join(list, ', ')	" create string from list items
-	:let s = string(list)		" String representation of list
-	:call map(list, '">> " .. v:val')  " prepend ">> " to each item
-
-Don't forget that a combination of features can make things simple.  For
-example, to add up all the numbers in a list: >
-	:exe 'let sum = ' .. join(nrlist, '+')
-
-
-1.4 Dictionaries ~
-				*dict* *Dict* *Dictionaries* *Dictionary*
-A Dictionary is an associative array: Each entry has a key and a value.  The
-entry can be located with the key.  The entries are stored without a specific
-ordering.
-
-
-Dictionary creation ~
-						*E720* *E721* *E722* *E723*
-A Dictionary is created with a comma-separated list of entries in curly
-braces.  Each entry has a key and a value, separated by a colon.  Each key can
-only appear once.  Examples: >
-	:let mydict = {1: 'one', 2: 'two', 3: 'three'}
-	:let emptydict = {}
-<							*E713* *E716* *E717*
-A key is always a String.  You can use a Number, it will be converted to a
-String automatically.  Thus the String '4' and the number 4 will find the same
-entry.  Note that the String '04' and the Number 04 are different, since the
-Number will be converted to the String '4', leading zeros are dropped.  The
-empty string can also be used as a key.
-
-In |Vim9| script a literal key can be used if it consists only of alphanumeric
-characters, underscore and dash, see |vim9-literal-dict|.
-						*literal-Dict* *#{}*
-To avoid having to put quotes around every key the #{} form can be used in
-legacy script.  This does require the key to consist only of ASCII letters,
-digits, '-' and '_'.  Example: >
-	:let mydict = #{zero: 0, one_key: 1, two-key: 2, 333: 3}
-Note that 333 here is the string "333".  Empty keys are not possible with #{}.
-In |Vim9| script the #{} form cannot be used because it can be confused with
-the start of a comment.
-
-A value can be any expression.  Using a Dictionary for a value creates a
-nested Dictionary: >
-	:let nestdict = {1: {11: 'a', 12: 'b'}, 2: {21: 'c'}}
-
-An extra comma after the last entry is ignored.
-
-
-Accessing entries ~
-
-The normal way to access an entry is by putting the key in square brackets: >
-	:let val = mydict["one"]
-	:let mydict["four"] = 4
-
-You can add new entries to an existing Dictionary this way, unlike Lists.
-
-For keys that consist entirely of letters, digits and underscore the following
-form can be used |expr-entry|: >
-	:let val = mydict.one
-	:let mydict.four = 4
-
-Since an entry can be any type, also a List and a Dictionary, the indexing and
-key lookup can be repeated: >
-	:echo dict.key[idx].key
-
-
-Dictionary to List conversion ~
-
-You may want to loop over the entries in a dictionary.  For this you need to
-turn the Dictionary into a List and pass it to |:for|.
-
-Most often you want to loop over the keys, using the |keys()| function: >
-	:for key in keys(mydict)
-	:   echo key .. ': ' .. mydict[key]
-	:endfor
-
-The List of keys is unsorted.  You may want to sort them first: >
-	:for key in sort(keys(mydict))
-
-To loop over the values use the |values()| function:  >
-	:for v in values(mydict)
-	:   echo "value: " .. v
-	:endfor
-
-If you want both the key and the value use the |items()| function.  It returns
-a List in which each item is a List with two items, the key and the value: >
-	:for [key, value] in items(mydict)
-	:   echo key .. ': ' .. value
-	:endfor
-
-
-Dictionary identity ~
-							*dict-identity*
-Just like Lists you need to use |copy()| and |deepcopy()| to make a copy of a
-Dictionary.  Otherwise, assignment results in referring to the same
-Dictionary: >
-	:let onedict = {'a': 1, 'b': 2}
-	:let adict = onedict
-	:let adict['a'] = 11
-	:echo onedict['a']
-	11
-
-Two Dictionaries compare equal if all the key-value pairs compare equal.  For
-more info see |list-identity|.
-
-
-Dictionary modification ~
-							*dict-modification*
-To change an already existing entry of a Dictionary, or to add a new entry,
-use |:let| this way: >
-	:let dict[4] = "four"
-	:let dict['one'] = item
-
-Removing an entry from a Dictionary is done with |remove()| or |:unlet|.
-Three ways to remove the entry with key "aaa" from dict: >
-	:let i = remove(dict, 'aaa')
-	:unlet dict.aaa
-	:unlet dict['aaa']
-
-Merging a Dictionary with another is done with |extend()|: >
-	:call extend(adict, bdict)
-This extends adict with all entries from bdict.  Duplicate keys cause entries
-in adict to be overwritten.  An optional third argument can change this.
-Note that the order of entries in a Dictionary is irrelevant, thus don't
-expect ":echo adict" to show the items from bdict after the older entries in
-adict.
-
-Weeding out entries from a Dictionary can be done with |filter()|: >
-	:call filter(dict, 'v:val =~ "x"')
-This removes all entries from "dict" with a value not matching 'x'.
-This can also be used to remove all entries: >
-	call filter(dict, 0)
-
-In some situations it is not allowed to remove or add entries to a Dictionary.
-Especially when iterating over all the entries.  You will get *E1313* or
-another error in that case.
-
-
-Dictionary function ~
-				*Dictionary-function* *self* *E725* *E862*
-When a function is defined with the "dict" attribute it can be used in a
-special way with a dictionary.  Example: >
-	:function Mylen() dict
-	:   return len(self.data)
-	:endfunction
-	:let mydict = {'data': [0, 1, 2, 3], 'len': function("Mylen")}
-	:echo mydict.len()
-
-This is like a method in object oriented programming.  The entry in the
-Dictionary is a |Funcref|.  The local variable "self" refers to the dictionary
-the function was invoked from.  When using |Vim9| script you can use classes
-and objects, see `:class`.
-
-It is also possible to add a function without the "dict" attribute as a
-Funcref to a Dictionary, but the "self" variable is not available then.
-
-				*numbered-function* *anonymous-function*
-To avoid the extra name for the function it can be defined and directly
-assigned to a Dictionary in this way: >
-	:let mydict = {'data': [0, 1, 2, 3]}
-	:function mydict.len()
-	:   return len(self.data)
-	:endfunction
-	:echo mydict.len()
-
-The function will then get a number and the value of dict.len is a |Funcref|
-that references this function.  The function can only be used through a
-|Funcref|.  It will automatically be deleted when there is no |Funcref|
-remaining that refers to it.
-
-It is not necessary to use the "dict" attribute for a numbered function.
-
-If you get an error for a numbered function, you can find out what it is with
-a trick.  Assuming the function is 42, the command is: >
-	:function g:42
-
-
-Functions for Dictionaries ~
-							*E715*
-Functions that can be used with a Dictionary: >
-	:if has_key(dict, 'foo')	" TRUE if dict has entry with key "foo"
-	:if empty(dict)			" TRUE if dict is empty
-	:let l = len(dict)		" number of items in dict
-	:let big = max(dict)		" maximum value in dict
-	:let small = min(dict)		" minimum value in dict
-	:let xs = count(dict, 'x')	" count nr of times 'x' appears in dict
-	:let s = string(dict)		" String representation of dict
-	:call map(dict, '">> " .. v:val')  " prepend ">> " to each item
-
-
-1.5 Blobs ~
-						*blob* *Blob* *Blobs* *E978*
-A Blob is a binary object.  It can be used to read an image from a file and
-send it over a channel, for example.
-
-A Blob mostly behaves like a |List| of numbers, where each number has the
-value of an 8-bit byte, from 0 to 255.
-
-
-Blob creation ~
-
-A Blob can be created with a |blob-literal|: >
-	:let b = 0zFF00ED015DAF
-Dots can be inserted between bytes (pair of hex characters) for readability,
-they don't change the value: >
-	:let b = 0zFF00.ED01.5DAF
-
-A blob can be read from a file with |readfile()| passing the {type} argument
-set to "B", for example: >
-	:let b = readfile('image.png', 'B')
-
-A blob can be read from a channel with the |ch_readblob()| function.
-
-
-Blob index ~
-							*blob-index* *E979*
-A byte in the Blob can be accessed by putting the index in square brackets
-after the Blob.  Indexes are zero-based, thus the first byte has index zero. >
-	:let myblob = 0z00112233
-	:let byte = myblob[0]		" get the first byte: 0x00
-	:let byte = myblob[2]		" get the third byte: 0x22
-
-A negative index is counted from the end.  Index -1 refers to the last byte in
-the Blob, -2 to the last but one byte, etc. >
-	:let last = myblob[-1]		" get the last byte: 0x33
-
-To avoid an error for an invalid index use the |get()| function.  When an item
-is not available it returns -1 or the default value you specify: >
-	:echo get(myblob, idx)
-	:echo get(myblob, idx, 999)
-
-
-Blob iteration ~
-
-The |:for| loop executes commands for each byte of a Blob.  The loop variable is
-set to each byte in the Blob.  Example: >
-	:for byte in 0z112233
-	:   call Doit(byte)
-	:endfor
-This calls Doit() with 0x11, 0x22 and 0x33.
-
-
-Blob concatenation ~
-
-Two blobs can be concatenated with the "+" operator: >
-	:let longblob = myblob + 0z4455
-	:let myblob += 0z6677
-
-To change a blob in-place see |blob-modification| below.
-
-
-Part of a blob ~
-
-A part of the Blob can be obtained by specifying the first and last index,
-separated by a colon in square brackets: >
-	:let myblob = 0z00112233
-	:let shortblob = myblob[1:2]	" get 0z1122
-	:let shortblob = myblob[2:-1]	" get 0z2233
-
-Omitting the first index is similar to zero.  Omitting the last index is
-similar to -1. >
-	:let endblob = myblob[2:]	" from item 2 to the end: 0z2233
-	:let shortblob = myblob[2:2]	" Blob with one byte: 0z22
-	:let otherblob = myblob[:]	" make a copy of the Blob
-
-If the first index is beyond the last byte of the Blob or the second index is
-before the first index, the result is an empty Blob.  There is no error
-message.
-
-If the second index is equal to or greater than the length of the list the
-length minus one is used: >
-	:echo myblob[2:8]		" result: 0z2233
-
-
-Blob modification ~
-					*blob-modification* *E1182* *E1184*
-To change a specific byte of a blob use |:let| this way: >
-	:let blob[4] = 0x44
-
-When the index is just one beyond the end of the Blob, it is appended. Any
-higher index is an error.
-
-To change a sequence of bytes the [:] notation can be used: >
-	let blob[1:3] = 0z445566
-The length of the replaced bytes must be exactly the same as the value
-provided. *E972*
-
-To change part of a blob you can specify the first and last byte to be
-modified.  The value must have the same number of bytes in the range: >
-	:let blob[3:5] = 0z334455
-
-You can also use the functions |add()|, |remove()| and |insert()|.
-
-
-Blob identity ~
-
-Blobs can be compared for equality: >
-	if blob == 0z001122
-And for equal identity: >
-	if blob is otherblob
-<							*blob-identity* *E977*
-When variable "aa" is a Blob and you assign it to another variable "bb", both
-variables refer to the same Blob.  Then the "is" operator returns true.
-
-When making a copy using [:] or |copy()| the values are the same, but the
-identity is different: >
-	:let blob = 0z112233
-	:let blob2 = blob
-	:echo blob == blob2
-<	1 >
-	:echo blob is blob2
-<	1 >
-	:let blob3 = blob[:]
-	:echo blob == blob3
-<	1 >
-	:echo blob is blob3
-<	0
-
-Making a copy of a Blob is done with the |copy()| function.  Using [:] also
-works, as explained above.
-
-
-1.6 More about variables ~
-							*more-variables*
-If you need to know the type of a variable or expression, use the |type()|
-function.
-
-When the '!' flag is included in the 'viminfo' option, global variables that
-start with an uppercase letter, and don't contain a lowercase letter, are
-stored in the viminfo file |viminfo-file|.
-
-When the 'sessionoptions' option contains "global", global variables that
-start with an uppercase letter and contain at least one lowercase letter are
-stored in the session file |session-file|.
-
-variable name		can be stored where ~
-my_var_6		not
-My_Var_6		session file
-MY_VAR_6		viminfo file
-
-
-In legacy script it is possible to form a variable name with curly braces, see
-|curly-braces-names|.
-
-==============================================================================
-2. Expression syntax					*expression-syntax*
-							*E1143*
-Expression syntax summary, from least to most significant:
-
-|expr1|	expr2
-	expr2 ? expr1 : expr1	if-then-else
-
-|expr2|	expr3
-	expr3 || expr3 ...	logical OR
-
-|expr3|	expr4
-	expr4 && expr4 ...	logical AND
-
-|expr4|	expr5
-	expr5 == expr5		equal
-	expr5 != expr5		not equal
-	expr5 >	 expr5		greater than
-	expr5 >= expr5		greater than or equal
-	expr5 <	 expr5		smaller than
-	expr5 <= expr5		smaller than or equal
-	expr5 =~ expr5		regexp matches
-	expr5 !~ expr5		regexp doesn't match
-
-	expr5 ==? expr5		equal, ignoring case
-	expr5 ==# expr5		equal, match case
-	etc.			As above, append ? for ignoring case, # for
-				matching case
-
-	expr5 is expr5		same |List|, |Dictionary| or |Blob| instance
-	expr5 isnot expr5	different |List|, |Dictionary| or |Blob|
-				instance
-
-|expr5|	expr6 << expr6		bitwise left shift
-	expr6 >> expr6		bitwise right shift
-
-|expr6|	expr7
-	expr7 +	 expr7 ...	number addition, list or blob concatenation
-	expr7 -	 expr7 ...	number subtraction
-	expr7 .	 expr7 ...	string concatenation
-	expr7 .. expr7 ...	string concatenation
-
-|expr7|	expr8
-	expr8 *	 expr8 ...	number multiplication
-	expr8 /	 expr8 ...	number division
-	expr8 %	 expr8 ...	number modulo
-
-|expr8|	expr9
-	<type>expr9		type check and conversion (|Vim9| only)
-
-|expr9|	expr10
-	! expr9			logical NOT
-	- expr9			unary minus
-	+ expr9			unary plus
-
-|expr10|  expr11
-	expr10[expr1]		byte of a String or item of a |List|
-	expr10[expr1 : expr1]	substring of a String or sublist of a |List|
-	expr10.name		entry in a |Dictionary|
-	expr10(expr1, ...)	function call with |Funcref| variable
-	expr10->name(expr1, ...)	|method| call
-
-|expr11|  number		number constant
-	"string"		string constant, backslash is special
-	'string'		string constant, ' is doubled
-	[expr1, ...]		|List|
-	{expr1: expr1, ...}	|Dictionary|
-	#{key: expr1, ...}	legacy |Dictionary|
-	&option			option value
-	(expr1)			nested expression
-	variable		internal variable
-	va{ria}ble		internal variable with curly braces
-	$VAR			environment variable
-	@r			contents of register 'r'
-	function(expr1, ...)	function call
-	func{ti}on(expr1, ...)	function call with curly braces
-	{args -> expr1}		legacy lambda expression
-	(args) => expr1		Vim9 lambda expression
-
-
-"..." indicates that the operations in this level can be concatenated.
-Example: >
-	&nu || &list && &shell == "csh"
-
-All expressions within one level are parsed from left to right.
-
-Expression nesting is limited to 1000 levels deep (300 when build with MSVC)
-to avoid running out of stack and crashing. *E1169*
-
-
-expr1				*expr1* *ternary* *falsy-operator* *??* *E109*
------
-
-The ternary operator: expr2 ? expr1 : expr1
-The falsy operator:   expr2 ?? expr1
-
-Ternary operator ~
-
-In legacy script the expression before the '?' is evaluated to a number.  If
-it evaluates to |TRUE|, the result is the value of the expression between the
-'?' and ':', otherwise the result is the value of the expression after the
-':'.
-
-In |Vim9| script the first expression must evaluate to a boolean, see
-|vim9-boolean|.
-
-Example: >
-	:echo lnum == 1 ? "top" : lnum
-
-Since the first expression is an "expr2", it cannot contain another ?:.  The
-other two expressions can, thus allow for recursive use of ?:.
-Example: >
-	:echo lnum == 1 ? "top" : lnum == 1000 ? "last" : lnum
-
-To keep this readable, using |line-continuation| is suggested: >
-	:echo lnum == 1
-	:\	? "top"
-	:\	: lnum == 1000
-	:\		? "last"
-	:\		: lnum
-
-You should always put a space before the ':', otherwise it can be mistaken for
-use in a variable such as "a:1".
-
-Falsy operator ~
-
-This is also known as the "null coalescing operator", but that's too
-complicated, thus we just call it the falsy operator.
-
-The expression before the '??' is evaluated.  If it evaluates to
-|truthy|, this is used as the result.  Otherwise the expression after the '??'
-is evaluated and used as the result.  This is most useful to have a default
-value for an expression that may result in zero or empty: >
-	echo theList ?? 'list is empty'
-	echo GetName() ?? 'unknown'
-
-These are similar, but not equal: >
-	expr2 ?? expr1
-	expr2 ? expr2 : expr1
-In the second line "expr2" is evaluated twice.  And in |Vim9| script the type
-of expr2 before "?" must be a boolean.
-
-
-expr2 and expr3						*expr2* *expr3*
----------------
-
-expr3 || expr3 ..	logical OR		*expr-barbar*
-expr4 && expr4 ..	logical AND		*expr-&&*
-
-The "||" and "&&" operators take one argument on each side.
-
-In legacy script the arguments are (converted to) Numbers.
-
-In |Vim9| script the values must be boolean, see |vim9-boolean|.  Use "!!" to
-convert any type to a boolean.
-
-The result is:
-    input			 output ~
-n1	n2		n1 || n2	n1 && n2 ~
-|FALSE|	|FALSE|		|FALSE|		|FALSE|
-|FALSE|	|TRUE|		|TRUE|		|FALSE|
-|TRUE|	|FALSE|		|TRUE|		|FALSE|
-|TRUE|	|TRUE|		|TRUE|		|TRUE|
-
-The operators can be concatenated, for example: >
-
-	&nu || &list && &shell == "csh"
-
-Note that "&&" takes precedence over "||", so this has the meaning of: >
-
-	&nu || (&list && &shell == "csh")
-
-Once the result is known, the expression "short-circuits", that is, further
-arguments are not evaluated.  This is like what happens in C.  For example: >
-
-	let a = 1
-	echo a || b
-
-This is valid even if there is no variable called "b" because "a" is |TRUE|,
-so the result must be |TRUE|.  Similarly below: >
-
-	echo exists("b") && b == "yes"
-
-This is valid whether "b" has been defined or not.  The second clause will
-only be evaluated if "b" has been defined.
-
-
-expr4							*expr4* *E1153*
------
-
-expr5 {cmp} expr5
-
-Compare two expr5 expressions.  In legacy script the result is a 0 if it
-evaluates to false, or 1 if it evaluates to true.  In |Vim9| script the result
-is |true| or |false|.
-
-			*expr-==*  *expr-!=*  *expr->*	 *expr->=*
-			*expr-<*   *expr-<=*  *expr-=~*  *expr-!~*
-			*expr-==#* *expr-!=#* *expr->#*  *expr->=#*
-			*expr-<#*  *expr-<=#* *expr-=~#* *expr-!~#*
-			*expr-==?* *expr-!=?* *expr->?*  *expr->=?*
-			*expr-<?*  *expr-<=?* *expr-=~?* *expr-!~?*
-			*expr-is* *expr-isnot* *expr-is#* *expr-isnot#*
-			*expr-is?* *expr-isnot?* *E1072*
-		use 'ignorecase'    match case	   ignore case ~
-equal			==		==#		==?
-not equal		!=		!=#		!=?
-greater than		>		>#		>?
-greater than or equal	>=		>=#		>=?
-smaller than		<		<#		<?
-smaller than or equal	<=		<=#		<=?
-regexp matches		=~		=~#		=~?
-regexp doesn't match	!~		!~#		!~?
-same instance		is		is#		is?
-different instance	isnot		isnot#		isnot?
-
-Examples:
-"abc" ==# "Abc"	  evaluates to 0
-"abc" ==? "Abc"	  evaluates to 1
-"abc" == "Abc"	  evaluates to 1 if 'ignorecase' is set, 0 otherwise
-NOTE: In |Vim9| script 'ignorecase' is not used.
-
-							*E691* *E692*
-A |List| can only be compared with a |List| and only "equal", "not equal",
-"is" and "isnot" can be used.  This compares the values of the list,
-recursively.  Ignoring case means case is ignored when comparing item values.
-
-							*E735* *E736*
-A |Dictionary| can only be compared with a |Dictionary| and only "equal", "not
-equal", "is" and "isnot" can be used.  This compares the key/values of the
-|Dictionary| recursively.  Ignoring case means case is ignored when comparing
-item values.
-
-							*E694*
-A |Funcref| can only be compared with a |Funcref| and only "equal", "not
-equal", "is" and "isnot" can be used.  Case is never ignored.  Whether
-arguments or a Dictionary are bound (with a partial) matters.  The
-Dictionaries must also be equal (or the same, in case of "is") and the
-arguments must be equal (or the same).
-
-To compare Funcrefs to see if they refer to the same function, ignoring bound
-Dictionary and arguments, use |get()| to get the function name: >
-	if get(Part1, 'name') == get(Part2, 'name')
-	   " Part1 and Part2 refer to the same function
-<							*E1037*
-Using "is" or "isnot" with a |List|, |Dictionary| or |Blob| checks whether
-the expressions are referring to the same |List|, |Dictionary| or |Blob|
-instance.  A copy of a |List| is different from the original |List|.  When
-using "is" without a |List|, |Dictionary| or |Blob|, it is equivalent to
-using "equal", using "isnot" equivalent to using "not equal".  Except that
-a different type means the values are different: >
-	echo 4 == '4'
-	1
-	echo 4 is '4'
-	0
-	echo 0 is []
-	0
-"is#"/"isnot#" and "is?"/"isnot?" can be used to match and ignore case.
-In |Vim9| script this doesn't work, two strings are never identical.
-
-In legacy script, when comparing a String with a Number, the String is
-converted to a Number, and the comparison is done on Numbers.  This means
-that: >
-	echo 0 == 'x'
-	1
-because 'x' converted to a Number is zero.  However: >
-	echo [0] == ['x']
-	0
-Inside a List or Dictionary this conversion is not used.
-
-In |Vim9| script the types must match.
-
-When comparing two Strings, this is done with strcmp() or stricmp().  This
-results in the mathematical difference (comparing byte values), not
-necessarily the alphabetical difference in the local language.
-
-When using the operators with a trailing '#', or the short version and
-'ignorecase' is off, the comparing is done with strcmp(): case matters.
-
-When using the operators with a trailing '?', or the short version and
-'ignorecase' is set, the comparing is done with stricmp(): case is ignored.
-
-'smartcase' is not used.
-
-The "=~" and "!~" operators match the lefthand argument with the righthand
-argument, which is used as a pattern.  See |pattern| for what a pattern is.
-This matching is always done like 'magic' was set and 'cpoptions' is empty, no
-matter what the actual value of 'magic' or 'cpoptions' is.  This makes scripts
-portable.  To avoid backslashes in the regexp pattern to be doubled, use a
-single-quote string, see |literal-string|.
-Since a string is considered to be a single line, a multi-line pattern
-(containing \n, backslash-n) will not match.  However, a literal NL character
-can be matched like an ordinary character.  Examples:
-	"foo\nbar" =~ "\n"	evaluates to 1
-	"foo\nbar" =~ "\\n"	evaluates to 0
-
-
-expr5						*expr5* *bitwise-shift*
------
-expr6 << expr6	bitwise left shift				*expr-<<*
-expr6 >> expr6	bitwise right shift				*expr->>*
-							*E1282* *E1283*
-The "<<" and ">>" operators can be used to perform bitwise left or right shift
-of the left operand by the number of bits specified by the right operand.  The
-operands are used as positive numbers.  When shifting right with ">>" the
-topmost bit (sometimes called the sign bit) is cleared.  If the right operand
-(shift amount) is more than the maximum number of bits in a number
-(|v:numbersize|) the result is zero.
-
-
-expr6 and expr7				*expr6* *expr7* *E1036* *E1051*
----------------
-expr7 + expr7   Number addition, |List| or |Blob| concatenation	*expr-+*
-expr7 - expr7   Number subtraction				*expr--*
-expr7 . expr7   String concatenation				*expr-.*
-expr7 .. expr7  String concatenation				*expr-..*
-
-For |Lists| only "+" is possible and then both expr7 must be a list.  The
-result is a new list with the two lists Concatenated.
-
-For String concatenation ".." is preferred, since "." is ambiguous, it is also
-used for |Dict| member access and floating point numbers.
-In |Vim9| script and when |vimscript-version| is 2 or higher, using "." is not
-allowed.
-
-In |Vim9| script the arguments of ".." are converted to String for simple
-types: Number, Float, Special and Bool.  For other types |string()| should be
-used.
-
-expr8 * expr8  Number multiplication				*expr-star*
-expr8 / expr8  Number division					*expr-/*
-expr8 % expr8  Number modulo					*expr-%*
-
-In legacy script, for all operators except "." and "..", Strings are converted
-to Numbers.
-
-For bitwise operators see |and()|, |or()| and |xor()|.
-
-Note the difference between "+" and ".." in legacy script:
-	"123" + "456" = 579
-	"123" .. "456" = "123456"
-
-Since '..' has the same precedence as '+' and '-', you need to read: >
-	1 .. 90 + 90.0
-As: >
-	(1 .. 90) + 90.0
-That works in legacy script, since the String "190" is automatically converted
-to the Number 190, which can be added to the Float 90.0.  However: >
-	1 .. 90 * 90.0
-Should be read as: >
-	1 .. (90 * 90.0)
-Since '..' has lower precedence than '*'.  This does NOT work, since this
-attempts to concatenate a Float and a String.
-
-When dividing a Number by zero the result depends on the value:
-	  0 / 0  = -0x80000000	(like NaN for Float)
-	 >0 / 0  =  0x7fffffff	(like positive infinity)
-	 <0 / 0  = -0x7fffffff	(like negative infinity)
-	(before Vim 7.2 it was always 0x7fffffff)
-In |Vim9| script dividing a number by zero is an error.	*E1154*
-
-When 64-bit Number support is enabled:
-	  0 / 0  = -0x8000000000000000	(like NaN for Float)
-	 >0 / 0  =  0x7fffffffffffffff	(like positive infinity)
-	 <0 / 0  = -0x7fffffffffffffff	(like negative infinity)
-
-When the righthand side of '%' is zero, the result is 0.
-
-None of these work for |Funcref|s.
-
-".", ".." and "%" do not work for Float. *E804* *E1035*
-
-
-expr8							*expr8*
------
-<type>expr9
-
-This is only available in |Vim9| script, see |type-casting|.
-
-
-expr9							*expr9*
------
-! expr9			logical NOT		*expr-!*
-- expr9			unary minus		*expr-unary--*
-+ expr9			unary plus		*expr-unary-+*
-
-For '!' |TRUE| becomes |FALSE|, |FALSE| becomes |TRUE| (one).
-For '-' the sign of the number is changed.
-For '+' the number is unchanged.  Note: "++" has no effect.
-
-In legacy script a String will be converted to a Number first.  Note that if
-the string does not start with a digit you likely don't get what you expect.
-
-In |Vim9| script an error is given when "-" or "+" is used and the type is not
-a number.
-
-In |Vim9| script "!" can be used for any type and the result is always a
-boolean.  Use "!!" to convert any type to a boolean, according to whether the
-value is |falsy|.
-
-These three can be repeated and mixed.  Examples:
-	!-1	    == 0
-	!!8	    == 1
-	--9	    == 9
-
-
-expr10							*expr10*
-------
-This expression is either |expr11| or a sequence of the alternatives below,
-in any order.  E.g., these are all possible:
-	expr10[expr1].name
-	expr10.name[expr1]
-	expr10(expr1, ...)[expr1].name
-	expr10->(expr1, ...)[expr1]
-Evaluation is always from left to right.
-
-expr10[expr1]		item of String or |List|	*expr-[]* *E111*
-						*E909* *subscript* *E1062*
-In legacy Vim script:
-If expr10 is a Number or String this results in a String that contains the
-expr1'th single byte from expr10.  expr10 is used as a String (a number is
-automatically converted to a String), expr1 as a Number.  This doesn't
-recognize multibyte encodings, see `byteidx()` for an alternative, or use
-`split()` to turn the string into a list of characters.  Example, to get the
-byte under the cursor: >
-	:let c = getline(".")[col(".") - 1]
-
-In |Vim9| script:					*E1147* *E1148*
-If expr10 is a String this results in a String that contains the expr1'th
-single character (including any composing characters) from expr10.  To use byte
-indexes use |strpart()|.
-
-Index zero gives the first byte or character.  Careful: text column numbers
-start with one!
-
-If the length of the String is less than the index, the result is an empty
-String.  A negative index always results in an empty string (reason: backward
-compatibility).  Use [-1:] to get the last byte or character.
-In Vim9 script a negative index is used like with a list: count from the end.
-
-If expr10 is a |List| then it results the item at index expr1.  See |list-index|
-for possible index values.  If the index is out of range this results in an
-error.  Example: >
-	:let item = mylist[-1]		" get last item
-
-Generally, if a |List| index is equal to or higher than the length of the
-|List|, or more negative than the length of the |List|, this results in an
-error.
-
-
-expr10[expr1a : expr1b]	substring or |sublist|		*expr-[:]* *substring*
-
-If expr10 is a String this results in the substring with the bytes or
-characters from expr1a to and including expr1b.  expr10 is used as a String,
-expr1a and expr1b are used as a Number.
-
-In legacy Vim script the indexes are byte indexes.  This doesn't recognize
-multibyte encodings, see |byteidx()| for computing the indexes.  If expr10 is
-a Number it is first converted to a String.
-
-In Vim9 script the indexes are character indexes and include composing
-characters.  To use byte indexes use |strpart()|.  To use character indexes
-without including composing characters use |strcharpart()|.
-
-The item at index expr1b is included, it is inclusive.  For an exclusive index
-use the |slice()| function.
-
-If expr1a is omitted zero is used.  If expr1b is omitted the length of the
-string minus one is used.
-
-A negative number can be used to measure from the end of the string.  -1 is
-the last character, -2 the last but one, etc.
-
-If an index goes out of range for the string characters are omitted.  If
-expr1b is smaller than expr1a the result is an empty string.
-
-Examples: >
-	:let c = name[-1:]		" last byte of a string
-	:let c = name[0:-1]		" the whole string
-	:let c = name[-2:-2]		" last but one byte of a string
-	:let s = line(".")[4:]		" from the fifth byte to the end
-	:let s = s[:-3]			" remove last two bytes
-<
-							*slice*
-If expr10 is a |List| this results in a new |List| with the items indicated by
-the indexes expr1a and expr1b.  This works like with a String, as explained
-just above. Also see |sublist| below.  Examples: >
-	:let l = mylist[:3]		" first four items
-	:let l = mylist[4:4]		" List with one item
-	:let l = mylist[:]		" shallow copy of a List
-
-If expr10 is a |Blob| this results in a new |Blob| with the bytes in the
-indexes expr1a and expr1b, inclusive.  Examples: >
-	:let b = 0zDEADBEEF
-	:let bs = b[1:2]		" 0zADBE
-	:let bs = b[:]			" copy of 0zDEADBEEF
-
-Using expr10[expr1] or expr10[expr1a : expr1b] on a |Funcref| results in an
-error.
-
-Watch out for confusion between a namespace and a variable followed by a colon
-for a sublist: >
-	mylist[n:]     " uses variable n
-	mylist[s:]     " uses namespace s:, error!
-
-
-expr10.name		entry in a |Dictionary|		*expr-entry*
-							*E1203* *E1229*
-If expr10 is a |Dictionary| and it is followed by a dot, then the following
-name will be used as a key in the |Dictionary|.  This is just like:
-expr10[name].
-
-The name must consist of alphanumeric characters, just like a variable name,
-but it may start with a number.  Curly braces cannot be used.
-
-There must not be white space before or after the dot.
-
-Examples: >
-	:let dict = {"one": 1, 2: "two"}
-	:echo dict.one		" shows "1"
-	:echo dict.2		" shows "two"
-	:echo dict .2		" error because of space before the dot
-
-Note that the dot is also used for String concatenation.  To avoid confusion
-always put spaces around the dot for String concatenation.
-
-
-expr10(expr1, ...)	|Funcref| function call		*E1085*
-
-When expr10 is a |Funcref| type variable, invoke the function it refers to.
-
-
-expr10->name([args])	method call			*method* *->*
-expr10->{lambda}([args])
-							*E260* *E276* *E1265*
-For methods that are also available as global functions this is the same as: >
-	name(expr10 [, args])
-There can also be methods specifically for the type of "expr10".
-
-This allows for chaining, passing the value that one method returns to the
-next method: >
-	mylist->filter(filterexpr)->map(mapexpr)->sort()->join()
-<
-Example of using a lambda: >
-	GetPercentage()->{x -> x * 100}()->printf('%d%%')
-<
-When using -> the |expr9| operators will be applied first, thus: >
-	-1.234->string()
-Is equivalent to: >
-	(-1.234)->string()
-And NOT: >
-	-(1.234->string())
-
-What comes after "->" can be a name, a simple expression (not containing any
-parenthesis), or any expression in parentheses: >
-	base->name(args)
-	base->some.name(args)
-	base->alist[idx](args)
-	base->(getFuncRef())(args)
-Note that in the last call the base is passed to the function resulting from
-"(getFuncRef())", inserted before "args".  *E1275*
-
-							*E274*
-"->name(" must not contain white space.  There can be white space before the
-"->" and after the "(", thus you can split the lines like this: >
-	mylist
-	\ ->filter(filterexpr)
-	\ ->map(mapexpr)
-	\ ->sort()
-	\ ->join()
-
-When using the lambda form there must be no white space between the } and the
-(.
-
-
-							*expr11*
-number
-------
-number			number constant			*expr-number*
-
-			*0x* *hex-number* *0o* *octal-number* *binary-number*
-Decimal, Hexadecimal (starting with 0x or 0X), Binary (starting with 0b or 0B)
-and Octal (starting with 0, 0o or 0O).
-
-Assuming 64 bit numbers are used (see |v:numbersize|) an unsigned number is
-truncated to 0x7fffffffffffffff or 9223372036854775807.  You can use -1 to get
-0xffffffffffffffff.
-
-						*floating-point-format*
-Floating point numbers can be written in two forms:
-
-	[-+]{N}.{M}
-	[-+]{N}.{M}[eE][-+]{exp}
-
-{N} and {M} are numbers.  Both {N} and {M} must be present and can only
-contain digits, except that in |Vim9| script in {N} single quotes between
-digits are ignored.
-[-+] means there is an optional plus or minus sign.
-{exp} is the exponent, power of 10.
-Only a decimal point is accepted, not a comma.  No matter what the current
-locale is.
-
-Examples:
-	123.456
-	+0.0001
-	55.0
-	-0.123
-	1.234e03
-	1.0E-6
-	-3.1416e+88
-
-These are INVALID:
-	3.		empty {M}
-	1e40		missing .{M}
-
-Rationale:
-Before floating point was introduced, the text "123.456" was interpreted as
-the two numbers "123" and "456", both converted to a string and concatenated,
-resulting in the string "123456".  Since this was considered pointless, and we
-could not find it intentionally being used in Vim scripts, this backwards
-incompatibility was accepted in favor of being able to use the normal notation
-for floating point numbers.
-
-							*float-pi* *float-e*
-A few useful values to copy&paste: >
-	:let pi = 3.14159265359
-	:let e  = 2.71828182846
-Or, if you don't want to write them in as floating-point literals, you can
-also use functions, like the following: >
-	:let pi = acos(-1.0)
-	:let e  = exp(1.0)
-<
-						*floating-point-precision*
-The precision and range of floating points numbers depends on what "double"
-means in the library Vim was compiled with.  There is no way to change this at
-runtime.
-
-The default for displaying a |Float| is to use 6 decimal places, like using
-printf("%g", f).  You can select something else when using the |printf()|
-function.  Example: >
-	:echo printf('%.15e', atan(1))
-<	7.853981633974483e-01
-
-
-
-string					*string* *String* *expr-string* *E114*
-------
-"string"		string constant		*expr-quote*
-
-Note that double quotes are used.
-
-A string constant accepts these special characters:
-\...	three-digit octal number (e.g., "\316")
-\..	two-digit octal number (must be followed by non-digit)
-\.	one-digit octal number (must be followed by non-digit)
-\x..	byte specified with two hex numbers (e.g., "\x1f")
-\x.	byte specified with one hex number (must be followed by non-hex char)
-\X..	same as \x..
-\X.	same as \x.
-\u....	character specified with up to 4 hex numbers, stored according to the
-	current value of 'encoding' (e.g., "\u02a4")
-\U....	same as \u but allows up to 8 hex numbers.
-\b	backspace <BS>
-\e	escape <Esc>
-\f	formfeed 0x0C
-\n	newline <NL>
-\r	return <CR>
-\t	tab <Tab>
-\\	backslash
-\"	double quote
-\<xxx>	Special key named "xxx".  e.g. "\<C-W>" for CTRL-W.  This is for use
-	in mappings, the 0x80 byte is escaped.
-	To use the double quote character it must be escaped: "<M-\">".
-	Don't use <Char-xxxx> to get a UTF-8 character, use \uxxxx as
-	mentioned above.
-\<*xxx>	Like \<xxx> but prepends a modifier instead of including it in the
-	character.  E.g. "\<C-w>" is one character 0x17 while "\<*C-w>" is four
-	bytes: 3 for the CTRL modifier and then character "W".
-
-Note that "\xff" is stored as the byte 255, which may be invalid in some
-encodings.  Use "\u00ff" to store character 255 according to the current value
-of 'encoding'.
-
-Note that "\000" and "\x00" force the end of the string.
-
-
-blob-literal				*blob-literal* *E973*
-------------
-
-Hexadecimal starting with 0z or 0Z, with an arbitrary number of bytes.
-The sequence must be an even number of hex characters.  Example: >
-	:let b = 0zFF00ED015DAF
-
-
-literal-string						*literal-string* *E115*
----------------
-'string'		string constant			*expr-'*
-
-Note that single quotes are used.
-
-This string is taken as it is.  No backslashes are removed or have a special
-meaning.  The only exception is that two quotes stand for one quote.
-
-Single quoted strings are useful for patterns, so that backslashes do not need
-to be doubled.  These two commands are equivalent: >
-	if a =~ "\\s*"
-	if a =~ '\s*'
-
-
-interpolated-string				*$quote* *interpolated-string*
---------------------
-$"string"		interpolated string constant		*expr-$quote*
-$'string'		interpolated literal string constant	*expr-$'*
-
-Interpolated strings are an extension of the |string| and |literal-string|,
-allowing the inclusion of Vim script expressions (see |expr1|).  Any
-expression returning a value can be enclosed between curly braces.  The value
-is converted to a string.  All the text and results of the expressions
-are concatenated to make a new string.
-							*E1278* *E1279*
-To include an opening brace '{' or closing brace '}' in the string content
-double it.  For double quoted strings using a backslash also works.  A single
-closing brace '}' will result in an error.
-
-Examples: >
-	let your_name = input("What's your name? ")
-<	What's your name?  Peter ~
->
-	echo
-	echo $"Hello, {your_name}!"
-<	Hello, Peter! ~
->
-	echo $"The square root of {{9}} is {sqrt(9)}"
-<	The square root of {9} is 3.0 ~
-
-						*string-offset-encoding*
-A string consists of multiple characters.  How the characters are stored
-depends on 'encoding'.  Most common is UTF-8, which uses one byte for ASCII
-characters, two bytes for other latin characters and more bytes for other
-characters.
-
-A string offset can count characters or bytes.  Other programs may use
-UTF-16 encoding (16-bit words) and an offset of UTF-16 words.  Some functions
-use byte offsets, usually for UTF-8 encoding.  Other functions use character
-offsets, in which case the encoding doesn't matter.
-
-The different offsets for the string "a©😊" are below:
-
-  UTF-8 offsets:
-      [0]: 61, [1]: C2, [2]: A9, [3]: F0, [4]: 9F, [5]: 98, [6]: 8A
-  UTF-16 offsets:
-      [0]: 0061, [1]: 00A9, [2]: D83D, [3]: DE0A
-  UTF-32 (character) offsets:
-      [0]: 00000061, [1]: 000000A9, [2]: 0001F60A
-
-You can use the "g8" and "ga" commands on a character to see the
-decimal/hex/octal values.
-
-The functions |byteidx()|, |utf16idx()| and |charidx()| can be used to convert
-between these indices.  The functions |strlen()|, |strutf16len()| and
-|strcharlen()| return the number of bytes, UTF-16 code units and characters in
-a string respectively.
-
-option						*expr-option* *E112* *E113*
-------
-&option			option value, local value if possible
-&g:option		global option value
-&l:option		local option value
-
-Examples: >
-	echo "tabstop is " .. &tabstop
-	if &insertmode
-
-Any option name can be used here.  See |options|.  When using the local value
-and there is no buffer-local or window-local value, the global value is used
-anyway.
-
-
-register						*expr-register* *@r*
---------
-@r			contents of register 'r'
-
-The result is the contents of the named register, as a single string.
-Newlines are inserted where required.  To get the contents of the unnamed
-register use @" or @@.  See |registers| for an explanation of the available
-registers.
-
-When using the '=' register you get the expression itself, not what it
-evaluates to.  Use |eval()| to evaluate it.
-
-
-nesting						*expr-nesting* *E110*
--------
-(expr1)			nested expression
-
-
-environment variable					*expr-env*
---------------------
-$VAR			environment variable
-
-The String value of any environment variable.  When it is not defined, the
-result is an empty string.
-
-The functions `getenv()` and `setenv()` can also be used and work for
-environment variables with non-alphanumeric names.
-The function `environ()` can be used to get a Dict with all environment
-variables.
-
-
-						*expr-env-expand*
-Note that there is a difference between using $VAR directly and using
-expand("$VAR").  Using it directly will only expand environment variables that
-are known inside the current Vim session.  Using expand() will first try using
-the environment variables known inside the current Vim session.  If that
-fails, a shell will be used to expand the variable.  This can be slow, but it
-does expand all variables that the shell knows about.  Example: >
-	:echo $shell
-	:echo expand("$shell")
-The first one probably doesn't echo anything, the second echoes the $shell
-variable (if your shell supports it).
-
-
-internal variable			*expr-variable* *E1015* *E1089*
------------------
-variable		internal variable
-See below |internal-variables|.
-
-
-function call		*expr-function* *E116* *E118* *E119* *E120*
--------------
-function(expr1, ...)	function call
-See below |functions|.
-
-
-lambda expression				*expr-lambda* *lambda*
------------------
-{args -> expr1}		legacy lambda expression		*E451*
-(args) => expr1		|Vim9| lambda expression
-
-A lambda expression creates a new unnamed function which returns the result of
-evaluating |expr1|.  Lambda expressions differ from |user-functions| in
-the following ways:
-
-1. The body of the lambda expression is an |expr1| and not a sequence of |Ex|
-   commands.
-2. The prefix "a:" should not be used for arguments.  E.g.: >
-	:let F = {arg1, arg2 -> arg1 - arg2}
-	:echo F(5, 2)
-<	3
-
-The arguments are optional.  Example: >
-	:let F = {-> 'error function'}
-	:echo F('ignored')
-<	error function
-
-The |Vim9| lambda does not only use a different syntax, it also adds type
-checking and can be split over multiple lines, see |vim9-lambda|.
-
-							*closure*
-Lambda expressions can access outer scope variables and arguments.  This is
-often called a closure.  Example where "i" and "a:arg" are used in a lambda
-while they already exist in the function scope.  They remain valid even after
-the function returns: >
-	:function Foo(arg)
-	:  let i = 3
-	:  return {x -> x + i - a:arg}
-	:endfunction
-	:let Bar = Foo(4)
-	:echo Bar(6)
-<	5
-
-Note that the variables must exist in the outer scope before the lambda is
-defined for this to work.  See also |:func-closure|.
-
-Lambda and closure support can be checked with: >
-	if has('lambda')
-
-Examples for using a lambda expression with |sort()|, |map()| and |filter()|: >
-	:echo map([1, 2, 3], {idx, val -> val + 1})
-<	[2, 3, 4] >
-	:echo sort([3,7,2,1,4], {a, b -> a - b})
-<	[1, 2, 3, 4, 7]
-
-The lambda expression is also useful for Channel, Job and timer: >
-	:let timer = timer_start(500,
-			\ {-> execute("echo 'Handler called'", "")},
-			\ {'repeat': 3})
-<	Handler called
-	Handler called
-	Handler called
-
-Note that it is possible to cause memory to be used and not freed if the
-closure is referenced by the context it depends on: >
-	function Function()
-	   let x = 0
-	   let F = {-> x}
-	 endfunction
-The closure uses "x" from the function scope, and "F" in that same scope
-refers to the closure.  This cycle results in the memory not being freed.
-Recommendation: don't do this.
-
-Notice how execute() is used to execute an Ex command.  That's ugly though.
-In Vim9 script you can use a command block, see |inline-function|.
-
-Although you can use the loop variable of a `for` command, it must still exist
-when the closure is called, otherwise you get an error.  *E1302*
-
-Lambda expressions have internal names like '<lambda>42'.  If you get an error
-for a lambda expression, you can find what it is with the following command: >
-	:function <lambda>42
-See also: |numbered-function|
-
-==============================================================================
-3. Internal variable			*internal-variables* *E461* *E1001*
-
-An internal variable name can be made up of letters, digits and '_'.  But it
-cannot start with a digit.  In legacy script it is also possible to use curly
-braces, see |curly-braces-names|.
-
-In legacy script an internal variable is created with the ":let" command
-|:let|.  An internal variable is explicitly destroyed with the ":unlet"
-command |:unlet|.
-Using a name that is not an internal variable or refers to a variable that has
-been destroyed results in an error.
-
-In |Vim9| script `:let` is not used and variables work differently, see |:var|.
-
-						*variable-scope*
-There are several name spaces for variables.  Which one is to be used is
-specified by what is prepended:
-
-		(nothing) In a function: local to the function;
-			  in a legacy script: global;
-			  in a |Vim9|  script: local to the script
-|buffer-variable|    b:	  Local to the current buffer.
-|window-variable|    w:	  Local to the current window.
-|tabpage-variable|   t:	  Local to the current tab page.
-|global-variable|    g:	  Global.
-|local-variable|     l:	  Local to a function (only in a legacy function)
-|script-variable|    s:	  Local to a |:source|'ed Vim script.
-|function-argument|  a:	  Function argument (only in a legacy function).
-|vim-variable|       v:	  Global, predefined by Vim.
-
-The scope name by itself can be used as a |Dictionary|.  For example, to
-delete all script-local variables: >
-	:for k in keys(s:)
-	:    unlet s:[k]
-	:endfor
-
-Note: in Vim9 script variables can also be local to a block of commands, see
-|vim9-scopes|.
-						*buffer-variable* *b:var* *b:*
-A variable name that is preceded with "b:" is local to the current buffer.
-Thus you can have several "b:foo" variables, one for each buffer.
-This kind of variable is deleted when the buffer is wiped out or deleted with
-|:bdelete|.
-
-One local buffer variable is predefined:
-					*b:changedtick* *changetick*
-b:changedtick	The total number of changes to the current buffer.  It is
-		incremented for each change.  An undo command is also a change
-		in this case.  Resetting 'modified' when writing the buffer is
-		also counted.
-		This can be used to perform an action only when the buffer has
-		changed.  Example: >
-		    :if my_changedtick != b:changedtick
-		    :	let my_changedtick = b:changedtick
-		    :	call My_Update()
-		    :endif
-<		You cannot change or delete the b:changedtick variable.
-		If you need more information about the change see
-		|listener_add()|.
-
-						*window-variable* *w:var* *w:*
-A variable name that is preceded with "w:" is local to the current window.  It
-is deleted when the window is closed.
-
-						*tabpage-variable* *t:var* *t:*
-A variable name that is preceded with "t:" is local to the current tab page,
-It is deleted when the tab page is closed. {not available when compiled
-without the |+windows| feature}
-
-						*global-variable* *g:var* *g:*
-Inside functions and in |Vim9| script global variables are accessed with "g:".
-Omitting this will access a variable local to a function or script.  "g:"
-can also be used in any other place if you like.
-
-						*local-variable* *l:var* *l:*
-Inside functions local variables are accessed without prepending anything.
-But you can also prepend "l:" if you like.  However, without prepending "l:"
-you may run into reserved variable names.  For example "count".  By itself it
-refers to "v:count".  Using "l:count" you can have a local variable with the
-same name.
-
-						*script-variable* *s:var*
-In a legacy Vim script variables starting with "s:" can be used.  They cannot
-be accessed from outside of the scripts, thus are local to the script.
-In |Vim9| script the "s:" prefix can be omitted, variables are script-local by
-default.
-
-They can be used in:
-- commands executed while the script is sourced
-- functions defined in the script
-- autocommands defined in the script
-- functions and autocommands defined in functions and autocommands which were
-  defined in the script (recursively)
-- user defined commands defined in the script
-Thus not in:
-- other scripts sourced from this one
-- mappings
-- menus
-- etc.
-
-Script variables can be used to avoid conflicts with global variable names.
-Take this example: >
-
-	let s:counter = 0
-	function MyCounter()
-	  let s:counter = s:counter + 1
-	  echo s:counter
-	endfunction
-	command Tick call MyCounter()
-
-You can now invoke "Tick" from any script, and the "s:counter" variable in
-that script will not be changed, only the "s:counter" in the script where
-"Tick" was defined is used.
-
-Another example that does the same: >
-
-	let s:counter = 0
-	command Tick let s:counter = s:counter + 1 | echo s:counter
-
-When calling a function and invoking a user-defined command, the context for
-script variables is set to the script where the function or command was
-defined.
-
-The script variables are also available when a function is defined inside a
-function that is defined in a script.  Example: >
-
-	let s:counter = 0
-	function StartCounting(incr)
-	  if a:incr
-	    function MyCounter()
-	      let s:counter = s:counter + 1
-	    endfunction
-	  else
-	    function MyCounter()
-	      let s:counter = s:counter - 1
-	    endfunction
-	  endif
-	endfunction
-
-This defines the MyCounter() function either for counting up or counting down
-when calling StartCounting().  It doesn't matter from where StartCounting() is
-called, the s:counter variable will be accessible in MyCounter().
-
-When the same script is sourced again it will use the same script variables.
-They will remain valid as long as Vim is running.  This can be used to
-maintain a counter: >
-
-	if !exists("s:counter")
-	  let s:counter = 1
-	  echo "script executed for the first time"
-	else
-	  let s:counter = s:counter + 1
-	  echo "script executed " .. s:counter .. " times now"
-	endif
-
-Note that this means that filetype plugins don't get a different set of script
-variables for each buffer.  Use local buffer variables instead |b:var|.
-
-
-PREDEFINED VIM VARIABLES			*vim-variable* *v:var* *v:*
-							*E963* *E1063*
-Some variables can be set by the user, but the type cannot be changed.
-
-					*v:argv* *argv-variable*
-v:argv		The command line arguments Vim was invoked with.  This is a
-		list of strings.  The first item is the Vim command.
-		See |v:progpath| for the command with full path.
-
-					*v:beval_col* *beval_col-variable*
-v:beval_col	The number of the column, over which the mouse pointer is.
-		This is the byte index in the |v:beval_lnum| line.
-		Only valid while evaluating the 'balloonexpr' option.
-
-					*v:beval_bufnr* *beval_bufnr-variable*
-v:beval_bufnr	The number of the buffer, over which the mouse pointer is. Only
-		valid while evaluating the 'balloonexpr' option.
-
-					*v:beval_lnum* *beval_lnum-variable*
-v:beval_lnum	The number of the line, over which the mouse pointer is. Only
-		valid while evaluating the 'balloonexpr' option.
-
-					*v:beval_text* *beval_text-variable*
-v:beval_text	The text under or after the mouse pointer.  Usually a word as
-		it is useful for debugging a C program.  'iskeyword' applies,
-		but a dot and "->" before the position is included.  When on a
-		']' the text before it is used, including the matching '[' and
-		word before it.  When on a Visual area within one line the
-		highlighted text is used.  Also see |<cexpr>|.
-		Only valid while evaluating the 'balloonexpr' option.
-
-					*v:beval_winnr* *beval_winnr-variable*
-v:beval_winnr	The number of the window, over which the mouse pointer is. Only
-		valid while evaluating the 'balloonexpr' option.  The first
-		window has number zero (unlike most other places where a
-		window gets a number).
-
-					*v:beval_winid* *beval_winid-variable*
-v:beval_winid	The |window-ID| of the window, over which the mouse pointer
-		is.  Otherwise like v:beval_winnr.
-
-					*v:char* *char-variable*
-v:char		Argument for evaluating 'formatexpr' and used for the typed
-		character when using <expr> in an abbreviation |:map-<expr>|.
-		It is also used by the |InsertCharPre| and |InsertEnter| events.
-
-			*v:charconvert_from* *charconvert_from-variable*
-v:charconvert_from
-		The name of the character encoding of a file to be converted.
-		Only valid while evaluating the 'charconvert' option.
-
-			*v:charconvert_to* *charconvert_to-variable*
-v:charconvert_to
-		The name of the character encoding of a file after conversion.
-		Only valid while evaluating the 'charconvert' option.
-
-					*v:cmdarg* *cmdarg-variable*
-v:cmdarg	This variable is used for two purposes:
-		1. The extra arguments given to a file read/write command.
-		   Currently these are "++enc=" and "++ff=".  This variable is
-		   set before an autocommand event for a file read/write
-		   command is triggered.  There is a leading space to make it
-		   possible to append this variable directly after the
-		   read/write command.  Note: The "+cmd" argument isn't
-		   included here, because it will be executed anyway.
-		2. When printing a PostScript file with ":hardcopy" this is
-		   the argument for the ":hardcopy" command.  This can be used
-		   in 'printexpr'.
-
-					*v:cmdbang* *cmdbang-variable*
-v:cmdbang	Set like v:cmdarg for a file read/write command.  When a "!"
-		was used the value is 1, otherwise it is 0.  Note that this
-		can only be used in autocommands.  For user commands |<bang>|
-		can be used.
-						*v:collate* *collate-variable*
-v:collate	The current locale setting for collation order of the runtime
-		environment.  This allows Vim scripts to be aware of the
-		current locale encoding.  Technical: it's the value of
-		LC_COLLATE.  When not using a locale the value is "C".
-		This variable can not be set directly, use the |:language|
-		command.
-		See |multi-lang|.
-
-								*v:colornames*
-v:colornames    A dictionary that maps color names to hex color strings. These
-		color names can be used with the |highlight-guifg|,
-		|highlight-guibg|, and |highlight-guisp| parameters. Updating
-		an entry in v:colornames has no immediate effect on the syntax
-		highlighting. The highlight commands (probably in a
-		colorscheme script) need to be re-evaluated in order to use
-		the updated color values. For example: >
-
-		    :let v:colornames['fuscia'] = '#cf3ab4'
-		    :let v:colornames['mauve'] = '#915f6d'
-		    :highlight Normal guifg=fuscia guibg=mauve
-<
-		This cannot be used to override the |cterm-colors| but it can
-		be used to override other colors. For example, the X11 colors
-		defined in the `colors/lists/default.vim` (previously defined
-		in |rgb.txt|). When defining new color names in a plugin, the
-		recommended practice is to set a color entry only when it does
-		not already exist. For example: >
-
-		    :call extend(v:colornames, {
-			\ 'fuscia': '#cf3ab4',
-			\ 'mauve': '#915f6d,
-			\ }, 'keep')
-<
-		Using |extend()| with the 'keep' option updates each color only
-		if it did not exist in |v:colornames|. Doing so allows the
-		user to choose the precise color value for a common name
-		by setting it in their |.vimrc|.
-
-		It is possible to remove entries from this dictionary but
-		doing so is NOT recommended, because it is disruptive to
-		other scripts. It is also unlikely to achieve the desired
-		result because the |:colorscheme| and |:highlight| commands will
-		both automatically load all `colors/lists/default.vim` color
-		scripts.
-
-				*v:completed_item* *completed_item-variable*
-v:completed_item
-		|Dictionary| containing the |complete-items| for the most
-		recently completed word after |CompleteDone|.  The
-		|Dictionary| is empty if the completion failed.
-		Note: Plugins can modify the value to emulate the builtin
-		|CompleteDone| event behavior.
-
-					*v:count* *count-variable*
-v:count		The count given for the last Normal mode command.  Can be used
-		to get the count before a mapping.  Read-only.  Example: >
-	:map _x :<C-U>echo "the count is " .. v:count<CR>
-<		Note: The <C-U> is required to remove the line range that you
-		get when typing ':' after a count.
-		When there are two counts, as in "3d2w", they are multiplied,
-		just like what happens in the command, "d6w" for the example.
-		Also used for evaluating the 'formatexpr' option.
-		"count" also works, for backwards compatibility, unless
-		|scriptversion| is 3 or higher.
-
-					*v:count1* *count1-variable*
-v:count1	Just like "v:count", but defaults to one when no count is
-		used.
-
-						*v:ctype* *ctype-variable*
-v:ctype		The current locale setting for characters of the runtime
-		environment.  This allows Vim scripts to be aware of the
-		current locale encoding.  Technical: it's the value of
-		LC_CTYPE.  When not using a locale the value is "C".
-		This variable can not be set directly, use the |:language|
-		command.
-		See |multi-lang|.
-
-					*v:dying* *dying-variable*
-v:dying		Normally zero.  When a deadly signal is caught it's set to
-		one.  When multiple signals are caught the number increases.
-		Can be used in an autocommand to check if Vim didn't
-		terminate normally. {only works on Unix}
-		Example: >
-	:au VimLeave * if v:dying | echo "\nAAAAaaaarrrggghhhh!!!\n" | endif
-<		Note: if another deadly signal is caught when v:dying is one,
-		VimLeave autocommands will not be executed.
-
-					*v:exiting* *exiting-variable*
-v:exiting	Vim exit code.  Normally zero, non-zero when something went
-		wrong.  The value is v:null before invoking the |VimLeavePre|
-		and |VimLeave| autocmds.  See |:q|, |:x| and |:cquit|.
-		Example: >
-			:au VimLeave * echo "Exit value is " .. v:exiting
-<
-					*v:echospace* *echospace-variable*
-v:echospace	Number of screen cells that can be used for an `:echo` message
-		in the last screen line before causing the |hit-enter-prompt|.
-		Depends on 'showcmd', 'ruler' and 'columns'.  You need to
-		check 'cmdheight' for whether there are full-width lines
-		available above the last line.
-
-					*v:errmsg* *errmsg-variable*
-v:errmsg	Last given error message.  It's allowed to set this variable.
-		Example: >
-	:let v:errmsg = ""
-	:silent! next
-	:if v:errmsg != ""
-	:  ... handle error
-<		"errmsg" also works, for backwards compatibility, unless
-		|scriptversion| is 3 or higher.
-
-				*v:errors* *errors-variable* *assert-return*
-v:errors	Errors found by assert functions, such as |assert_true()|.
-		This is a list of strings.
-		The assert functions append an item when an assert fails.
-		The return value indicates this: a one is returned if an item
-		was added to v:errors, otherwise zero is returned.
-		To remove old results make it empty: >
-	:let v:errors = []
-<		If v:errors is set to anything but a list it is made an empty
-		list by the assert function.
-
-					*v:event* *event-variable*
-v:event		Dictionary containing information about the current
-		|autocommand|.  See the specific event for what it puts in
-		this dictionary.
-		The dictionary is emptied when the |autocommand| finishes,
-		please refer to |dict-identity| for how to get an independent
-		copy of it.  Use |deepcopy()| if you want to keep the
-		information after the event triggers.  Example: >
-			au TextYankPost * let g:foo = deepcopy(v:event)
-<
-					*v:exception* *exception-variable*
-v:exception	The value of the exception most recently caught and not
-		finished.  See also |v:throwpoint| and |throw-variables|.
-		Example: >
-	:try
-	:  throw "oops"
-	:catch /.*/
-	:  echo "caught " .. v:exception
-	:endtry
-<		Output: "caught oops".
-
-					*v:false* *false-variable*
-v:false		A Number with value zero. Used to put "false" in JSON.  See
-		|json_encode()|.
-		When used as a string this evaluates to "v:false". >
-			echo v:false
-<			v:false ~
-		That is so that eval() can parse the string back to the same
-		value.  Read-only.
-		In |Vim9| script "false" can be used which has a boolean type.
-
-					*v:fcs_reason* *fcs_reason-variable*
-v:fcs_reason	The reason why the |FileChangedShell| event was triggered.
-		Can be used in an autocommand to decide what to do and/or what
-		to set v:fcs_choice to.  Possible values:
-			deleted		file no longer exists
-			conflict	file contents, mode or timestamp was
-					changed and buffer is modified
-			changed		file contents has changed
-			mode		mode of file changed
-			time		only file timestamp changed
-
-					*v:fcs_choice* *fcs_choice-variable*
-v:fcs_choice	What should happen after a |FileChangedShell| event was
-		triggered.  Can be used in an autocommand to tell Vim what to
-		do with the affected buffer:
-			reload		Reload the buffer (does not work if
-					the file was deleted).
-			edit		Reload the buffer and detect the
-					values for options such as
-					'fileformat', 'fileencoding', 'binary'
-					(does not work if the file was
-					deleted).
-			ask		Ask the user what to do, as if there
-					was no autocommand.  Except that when
-					only the timestamp changed nothing
-					will happen.
-			<empty>		Nothing, the autocommand should do
-					everything that needs to be done.
-		The default is empty.  If another (invalid) value is used then
-		Vim behaves like it is empty, there is no warning message.
-
-					*v:fname* *fname-variable*
-v:fname		When evaluating 'includeexpr': the file name that was
-		detected.  Empty otherwise.
-
-					*v:fname_in* *fname_in-variable*
-v:fname_in	The name of the input file.  Valid while evaluating:
-			option		used for ~
-			'charconvert'	file to be converted
-			'diffexpr'	original file
-			'patchexpr'	original file
-			'printexpr'	file to be printed
-		And set to the swap file name for |SwapExists|.
-
-					*v:fname_out* *fname_out-variable*
-v:fname_out	The name of the output file.  Only valid while
-		evaluating:
-			option		used for ~
-			'charconvert'	resulting converted file (*)
-			'diffexpr'	output of diff
-			'patchexpr'	resulting patched file
-		(*) When doing conversion for a write command (e.g., ":w
-		file") it will be equal to v:fname_in.  When doing conversion
-		for a read command (e.g., ":e file") it will be a temporary
-		file and different from v:fname_in.
-
-					*v:fname_new* *fname_new-variable*
-v:fname_new	The name of the new version of the file.  Only valid while
-		evaluating 'diffexpr'.
-
-					*v:fname_diff* *fname_diff-variable*
-v:fname_diff	The name of the diff (patch) file.  Only valid while
-		evaluating 'patchexpr'.
-
-					*v:folddashes* *folddashes-variable*
-v:folddashes	Used for 'foldtext': dashes representing foldlevel of a closed
-		fold.
-		Read-only in the |sandbox|. |fold-foldtext|
-
-					*v:foldlevel* *foldlevel-variable*
-v:foldlevel	Used for 'foldtext': foldlevel of closed fold.
-		Read-only in the |sandbox|. |fold-foldtext|
-
-					*v:foldend* *foldend-variable*
-v:foldend	Used for 'foldtext': last line of closed fold.
-		Read-only in the |sandbox|. |fold-foldtext|
-
-					*v:foldstart* *foldstart-variable*
-v:foldstart	Used for 'foldtext': first line of closed fold.
-		Read-only in the |sandbox|. |fold-foldtext|
-
-					*v:hlsearch* *hlsearch-variable*
-v:hlsearch	Variable that indicates whether search highlighting is on.
-		Setting it makes sense only if 'hlsearch' is enabled which
-		requires |+extra_search|. Setting this variable to zero acts
-		like the |:nohlsearch| command, setting it to one acts like >
-			let &hlsearch = &hlsearch
-<		Note that the value is restored when returning from a
-		function. |function-search-undo|.
-
-					*v:insertmode* *insertmode-variable*
-v:insertmode	Used for the |InsertEnter| and |InsertChange| autocommand
-		events.  Values:
-			i	Insert mode
-			r	Replace mode
-			v	Virtual Replace mode
-
-						*v:key* *key-variable*
-v:key		Key of the current item of a |Dictionary|.  Only valid while
-		evaluating the expression used with |map()| and |filter()|.
-		Read-only.
-
-						*v:lang* *lang-variable*
-v:lang		The current locale setting for messages of the runtime
-		environment.  This allows Vim scripts to be aware of the
-		current language.  Technical: it's the value of LC_MESSAGES.
-		The value is system dependent.
-		This variable can not be set directly, use the |:language|
-		command.
-		It can be different from |v:ctype| when messages are desired
-		in a different language than what is used for character
-		encoding.  See |multi-lang|.
-
-						*v:lc_time* *lc_time-variable*
-v:lc_time	The current locale setting for time messages of the runtime
-		environment.  This allows Vim scripts to be aware of the
-		current language.  Technical: it's the value of LC_TIME.
-		This variable can not be set directly, use the |:language|
-		command.  See |multi-lang|.
-
-						*v:lnum* *lnum-variable*
-v:lnum		Line number for the 'foldexpr' |fold-expr|, 'formatexpr' and
-		'indentexpr' expressions, tab page number for 'guitablabel'
-		and 'guitabtooltip'.  Only valid while one of these
-		expressions is being evaluated.  Read-only when in the
-		|sandbox|.
-
-						*v:maxcol* *maxcol-variable*
-v:maxcol	Maximum line length.  Depending on where it is used it can be
-		screen columns, characters or bytes.  The value currently is
-		2147483647 on all systems.
-
-					*v:mouse_win* *mouse_win-variable*
-v:mouse_win	Window number for a mouse click obtained with |getchar()|.
-		First window has number 1, like with |winnr()|.  The value is
-		zero when there was no mouse button click.
-
-					*v:mouse_winid* *mouse_winid-variable*
-v:mouse_winid	Window ID for a mouse click obtained with |getchar()|.
-		The value is zero when there was no mouse button click.
-
-					*v:mouse_lnum* *mouse_lnum-variable*
-v:mouse_lnum	Line number for a mouse click obtained with |getchar()|.
-		This is the text line number, not the screen line number.  The
-		value is zero when there was no mouse button click.
-
-					*v:mouse_col* *mouse_col-variable*
-v:mouse_col	Column number for a mouse click obtained with |getchar()|.
-		This is the screen column number, like with |virtcol()|.  The
-		value is zero when there was no mouse button click.
-
-					*v:none* *none-variable* *None*
-v:none		An empty String. Used to put an empty item in JSON.  See
-		|json_encode()|.
-		This can also be used as a function argument to use the
-		default value, see |none-function_argument|.
-		When used as a number this evaluates to zero.
-		When used as a string this evaluates to "v:none". >
-			echo v:none
-<			v:none ~
-		That is so that eval() can parse the string back to the same
-		value.  Read-only.
-		Note that using `== v:none` and `!= v:none`  will often give
-		an error.  Instead, use `is v:none` and `isnot v:none` .
-
-					*v:null* *null-variable*
-v:null		An empty String. Used to put "null" in JSON.  See
-		|json_encode()|.
-		When used as a number this evaluates to zero.
-		When used as a string this evaluates to "v:null". >
-			echo v:null
-<			v:null ~
-		That is so that eval() can parse the string back to the same
-		value.  Read-only.
-		In |Vim9| script `null` can be used without "v:".
-		In some places `v:null` and `null` can be used for a List,
-		Dict, Job, etc. that is not set.  That is slightly different
-		than an empty List, Dict, etc.
-
-					*v:numbermax* *numbermax-variable*
-v:numbermax	Maximum value of a number.
-
-					*v:numbermin* *numbermin-variable*
-v:numbermin	Minimum value of a number (negative).
-
-					*v:numbersize* *numbersize-variable*
-v:numbersize	Number of bits in a Number.  This is normally 64, but on some
-		systems it may be 32.
-
-					*v:oldfiles* *oldfiles-variable*
-v:oldfiles	List of file names that is loaded from the |viminfo| file on
-		startup.  These are the files that Vim remembers marks for.
-		The length of the List is limited by the ' argument of the
-		'viminfo' option (default is 100).
-		When the |viminfo| file is not used the List is empty.
-		Also see |:oldfiles| and |c_#<|.
-		The List can be modified, but this has no effect on what is
-		stored in the |viminfo| file later.  If you use values other
-		than String this will cause trouble.
-		{only when compiled with the |+viminfo| feature}
-
-						    *v:option_new*
-v:option_new    New value of the option. Valid while executing an |OptionSet|
-		autocommand.
-						    *v:option_old*
-v:option_old    Old value of the option. Valid while executing an |OptionSet|
-		autocommand. Depending on the command used for setting and the
-		kind of option this is either the local old value or the
-		global old value.
-						    *v:option_oldlocal*
-v:option_oldlocal
-		Old local value of the option. Valid while executing an
-		|OptionSet| autocommand.
-						    *v:option_oldglobal*
-v:option_oldglobal
-		Old global value of the option. Valid while executing an
-		|OptionSet| autocommand.
-						    *v:option_type*
-v:option_type   Scope of the set command. Valid while executing an
-		|OptionSet| autocommand. Can be either "global" or "local"
-						    *v:option_command*
-v:option_command
-		Command used to set the option. Valid while executing an
-		|OptionSet| autocommand.
-			value		option was set via   ~
-			"setlocal"	|:setlocal| or ":let l:xxx"
-			"setglobal"	|:setglobal| or ":let g:xxx"
-			"set"		|:set| or |:let|
-			"modeline"	|modeline|
-					*v:operator* *operator-variable*
-v:operator	The last operator given in Normal mode.  This is a single
-		character except for commands starting with <g> or <z>,
-		in which case it is two characters.  Best used alongside
-		|v:prevcount| and |v:register|.  Useful if you want to cancel
-		Operator-pending mode and then use the operator, e.g.: >
-			:omap O <Esc>:call MyMotion(v:operator)<CR>
-<		The value remains set until another operator is entered, thus
-		don't expect it to be empty.
-		v:operator is not set for |:delete|, |:yank| or other Ex
-		commands.
-		Read-only.
-
-					*v:prevcount* *prevcount-variable*
-v:prevcount	The count given for the last but one Normal mode command.
-		This is the v:count value of the previous command.  Useful if
-		you want to cancel Visual or Operator-pending mode and then
-		use the count, e.g.: >
-			:vmap % <Esc>:call MyFilter(v:prevcount)<CR>
-<		Read-only.
-
-					*v:profiling* *profiling-variable*
-v:profiling	Normally zero.  Set to one after using ":profile start".
-		See |profiling|.
-
-					*v:progname* *progname-variable*
-v:progname	Contains the name (with path removed) with which Vim was
-		invoked.  Allows you to do special initialisations for |view|,
-		|evim| etc., or any other name you might symlink to Vim.
-		Read-only.
-
-					*v:progpath* *progpath-variable*
-v:progpath	Contains the command with which Vim was invoked, in a form
-		that when passed to the shell will run the same Vim executable
-		as the current one (if $PATH remains unchanged).
-		Useful if you want to message a Vim server using a
-		|--remote-expr|.
-		To get the full path use: >
-			echo exepath(v:progpath)
-<		If the command has a relative path it will be expanded to the
-		full path, so that it still works after `:cd`. Thus starting
-		"./vim" results in "/home/user/path/to/vim/src/vim".
-		On Linux and other systems it will always be the full path.
-		On Mac it may just be "vim" and using exepath() as mentioned
-		above should be used to get the full path.
-		On MS-Windows the executable may be called "vim.exe", but the
-		".exe" is not added to v:progpath.
-		Read-only.
-
-					*v:register* *register-variable*
-v:register	The name of the register in effect for the current normal mode
-		command (regardless of whether that command actually used a
-		register).  Or for the currently executing normal mode mapping
-		(use this in custom commands that take a register).
-		If none is supplied it is the default register '"', unless
-		'clipboard' contains "unnamed" or "unnamedplus", then it is
-		'*' or '+'.
-		Also see |getreg()| and |setreg()|
-
-					*v:scrollstart* *scrollstart-variable*
-v:scrollstart	String describing the script or function that caused the
-		screen to scroll up.  It's only set when it is empty, thus the
-		first reason is remembered.  It is set to "Unknown" for a
-		typed command.
-		This can be used to find out why your script causes the
-		hit-enter prompt.
-
-					*v:servername* *servername-variable*
-v:servername	The resulting registered |client-server-name| if any.
-		Read-only.
-
-
-v:searchforward			*v:searchforward* *searchforward-variable*
-		Search direction:  1 after a forward search, 0 after a
-		backward search.  It is reset to forward when directly setting
-		the last search pattern, see |quote/|.
-		Note that the value is restored when returning from a
-		function. |function-search-undo|.
-		Read-write.
-
-					*v:shell_error* *shell_error-variable*
-v:shell_error	Result of the last shell command.  When non-zero, the last
-		shell command had an error.  When zero, there was no problem.
-		This only works when the shell returns the error code to Vim.
-		The value -1 is often used when the command could not be
-		executed.  Read-only.
-		Example: >
-	:!mv foo bar
-	:if v:shell_error
-	:  echo 'could not rename "foo" to "bar"!'
-	:endif
-<		"shell_error" also works, for backwards compatibility, unless
-		|scriptversion| is 3 or higher.
-
-					*v:sizeofint* *sizeofint-variable*
-v:sizeofint	Number of bytes in an int.  Depends on how Vim was compiled.
-		This is only useful for deciding whether a test will give the
-		expected result.
-
-					*v:sizeoflong* *sizeoflong-variable*
-v:sizeoflong	Number of bytes in a long.  Depends on how Vim was compiled.
-		This is only useful for deciding whether a test will give the
-		expected result.
-
-				*v:sizeofpointer* *sizeofpointer-variable*
-v:sizeofpointer	Number of bytes in a pointer.  Depends on how Vim was compiled.
-		This is only useful for deciding whether a test will give the
-		expected result.
-
-					*v:statusmsg* *statusmsg-variable*
-v:statusmsg	Last given status message.  It's allowed to set this variable.
-
-					*v:swapname* *swapname-variable*
-v:swapname	Only valid when executing |SwapExists| autocommands: Name of
-		the swap file found.  Read-only.
-
-					*v:swapchoice* *swapchoice-variable*
-v:swapchoice	|SwapExists| autocommands can set this to the selected choice
-		for handling an existing swap file:
-			'o'	Open read-only
-			'e'	Edit anyway
-			'r'	Recover
-			'd'	Delete swapfile
-			'q'	Quit
-			'a'	Abort
-		The value should be a single-character string.  An empty value
-		results in the user being asked, as would happen when there is
-		no SwapExists autocommand.  The default is empty.
-
-					*v:swapcommand* *swapcommand-variable*
-v:swapcommand	Normal mode command to be executed after a file has been
-		opened.  Can be used for a |SwapExists| autocommand to have
-		another Vim open the file and jump to the right place.  For
-		example, when jumping to a tag the value is ":tag tagname\r".
-		For ":edit +cmd file" the value is ":cmd\r".
-
-				*v:t_TYPE* *v:t_bool* *t_bool-variable*
-v:t_bool	Value of |Boolean| type.  Read-only.  See: |type()|
-					*v:t_channel* *t_channel-variable*
-v:t_channel	Value of |Channel| type.  Read-only.  See: |type()|
-					*v:t_dict* *t_dict-variable*
-v:t_dict	Value of |Dictionary| type.  Read-only.  See: |type()|
-					*v:t_float* *t_float-variable*
-v:t_float	Value of |Float| type.  Read-only.  See: |type()|
-					*v:t_func* *t_func-variable*
-v:t_func	Value of |Funcref| type.  Read-only.  See: |type()|
-					*v:t_job* *t_job-variable*
-v:t_job		Value of |Job| type.  Read-only.  See: |type()|
-					*v:t_list* *t_list-variable*
-v:t_list	Value of |List| type.  Read-only.  See: |type()|
-					*v:t_none* *t_none-variable*
-v:t_none	Value of |None| type.  Read-only.  See: |type()|
-					*v:t_number* *t_number-variable*
-v:t_number	Value of |Number| type.  Read-only.  See: |type()|
-					*v:t_string* *t_string-variable*
-v:t_string	Value of |String| type.  Read-only.  See: |type()|
-					*v:t_blob* *t_blob-variable*
-v:t_blob	Value of |Blob| type.  Read-only.  See: |type()|
-					*v:t_class* *t_class-variable*
-v:t_class	Value of |class| type.  Read-only.  See: |type()|
-					*v:t_object* *t_object-variable*
-v:t_object	Value of |object| type.  Read-only.  See: |type()|
-
-				*v:termresponse* *termresponse-variable*
-v:termresponse	The escape sequence returned by the terminal for the |t_RV|
-		termcap entry.  It is set when Vim receives an escape sequence
-		that starts with ESC [ or CSI, then '>' or '?' and ends in a
-		'c', with only digits and ';' in between.
-		When this option is set, the TermResponse autocommand event is
-		fired, so that you can react to the response from the
-		terminal.  You can use |terminalprops()| to see what Vim
-		figured out about the terminal.
-		The response from a new xterm is: "<Esc>[> Pp ; Pv ; Pc c".  Pp
-		is the terminal type: 0 for vt100 and 1 for vt220.  Pv is the
-		patch level (since this was introduced in patch 95, it's
-		always 95 or higher).  Pc is always zero.
-		If Pv is 141 or higher then Vim will try to request terminal
-		codes.  This only works with xterm |xterm-codes|.
-		{only when compiled with |+termresponse| feature}
-
-						*v:termblinkresp*
-v:termblinkresp	The escape sequence returned by the terminal for the |t_RC|
-		termcap entry.  This is used to find out whether the terminal
-		cursor is blinking. This is used by |term_getcursor()|.
-
-						*v:termstyleresp*
-v:termstyleresp	The escape sequence returned by the terminal for the |t_RS|
-		termcap entry.  This is used to find out what the shape of the
-		cursor is.  This is used by |term_getcursor()|.
-
-						*v:termrbgresp*
-v:termrbgresp	The escape sequence returned by the terminal for the |t_RB|
-		termcap entry.  This is used to find out what the terminal
-		background color is, see 'background'.
-
-						*v:termrfgresp*
-v:termrfgresp	The escape sequence returned by the terminal for the |t_RF|
-		termcap entry.  This is used to find out what the terminal
-		foreground color is.
-
-						*v:termu7resp*
-v:termu7resp	The escape sequence returned by the terminal for the |t_u7|
-		termcap entry.  This is used to find out what the terminal
-		does with ambiguous width characters, see 'ambiwidth'.
-
-					*v:testing* *testing-variable*
-v:testing	Must be set before using `test_garbagecollect_now()`.
-		Also, when set certain error messages won't be shown for 2
-		seconds. (e.g. "'dictionary' option is empty")
-
-				*v:this_session* *this_session-variable*
-v:this_session	Full filename of the last loaded or saved session file.  See
-		|:mksession|.  It is allowed to set this variable.  When no
-		session file has been saved, this variable is empty.
-		"this_session" also works, for backwards compatibility, unless
-		|scriptversion| is 3 or higher
-
-					*v:throwpoint* *throwpoint-variable*
-v:throwpoint	The point where the exception most recently caught and not
-		finished was thrown.  Not set when commands are typed.  See
-		also |v:exception| and |throw-variables|.
-		Example: >
-	:try
-	:  throw "oops"
-	:catch /.*/
-	:  echo "Exception from" v:throwpoint
-	:endtry
-<		Output: "Exception from test.vim, line 2"
-
-						*v:true* *true-variable*
-v:true		A Number with value one. Used to put "true" in JSON.  See
-		|json_encode()|.
-		When used as a string this evaluates to "v:true". >
-			echo v:true
-<			v:true ~
-		That is so that eval() can parse the string back to the same
-		value.  Read-only.
-		In |Vim9| script "true" can be used which has a boolean type.
-						*v:val* *val-variable*
-v:val		Value of the current item of a |List| or |Dictionary|.  Only
-		valid while evaluating the expression used with |map()| and
-		|filter()|.  Read-only.
-
-					*v:version* *version-variable*
-v:version	Version number of Vim: Major version number times 100 plus
-		minor version number.  Version 5.0 is 500.  Version 5.1
-		is 501.  Read-only.  "version" also works, for backwards
-		compatibility, unless |scriptversion| is 3 or higher.
-		Use |has()| to check if a certain patch was included, e.g.: >
-			if has("patch-7.4.123")
-<		Note that patch numbers are specific to the version, thus both
-		version 5.0 and 5.1 may have a patch 123, but these are
-		completely different.
-
-					*v:versionlong* *versionlong-variable*
-v:versionlong	Like v:version, but also including the patchlevel in the last
-		four digits.  Version 8.1 with patch 123 has value 8010123.
-		This can be used like this: >
-			if v:versionlong >= 8010123
-<		However, if there are gaps in the list of patches included
-		this will not work well.  This can happen if a recent patch
-		was included into an older version, e.g. for a security fix.
-		Use the has() function to make sure the patch is actually
-		included.
-
-				*v:vim_did_enter* *vim_did_enter-variable*
-v:vim_did_enter	Zero until most of startup is done.  It is set to one just
-		before |VimEnter| autocommands are triggered.
-
-					*v:warningmsg* *warningmsg-variable*
-v:warningmsg	Last given warning message.  It's allowed to set this variable.
-
-					*v:windowid* *windowid-variable*
-v:windowid	When any X11 based GUI is running or when running in a
-		terminal and Vim connects to the X server (|-X|) this will be
-		set to the window ID.
-		When an MS-Windows GUI is running this will be set to the
-		window handle.
-		Otherwise the value is zero.
-		Note: for windows inside Vim use |winnr()| or |win_getid()|,
-		see |window-ID|.
-
-==============================================================================
-4. Builtin Functions					*functions*
-
-See |function-list| for a list grouped by what the function is used for.
-
-The alphabetic list of all builtin functions and details are in a separate
-help file: |builtin-functions|.
-
-==============================================================================
-5. Defining functions					*user-functions*
-
-New functions can be defined.  These can be called just like builtin
-functions.  The function takes arguments, executes a sequence of Ex commands
-and can return a value.
-
-You can find most information about defining functions in |userfunc.txt|.
-For Vim9 functions, which execute much faster, support type checking and more,
-see |vim9.txt|.
-
-==============================================================================
-6. Curly braces names					*curly-braces-names*
-
-In most places where you can use a variable, you can use a "curly braces name"
-variable.  This is a regular variable name with one or more expressions
-wrapped in braces {} like this: >
-	my_{adjective}_variable
-
-This only works in legacy Vim script, not in |Vim9| script.
-
-When Vim encounters this, it evaluates the expression inside the braces, puts
-that in place of the expression, and re-interprets the whole as a variable
-name.  So in the above example, if the variable "adjective" was set to
-"noisy", then the reference would be to "my_noisy_variable", whereas if
-"adjective" was set to "quiet", then it would be to "my_quiet_variable".
-
-One application for this is to create a set of variables governed by an option
-value.  For example, the statement >
-	echo my_{&background}_message
-
-would output the contents of "my_dark_message" or "my_light_message" depending
-on the current value of 'background'.
-
-You can use multiple brace pairs: >
-	echo my_{adverb}_{adjective}_message
-..or even nest them: >
-	echo my_{ad{end_of_word}}_message
-where "end_of_word" is either "verb" or "jective".
-
-However, the expression inside the braces must evaluate to a valid single
-variable name, e.g. this is invalid: >
-	:let foo='a + b'
-	:echo c{foo}d
-.. since the result of expansion is "ca + bd", which is not a variable name.
-
-						*curly-braces-function-names*
-You can call and define functions by an evaluated name in a similar way.
-Example: >
-	:let func_end='whizz'
-	:call my_func_{func_end}(parameter)
-
-This would call the function "my_func_whizz(parameter)".
-
-This does NOT work: >
-  :let i = 3
-  :let @{i} = ''  " error
-  :echo @{i}      " error
-
-==============================================================================
-7. Commands						*expression-commands*
-
-Note: in |Vim9| script `:let` is not used.  `:var` is used for variable
-declarations and assignments do not use a command.  |vim9-declaration|
-
-:let {var-name} = {expr1}				*:let* *E18*
-			Set internal variable {var-name} to the result of the
-			expression {expr1}.  The variable will get the type
-			from the {expr}.  If {var-name} didn't exist yet, it
-			is created.
-
-:let {var-name}[{idx}] = {expr1}			*E689* *E1141*
-			Set a list item to the result of the expression
-			{expr1}.  {var-name} must refer to a list and {idx}
-			must be a valid index in that list.  For nested list
-			the index can be repeated.
-			This cannot be used to add an item to a |List|.
-			This cannot be used to set a byte in a String.  You
-			can do that like this: >
-				:let var = var[0:2] .. 'X' .. var[4:]
-<			When {var-name} is a |Blob| then {idx} can be the
-			length of the blob, in which case one byte is
-			appended.
-
-					*E711* *E719* *E1165* *E1166* *E1183*
-:let {var-name}[{idx1}:{idx2}] = {expr1}		*E708* *E709* *E710*
-			Set a sequence of items in a |List| to the result of
-			the expression {expr1}, which must be a list with the
-			correct number of items.
-			{idx1} can be omitted, zero is used instead.
-			{idx2} can be omitted, meaning the end of the list.
-			When the selected range of items is partly past the
-			end of the list, items will be added.
-
-			*:let+=* *:let-=* *:letstar=* *:let/=*  *:let%=*
-			*:let.=* *:let..=* *E734* *E985* *E1019*
-:let {var} += {expr1}	Like ":let {var} = {var} + {expr1}".
-:let {var} -= {expr1}	Like ":let {var} = {var} - {expr1}".
-:let {var} *= {expr1}	Like ":let {var} = {var} * {expr1}".
-:let {var} /= {expr1}	Like ":let {var} = {var} / {expr1}".
-:let {var} %= {expr1}	Like ":let {var} = {var} % {expr1}".
-:let {var} .= {expr1}	Like ":let {var} = {var} . {expr1}".
-:let {var} ..= {expr1}	Like ":let {var} = {var} .. {expr1}".
-			These fail if {var} was not set yet and when the type
-			of {var} and {expr1} don't fit the operator.
-			`.=` is not supported with Vim script version 2 and
-			later, see |vimscript-version|.
-
-
-:let ${env-name} = {expr1}			*:let-environment* *:let-$*
-			Set environment variable {env-name} to the result of
-			the expression {expr1}.  The type is always String.
-
-			On some systems making an environment variable empty
-			causes it to be deleted.  Many systems do not make a
-			difference between an environment variable that is not
-			set and an environment variable that is empty.
-
-:let ${env-name} .= {expr1}
-			Append {expr1} to the environment variable {env-name}.
-			If the environment variable didn't exist yet this
-			works like "=".
-
-:let @{reg-name} = {expr1}			*:let-register* *:let-@*
-			Write the result of the expression {expr1} in register
-			{reg-name}.  {reg-name} must be a single letter, and
-			must be the name of a writable register (see
-			|registers|).  "@@" can be used for the unnamed
-			register, "@/" for the search pattern.
-			If the result of {expr1} ends in a <CR> or <NL>, the
-			register will be linewise, otherwise it will be set to
-			characterwise.
-			This can be used to clear the last search pattern: >
-				:let @/ = ""
-<			This is different from searching for an empty string,
-			that would match everywhere.
-
-:let @{reg-name} .= {expr1}
-			Append {expr1} to register {reg-name}.  If the
-			register was empty it's like setting it to {expr1}.
-
-:let &{option-name} = {expr1}			*:let-option* *:let-&*
-			Set option {option-name} to the result of the
-			expression {expr1}.  A String or Number value is
-			always converted to the type of the option.
-			For an option local to a window or buffer the effect
-			is just like using the |:set| command: both the local
-			value and the global value are changed.
-			Example: >
-				:let &path = &path .. ',/usr/local/include'
-<			This also works for terminal codes in the form t_xx.
-			But only for alphanumerical names.  Example: >
-				:let &t_k1 = "\<Esc>[234;"
-<			When the code does not exist yet it will be created as
-			a terminal key code, there is no error.
-
-:let &{option-name} .= {expr1}
-			For a string option: Append {expr1} to the value.
-			Does not insert a comma like |:set+=|.
-
-:let &{option-name} += {expr1}
-:let &{option-name} -= {expr1}
-			For a number or boolean option: Add or subtract
-			{expr1}.
-
-:let &l:{option-name} = {expr1}
-:let &l:{option-name} .= {expr1}
-:let &l:{option-name} += {expr1}
-:let &l:{option-name} -= {expr1}
-			Like above, but only set the local value of an option
-			(if there is one).  Works like |:setlocal|.
-
-:let &g:{option-name} = {expr1}
-:let &g:{option-name} .= {expr1}
-:let &g:{option-name} += {expr1}
-:let &g:{option-name} -= {expr1}
-			Like above, but only set the global value of an option
-			(if there is one).  Works like |:setglobal|.
-								*E1093*
-:let [{name1}, {name2}, ...] = {expr1}		*:let-unpack* *E687* *E688*
-			{expr1} must evaluate to a |List|.  The first item in
-			the list is assigned to {name1}, the second item to
-			{name2}, etc.
-			The number of names must match the number of items in
-			the |List|.
-			Each name can be one of the items of the ":let"
-			command as mentioned above.
-			Example: >
-				:let [s, item] = GetItem(s)
-<			Detail: {expr1} is evaluated first, then the
-			assignments are done in sequence.  This matters if
-			{name2} depends on {name1}.  Example: >
-				:let x = [0, 1]
-				:let i = 0
-				:let [i, x[i]] = [1, 2]
-				:echo x
-<			The result is [0, 2].
-
-:let [{name1}, {name2}, ...] .= {expr1}
-:let [{name1}, {name2}, ...] += {expr1}
-:let [{name1}, {name2}, ...] -= {expr1}
-			Like above, but append/add/subtract the value for each
-			|List| item.
-
-:let [{name}, ..., ; {lastname}] = {expr1}				*E452*
-			Like |:let-unpack| above, but the |List| may have more
-			items than there are names.  A list of the remaining
-			items is assigned to {lastname}.  If there are no
-			remaining items {lastname} is set to an empty list.
-			Example: >
-				:let [a, b; rest] = ["aval", "bval", 3, 4]
-<
-:let [{name}, ..., ; {lastname}] .= {expr1}
-:let [{name}, ..., ; {lastname}] += {expr1}
-:let [{name}, ..., ; {lastname}] -= {expr1}
-			Like above, but append/add/subtract the value for each
-			|List| item.
-
-						*:let=<<* *:let-heredoc*
-					*E990* *E991* *E172* *E221* *E1145*
-:let {var-name} =<< [trim] [eval] {endmarker}
-text...
-text...
-{endmarker}
-			Set internal variable {var-name} to a |List|
-			containing the lines of text bounded by the string
-			{endmarker}.
-
-			If "eval" is not specified, then each line of text is
-			used as a |literal-string|, except that single quotes
-			does not need to be doubled.
-			If "eval" is specified, then any Vim expression in the
-			form {expr} is evaluated and the result replaces the
-			expression, like with |interpolated-string|.
-			Example where $HOME is expanded: >
-				let lines =<< trim eval END
-				  some text
-				  See the file {$HOME}/.vimrc
-				  more text
-				END
-<			There can be multiple Vim expressions in a single line
-			but an expression cannot span multiple lines.  If any
-			expression evaluation fails, then the assignment fails.
-
-			{endmarker} must not contain white space.
-			{endmarker} cannot start with a lower case character.
-			The last line should end only with the {endmarker}
-			string without any other character.  Watch out for
-			white space after {endmarker}!
-
-			Without "trim" any white space characters in the lines
-			of text are preserved.  If "trim" is specified before
-			{endmarker}, then indentation is stripped so you can
-			do: >
-				let text =<< trim END
-				   if ok
-				     echo 'done'
-				   endif
-				END
-<			Results in: ["if ok", "  echo 'done'", "endif"]
-			The marker must line up with "let" and the indentation
-			of the first line is removed from all the text lines.
-			Specifically: all the leading indentation exactly
-			matching the leading indentation of the first
-			non-empty text line is stripped from the input lines.
-			All leading indentation exactly matching the leading
-			indentation before `let` is stripped from the line
-			containing {endmarker}.  Note that the difference
-			between space and tab matters here.
-
-			If {var-name} didn't exist yet, it is created.
-			Cannot be followed by another command, but can be
-			followed by a comment.
-
-			To avoid line continuation to be applied, consider
-			adding 'C' to 'cpoptions': >
-				set cpo+=C
-				let var =<< END
-				   \ leading backslash
-				END
-				set cpo-=C
-<
-			Examples: >
-				let var1 =<< END
-				Sample text 1
-				    Sample text 2
-				Sample text 3
-				END
-
-				let data =<< trim DATA
-					1 2 3 4
-					5 6 7 8
-				DATA
-
-				let code =<< trim eval CODE
-				   let v = {10 + 20}
-				   let h = "{$HOME}"
-				   let s = "{Str1()} abc {Str2()}"
-				   let n = {MyFunc(3, 4)}
-				CODE
-<
-								*E121*
-:let {var-name}	..	List the value of variable {var-name}.  Multiple
-			variable names may be given.  Special names recognized
-			here:				*E738*
-			  g:	global variables
-			  b:	local buffer variables
-			  w:	local window variables
-			  t:	local tab page variables
-			  s:	script-local variables
-			  l:	local function variables
-			  v:	Vim variables.
-			This does not work in Vim9 script. |vim9-declaration|
-
-:let			List the values of all variables.  The type of the
-			variable is indicated before the value:
-			    <nothing>	String
-				#	Number
-				*	Funcref
-			This does not work in Vim9 script. |vim9-declaration|
-
-:unl[et][!] {name} ...			*:unlet* *:unl* *E108* *E795* *E1081*
-			Remove the internal variable {name}.  Several variable
-			names can be given, they are all removed.  The name
-			may also be a |List| or |Dictionary| item.
-			With [!] no error message is given for non-existing
-			variables.
-			One or more items from a |List| can be removed: >
-				:unlet list[3]	  " remove fourth item
-				:unlet list[3:]   " remove fourth item to last
-<			One item from a |Dictionary| can be removed at a time: >
-				:unlet dict['two']
-				:unlet dict.two
-<			This is especially useful to clean up used global
-			variables and script-local variables (these are not
-			deleted when the script ends).  Function-local
-			variables are automatically deleted when the function
-			ends.
-			In |Vim9| script variables declared in a function or
-			script cannot be removed.
-
-:unl[et] ${env-name} ...			*:unlet-environment* *:unlet-$*
-			Remove environment variable {env-name}.
-			Can mix {name} and ${env-name} in one :unlet command.
-			No error message is given for a non-existing
-			variable, also without !.
-			If the system does not support deleting an environment
-			variable, it is made empty.
-
-						*:cons* *:const* *E1018*
-:cons[t] {var-name} = {expr1}
-:cons[t] [{name1}, {name2}, ...] = {expr1}
-:cons[t] [{name}, ..., ; {lastname}] = {expr1}
-:cons[t] {var-name} =<< [trim] {marker}
-text...
-text...
-{marker}
-			Similar to |:let|, but additionally lock the variable
-			after setting the value.  This is the same as locking
-			the variable with |:lockvar| just after |:let|, thus: >
-				:const x = 1
-<			is equivalent to: >
-				:let x = 1
-				:lockvar! x
-<			NOTE: in Vim9 script `:const` works differently, see
-			|vim9-const|
-			This is useful if you want to make sure the variable
-			is not modified.  If the value is a List or Dictionary
-			literal then the items also cannot be changed: >
-				const ll = [1, 2, 3]
-				let ll[1] = 5  " Error!
-<			Nested references are not locked: >
-				let lvar = ['a']
-				const lconst = [0, lvar]
-				let lconst[0] = 2  " Error!
-				let lconst[1][0] = 'b'  " OK
-<							*E995*
-			|:const| does not allow to for changing a variable: >
-				:let x = 1
-				:const x = 2  " Error!
-<							*E996*
-			Note that environment variables, option values and
-			register values cannot be used here, since they cannot
-			be locked.
-
-:cons[t]
-:cons[t] {var-name}
-			If no argument is given or only {var-name} is given,
-			the behavior is the same as |:let|.
-
-:lockv[ar][!] [depth] {name} ...			*:lockvar* *:lockv*
-			Lock the internal variable {name}.  Locking means that
-			it can no longer be changed (until it is unlocked).
-			A locked variable can be deleted: >
-				:lockvar v
-				:let v = 'asdf'	  " fails!
-				:unlet v	  " works
-<			*E741* *E940* *E1118* *E1119* *E1120* *E1121* *E1122*
-			If you try to change a locked variable you get an
-			error message: "E741: Value is locked: {name}".
-			If you try to lock or unlock a built-in variable you
-			get an error message: "E940: Cannot lock or unlock
-			variable {name}".
-
-			[depth] is relevant when locking a |List| or
-			|Dictionary|.  It specifies how deep the locking goes:
-				0	Lock the variable {name} but not its
-					value.
-				1	Lock the |List| or |Dictionary| itself,
-					cannot add or remove items, but can
-					still change their values.
-				2	Also lock the values, cannot change
-					the items.  If an item is a |List| or
-					|Dictionary|, cannot add or remove
-					items, but can still change the
-					values.
-				3	Like 2 but for the |List| /
-					|Dictionary| in the |List| /
-					|Dictionary|, one level deeper.
-			The default [depth] is 2, thus when {name} is a |List|
-			or |Dictionary| the values cannot be changed.
-
-			Example with [depth] 0: >
-				let mylist = [1, 2, 3]
-				lockvar 0 mylist
-				let mylist[0] = 77	" OK
-				call add(mylist, 4)	" OK
-				let mylist = [7, 8, 9]  " Error!
-<								*E743*
-			For unlimited depth use [!] and omit [depth].
-			However, there is a maximum depth of 100 to catch
-			loops.
-
-			Note that when two variables refer to the same |List|
-			and you lock one of them, the |List| will also be
-			locked when used through the other variable.
-			Example: >
-				:let l = [0, 1, 2, 3]
-				:let cl = l
-				:lockvar l
-				:let cl[1] = 99		" won't work!
-<			You may want to make a copy of a list to avoid this.
-			See |deepcopy()|.
-
-
-:unlo[ckvar][!] [depth] {name} ...		*:unlockvar* *:unlo* *E1246*
-			Unlock the internal variable {name}.  Does the
-			opposite of |:lockvar|.
-
-			If {name} does not exist:
-			- In |Vim9| script an error is given.
-			- In legacy script this is silently ignored.
-
-:if {expr1}			*:if* *:end* *:endif* *:en* *E171* *E579* *E580*
-:en[dif]		Execute the commands until the next matching `:else`
-			or `:endif` if {expr1} evaluates to non-zero.
-			Although the short forms work, it is recommended to
-			always use `:endif` to avoid confusion and to make
-			auto-indenting work properly.
-
-			From Vim version 4.5 until 5.0, every Ex command in
-			between the `:if` and `:endif` is ignored.  These two
-			commands were just to allow for future expansions in a
-			backward compatible way.  Nesting was allowed.  Note
-			that any `:else` or `:elseif` was ignored, the `else`
-			part was not executed either.
-
-			You can use this to remain compatible with older
-			versions: >
-				:if version >= 500
-				:  version-5-specific-commands
-				:endif
-<			The commands still need to be parsed to find the
-			`endif`.  Sometimes an older Vim has a problem with a
-			new command.  For example, `:silent` is recognized as
-			a `:substitute` command.  In that case `:execute` can
-			avoid problems: >
-				:if version >= 600
-				:  execute "silent 1,$delete"
-				:endif
-<
-			In |Vim9| script `:endif` cannot be shortened, to
-			improve script readability.
-			NOTE: The `:append` and `:insert` commands don't work
-			properly in between `:if` and `:endif`.
-
-						*:else* *:el* *E581* *E583*
-:el[se]			Execute the commands until the next matching `:else`
-			or `:endif` if they previously were not being
-			executed.
-			In |Vim9| script `:else` cannot be shortened, to
-			improve script readability.
-
-					*:elseif* *:elsei* *E582* *E584*
-:elsei[f] {expr1}	Short for `:else` `:if`, with the addition that there
-			is no extra `:endif`.
-			In |Vim9| script `:elseif` cannot be shortened, to
-			improve script readability.
-
-:wh[ile] {expr1}			*:while* *:endwhile* *:wh* *:endw*
-						*E170* *E585* *E588* *E733*
-:endw[hile]		Repeat the commands between `:while` and `:endwhile`,
-			as long as {expr1} evaluates to non-zero.
-			When an error is detected from a command inside the
-			loop, execution continues after the `endwhile`.
-			Example: >
-				:let lnum = 1
-				:while lnum <= line("$")
-				   :call FixLine(lnum)
-				   :let lnum = lnum + 1
-				:endwhile
-<
-			In |Vim9| script `:while`  and `:endwhile` cannot be
-			shortened, to improve script readability.
-			NOTE: The `:append` and `:insert` commands don't work
-			properly inside a `:while` and `:for` loop.
-
-:for {var} in {object}					*:for* *E690* *E732*
-:endfo[r]						*:endfo* *:endfor*
-			Repeat the commands between `:for` and `:endfor` for
-			each item in {object}.  {object} can be a |List|,
-			a |Blob| or a |String|. *E1177*
-
-			Variable {var} is set to the value of each item.
-			In |Vim9| script the loop variable must not have been
-			declared yet, unless when it is a
-			global/window/tab/buffer variable.
-
-			When an error is detected for a command inside the
-			loop, execution continues after the `endfor`.
-			Changing {object} inside the loop affects what items
-			are used.  Make a copy if this is unwanted: >
-				:for item in copy(mylist)
-<
-			When {object} is a |List| and not making a copy, in
-			legacy script Vim stores a reference to the next item
-			in the |List| before executing the commands with the
-			current item.  Thus the current item can be removed
-			without effect.  Removing any later item means it will
-			not be found.  Thus the following example works (an
-			inefficient way to make a |List| empty): >
-				for item in mylist
-				   call remove(mylist, 0)
-				endfor
-<			Note that reordering the |List| (e.g., with sort() or
-			reverse()) may have unexpected effects.
-			In |Vim9| script the index is used.  If an item before
-			the current one is deleted the next item will be
-			skipped.
-
-			When {object} is a |Blob|, Vim always makes a copy to
-			iterate over.  Unlike with |List|, modifying the
-			|Blob| does not affect the iteration.
-
-			When {object} is a |String| each item is a string with
-			one character, plus any combining characters.
-
-			In |Vim9| script `:endfor` cannot be shortened, to
-			improve script readability.
-
-:for [{var1}, {var2}, ...] in {listlist}
-:endfo[r]							*E1140*
-			Like `:for` above, but each item in {listlist} must be
-			a list, of which each item is assigned to {var1},
-			{var2}, etc.  Example: >
-				:for [lnum, col] in [[1, 3], [2, 5], [3, 8]]
-				   :echo getline(lnum)[col]
-				:endfor
-<
-						*:continue* *:con* *E586*
-:con[tinue]		When used inside a `:while` or `:for` loop, jumps back
-			to the start of the loop.
-			If it is used after a `:try` inside the loop but
-			before the matching `:finally` (if present), the
-			commands following the `:finally` up to the matching
-			`:endtry` are executed first.  This process applies to
-			all nested `:try`s inside the loop.  The outermost
-			`:endtry` then jumps back to the start of the loop.
-
-			In |Vim9| script `:cont` is the shortest form, to
-			improve script readability.
-						*:break* *:brea* *E587*
-:brea[k]		When used inside a `:while` or `:for` loop, skips to
-			the command after the matching `:endwhile` or
-			`:endfor`.
-			If it is used after a `:try` inside the loop but
-			before the matching `:finally` (if present), the
-			commands following the `:finally` up to the matching
-			`:endtry` are executed first.  This process applies to
-			all nested `:try`s inside the loop.  The outermost
-			`:endtry` then jumps to the command after the loop.
-
-			In |Vim9| script `:break` cannot be shortened, to
-			improve script readability.
-
-:try						*:try* *:endt* *:endtry*
-						*E600* *E601* *E602* *E1032*
-:endt[ry]		Change the error handling for the commands between
-			`:try` and `:endtry` including everything being
-			executed across `:source` commands, function calls,
-			or autocommand invocations.
-
-			When an error or interrupt is detected and there is
-			a `:finally` command following, execution continues
-			after the `:finally`.  Otherwise, or when the
-			`:endtry` is reached thereafter, the next
-			(dynamically) surrounding `:try` is checked for
-			a corresponding `:finally` etc.  Then the script
-			processing is terminated.  Whether a function
-			definition has an "abort" argument does not matter.
-			Example: >
-		try | call Unknown() | finally | echomsg "cleanup" | endtry
-		echomsg "not reached"
-<
-			Moreover, an error or interrupt (dynamically) inside
-			`:try` and `:endtry` is converted to an exception.  It
-			can be caught as if it were thrown by a `:throw`
-			command (see `:catch`).  In this case, the script
-			processing is not terminated.
-
-			The value "Vim:Interrupt" is used for an interrupt
-			exception.  An error in a Vim command is converted
-			to a value of the form "Vim({command}):{errmsg}",
-			other errors are converted to a value of the form
-			"Vim:{errmsg}".  {command} is the full command name,
-			and {errmsg} is the message that is displayed if the
-			error exception is not caught, always beginning with
-			the error number.
-			Examples: >
-		try | sleep 100 | catch /^Vim:Interrupt$/ | endtry
-		try | edit | catch /^Vim(edit):E\d\+/ | echo "error" | endtry
-<
-			In |Vim9| script `:endtry` cannot be shortened, to
-			improve script readability.
-
-					*:cat* *:catch*
-					*E603* *E604* *E605* *E654* *E1033*
-:cat[ch] /{pattern}/	The following commands until the next `:catch`,
-			`:finally`, or `:endtry` that belongs to the same
-			`:try` as the `:catch` are executed when an exception
-			matching {pattern} is being thrown and has not yet
-			been caught by a previous `:catch`.  Otherwise, these
-			commands are skipped.
-			When {pattern} is omitted all errors are caught.
-			Examples: >
-		:catch /^Vim:Interrupt$/	 " catch interrupts (CTRL-C)
-		:catch /^Vim\%((\a\+)\)\=:E/	 " catch all Vim errors
-		:catch /^Vim\%((\a\+)\)\=:/	 " catch errors and interrupts
-		:catch /^Vim(write):/		 " catch all errors in :write
-		:catch /^Vim\%((\a\+)\)\=:E123:/ " catch error E123
-		:catch /my-exception/		 " catch user exception
-		:catch /.*/			 " catch everything
-		:catch				 " same as /.*/
-<
-			Another character can be used instead of / around the
-			{pattern}, so long as it does not have a special
-			meaning (e.g., '|' or '"') and doesn't occur inside
-			{pattern}. *E1067*
-			Information about the exception is available in
-			|v:exception|.  Also see |throw-variables|.
-			NOTE: It is not reliable to ":catch" the TEXT of
-			an error message because it may vary in different
-			locales.
-			In |Vim9| script `:catch` cannot be shortened, to
-			improve script readability.
-
-					*:fina* *:finally* *E606* *E607*
-:fina[lly]		The following commands until the matching `:endtry`
-			are executed whenever the part between the matching
-			`:try` and the `:finally` is left:  either by falling
-			through to the `:finally` or by a `:continue`,
-			`:break`, `:finish`, or `:return`, or by an error or
-			interrupt or exception (see `:throw`).
-
-			In |Vim9| script `:finally` cannot be shortened, to
-			improve script readability and avoid confusion with
-			`:final`.
-
-						*:th* *:throw* *E608* *E1129*
-:th[row] {expr1}	The {expr1} is evaluated and thrown as an exception.
-			If the ":throw" is used after a `:try` but before the
-			first corresponding `:catch`, commands are skipped
-			until the first `:catch` matching {expr1} is reached.
-			If there is no such `:catch` or if the ":throw" is
-			used after a `:catch` but before the `:finally`, the
-			commands following the `:finally` (if present) up to
-			the matching `:endtry` are executed.  If the `:throw`
-			is after the `:finally`, commands up to the `:endtry`
-			are skipped.  At the ":endtry", this process applies
-			again for the next dynamically surrounding `:try`
-			(which may be found in a calling function or sourcing
-			script), until a matching `:catch` has been found.
-			If the exception is not caught, the command processing
-			is terminated.
-			Example: >
-		:try | throw "oops" | catch /^oo/ | echo "caught" | endtry
-<			Note that "catch" may need to be on a separate line
-			for when an error causes the parsing to skip the whole
-			line and not see the "|" that separates the commands.
-
-			In |Vim9| script `:throw` cannot be shortened, to
-			improve script readability.
-
-							*:ec* *:echo*
-:ec[ho] {expr1} ..	Echoes each {expr1}, with a space in between.  The
-			first {expr1} starts on a new line.
-			Also see |:comment|.
-			Use "\n" to start a new line.  Use "\r" to move the
-			cursor to the first column.
-			Uses the highlighting set by the `:echohl` command.
-			Cannot be followed by a comment.
-			Example: >
-		:echo "the value of 'shell' is" &shell
-<							*:echo-redraw*
-			A later redraw may make the message disappear again.
-			And since Vim mostly postpones redrawing until it's
-			finished with a sequence of commands this happens
-			quite often.  To avoid that a command from before the
-			`:echo` causes a redraw afterwards (redraws are often
-			postponed until you type something), force a redraw
-			with the `:redraw` command.  Example: >
-		:new | redraw | echo "there is a new window"
-<
-							*:echon*
-:echon {expr1} ..	Echoes each {expr1}, without anything added.  Also see
-			|:comment|.
-			Uses the highlighting set by the `:echohl` command.
-			Cannot be followed by a comment.
-			Example: >
-				:echon "the value of 'shell' is " &shell
-<
-			Note the difference between using `:echo`, which is a
-			Vim command, and `:!echo`, which is an external shell
-			command: >
-		:!echo %		--> filename
-<			The arguments of ":!" are expanded, see |:_%|. >
-		:!echo "%"		--> filename or "filename"
-<			Like the previous example.  Whether you see the double
-			quotes or not depends on your 'shell'. >
-		:echo %			--> nothing
-<			The '%' is an illegal character in an expression. >
-		:echo "%"		--> %
-<			This just echoes the '%' character. >
-		:echo expand("%")	--> filename
-<			This calls the expand() function to expand the '%'.
-
-							*:echoh* *:echohl*
-:echoh[l] {name}	Use the highlight group {name} for the following
-			`:echo`, `:echon` and `:echomsg` commands.  Also used
-			for the `input()` prompt.  Example: >
-		:echohl WarningMsg | echo "Don't panic!" | echohl None
-<			Don't forget to set the group back to "None",
-			otherwise all following echo's will be highlighted.
-
-							*:echom* *:echomsg*
-:echom[sg] {expr1} ..	Echo the expression(s) as a true message, saving the
-			message in the |message-history|.
-			Spaces are placed between the arguments as with the
-			`:echo` command.  But unprintable characters are
-			displayed, not interpreted.
-			The parsing works slightly different from `:echo`,
-			more like `:execute`.  All the expressions are first
-			evaluated and concatenated before echoing anything.
-			If expressions does not evaluate to a Number or
-			String, string() is used to turn it into a string.
-			Uses the highlighting set by the `:echohl` command.
-			Example: >
-		:echomsg "It's a Zizzer Zazzer Zuzz, as you can plainly see."
-<			See |:echo-redraw| to avoid the message disappearing
-			when the screen is redrawn.
-
-					*:echow* *:echowin* *:echowindow*
-:[N]echow[indow] {expr1} ..
-			Like |:echomsg| but when the messages popup window is
-			available the message is displayed there.  This means
-			it will show for three seconds and avoid a
-			|hit-enter| prompt.  If you want to hide it before
-			that, press Esc in Normal mode (when it would
-			otherwise beep).  If it disappears too soon you can
-			use `:messages` to see the text.
-			When [N] is given then the window will show up for
-			this number of seconds.  The last `:echowindow` with a
-			count matters, it is used once only.
-			The message window is available when Vim was compiled
-			with the +timer and the +popupwin features.
-
-							*:echoe* *:echoerr*
-:echoe[rr] {expr1} ..	Echo the expression(s) as an error message, saving the
-			message in the |message-history|.  When used in a
-			script or function the line number will be added.
-			Spaces are placed between the arguments as with the
-			`:echomsg` command.  When used inside a try conditional,
-			the message is raised as an error exception instead
-			(see |try-echoerr|).
-			Example: >
-		:echoerr "This script just failed!"
-<			If you just want a highlighted message use `:echohl`.
-			And to get a beep: >
-		:exe "normal \<Esc>"
-
-:echoc[onsole] {expr1} ..				*:echoc* *:echoconsole*
-			Intended for testing: works like `:echomsg` but when
-			running in the GUI and started from a terminal write
-			the text to stdout.
-
-							*:eval*
-:eval {expr}		Evaluate {expr} and discard the result.  Example: >
-				:eval Getlist()->Filter()->append('$')
-
-<			The expression is supposed to have a side effect,
-			since the resulting value is not used.  In the example
-			the `append()` call appends the List with text to the
-			buffer.  This is similar to `:call` but works with any
-			expression.
-			In |Vim9| script an expression without an effect will
-			result in error *E1207* .  This should help noticing
-			mistakes.
-
-			The command can be shortened to `:ev` or `:eva`, but
-			these are hard to recognize and therefore not to be
-			used.
-
-			The command cannot be followed by "|" and another
-			command, since "|" is seen as part of the expression.
-
-
-							*:exe* *:execute*
-:exe[cute] {expr1} ..	Executes the string that results from the evaluation
-			of {expr1} as an Ex command.
-			Multiple arguments are concatenated, with a space in
-			between.  To avoid the extra space use the ".."
-			operator to concatenate strings into one argument.
-			{expr1} is used as the processed command, command line
-			editing keys are not recognized.
-			Cannot be followed by a comment.
-			Examples: >
-		:execute "buffer" nextbuf
-		:execute "normal" count .. "w"
-<
-			":execute" can be used to append a command to commands
-			that don't accept a '|'.  Example: >
-		:execute '!ls' | echo "theend"
-
-<			":execute" is also a nice way to avoid having to type
-			control characters in a Vim script for a ":normal"
-			command: >
-		:execute "normal ixxx\<Esc>"
-<			This has an <Esc> character, see |expr-string|.
-
-			Be careful to correctly escape special characters in
-			file names.  The |fnameescape()| function can be used
-			for Vim commands, |shellescape()| for |:!| commands.
-			Examples: >
-		:execute "e " .. fnameescape(filename)
-		:execute "!ls " .. shellescape(filename, 1)
-<
-			Note: The executed string may be any command-line, but
-			starting or ending "if", "while" and "for" does not
-			always work, because when commands are skipped the
-			":execute" is not evaluated and Vim loses track of
-			where blocks start and end.  Also "break" and
-			"continue" should not be inside ":execute".
-			This example does not work, because the ":execute" is
-			not evaluated and Vim does not see the "while", and
-			gives an error for finding an ":endwhile": >
-		:if 0
-		: execute 'while i > 5'
-		:  echo "test"
-		: endwhile
-		:endif
-<
-			It is allowed to have a "while" or "if" command
-			completely in the executed string: >
-		:execute 'while i < 5 | echo i | let i = i + 1 | endwhile'
-<
-
-							*:exe-comment*
-			":execute", ":echo" and ":echon" cannot be followed by
-			a comment directly, because they see the '"' as the
-			start of a string.  But, you can use '|' followed by a
-			comment.  Example: >
-		:echo "foo" | "this is a comment
-
-==============================================================================
-8. Exception handling					*exception-handling*
-
-The Vim script language comprises an exception handling feature.  This section
-explains how it can be used in a Vim script.
-
-Exceptions may be raised by Vim on an error or on interrupt, see
-|catch-errors| and |catch-interrupt|.  You can also explicitly throw an
-exception by using the ":throw" command, see |throw-catch|.
-
-
-TRY CONDITIONALS					*try-conditionals*
-
-Exceptions can be caught or can cause cleanup code to be executed.  You can
-use a try conditional to specify catch clauses (that catch exceptions) and/or
-a finally clause (to be executed for cleanup).
-   A try conditional begins with a |:try| command and ends at the matching
-|:endtry| command.  In between, you can use a |:catch| command to start
-a catch clause, or a |:finally| command to start a finally clause.  There may
-be none or multiple catch clauses, but there is at most one finally clause,
-which must not be followed by any catch clauses.  The lines before the catch
-clauses and the finally clause is called a try block. >
-
-     :try
-     :	...
-     :	...				TRY BLOCK
-     :	...
-     :catch /{pattern}/
-     :	...
-     :	...				CATCH CLAUSE
-     :	...
-     :catch /{pattern}/
-     :	...
-     :	...				CATCH CLAUSE
-     :	...
-     :finally
-     :	...
-     :	...				FINALLY CLAUSE
-     :	...
-     :endtry
-
-The try conditional allows to watch code for exceptions and to take the
-appropriate actions.  Exceptions from the try block may be caught.  Exceptions
-from the try block and also the catch clauses may cause cleanup actions.
-   When no exception is thrown during execution of the try block, the control
-is transferred to the finally clause, if present.  After its execution, the
-script continues with the line following the ":endtry".
-   When an exception occurs during execution of the try block, the remaining
-lines in the try block are skipped.  The exception is matched against the
-patterns specified as arguments to the ":catch" commands.  The catch clause
-after the first matching ":catch" is taken, other catch clauses are not
-executed.  The catch clause ends when the next ":catch", ":finally", or
-":endtry" command is reached - whatever is first.  Then, the finally clause
-(if present) is executed.  When the ":endtry" is reached, the script execution
-continues in the following line as usual.
-   When an exception that does not match any of the patterns specified by the
-":catch" commands is thrown in the try block, the exception is not caught by
-that try conditional and none of the catch clauses is executed.  Only the
-finally clause, if present, is taken.  The exception pends during execution of
-the finally clause.  It is resumed at the ":endtry", so that commands after
-the ":endtry" are not executed and the exception might be caught elsewhere,
-see |try-nesting|.
-   When during execution of a catch clause another exception is thrown, the
-remaining lines in that catch clause are not executed.  The new exception is
-not matched against the patterns in any of the ":catch" commands of the same
-try conditional and none of its catch clauses is taken.  If there is, however,
-a finally clause, it is executed, and the exception pends during its
-execution.  The commands following the ":endtry" are not executed.  The new
-exception might, however, be caught elsewhere, see |try-nesting|.
-   When during execution of the finally clause (if present) an exception is
-thrown, the remaining lines in the finally clause are skipped.  If the finally
-clause has been taken because of an exception from the try block or one of the
-catch clauses, the original (pending) exception is discarded.  The commands
-following the ":endtry" are not executed, and the exception from the finally
-clause is propagated and can be caught elsewhere, see |try-nesting|.
-
-The finally clause is also executed, when a ":break" or ":continue" for
-a ":while" loop enclosing the complete try conditional is executed from the
-try block or a catch clause.  Or when a ":return" or ":finish" is executed
-from the try block or a catch clause of a try conditional in a function or
-sourced script, respectively.  The ":break", ":continue", ":return", or
-":finish" pends during execution of the finally clause and is resumed when the
-":endtry" is reached.  It is, however, discarded when an exception is thrown
-from the finally clause.
-   When a ":break" or ":continue" for a ":while" loop enclosing the complete
-try conditional or when a ":return" or ":finish" is encountered in the finally
-clause, the rest of the finally clause is skipped, and the ":break",
-":continue", ":return" or ":finish" is executed as usual.  If the finally
-clause has been taken because of an exception or an earlier ":break",
-":continue", ":return", or ":finish" from the try block or a catch clause,
-this pending exception or command is discarded.
-
-For examples see |throw-catch| and |try-finally|.
-
-
-NESTING OF TRY CONDITIONALS				*try-nesting*
-
-Try conditionals can be nested arbitrarily.  That is, a complete try
-conditional can be put into the try block, a catch clause, or the finally
-clause of another try conditional.  If the inner try conditional does not
-catch an exception thrown in its try block or throws a new exception from one
-of its catch clauses or its finally clause, the outer try conditional is
-checked according to the rules above.  If the inner try conditional is in the
-try block of the outer try conditional, its catch clauses are checked, but
-otherwise only the finally clause is executed.  It does not matter for
-nesting, whether the inner try conditional is directly contained in the outer
-one, or whether the outer one sources a script or calls a function containing
-the inner try conditional.
-
-When none of the active try conditionals catches an exception, just their
-finally clauses are executed.  Thereafter, the script processing terminates.
-An error message is displayed in case of an uncaught exception explicitly
-thrown by a ":throw" command.  For uncaught error and interrupt exceptions
-implicitly raised by Vim, the error message(s) or interrupt message are shown
-as usual.
-
-For examples see |throw-catch|.
-
-
-EXAMINING EXCEPTION HANDLING CODE			*except-examine*
-
-Exception handling code can get tricky.  If you are in doubt what happens, set
-'verbose' to 13 or use the ":13verbose" command modifier when sourcing your
-script file.  Then you see when an exception is thrown, discarded, caught, or
-finished.  When using a verbosity level of at least 14, things pending in
-a finally clause are also shown.  This information is also given in debug mode
-(see |debug-scripts|).
-
-
-THROWING AND CATCHING EXCEPTIONS			*throw-catch*
-
-You can throw any number or string as an exception.  Use the |:throw| command
-and pass the value to be thrown as argument: >
-	:throw 4711
-	:throw "string"
-<							*throw-expression*
-You can also specify an expression argument.  The expression is then evaluated
-first, and the result is thrown: >
-	:throw 4705 + strlen("string")
-	:throw strpart("strings", 0, 6)
-
-An exception might be thrown during evaluation of the argument of the ":throw"
-command.  Unless it is caught there, the expression evaluation is abandoned.
-The ":throw" command then does not throw a new exception.
-   Example: >
-
-	:function! Foo(arg)
-	:  try
-	:    throw a:arg
-	:  catch /foo/
-	:  endtry
-	:  return 1
-	:endfunction
-	:
-	:function! Bar()
-	:  echo "in Bar"
-	:  return 4710
-	:endfunction
-	:
-	:throw Foo("arrgh") + Bar()
-
-This throws "arrgh", and "in Bar" is not displayed since Bar() is not
-executed. >
-	:throw Foo("foo") + Bar()
-however displays "in Bar" and throws 4711.
-
-Any other command that takes an expression as argument might also be
-abandoned by an (uncaught) exception during the expression evaluation.  The
-exception is then propagated to the caller of the command.
-   Example: >
-
-	:if Foo("arrgh")
-	:  echo "then"
-	:else
-	:  echo "else"
-	:endif
-
-Here neither of "then" or "else" is displayed.
-
-							*catch-order*
-Exceptions can be caught by a try conditional with one or more |:catch|
-commands, see |try-conditionals|.   The values to be caught by each ":catch"
-command can be specified as a pattern argument.  The subsequent catch clause
-gets executed when a matching exception is caught.
-   Example: >
-
-	:function! Foo(value)
-	:  try
-	:    throw a:value
-	:  catch /^\d\+$/
-	:    echo "Number thrown"
-	:  catch /.*/
-	:    echo "String thrown"
-	:  endtry
-	:endfunction
-	:
-	:call Foo(0x1267)
-	:call Foo('string')
-
-The first call to Foo() displays "Number thrown", the second "String thrown".
-An exception is matched against the ":catch" commands in the order they are
-specified.  Only the first match counts.  So you should place the more
-specific ":catch" first.  The following order does not make sense: >
-
-	:  catch /.*/
-	:    echo "String thrown"
-	:  catch /^\d\+$/
-	:    echo "Number thrown"
-
-The first ":catch" here matches always, so that the second catch clause is
-never taken.
-
-							*throw-variables*
-If you catch an exception by a general pattern, you may access the exact value
-in the variable |v:exception|: >
-
-	:  catch /^\d\+$/
-	:    echo "Number thrown.  Value is" v:exception
-
-You may also be interested where an exception was thrown.  This is stored in
-|v:throwpoint|.  Note that "v:exception" and "v:throwpoint" are valid for the
-exception most recently caught as long it is not finished.
-   Example: >
-
-	:function! Caught()
-	:  if v:exception != ""
-	:    echo 'Caught "' . v:exception .. '" in ' .. v:throwpoint
-	:  else
-	:    echo 'Nothing caught'
-	:  endif
-	:endfunction
-	:
-	:function! Foo()
-	:  try
-	:    try
-	:      try
-	:	 throw 4711
-	:      finally
-	:	 call Caught()
-	:      endtry
-	:    catch /.*/
-	:      call Caught()
-	:      throw "oops"
-	:    endtry
-	:  catch /.*/
-	:    call Caught()
-	:  finally
-	:    call Caught()
-	:  endtry
-	:endfunction
-	:
-	:call Foo()
-
-This displays >
-
-	Nothing caught
-	Caught "4711" in function Foo, line 4
-	Caught "oops" in function Foo, line 10
-	Nothing caught
-
-A practical example:  The following command ":LineNumber" displays the line
-number in the script or function where it has been used: >
-
-	:function! LineNumber()
-	:    return substitute(v:throwpoint, '.*\D\(\d\+\).*', '\1', "")
-	:endfunction
-	:command! LineNumber try | throw "" | catch | echo LineNumber() | endtry
-<
-							*try-nested*
-An exception that is not caught by a try conditional can be caught by
-a surrounding try conditional: >
-
-	:try
-	:  try
-	:    throw "foo"
-	:  catch /foobar/
-	:    echo "foobar"
-	:  finally
-	:    echo "inner finally"
-	:  endtry
-	:catch /foo/
-	:  echo "foo"
-	:endtry
-
-The inner try conditional does not catch the exception, just its finally
-clause is executed.  The exception is then caught by the outer try
-conditional.  The example displays "inner finally" and then "foo".
-
-							*throw-from-catch*
-You can catch an exception and throw a new one to be caught elsewhere from the
-catch clause: >
-
-	:function! Foo()
-	:  throw "foo"
-	:endfunction
-	:
-	:function! Bar()
-	:  try
-	:    call Foo()
-	:  catch /foo/
-	:    echo "Caught foo, throw bar"
-	:    throw "bar"
-	:  endtry
-	:endfunction
-	:
-	:try
-	:  call Bar()
-	:catch /.*/
-	:  echo "Caught" v:exception
-	:endtry
-
-This displays "Caught foo, throw bar" and then "Caught bar".
-
-							*rethrow*
-There is no real rethrow in the Vim script language, but you may throw
-"v:exception" instead: >
-
-	:function! Bar()
-	:  try
-	:    call Foo()
-	:  catch /.*/
-	:    echo "Rethrow" v:exception
-	:    throw v:exception
-	:  endtry
-	:endfunction
-<							*try-echoerr*
-Note that this method cannot be used to "rethrow" Vim error or interrupt
-exceptions, because it is not possible to fake Vim internal exceptions.
-Trying so causes an error exception.  You should throw your own exception
-denoting the situation.  If you want to cause a Vim error exception containing
-the original error exception value, you can use the |:echoerr| command: >
-
-	:try
-	:  try
-	:    asdf
-	:  catch /.*/
-	:    echoerr v:exception
-	:  endtry
-	:catch /.*/
-	:  echo v:exception
-	:endtry
-
-This code displays
-
-	Vim(echoerr):Vim:E492: Not an editor command:	asdf ~
-
-
-CLEANUP CODE						*try-finally*
-
-Scripts often change global settings and restore them at their end.  If the
-user however interrupts the script by pressing CTRL-C, the settings remain in
-an inconsistent state.  The same may happen to you in the development phase of
-a script when an error occurs or you explicitly throw an exception without
-catching it.  You can solve these problems by using a try conditional with
-a finally clause for restoring the settings.  Its execution is guaranteed on
-normal control flow, on error, on an explicit ":throw", and on interrupt.
-(Note that errors and interrupts from inside the try conditional are converted
-to exceptions.  When not caught, they terminate the script after the finally
-clause has been executed.)
-Example: >
-
-	:try
-	:  let s:saved_ts = &ts
-	:  set ts=17
-	:
-	:  " Do the hard work here.
-	:
-	:finally
-	:  let &ts = s:saved_ts
-	:  unlet s:saved_ts
-	:endtry
-
-This method should be used locally whenever a function or part of a script
-changes global settings which need to be restored on failure or normal exit of
-that function or script part.
-
-							*break-finally*
-Cleanup code works also when the try block or a catch clause is left by
-a ":continue", ":break", ":return", or ":finish".
-   Example: >
-
-	:let first = 1
-	:while 1
-	:  try
-	:    if first
-	:      echo "first"
-	:      let first = 0
-	:      continue
-	:    else
-	:      throw "second"
-	:    endif
-	:  catch /.*/
-	:    echo v:exception
-	:    break
-	:  finally
-	:    echo "cleanup"
-	:  endtry
-	:  echo "still in while"
-	:endwhile
-	:echo "end"
-
-This displays "first", "cleanup", "second", "cleanup", and "end". >
-
-	:function! Foo()
-	:  try
-	:    return 4711
-	:  finally
-	:    echo "cleanup\n"
-	:  endtry
-	:  echo "Foo still active"
-	:endfunction
-	:
-	:echo Foo() "returned by Foo"
-
-This displays "cleanup" and "4711 returned by Foo".  You don't need to add an
-extra ":return" in the finally clause.  (Above all, this would override the
-return value.)
-
-							*except-from-finally*
-Using either of ":continue", ":break", ":return", ":finish", or ":throw" in
-a finally clause is possible, but not recommended since it abandons the
-cleanup actions for the try conditional.  But, of course, interrupt and error
-exceptions might get raised from a finally clause.
-   Example where an error in the finally clause stops an interrupt from
-working correctly: >
-
-	:try
-	:  try
-	:    echo "Press CTRL-C for interrupt"
-	:    while 1
-	:    endwhile
-	:  finally
-	:    unlet novar
-	:  endtry
-	:catch /novar/
-	:endtry
-	:echo "Script still running"
-	:sleep 1
-
-If you need to put commands that could fail into a finally clause, you should
-think about catching or ignoring the errors in these commands, see
-|catch-errors| and |ignore-errors|.
-
-
-CATCHING ERRORS						*catch-errors*
-
-If you want to catch specific errors, you just have to put the code to be
-watched in a try block and add a catch clause for the error message.  The
-presence of the try conditional causes all errors to be converted to an
-exception.  No message is displayed and |v:errmsg| is not set then.  To find
-the right pattern for the ":catch" command, you have to know how the format of
-the error exception is.
-   Error exceptions have the following format: >
-
-	Vim({cmdname}):{errmsg}
-or >
-	Vim:{errmsg}
-
-{cmdname} is the name of the command that failed; the second form is used when
-the command name is not known.  {errmsg} is the error message usually produced
-when the error occurs outside try conditionals.  It always begins with
-a capital "E", followed by a two or three-digit error number, a colon, and
-a space.
-
-Examples:
-
-The command >
-	:unlet novar
-normally produces the error message >
-	E108: No such variable: "novar"
-which is converted inside try conditionals to an exception >
-	Vim(unlet):E108: No such variable: "novar"
-
-The command >
-	:dwim
-normally produces the error message >
-	E492: Not an editor command: dwim
-which is converted inside try conditionals to an exception >
-	Vim:E492: Not an editor command: dwim
-
-You can catch all ":unlet" errors by a >
-	:catch /^Vim(unlet):/
-or all errors for misspelled command names by a >
-	:catch /^Vim:E492:/
-
-Some error messages may be produced by different commands: >
-	:function nofunc
-and >
-	:delfunction nofunc
-both produce the error message >
-	E128: Function name must start with a capital: nofunc
-which is converted inside try conditionals to an exception >
-	Vim(function):E128: Function name must start with a capital: nofunc
-or >
-	Vim(delfunction):E128: Function name must start with a capital: nofunc
-respectively.  You can catch the error by its number independently on the
-command that caused it if you use the following pattern: >
-	:catch /^Vim(\a\+):E128:/
-
-Some commands like >
-	:let x = novar
-produce multiple error messages, here: >
-	E121: Undefined variable: novar
-	E15: Invalid expression:  novar
-Only the first is used for the exception value, since it is the most specific
-one (see |except-several-errors|).  So you can catch it by >
-	:catch /^Vim(\a\+):E121:/
-
-You can catch all errors related to the name "nofunc" by >
-	:catch /\<nofunc\>/
-
-You can catch all Vim errors in the ":write" and ":read" commands by >
-	:catch /^Vim(\(write\|read\)):E\d\+:/
-
-You can catch all Vim errors by the pattern >
-	:catch /^Vim\((\a\+)\)\=:E\d\+:/
-<
-							*catch-text*
-NOTE: You should never catch the error message text itself: >
-	:catch /No such variable/
-only works in the English locale, but not when the user has selected
-a different language by the |:language| command.  It is however helpful to
-cite the message text in a comment: >
-	:catch /^Vim(\a\+):E108:/   " No such variable
-
-
-IGNORING ERRORS						*ignore-errors*
-
-You can ignore errors in a specific Vim command by catching them locally: >
-
-	:try
-	:  write
-	:catch
-	:endtry
-
-But you are strongly recommended NOT to use this simple form, since it could
-catch more than you want.  With the ":write" command, some autocommands could
-be executed and cause errors not related to writing, for instance: >
-
-	:au BufWritePre * unlet novar
-
-There could even be such errors you are not responsible for as a script
-writer: a user of your script might have defined such autocommands.  You would
-then hide the error from the user.
-   It is much better to use >
-
-	:try
-	:  write
-	:catch /^Vim(write):/
-	:endtry
-
-which only catches real write errors.  So catch only what you'd like to ignore
-intentionally.
-
-For a single command that does not cause execution of autocommands, you could
-even suppress the conversion of errors to exceptions by the ":silent!"
-command: >
-	:silent! nunmap k
-This works also when a try conditional is active.
-
-
-CATCHING INTERRUPTS					*catch-interrupt*
-
-When there are active try conditionals, an interrupt (CTRL-C) is converted to
-the exception "Vim:Interrupt".  You can catch it like every exception.  The
-script is not terminated, then.
-   Example: >
-
-	:function! TASK1()
-	:  sleep 10
-	:endfunction
-
-	:function! TASK2()
-	:  sleep 20
-	:endfunction
-
-	:while 1
-	:  let command = input("Type a command: ")
-	:  try
-	:    if command == ""
-	:      continue
-	:    elseif command == "END"
-	:      break
-	:    elseif command == "TASK1"
-	:      call TASK1()
-	:    elseif command == "TASK2"
-	:      call TASK2()
-	:    else
-	:      echo "\nIllegal command:" command
-	:      continue
-	:    endif
-	:  catch /^Vim:Interrupt$/
-	:    echo "\nCommand interrupted"
-	:    " Caught the interrupt.  Continue with next prompt.
-	:  endtry
-	:endwhile
-
-You can interrupt a task here by pressing CTRL-C; the script then asks for
-a new command.  If you press CTRL-C at the prompt, the script is terminated.
-
-For testing what happens when CTRL-C would be pressed on a specific line in
-your script, use the debug mode and execute the |>quit| or |>interrupt|
-command on that line.  See |debug-scripts|.
-
-
-CATCHING ALL						*catch-all*
-
-The commands >
-
-	:catch /.*/
-	:catch //
-	:catch
-
-catch everything, error exceptions, interrupt exceptions and exceptions
-explicitly thrown by the |:throw| command.  This is useful at the top level of
-a script in order to catch unexpected things.
-   Example: >
-
-	:try
-	:
-	:  " do the hard work here
-	:
-	:catch /MyException/
-	:
-	:  " handle known problem
-	:
-	:catch /^Vim:Interrupt$/
-	:    echo "Script interrupted"
-	:catch /.*/
-	:  echo "Internal error (" .. v:exception .. ")"
-	:  echo " - occurred at " .. v:throwpoint
-	:endtry
-	:" end of script
-
-Note: Catching all might catch more things than you want.  Thus, you are
-strongly encouraged to catch only for problems that you can really handle by
-specifying a pattern argument to the ":catch".
-   Example: Catching all could make it nearly impossible to interrupt a script
-by pressing CTRL-C: >
-
-	:while 1
-	:  try
-	:    sleep 1
-	:  catch
-	:  endtry
-	:endwhile
-
-
-EXCEPTIONS AND AUTOCOMMANDS				*except-autocmd*
-
-Exceptions may be used during execution of autocommands.  Example: >
-
-	:autocmd User x try
-	:autocmd User x   throw "Oops!"
-	:autocmd User x catch
-	:autocmd User x   echo v:exception
-	:autocmd User x endtry
-	:autocmd User x throw "Arrgh!"
-	:autocmd User x echo "Should not be displayed"
-	:
-	:try
-	:  doautocmd User x
-	:catch
-	:  echo v:exception
-	:endtry
-
-This displays "Oops!" and "Arrgh!".
-
-							*except-autocmd-Pre*
-For some commands, autocommands get executed before the main action of the
-command takes place.  If an exception is thrown and not caught in the sequence
-of autocommands, the sequence and the command that caused its execution are
-abandoned and the exception is propagated to the caller of the command.
-   Example: >
-
-	:autocmd BufWritePre * throw "FAIL"
-	:autocmd BufWritePre * echo "Should not be displayed"
-	:
-	:try
-	:  write
-	:catch
-	:  echo "Caught:" v:exception "from" v:throwpoint
-	:endtry
-
-Here, the ":write" command does not write the file currently being edited (as
-you can see by checking 'modified'), since the exception from the BufWritePre
-autocommand abandons the ":write".  The exception is then caught and the
-script displays: >
-
-	Caught: FAIL from BufWrite Auto commands for "*"
-<
-							*except-autocmd-Post*
-For some commands, autocommands get executed after the main action of the
-command has taken place.  If this main action fails and the command is inside
-an active try conditional, the autocommands are skipped and an error exception
-is thrown that can be caught by the caller of the command.
-   Example: >
-
-	:autocmd BufWritePost * echo "File successfully written!"
-	:
-	:try
-	:  write /i/m/p/o/s/s/i/b/l/e
-	:catch
-	:  echo v:exception
-	:endtry
-
-This just displays: >
-
-	Vim(write):E212: Can't open file for writing (/i/m/p/o/s/s/i/b/l/e)
-
-If you really need to execute the autocommands even when the main action
-fails, trigger the event from the catch clause.
-   Example: >
-
-	:autocmd BufWritePre  * set noreadonly
-	:autocmd BufWritePost * set readonly
-	:
-	:try
-	:  write /i/m/p/o/s/s/i/b/l/e
-	:catch
-	:  doautocmd BufWritePost /i/m/p/o/s/s/i/b/l/e
-	:endtry
-<
-You can also use ":silent!": >
-
-	:let x = "ok"
-	:let v:errmsg = ""
-	:autocmd BufWritePost * if v:errmsg != ""
-	:autocmd BufWritePost *   let x = "after fail"
-	:autocmd BufWritePost * endif
-	:try
-	:  silent! write /i/m/p/o/s/s/i/b/l/e
-	:catch
-	:endtry
-	:echo x
-
-This displays "after fail".
-
-If the main action of the command does not fail, exceptions from the
-autocommands will be catchable by the caller of the command:  >
-
-	:autocmd BufWritePost * throw ":-("
-	:autocmd BufWritePost * echo "Should not be displayed"
-	:
-	:try
-	:  write
-	:catch
-	:  echo v:exception
-	:endtry
-<
-							*except-autocmd-Cmd*
-For some commands, the normal action can be replaced by a sequence of
-autocommands.  Exceptions from that sequence will be catchable by the caller
-of the command.
-   Example:  For the ":write" command, the caller cannot know whether the file
-had actually been written when the exception occurred.  You need to tell it in
-some way. >
-
-	:if !exists("cnt")
-	:  let cnt = 0
-	:
-	:  autocmd BufWriteCmd * if &modified
-	:  autocmd BufWriteCmd *   let cnt = cnt + 1
-	:  autocmd BufWriteCmd *   if cnt % 3 == 2
-	:  autocmd BufWriteCmd *     throw "BufWriteCmdError"
-	:  autocmd BufWriteCmd *   endif
-	:  autocmd BufWriteCmd *   write | set nomodified
-	:  autocmd BufWriteCmd *   if cnt % 3 == 0
-	:  autocmd BufWriteCmd *     throw "BufWriteCmdError"
-	:  autocmd BufWriteCmd *   endif
-	:  autocmd BufWriteCmd *   echo "File successfully written!"
-	:  autocmd BufWriteCmd * endif
-	:endif
-	:
-	:try
-	:	write
-	:catch /^BufWriteCmdError$/
-	:  if &modified
-	:    echo "Error on writing (file contents not changed)"
-	:  else
-	:    echo "Error after writing"
-	:  endif
-	:catch /^Vim(write):/
-	:    echo "Error on writing"
-	:endtry
-
-When this script is sourced several times after making changes, it displays
-first >
-	File successfully written!
-then >
-	Error on writing (file contents not changed)
-then >
-	Error after writing
-etc.
-
-							*except-autocmd-ill*
-You cannot spread a try conditional over autocommands for different events.
-The following code is ill-formed: >
-
-	:autocmd BufWritePre  * try
-	:
-	:autocmd BufWritePost * catch
-	:autocmd BufWritePost *   echo v:exception
-	:autocmd BufWritePost * endtry
-	:
-	:write
-
-
-EXCEPTION HIERARCHIES AND PARAMETERIZED EXCEPTIONS	*except-hier-param*
-
-Some programming languages allow to use hierarchies of exception classes or to
-pass additional information with the object of an exception class.  You can do
-similar things in Vim.
-   In order to throw an exception from a hierarchy, just throw the complete
-class name with the components separated by a colon, for instance throw the
-string "EXCEPT:MATHERR:OVERFLOW" for an overflow in a mathematical library.
-   When you want to pass additional information with your exception class, add
-it in parentheses, for instance throw the string "EXCEPT:IO:WRITEERR(myfile)"
-for an error when writing "myfile".
-   With the appropriate patterns in the ":catch" command, you can catch for
-base classes or derived classes of your hierarchy.  Additional information in
-parentheses can be cut out from |v:exception| with the ":substitute" command.
-   Example: >
-
-	:function! CheckRange(a, func)
-	:  if a:a < 0
-	:    throw "EXCEPT:MATHERR:RANGE(" .. a:func .. ")"
-	:  endif
-	:endfunction
-	:
-	:function! Add(a, b)
-	:  call CheckRange(a:a, "Add")
-	:  call CheckRange(a:b, "Add")
-	:  let c = a:a + a:b
-	:  if c < 0
-	:    throw "EXCEPT:MATHERR:OVERFLOW"
-	:  endif
-	:  return c
-	:endfunction
-	:
-	:function! Div(a, b)
-	:  call CheckRange(a:a, "Div")
-	:  call CheckRange(a:b, "Div")
-	:  if (a:b == 0)
-	:    throw "EXCEPT:MATHERR:ZERODIV"
-	:  endif
-	:  return a:a / a:b
-	:endfunction
-	:
-	:function! Write(file)
-	:  try
-	:    execute "write" fnameescape(a:file)
-	:  catch /^Vim(write):/
-	:    throw "EXCEPT:IO(" .. getcwd() .. ", " .. a:file .. "):WRITEERR"
-	:  endtry
-	:endfunction
-	:
-	:try
-	:
-	:  " something with arithmetic and I/O
-	:
-	:catch /^EXCEPT:MATHERR:RANGE/
-	:  let function = substitute(v:exception, '.*(\(\a\+\)).*', '\1', "")
-	:  echo "Range error in" function
-	:
-	:catch /^EXCEPT:MATHERR/	" catches OVERFLOW and ZERODIV
-	:  echo "Math error"
-	:
-	:catch /^EXCEPT:IO/
-	:  let dir = substitute(v:exception, '.*(\(.\+\),\s*.\+).*', '\1', "")
-	:  let file = substitute(v:exception, '.*(.\+,\s*\(.\+\)).*', '\1', "")
-	:  if file !~ '^/'
-	:    let file = dir .. "/" .. file
-	:  endif
-	:  echo 'I/O error for "' .. file .. '"'
-	:
-	:catch /^EXCEPT/
-	:  echo "Unspecified error"
-	:
-	:endtry
-
-The exceptions raised by Vim itself (on error or when pressing CTRL-C) use
-a flat hierarchy:  they are all in the "Vim" class.  You cannot throw yourself
-exceptions with the "Vim" prefix; they are reserved for Vim.
-   Vim error exceptions are parameterized with the name of the command that
-failed, if known.  See |catch-errors|.
-
-
-PECULIARITIES
-							*except-compat*
-The exception handling concept requires that the command sequence causing the
-exception is aborted immediately and control is transferred to finally clauses
-and/or a catch clause.
-
-In the Vim script language there are cases where scripts and functions
-continue after an error: in functions without the "abort" flag or in a command
-after ":silent!", control flow goes to the following line, and outside
-functions, control flow goes to the line following the outermost ":endwhile"
-or ":endif".  On the other hand, errors should be catchable as exceptions
-(thus, requiring the immediate abortion).
-
-This problem has been solved by converting errors to exceptions and using
-immediate abortion (if not suppressed by ":silent!") only when a try
-conditional is active.  This is no restriction since an (error) exception can
-be caught only from an active try conditional.  If you want an immediate
-termination without catching the error, just use a try conditional without
-catch clause.  (You can cause cleanup code being executed before termination
-by specifying a finally clause.)
-
-When no try conditional is active, the usual abortion and continuation
-behavior is used instead of immediate abortion.  This ensures compatibility of
-scripts written for Vim 6.1 and earlier.
-
-However, when sourcing an existing script that does not use exception handling
-commands (or when calling one of its functions) from inside an active try
-conditional of a new script, you might change the control flow of the existing
-script on error.  You get the immediate abortion on error and can catch the
-error in the new script.  If however the sourced script suppresses error
-messages by using the ":silent!" command (checking for errors by testing
-|v:errmsg| if appropriate), its execution path is not changed.  The error is
-not converted to an exception.  (See |:silent|.)  So the only remaining cause
-where this happens is for scripts that don't care about errors and produce
-error messages.  You probably won't want to use such code from your new
-scripts.
-
-							*except-syntax-err*
-Syntax errors in the exception handling commands are never caught by any of
-the ":catch" commands of the try conditional they belong to.  Its finally
-clauses, however, is executed.
-   Example: >
-
-	:try
-	:  try
-	:    throw 4711
-	:  catch /\(/
-	:    echo "in catch with syntax error"
-	:  catch
-	:    echo "inner catch-all"
-	:  finally
-	:    echo "inner finally"
-	:  endtry
-	:catch
-	:  echo 'outer catch-all caught "' .. v:exception .. '"'
-	:  finally
-	:    echo "outer finally"
-	:endtry
-
-This displays: >
-    inner finally
-    outer catch-all caught "Vim(catch):E54: Unmatched \("
-    outer finally
-The original exception is discarded and an error exception is raised, instead.
-
-							*except-single-line*
-The ":try", ":catch", ":finally", and ":endtry" commands can be put on
-a single line, but then syntax errors may make it difficult to recognize the
-"catch" line, thus you better avoid this.
-   Example: >
-	:try | unlet! foo # | catch | endtry
-raises an error exception for the trailing characters after the ":unlet!"
-argument, but does not see the ":catch" and ":endtry" commands, so that the
-error exception is discarded and the "E488: Trailing characters" message gets
-displayed.
-
-							*except-several-errors*
-When several errors appear in a single command, the first error message is
-usually the most specific one and therefore converted to the error exception.
-   Example: >
-	echo novar
-causes >
-	E121: Undefined variable: novar
-	E15: Invalid expression: novar
-The value of the error exception inside try conditionals is: >
-	Vim(echo):E121: Undefined variable: novar
-<							*except-syntax-error*
-But when a syntax error is detected after a normal error in the same command,
-the syntax error is used for the exception being thrown.
-   Example: >
-	unlet novar #
-causes >
-	E108: No such variable: "novar"
-	E488: Trailing characters
-The value of the error exception inside try conditionals is: >
-	Vim(unlet):E488: Trailing characters
-This is done because the syntax error might change the execution path in a way
-not intended by the user.  Example: >
-	try
-	    try | unlet novar # | catch | echo v:exception | endtry
-	catch /.*/
-	    echo "outer catch:" v:exception
-	endtry
-This displays "outer catch: Vim(unlet):E488: Trailing characters", and then
-a "E600: Missing :endtry" error message is given, see |except-single-line|.
-
-==============================================================================
-9. Examples						*eval-examples*
-
-Printing in Binary ~
->
-  :" The function Nr2Bin() returns the binary string representation of a number.
-  :func Nr2Bin(nr)
-  :  let n = a:nr
-  :  let r = ""
-  :  while n
-  :    let r = '01'[n % 2] .. r
-  :    let n = n / 2
-  :  endwhile
-  :  return r
-  :endfunc
-
-  :" The function String2Bin() converts each character in a string to a
-  :" binary string, separated with dashes.
-  :func String2Bin(str)
-  :  let out = ''
-  :  for ix in range(strlen(a:str))
-  :    let out = out .. '-' .. Nr2Bin(char2nr(a:str[ix]))
-  :  endfor
-  :  return out[1:]
-  :endfunc
-
-Example of its use: >
-  :echo Nr2Bin(32)
-result: "100000" >
-  :echo String2Bin("32")
-result: "110011-110010"
-
-
-Sorting lines ~
-
-This example sorts lines with a specific compare function. >
-
-  :func SortBuffer()
-  :  let lines = getline(1, '$')
-  :  call sort(lines, function("Strcmp"))
-  :  call setline(1, lines)
-  :endfunction
-
-As a one-liner: >
-  :call setline(1, sort(getline(1, '$'), function("Strcmp")))
-
-
-scanf() replacement ~
-							*sscanf*
-There is no sscanf() function in Vim.  If you need to extract parts from a
-line, you can use matchstr() and substitute() to do it.  This example shows
-how to get the file name, line number and column number out of a line like
-"foobar.txt, 123, 45". >
-   :" Set up the match bit
-   :let mx='\(\f\+\),\s*\(\d\+\),\s*\(\d\+\)'
-   :"get the part matching the whole expression
-   :let l = matchstr(line, mx)
-   :"get each item out of the match
-   :let file = substitute(l, mx, '\1', '')
-   :let lnum = substitute(l, mx, '\2', '')
-   :let col = substitute(l, mx, '\3', '')
-
-The input is in the variable "line", the results in the variables "file",
-"lnum" and "col". (idea from Michael Geddes)
-
-
-getting the scriptnames in a Dictionary ~
-						*scriptnames-dictionary*
-The `:scriptnames` command can be used to get a list of all script files that
-have been sourced.  There is also the `getscriptinfo()` function, but the
-information returned is not exactly the same.  In case you need to manipulate
-the list, this code can be used as a base: >
-
-    # Create or update scripts dictionary, indexed by SNR, and return it.
-    def Scripts(scripts: dict<string> = {}): dict<string>
-      for info in getscriptinfo()
-        if scripts->has_key(info.sid)
-          continue
-        endif
-        scripts[info.sid] = info.name
-      endfor
-      return scripts
-    enddef
-
-==============================================================================
-10. Vim script versions		*vimscript-version* *vimscript-versions*
-							*scriptversion*
-Over time many features have been added to Vim script.  This includes Ex
-commands, functions, variable types, etc.  Each individual feature can be
-checked with the |has()| and |exists()| functions.
-
-Sometimes old syntax of functionality gets in the way of making Vim better.
-When support is taken away this will break older Vim scripts.  To make this
-explicit the |:scriptversion| command can be used.  When a Vim script is not
-compatible with older versions of Vim this will give an explicit error,
-instead of failing in mysterious ways.
-
-When using a legacy function, defined with `:function`, in |Vim9| script then
-scriptversion 4 is used.
-
-							*scriptversion-1*  >
- :scriptversion 1
-<	This is the original Vim script, same as not using a |:scriptversion|
-	command.  Can be used to go back to old syntax for a range of lines.
-	Test for support with: >
-		has('vimscript-1')
-
-<							*scriptversion-2*  >
- :scriptversion 2
-<	String concatenation with "." is not supported, use ".." instead.
-	This avoids the ambiguity using "." for Dict member access and
-	floating point numbers.  Now ".5" means the number 0.5.
-
-							*scriptversion-3*  >
- :scriptversion 3
-<	All |vim-variable|s must be prefixed by "v:".  E.g. "version" doesn't
-	work as |v:version| anymore, it can be used as a normal variable.
-	Same for some obvious names as "count" and others.
-
-	Test for support with: >
-		has('vimscript-3')
-<
-							*scriptversion-4*  >
- :scriptversion 4
-<	Numbers with a leading zero are not recognized as octal.  "0o" or "0O"
-	is still recognized as octal.  With the
-	previous version you get: >
-		echo 017   " displays 15 (octal)
-		echo 0o17  " displays 15 (octal)
-		echo 018   " displays 18 (decimal)
-<	with script version 4: >
-		echo 017   " displays 17 (decimal)
-		echo 0o17  " displays 15 (octal)
-		echo 018   " displays 18 (decimal)
-<	Also, it is possible to use single quotes inside numbers to make them
-	easier to read: >
-		echo 1'000'000
-<	The quotes must be surrounded by digits.
-
-	Test for support with: >
-		has('vimscript-4')
-
-==============================================================================
-11. No +eval feature				*no-eval-feature*
-
-When the |+eval| feature was disabled at compile time, none of the expression
-evaluation commands are available.  To prevent this from causing Vim scripts
-to generate all kinds of errors, the ":if" and ":endif" commands are still
-recognized, though the argument of the ":if" and everything between the ":if"
-and the matching ":endif" is ignored.  Nesting of ":if" blocks is allowed, but
-only if the commands are at the start of the line.  The ":else" command is not
-recognized.
-
-Example of how to avoid executing commands when the |+eval| feature is
-missing: >
-
-	:if 1
-	:  echo "Expression evaluation is compiled in"
-	:else
-	:  echo "You will _never_ see this message"
-	:endif
-
-To execute a command only when the |+eval| feature is disabled can be done in
-two ways.  The simplest is to exit the script (or Vim) prematurely: >
-	if 1
-	   echo "commands executed with +eval"
-	   finish
-	endif
-	args  " command executed without +eval
-
-If you do not want to abort loading the script you can use a trick, as this
-example shows: >
-
-	silent! while 0
-	  set history=111
-	silent! endwhile
-
-When the |+eval| feature is available the command is skipped because of the
-"while 0".  Without the |+eval| feature the "while 0" is an error, which is
-silently ignored, and the command is executed.
-
-==============================================================================
-12. The sandbox					*eval-sandbox* *sandbox*
-
-The 'foldexpr', 'formatexpr', 'includeexpr', 'indentexpr', 'statusline' and
-'foldtext' options may be evaluated in a sandbox.  This means that you are
-protected from these expressions having nasty side effects.  This gives some
-safety for when these options are set from a modeline.  It is also used when
-the command from a tags file is executed and for CTRL-R = in the command line.
-The sandbox is also used for the |:sandbox| command.
-								*E48*
-These items are not allowed in the sandbox:
-	- changing the buffer text
-	- defining or changing mapping, autocommands, user commands
-	- setting certain options (see |option-summary|)
-	- setting certain v: variables (see |v:var|)  *E794*
-	- executing a shell command
-	- reading or writing a file
-	- jumping to another buffer or editing a file
-	- executing Python, Perl, etc. commands
-This is not guaranteed 100% secure, but it should block most attacks.
-
-							*:san* *:sandbox*
-:san[dbox] {cmd}	Execute {cmd} in the sandbox.  Useful to evaluate an
-			option that may have been set from a modeline, e.g.
-			'foldexpr'.
-
-							*sandbox-option*
-A few options contain an expression.  When this expression is evaluated it may
-have to be done in the sandbox to avoid a security risk.  But the sandbox is
-restrictive, thus this only happens when the option was set from an insecure
-location.  Insecure in this context are:
-- sourcing a .vimrc or .exrc in the current directory
-- while executing in the sandbox
-- value coming from a modeline
-- executing a function that was defined in the sandbox
-
-Note that when in the sandbox and saving an option value and restoring it, the
-option will still be marked as it was set in the sandbox.
-
-==============================================================================
-13. Textlock							*textlock*
-
-In a few situations it is not allowed to change the text in the buffer, jump
-to another window and some other things that might confuse or break what Vim
-is currently doing.  This mostly applies to things that happen when Vim is
-actually doing something else.  For example, evaluating the 'balloonexpr' may
-happen any moment the mouse cursor is resting at some position.
-
-This is not allowed when the textlock is active:
-	- changing the buffer text
-	- jumping to another buffer or window
-	- editing another file
-	- closing a window or quitting Vim
-	- etc.
-
-
- vim:tw=78:ts=8:noet:ft=help:norl:
+*eval.txt*	For Vim version 9.0.  Last change: 2023 Jun 01
+
+
+		  VIM REFERENCE MANUAL	  by Bram Moolenaar
+
+
+Expression evaluation			*expression* *expr* *E15* *eval*
+							*E1002*
+Using expressions is introduced in chapter 41 of the user manual |usr_41.txt|.
+
+Note: Expression evaluation can be disabled at compile time.  If this has been
+done, the features in this document are not available.  See |+eval| and
+|no-eval-feature|.
+
+This file is mainly about the backwards compatible (legacy) Vim script.  For
+specifics of Vim9 script, which can execute much faster, supports type
+checking and much more, see |vim9.txt|.  Where the syntax or semantics differ
+a remark is given.
+
+1.  Variables			|variables|
+    1.1 Variable types
+    1.2 Function references		|Funcref|
+    1.3 Lists				|Lists|
+    1.4 Dictionaries			|Dictionaries|
+    1.5 Blobs				|Blobs|
+    1.6 More about variables		|more-variables|
+2.  Expression syntax		|expression-syntax|
+3.  Internal variable		|internal-variables|
+4.  Builtin Functions		|functions|
+5.  Defining functions		|user-functions|
+6.  Curly braces names		|curly-braces-names|
+7.  Commands			|expression-commands|
+8.  Exception handling		|exception-handling|
+9.  Examples			|eval-examples|
+10. Vim script version		|vimscript-version|
+11. No +eval feature		|no-eval-feature|
+12. The sandbox			|eval-sandbox|
+13. Textlock			|textlock|
+
+Testing support is documented in |testing.txt|.
+Profiling is documented at |profiling|.
+
+==============================================================================
+1. Variables						*variables*
+
+1.1 Variable types ~
+					*E712* *E896* *E897* *E899* *E1098*
+					*E1107* *E1135* *E1138*
+There are ten types of variables:
+
+							*Number* *Integer*
+Number		A 32 or 64 bit signed number.  |expr-number|
+		The number of bits is available in |v:numbersize|.
+		Examples:  -123  0x10  0177  0o177 0b1011
+
+Float		A floating point number. |floating-point-format| *Float*
+		Examples: 123.456  1.15e-6  -1.1e3
+
+String		A NUL terminated string of 8-bit unsigned characters (bytes).
+		|expr-string| Examples: "ab\txx\"--"  'x-z''a,c'
+
+List		An ordered sequence of items, see |List| for details.
+		Example: [1, 2, ['a', 'b']]
+
+Dictionary	An associative, unordered array: Each entry has a key and a
+		value. |Dictionary|
+		Examples:
+			{'blue': "#0000ff", 'red': "#ff0000"}
+			#{blue: "#0000ff", red: "#ff0000"}
+
+Funcref		A reference to a function |Funcref|.
+		Example: function("strlen")
+		It can be bound to a dictionary and arguments, it then works
+		like a Partial.
+		Example: function("Callback", [arg], myDict)
+
+Special		|v:false|, |v:true|, |v:none| and |v:null|.  *Special*
+
+Job		Used for a job, see |job_start()|. *Job* *Jobs*
+
+Channel		Used for a channel, see |ch_open()|. *Channel* *Channels*
+
+Blob		Binary Large Object. Stores any sequence of bytes.  See |Blob|
+		for details
+		Example: 0zFF00ED015DAF
+		0z is an empty Blob.
+
+The Number and String types are converted automatically, depending on how they
+are used.
+
+Conversion from a Number to a String is by making the ASCII representation of
+the Number.  Examples:
+	Number 123	-->	String "123" ~
+	Number 0	-->	String "0" ~
+	Number -1	-->	String "-1" ~
+							*octal*
+Conversion from a String to a Number only happens in legacy Vim script, not in
+Vim9 script.  It is done by converting the first digits to a number.
+Hexadecimal "0xf9", Octal "017" or "0o17", and Binary "0b10"
+numbers are recognized
+NOTE: when using |Vim9| script or |scriptversion-4| octal with a leading "0"
+is not recognized.  The 0o notation requires patch 8.2.0886.
+If the String doesn't start with digits, the result is zero.
+Examples:
+	String "456"	-->	Number 456 ~
+	String "6bar"	-->	Number 6 ~
+	String "foo"	-->	Number 0 ~
+	String "0xf1"	-->	Number 241 ~
+	String "0100"	-->	Number 64 ~
+	String "0o100"	-->	Number 64 ~
+	String "0b101"	-->	Number 5 ~
+	String "-8"	-->	Number -8 ~
+	String "+8"	-->	Number 0 ~
+
+To force conversion from String to Number, add zero to it: >
+	:echo "0100" + 0
+<	64 ~
+
+To avoid a leading zero to cause octal conversion, or for using a different
+base, use |str2nr()|.
+
+						*TRUE* *FALSE* *Boolean*
+For boolean operators Numbers are used.  Zero is FALSE, non-zero is TRUE.
+You can also use |v:false| and |v:true|, in Vim9 script |false| and |true|.
+When TRUE is returned from a function it is the Number one, FALSE is the
+number zero.
+
+Note that in the command: >
+	:if "foo"
+	:" NOT executed
+"foo" is converted to 0, which means FALSE.  If the string starts with a
+non-zero number it means TRUE: >
+	:if "8foo"
+	:" executed
+To test for a non-empty string, use empty(): >
+	:if !empty("foo")
+
+<						*falsy* *truthy*
+An expression can be used as a condition, ignoring the type and only using
+whether the value is "sort of true" or "sort of false".  Falsy is:
+	the number zero
+	empty string, blob, list or dictionary
+Other values are truthy.  Examples:
+	0	falsy
+	1	truthy
+	-1	truthy
+	0.0	falsy
+	0.1	truthy
+	''	falsy
+	'x'	truthy
+	[]	falsy
+	[0]	truthy
+	{}	falsy
+	#{x: 1} truthy
+	0z	falsy
+	0z00	truthy
+
+							*non-zero-arg*
+Function arguments often behave slightly different from |TRUE|: If the
+argument is present and it evaluates to a non-zero Number, |v:true| or a
+non-empty String, then the value is considered to be TRUE.
+Note that " " and "0" are also non-empty strings, thus considered to be TRUE.
+A List, Dictionary or Float is not a Number or String, thus evaluate to FALSE.
+
+		*E611* *E745* *E728* *E703* *E729* *E730* *E731* *E908* *E910*
+		*E913* *E974* *E975* *E976* *E1319* *E1320* *E1321* *E1322*
+		*E1323* *E1324*
+|List|, |Dictionary|, |Funcref|, |Job|, |Channel|, |Blob|, |Class| and
+|object| types are not automatically converted.
+
+							*E805* *E806* *E808*
+When mixing Number and Float the Number is converted to Float.  Otherwise
+there is no automatic conversion of Float.  You can use str2float() for String
+to Float, printf() for Float to String and float2nr() for Float to Number.
+
+			*E362* *E891* *E892* *E893* *E894* *E907* *E911* *E914*
+When expecting a Float a Number can also be used, but nothing else.
+
+						*no-type-checking*
+You will not get an error if you try to change the type of a variable.
+
+
+1.2 Function references ~
+					*Funcref* *E695* *E718* *E1192*
+A Funcref variable is obtained with the |function()| function, the |funcref()|
+function, (in |Vim9| script) the name of a function, or created with the
+lambda expression |expr-lambda|.  It can be used in an expression in the place
+of a function name, before the parenthesis around the arguments, to invoke the
+function it refers to.  Example in |Vim9| script: >
+
+	:var Fn = MyFunc
+	:echo Fn()
+
+Legacy script: >
+	:let Fn = function("MyFunc")
+	:echo Fn()
+<							*E704* *E705* *E707*
+A Funcref variable must start with a capital, "s:", "w:", "t:" or "b:".  You
+can use "g:" but the following name must still start with a capital.  You
+cannot have both a Funcref variable and a function with the same name.
+
+A special case is defining a function and directly assigning its Funcref to a
+Dictionary entry.  Example: >
+	:function dict.init() dict
+	:   let self.val = 0
+	:endfunction
+
+The key of the Dictionary can start with a lower case letter.  The actual
+function name is not used here.  Also see |numbered-function|.
+
+A Funcref can also be used with the |:call| command: >
+	:call Fn()
+	:call dict.init()
+
+The name of the referenced function can be obtained with |string()|. >
+	:let func = string(Fn)
+
+You can use |call()| to invoke a Funcref and use a list variable for the
+arguments: >
+	:let r = call(Fn, mylist)
+<
+								*Partial*
+A Funcref optionally binds a Dictionary and/or arguments.  This is also called
+a Partial.  This is created by passing the Dictionary and/or arguments to
+function() or funcref().  When calling the function the Dictionary and/or
+arguments will be passed to the function.  Example: >
+
+	let Cb = function('Callback', ['foo'], myDict)
+	call Cb('bar')
+
+This will invoke the function as if using: >
+	call myDict.Callback('foo', 'bar')
+
+This is very useful when passing a function around, e.g. in the arguments of
+|ch_open()|.
+
+Note that binding a function to a Dictionary also happens when the function is
+a member of the Dictionary: >
+
+	let myDict.myFunction = MyFunction
+	call myDict.myFunction()
+
+Here MyFunction() will get myDict passed as "self".  This happens when the
+"myFunction" member is accessed.  When making assigning "myFunction" to
+otherDict and calling it, it will be bound to otherDict: >
+
+	let otherDict.myFunction = myDict.myFunction
+	call otherDict.myFunction()
+
+Now "self" will be "otherDict".  But when the dictionary was bound explicitly
+this won't happen: >
+
+	let myDict.myFunction = function(MyFunction, myDict)
+	let otherDict.myFunction = myDict.myFunction
+	call otherDict.myFunction()
+
+Here "self" will be "myDict", because it was bound explicitly.
+
+
+1.3 Lists ~
+						*list* *List* *Lists* *E686*
+A List is an ordered sequence of items.  An item can be of any type.  Items
+can be accessed by their index number.  Items can be added and removed at any
+position in the sequence.
+
+
+List creation ~
+							*E696* *E697*
+A List is created with a comma-separated list of items in square brackets.
+Examples: >
+	:let mylist = [1, two, 3, "four"]
+	:let emptylist = []
+
+An item can be any expression.  Using a List for an item creates a
+List of Lists: >
+	:let nestlist = [[11, 12], [21, 22], [31, 32]]
+
+An extra comma after the last item is ignored.
+
+
+List index ~
+							*list-index* *E684*
+An item in the List can be accessed by putting the index in square brackets
+after the List.  Indexes are zero-based, thus the first item has index zero. >
+	:let item = mylist[0]		" get the first item: 1
+	:let item = mylist[2]		" get the third item: 3
+
+When the resulting item is a list this can be repeated: >
+	:let item = nestlist[0][1]	" get the first list, second item: 12
+<
+A negative index is counted from the end.  Index -1 refers to the last item in
+the List, -2 to the last but one item, etc. >
+	:let last = mylist[-1]		" get the last item: "four"
+
+To avoid an error for an invalid index use the |get()| function.  When an item
+is not available it returns zero or the default value you specify: >
+	:echo get(mylist, idx)
+	:echo get(mylist, idx, "NONE")
+
+
+List concatenation ~
+							*list-concatenation*
+Two lists can be concatenated with the "+" operator: >
+	:let longlist = mylist + [5, 6]
+	:let mylist += [7, 8]
+
+To prepend or append an item, turn the item into a list by putting [] around
+it.  To change a list in-place, refer to |list-modification| below.
+
+
+Sublist ~
+							*sublist*
+A part of the List can be obtained by specifying the first and last index,
+separated by a colon in square brackets: >
+	:let shortlist = mylist[2:-1]	" get List [3, "four"]
+
+Omitting the first index is similar to zero.  Omitting the last index is
+similar to -1. >
+	:let endlist = mylist[2:]	" from item 2 to the end: [3, "four"]
+	:let shortlist = mylist[2:2]	" List with one item: [3]
+	:let otherlist = mylist[:]	" make a copy of the List
+
+Notice that the last index is inclusive.  If you prefer using an exclusive
+index use the |slice()| method.
+
+If the first index is beyond the last item of the List or the second item is
+before the first item, the result is an empty list.  There is no error
+message.
+
+If the second index is equal to or greater than the length of the list the
+length minus one is used: >
+	:let mylist = [0, 1, 2, 3]
+	:echo mylist[2:8]		" result: [2, 3]
+
+NOTE: mylist[s:e] means using the variable "s:e" as index.  Watch out for
+using a single letter variable before the ":".  Insert a space when needed:
+mylist[s : e].
+
+
+List identity ~
+							*list-identity*
+When variable "aa" is a list and you assign it to another variable "bb", both
+variables refer to the same list.  Thus changing the list "aa" will also
+change "bb": >
+	:let aa = [1, 2, 3]
+	:let bb = aa
+	:call add(aa, 4)
+	:echo bb
+<	[1, 2, 3, 4]
+
+Making a copy of a list is done with the |copy()| function.  Using [:] also
+works, as explained above.  This creates a shallow copy of the list: Changing
+a list item in the list will also change the item in the copied list: >
+	:let aa = [[1, 'a'], 2, 3]
+	:let bb = copy(aa)
+	:call add(aa, 4)
+	:let aa[0][1] = 'aaa'
+	:echo aa
+<	[[1, aaa], 2, 3, 4] >
+	:echo bb
+<	[[1, aaa], 2, 3]
+
+To make a completely independent list use |deepcopy()|.  This also makes a
+copy of the values in the list, recursively.  Up to a hundred levels deep.
+
+The operator "is" can be used to check if two variables refer to the same
+List.  "isnot" does the opposite.  In contrast "==" compares if two lists have
+the same value. >
+	:let alist = [1, 2, 3]
+	:let blist = [1, 2, 3]
+	:echo alist is blist
+<	0 >
+	:echo alist == blist
+<	1
+
+Note about comparing lists: Two lists are considered equal if they have the
+same length and all items compare equal, as with using "==".  There is one
+exception: When comparing a number with a string they are considered
+different.  There is no automatic type conversion, as with using "==" on
+variables.  Example: >
+	echo 4 == "4"
+<	1 >
+	echo [4] == ["4"]
+<	0
+
+Thus comparing Lists is more strict than comparing numbers and strings.  You
+can compare simple values this way too by putting them in a list: >
+
+	:let a = 5
+	:let b = "5"
+	:echo a == b
+<	1 >
+	:echo [a] == [b]
+<	0
+
+
+List unpack ~
+
+To unpack the items in a list to individual variables, put the variables in
+square brackets, like list items: >
+	:let [var1, var2] = mylist
+
+When the number of variables does not match the number of items in the list
+this produces an error.  To handle any extra items from the list append ";"
+and a variable name: >
+	:let [var1, var2; rest] = mylist
+
+This works like: >
+	:let var1 = mylist[0]
+	:let var2 = mylist[1]
+	:let rest = mylist[2:]
+
+Except that there is no error if there are only two items.  "rest" will be an
+empty list then.
+
+
+List modification ~
+							*list-modification*
+To change a specific item of a list use |:let| this way: >
+	:let list[4] = "four"
+	:let listlist[0][3] = item
+
+To change part of a list you can specify the first and last item to be
+modified.  The value must at least have the number of items in the range: >
+	:let list[3:5] = [3, 4, 5]
+
+Adding and removing items from a list is done with functions.  Here are a few
+examples: >
+	:call insert(list, 'a')		" prepend item 'a'
+	:call insert(list, 'a', 3)	" insert item 'a' before list[3]
+	:call add(list, "new")		" append String item
+	:call add(list, [1, 2])		" append a List as one new item
+	:call extend(list, [1, 2])	" extend the list with two more items
+	:let i = remove(list, 3)	" remove item 3
+	:unlet list[3]			" idem
+	:let l = remove(list, 3, -1)	" remove items 3 to last item
+	:unlet list[3 : ]		" idem
+	:call filter(list, 'v:val !~ "x"')  " remove items with an 'x'
+
+Changing the order of items in a list: >
+	:call sort(list)		" sort a list alphabetically
+	:call reverse(list)		" reverse the order of items
+	:call uniq(sort(list))		" sort and remove duplicates
+
+
+For loop ~
+
+The |:for| loop executes commands for each item in a List, String or Blob.
+A variable is set to each item in sequence.  Example with a List: >
+	:for item in mylist
+	:   call Doit(item)
+	:endfor
+
+This works like: >
+	:let index = 0
+	:while index < len(mylist)
+	:   let item = mylist[index]
+	:   :call Doit(item)
+	:   let index = index + 1
+	:endwhile
+
+If all you want to do is modify each item in the list then the |map()|
+function will be a simpler method than a for loop.
+
+Just like the |:let| command, |:for| also accepts a list of variables.  This
+requires the argument to be a List of Lists. >
+	:for [lnum, col] in [[1, 3], [2, 8], [3, 0]]
+	:   call Doit(lnum, col)
+	:endfor
+
+This works like a |:let| command is done for each list item.  Again, the types
+must remain the same to avoid an error.
+
+It is also possible to put remaining items in a List variable: >
+	:for [i, j; rest] in listlist
+	:   call Doit(i, j)
+	:   if !empty(rest)
+	:      echo "remainder: " .. string(rest)
+	:   endif
+	:endfor
+
+For a Blob one byte at a time is used.
+
+For a String one character, including any composing characters, is used as a
+String.  Example: >
+	for c in text
+	  echo 'This character is ' .. c
+	endfor
+
+
+List functions ~
+						*E714*
+Functions that are useful with a List: >
+	:let r = call(funcname, list)	" call a function with an argument list
+	:if empty(list)			" check if list is empty
+	:let l = len(list)		" number of items in list
+	:let big = max(list)		" maximum value in list
+	:let small = min(list)		" minimum value in list
+	:let xs = count(list, 'x')	" count nr of times 'x' appears in list
+	:let i = index(list, 'x')	" index of first 'x' in list
+	:let lines = getline(1, 10)	" get ten text lines from buffer
+	:call append('$', lines)	" append text lines in buffer
+	:let list = split("a b c")	" create list from items in a string
+	:let string = join(list, ', ')	" create string from list items
+	:let s = string(list)		" String representation of list
+	:call map(list, '">> " .. v:val')  " prepend ">> " to each item
+
+Don't forget that a combination of features can make things simple.  For
+example, to add up all the numbers in a list: >
+	:exe 'let sum = ' .. join(nrlist, '+')
+
+
+1.4 Dictionaries ~
+				*dict* *Dict* *Dictionaries* *Dictionary*
+A Dictionary is an associative array: Each entry has a key and a value.  The
+entry can be located with the key.  The entries are stored without a specific
+ordering.
+
+
+Dictionary creation ~
+						*E720* *E721* *E722* *E723*
+A Dictionary is created with a comma-separated list of entries in curly
+braces.  Each entry has a key and a value, separated by a colon.  Each key can
+only appear once.  Examples: >
+	:let mydict = {1: 'one', 2: 'two', 3: 'three'}
+	:let emptydict = {}
+<							*E713* *E716* *E717*
+A key is always a String.  You can use a Number, it will be converted to a
+String automatically.  Thus the String '4' and the number 4 will find the same
+entry.  Note that the String '04' and the Number 04 are different, since the
+Number will be converted to the String '4', leading zeros are dropped.  The
+empty string can also be used as a key.
+
+In |Vim9| script a literal key can be used if it consists only of alphanumeric
+characters, underscore and dash, see |vim9-literal-dict|.
+						*literal-Dict* *#{}*
+To avoid having to put quotes around every key the #{} form can be used in
+legacy script.  This does require the key to consist only of ASCII letters,
+digits, '-' and '_'.  Example: >
+	:let mydict = #{zero: 0, one_key: 1, two-key: 2, 333: 3}
+Note that 333 here is the string "333".  Empty keys are not possible with #{}.
+In |Vim9| script the #{} form cannot be used because it can be confused with
+the start of a comment.
+
+A value can be any expression.  Using a Dictionary for a value creates a
+nested Dictionary: >
+	:let nestdict = {1: {11: 'a', 12: 'b'}, 2: {21: 'c'}}
+
+An extra comma after the last entry is ignored.
+
+
+Accessing entries ~
+
+The normal way to access an entry is by putting the key in square brackets: >
+	:let val = mydict["one"]
+	:let mydict["four"] = 4
+
+You can add new entries to an existing Dictionary this way, unlike Lists.
+
+For keys that consist entirely of letters, digits and underscore the following
+form can be used |expr-entry|: >
+	:let val = mydict.one
+	:let mydict.four = 4
+
+Since an entry can be any type, also a List and a Dictionary, the indexing and
+key lookup can be repeated: >
+	:echo dict.key[idx].key
+
+
+Dictionary to List conversion ~
+
+You may want to loop over the entries in a dictionary.  For this you need to
+turn the Dictionary into a List and pass it to |:for|.
+
+Most often you want to loop over the keys, using the |keys()| function: >
+	:for key in keys(mydict)
+	:   echo key .. ': ' .. mydict[key]
+	:endfor
+
+The List of keys is unsorted.  You may want to sort them first: >
+	:for key in sort(keys(mydict))
+
+To loop over the values use the |values()| function:  >
+	:for v in values(mydict)
+	:   echo "value: " .. v
+	:endfor
+
+If you want both the key and the value use the |items()| function.  It returns
+a List in which each item is a List with two items, the key and the value: >
+	:for [key, value] in items(mydict)
+	:   echo key .. ': ' .. value
+	:endfor
+
+
+Dictionary identity ~
+							*dict-identity*
+Just like Lists you need to use |copy()| and |deepcopy()| to make a copy of a
+Dictionary.  Otherwise, assignment results in referring to the same
+Dictionary: >
+	:let onedict = {'a': 1, 'b': 2}
+	:let adict = onedict
+	:let adict['a'] = 11
+	:echo onedict['a']
+	11
+
+Two Dictionaries compare equal if all the key-value pairs compare equal.  For
+more info see |list-identity|.
+
+
+Dictionary modification ~
+							*dict-modification*
+To change an already existing entry of a Dictionary, or to add a new entry,
+use |:let| this way: >
+	:let dict[4] = "four"
+	:let dict['one'] = item
+
+Removing an entry from a Dictionary is done with |remove()| or |:unlet|.
+Three ways to remove the entry with key "aaa" from dict: >
+	:let i = remove(dict, 'aaa')
+	:unlet dict.aaa
+	:unlet dict['aaa']
+
+Merging a Dictionary with another is done with |extend()|: >
+	:call extend(adict, bdict)
+This extends adict with all entries from bdict.  Duplicate keys cause entries
+in adict to be overwritten.  An optional third argument can change this.
+Note that the order of entries in a Dictionary is irrelevant, thus don't
+expect ":echo adict" to show the items from bdict after the older entries in
+adict.
+
+Weeding out entries from a Dictionary can be done with |filter()|: >
+	:call filter(dict, 'v:val =~ "x"')
+This removes all entries from "dict" with a value not matching 'x'.
+This can also be used to remove all entries: >
+	call filter(dict, 0)
+
+In some situations it is not allowed to remove or add entries to a Dictionary.
+Especially when iterating over all the entries.  You will get *E1313* or
+another error in that case.
+
+
+Dictionary function ~
+				*Dictionary-function* *self* *E725* *E862*
+When a function is defined with the "dict" attribute it can be used in a
+special way with a dictionary.  Example: >
+	:function Mylen() dict
+	:   return len(self.data)
+	:endfunction
+	:let mydict = {'data': [0, 1, 2, 3], 'len': function("Mylen")}
+	:echo mydict.len()
+
+This is like a method in object oriented programming.  The entry in the
+Dictionary is a |Funcref|.  The local variable "self" refers to the dictionary
+the function was invoked from.  When using |Vim9| script you can use classes
+and objects, see `:class`.
+
+It is also possible to add a function without the "dict" attribute as a
+Funcref to a Dictionary, but the "self" variable is not available then.
+
+				*numbered-function* *anonymous-function*
+To avoid the extra name for the function it can be defined and directly
+assigned to a Dictionary in this way: >
+	:let mydict = {'data': [0, 1, 2, 3]}
+	:function mydict.len()
+	:   return len(self.data)
+	:endfunction
+	:echo mydict.len()
+
+The function will then get a number and the value of dict.len is a |Funcref|
+that references this function.  The function can only be used through a
+|Funcref|.  It will automatically be deleted when there is no |Funcref|
+remaining that refers to it.
+
+It is not necessary to use the "dict" attribute for a numbered function.
+
+If you get an error for a numbered function, you can find out what it is with
+a trick.  Assuming the function is 42, the command is: >
+	:function g:42
+
+
+Functions for Dictionaries ~
+							*E715*
+Functions that can be used with a Dictionary: >
+	:if has_key(dict, 'foo')	" TRUE if dict has entry with key "foo"
+	:if empty(dict)			" TRUE if dict is empty
+	:let l = len(dict)		" number of items in dict
+	:let big = max(dict)		" maximum value in dict
+	:let small = min(dict)		" minimum value in dict
+	:let xs = count(dict, 'x')	" count nr of times 'x' appears in dict
+	:let s = string(dict)		" String representation of dict
+	:call map(dict, '">> " .. v:val')  " prepend ">> " to each item
+
+
+1.5 Blobs ~
+						*blob* *Blob* *Blobs* *E978*
+A Blob is a binary object.  It can be used to read an image from a file and
+send it over a channel, for example.
+
+A Blob mostly behaves like a |List| of numbers, where each number has the
+value of an 8-bit byte, from 0 to 255.
+
+
+Blob creation ~
+
+A Blob can be created with a |blob-literal|: >
+	:let b = 0zFF00ED015DAF
+Dots can be inserted between bytes (pair of hex characters) for readability,
+they don't change the value: >
+	:let b = 0zFF00.ED01.5DAF
+
+A blob can be read from a file with |readfile()| passing the {type} argument
+set to "B", for example: >
+	:let b = readfile('image.png', 'B')
+
+A blob can be read from a channel with the |ch_readblob()| function.
+
+
+Blob index ~
+							*blob-index* *E979*
+A byte in the Blob can be accessed by putting the index in square brackets
+after the Blob.  Indexes are zero-based, thus the first byte has index zero. >
+	:let myblob = 0z00112233
+	:let byte = myblob[0]		" get the first byte: 0x00
+	:let byte = myblob[2]		" get the third byte: 0x22
+
+A negative index is counted from the end.  Index -1 refers to the last byte in
+the Blob, -2 to the last but one byte, etc. >
+	:let last = myblob[-1]		" get the last byte: 0x33
+
+To avoid an error for an invalid index use the |get()| function.  When an item
+is not available it returns -1 or the default value you specify: >
+	:echo get(myblob, idx)
+	:echo get(myblob, idx, 999)
+
+
+Blob iteration ~
+
+The |:for| loop executes commands for each byte of a Blob.  The loop variable is
+set to each byte in the Blob.  Example: >
+	:for byte in 0z112233
+	:   call Doit(byte)
+	:endfor
+This calls Doit() with 0x11, 0x22 and 0x33.
+
+
+Blob concatenation ~
+
+Two blobs can be concatenated with the "+" operator: >
+	:let longblob = myblob + 0z4455
+	:let myblob += 0z6677
+
+To change a blob in-place see |blob-modification| below.
+
+
+Part of a blob ~
+
+A part of the Blob can be obtained by specifying the first and last index,
+separated by a colon in square brackets: >
+	:let myblob = 0z00112233
+	:let shortblob = myblob[1:2]	" get 0z1122
+	:let shortblob = myblob[2:-1]	" get 0z2233
+
+Omitting the first index is similar to zero.  Omitting the last index is
+similar to -1. >
+	:let endblob = myblob[2:]	" from item 2 to the end: 0z2233
+	:let shortblob = myblob[2:2]	" Blob with one byte: 0z22
+	:let otherblob = myblob[:]	" make a copy of the Blob
+
+If the first index is beyond the last byte of the Blob or the second index is
+before the first index, the result is an empty Blob.  There is no error
+message.
+
+If the second index is equal to or greater than the length of the list the
+length minus one is used: >
+	:echo myblob[2:8]		" result: 0z2233
+
+
+Blob modification ~
+					*blob-modification* *E1182* *E1184*
+To change a specific byte of a blob use |:let| this way: >
+	:let blob[4] = 0x44
+
+When the index is just one beyond the end of the Blob, it is appended. Any
+higher index is an error.
+
+To change a sequence of bytes the [:] notation can be used: >
+	let blob[1:3] = 0z445566
+The length of the replaced bytes must be exactly the same as the value
+provided. *E972*
+
+To change part of a blob you can specify the first and last byte to be
+modified.  The value must have the same number of bytes in the range: >
+	:let blob[3:5] = 0z334455
+
+You can also use the functions |add()|, |remove()| and |insert()|.
+
+
+Blob identity ~
+
+Blobs can be compared for equality: >
+	if blob == 0z001122
+And for equal identity: >
+	if blob is otherblob
+<							*blob-identity* *E977*
+When variable "aa" is a Blob and you assign it to another variable "bb", both
+variables refer to the same Blob.  Then the "is" operator returns true.
+
+When making a copy using [:] or |copy()| the values are the same, but the
+identity is different: >
+	:let blob = 0z112233
+	:let blob2 = blob
+	:echo blob == blob2
+<	1 >
+	:echo blob is blob2
+<	1 >
+	:let blob3 = blob[:]
+	:echo blob == blob3
+<	1 >
+	:echo blob is blob3
+<	0
+
+Making a copy of a Blob is done with the |copy()| function.  Using [:] also
+works, as explained above.
+
+
+1.6 More about variables ~
+							*more-variables*
+If you need to know the type of a variable or expression, use the |type()|
+function.
+
+When the '!' flag is included in the 'viminfo' option, global variables that
+start with an uppercase letter, and don't contain a lowercase letter, are
+stored in the viminfo file |viminfo-file|.
+
+When the 'sessionoptions' option contains "global", global variables that
+start with an uppercase letter and contain at least one lowercase letter are
+stored in the session file |session-file|.
+
+variable name		can be stored where ~
+my_var_6		not
+My_Var_6		session file
+MY_VAR_6		viminfo file
+
+
+In legacy script it is possible to form a variable name with curly braces, see
+|curly-braces-names|.
+
+==============================================================================
+2. Expression syntax					*expression-syntax*
+							*E1143*
+Expression syntax summary, from least to most significant:
+
+|expr1|	expr2
+	expr2 ? expr1 : expr1	if-then-else
+
+|expr2|	expr3
+	expr3 || expr3 ...	logical OR
+
+|expr3|	expr4
+	expr4 && expr4 ...	logical AND
+
+|expr4|	expr5
+	expr5 == expr5		equal
+	expr5 != expr5		not equal
+	expr5 >	 expr5		greater than
+	expr5 >= expr5		greater than or equal
+	expr5 <	 expr5		smaller than
+	expr5 <= expr5		smaller than or equal
+	expr5 =~ expr5		regexp matches
+	expr5 !~ expr5		regexp doesn't match
+
+	expr5 ==? expr5		equal, ignoring case
+	expr5 ==# expr5		equal, match case
+	etc.			As above, append ? for ignoring case, # for
+				matching case
+
+	expr5 is expr5		same |List|, |Dictionary| or |Blob| instance
+	expr5 isnot expr5	different |List|, |Dictionary| or |Blob|
+				instance
+
+|expr5|	expr6 << expr6		bitwise left shift
+	expr6 >> expr6		bitwise right shift
+
+|expr6|	expr7
+	expr7 +	 expr7 ...	number addition, list or blob concatenation
+	expr7 -	 expr7 ...	number subtraction
+	expr7 .	 expr7 ...	string concatenation
+	expr7 .. expr7 ...	string concatenation
+
+|expr7|	expr8
+	expr8 *	 expr8 ...	number multiplication
+	expr8 /	 expr8 ...	number division
+	expr8 %	 expr8 ...	number modulo
+
+|expr8|	expr9
+	<type>expr9		type check and conversion (|Vim9| only)
+
+|expr9|	expr10
+	! expr9			logical NOT
+	- expr9			unary minus
+	+ expr9			unary plus
+
+|expr10|  expr11
+	expr10[expr1]		byte of a String or item of a |List|
+	expr10[expr1 : expr1]	substring of a String or sublist of a |List|
+	expr10.name		entry in a |Dictionary|
+	expr10(expr1, ...)	function call with |Funcref| variable
+	expr10->name(expr1, ...)	|method| call
+
+|expr11|  number		number constant
+	"string"		string constant, backslash is special
+	'string'		string constant, ' is doubled
+	[expr1, ...]		|List|
+	{expr1: expr1, ...}	|Dictionary|
+	#{key: expr1, ...}	legacy |Dictionary|
+	&option			option value
+	(expr1)			nested expression
+	variable		internal variable
+	va{ria}ble		internal variable with curly braces
+	$VAR			environment variable
+	@r			contents of register 'r'
+	function(expr1, ...)	function call
+	func{ti}on(expr1, ...)	function call with curly braces
+	{args -> expr1}		legacy lambda expression
+	(args) => expr1		Vim9 lambda expression
+
+
+"..." indicates that the operations in this level can be concatenated.
+Example: >
+	&nu || &list && &shell == "csh"
+
+All expressions within one level are parsed from left to right.
+
+Expression nesting is limited to 1000 levels deep (300 when build with MSVC)
+to avoid running out of stack and crashing. *E1169*
+
+
+expr1				*expr1* *ternary* *falsy-operator* *??* *E109*
+-----
+
+The ternary operator: expr2 ? expr1 : expr1
+The falsy operator:   expr2 ?? expr1
+
+Ternary operator ~
+
+In legacy script the expression before the '?' is evaluated to a number.  If
+it evaluates to |TRUE|, the result is the value of the expression between the
+'?' and ':', otherwise the result is the value of the expression after the
+':'.
+
+In |Vim9| script the first expression must evaluate to a boolean, see
+|vim9-boolean|.
+
+Example: >
+	:echo lnum == 1 ? "top" : lnum
+
+Since the first expression is an "expr2", it cannot contain another ?:.  The
+other two expressions can, thus allow for recursive use of ?:.
+Example: >
+	:echo lnum == 1 ? "top" : lnum == 1000 ? "last" : lnum
+
+To keep this readable, using |line-continuation| is suggested: >
+	:echo lnum == 1
+	:\	? "top"
+	:\	: lnum == 1000
+	:\		? "last"
+	:\		: lnum
+
+You should always put a space before the ':', otherwise it can be mistaken for
+use in a variable such as "a:1".
+
+Falsy operator ~
+
+This is also known as the "null coalescing operator", but that's too
+complicated, thus we just call it the falsy operator.
+
+The expression before the '??' is evaluated.  If it evaluates to
+|truthy|, this is used as the result.  Otherwise the expression after the '??'
+is evaluated and used as the result.  This is most useful to have a default
+value for an expression that may result in zero or empty: >
+	echo theList ?? 'list is empty'
+	echo GetName() ?? 'unknown'
+
+These are similar, but not equal: >
+	expr2 ?? expr1
+	expr2 ? expr2 : expr1
+In the second line "expr2" is evaluated twice.  And in |Vim9| script the type
+of expr2 before "?" must be a boolean.
+
+
+expr2 and expr3						*expr2* *expr3*
+---------------
+
+expr3 || expr3 ..	logical OR		*expr-barbar*
+expr4 && expr4 ..	logical AND		*expr-&&*
+
+The "||" and "&&" operators take one argument on each side.
+
+In legacy script the arguments are (converted to) Numbers.
+
+In |Vim9| script the values must be boolean, see |vim9-boolean|.  Use "!!" to
+convert any type to a boolean.
+
+The result is:
+    input			 output ~
+n1	n2		n1 || n2	n1 && n2 ~
+|FALSE|	|FALSE|		|FALSE|		|FALSE|
+|FALSE|	|TRUE|		|TRUE|		|FALSE|
+|TRUE|	|FALSE|		|TRUE|		|FALSE|
+|TRUE|	|TRUE|		|TRUE|		|TRUE|
+
+The operators can be concatenated, for example: >
+
+	&nu || &list && &shell == "csh"
+
+Note that "&&" takes precedence over "||", so this has the meaning of: >
+
+	&nu || (&list && &shell == "csh")
+
+Once the result is known, the expression "short-circuits", that is, further
+arguments are not evaluated.  This is like what happens in C.  For example: >
+
+	let a = 1
+	echo a || b
+
+This is valid even if there is no variable called "b" because "a" is |TRUE|,
+so the result must be |TRUE|.  Similarly below: >
+
+	echo exists("b") && b == "yes"
+
+This is valid whether "b" has been defined or not.  The second clause will
+only be evaluated if "b" has been defined.
+
+
+expr4							*expr4* *E1153*
+-----
+
+expr5 {cmp} expr5
+
+Compare two expr5 expressions.  In legacy script the result is a 0 if it
+evaluates to false, or 1 if it evaluates to true.  In |Vim9| script the result
+is |true| or |false|.
+
+			*expr-==*  *expr-!=*  *expr->*	 *expr->=*
+			*expr-<*   *expr-<=*  *expr-=~*  *expr-!~*
+			*expr-==#* *expr-!=#* *expr->#*  *expr->=#*
+			*expr-<#*  *expr-<=#* *expr-=~#* *expr-!~#*
+			*expr-==?* *expr-!=?* *expr->?*  *expr->=?*
+			*expr-<?*  *expr-<=?* *expr-=~?* *expr-!~?*
+			*expr-is* *expr-isnot* *expr-is#* *expr-isnot#*
+			*expr-is?* *expr-isnot?* *E1072*
+		use 'ignorecase'    match case	   ignore case ~
+equal			==		==#		==?
+not equal		!=		!=#		!=?
+greater than		>		>#		>?
+greater than or equal	>=		>=#		>=?
+smaller than		<		<#		<?
+smaller than or equal	<=		<=#		<=?
+regexp matches		=~		=~#		=~?
+regexp doesn't match	!~		!~#		!~?
+same instance		is		is#		is?
+different instance	isnot		isnot#		isnot?
+
+Examples:
+"abc" ==# "Abc"	  evaluates to 0
+"abc" ==? "Abc"	  evaluates to 1
+"abc" == "Abc"	  evaluates to 1 if 'ignorecase' is set, 0 otherwise
+NOTE: In |Vim9| script 'ignorecase' is not used.
+
+							*E691* *E692*
+A |List| can only be compared with a |List| and only "equal", "not equal",
+"is" and "isnot" can be used.  This compares the values of the list,
+recursively.  Ignoring case means case is ignored when comparing item values.
+
+							*E735* *E736*
+A |Dictionary| can only be compared with a |Dictionary| and only "equal", "not
+equal", "is" and "isnot" can be used.  This compares the key/values of the
+|Dictionary| recursively.  Ignoring case means case is ignored when comparing
+item values.
+
+							*E694*
+A |Funcref| can only be compared with a |Funcref| and only "equal", "not
+equal", "is" and "isnot" can be used.  Case is never ignored.  Whether
+arguments or a Dictionary are bound (with a partial) matters.  The
+Dictionaries must also be equal (or the same, in case of "is") and the
+arguments must be equal (or the same).
+
+To compare Funcrefs to see if they refer to the same function, ignoring bound
+Dictionary and arguments, use |get()| to get the function name: >
+	if get(Part1, 'name') == get(Part2, 'name')
+	   " Part1 and Part2 refer to the same function
+<							*E1037*
+Using "is" or "isnot" with a |List|, |Dictionary| or |Blob| checks whether
+the expressions are referring to the same |List|, |Dictionary| or |Blob|
+instance.  A copy of a |List| is different from the original |List|.  When
+using "is" without a |List|, |Dictionary| or |Blob|, it is equivalent to
+using "equal", using "isnot" equivalent to using "not equal".  Except that
+a different type means the values are different: >
+	echo 4 == '4'
+	1
+	echo 4 is '4'
+	0
+	echo 0 is []
+	0
+"is#"/"isnot#" and "is?"/"isnot?" can be used to match and ignore case.
+In |Vim9| script this doesn't work, two strings are never identical.
+
+In legacy script, when comparing a String with a Number, the String is
+converted to a Number, and the comparison is done on Numbers.  This means
+that: >
+	echo 0 == 'x'
+	1
+because 'x' converted to a Number is zero.  However: >
+	echo [0] == ['x']
+	0
+Inside a List or Dictionary this conversion is not used.
+
+In |Vim9| script the types must match.
+
+When comparing two Strings, this is done with strcmp() or stricmp().  This
+results in the mathematical difference (comparing byte values), not
+necessarily the alphabetical difference in the local language.
+
+When using the operators with a trailing '#', or the short version and
+'ignorecase' is off, the comparing is done with strcmp(): case matters.
+
+When using the operators with a trailing '?', or the short version and
+'ignorecase' is set, the comparing is done with stricmp(): case is ignored.
+
+'smartcase' is not used.
+
+The "=~" and "!~" operators match the lefthand argument with the righthand
+argument, which is used as a pattern.  See |pattern| for what a pattern is.
+This matching is always done like 'magic' was set and 'cpoptions' is empty, no
+matter what the actual value of 'magic' or 'cpoptions' is.  This makes scripts
+portable.  To avoid backslashes in the regexp pattern to be doubled, use a
+single-quote string, see |literal-string|.
+Since a string is considered to be a single line, a multi-line pattern
+(containing \n, backslash-n) will not match.  However, a literal NL character
+can be matched like an ordinary character.  Examples:
+	"foo\nbar" =~ "\n"	evaluates to 1
+	"foo\nbar" =~ "\\n"	evaluates to 0
+
+
+expr5						*expr5* *bitwise-shift*
+-----
+expr6 << expr6	bitwise left shift				*expr-<<*
+expr6 >> expr6	bitwise right shift				*expr->>*
+							*E1282* *E1283*
+The "<<" and ">>" operators can be used to perform bitwise left or right shift
+of the left operand by the number of bits specified by the right operand.  The
+operands are used as positive numbers.  When shifting right with ">>" the
+topmost bit (sometimes called the sign bit) is cleared.  If the right operand
+(shift amount) is more than the maximum number of bits in a number
+(|v:numbersize|) the result is zero.
+
+
+expr6 and expr7				*expr6* *expr7* *E1036* *E1051*
+---------------
+expr7 + expr7   Number addition, |List| or |Blob| concatenation	*expr-+*
+expr7 - expr7   Number subtraction				*expr--*
+expr7 . expr7   String concatenation				*expr-.*
+expr7 .. expr7  String concatenation				*expr-..*
+
+For |Lists| only "+" is possible and then both expr7 must be a list.  The
+result is a new list with the two lists Concatenated.
+
+For String concatenation ".." is preferred, since "." is ambiguous, it is also
+used for |Dict| member access and floating point numbers.
+In |Vim9| script and when |vimscript-version| is 2 or higher, using "." is not
+allowed.
+
+In |Vim9| script the arguments of ".." are converted to String for simple
+types: Number, Float, Special and Bool.  For other types |string()| should be
+used.
+
+expr8 * expr8  Number multiplication				*expr-star*
+expr8 / expr8  Number division					*expr-/*
+expr8 % expr8  Number modulo					*expr-%*
+
+In legacy script, for all operators except "." and "..", Strings are converted
+to Numbers.
+
+For bitwise operators see |and()|, |or()| and |xor()|.
+
+Note the difference between "+" and ".." in legacy script:
+	"123" + "456" = 579
+	"123" .. "456" = "123456"
+
+Since '..' has the same precedence as '+' and '-', you need to read: >
+	1 .. 90 + 90.0
+As: >
+	(1 .. 90) + 90.0
+That works in legacy script, since the String "190" is automatically converted
+to the Number 190, which can be added to the Float 90.0.  However: >
+	1 .. 90 * 90.0
+Should be read as: >
+	1 .. (90 * 90.0)
+Since '..' has lower precedence than '*'.  This does NOT work, since this
+attempts to concatenate a Float and a String.
+
+When dividing a Number by zero the result depends on the value:
+	  0 / 0  = -0x80000000	(like NaN for Float)
+	 >0 / 0  =  0x7fffffff	(like positive infinity)
+	 <0 / 0  = -0x7fffffff	(like negative infinity)
+	(before Vim 7.2 it was always 0x7fffffff)
+In |Vim9| script dividing a number by zero is an error.	*E1154*
+
+When 64-bit Number support is enabled:
+	  0 / 0  = -0x8000000000000000	(like NaN for Float)
+	 >0 / 0  =  0x7fffffffffffffff	(like positive infinity)
+	 <0 / 0  = -0x7fffffffffffffff	(like negative infinity)
+
+When the righthand side of '%' is zero, the result is 0.
+
+None of these work for |Funcref|s.
+
+".", ".." and "%" do not work for Float. *E804* *E1035*
+
+
+expr8							*expr8*
+-----
+<type>expr9
+
+This is only available in |Vim9| script, see |type-casting|.
+
+
+expr9							*expr9*
+-----
+! expr9			logical NOT		*expr-!*
+- expr9			unary minus		*expr-unary--*
++ expr9			unary plus		*expr-unary-+*
+
+For '!' |TRUE| becomes |FALSE|, |FALSE| becomes |TRUE| (one).
+For '-' the sign of the number is changed.
+For '+' the number is unchanged.  Note: "++" has no effect.
+
+In legacy script a String will be converted to a Number first.  Note that if
+the string does not start with a digit you likely don't get what you expect.
+
+In |Vim9| script an error is given when "-" or "+" is used and the type is not
+a number.
+
+In |Vim9| script "!" can be used for any type and the result is always a
+boolean.  Use "!!" to convert any type to a boolean, according to whether the
+value is |falsy|.
+
+These three can be repeated and mixed.  Examples:
+	!-1	    == 0
+	!!8	    == 1
+	--9	    == 9
+
+
+expr10							*expr10*
+------
+This expression is either |expr11| or a sequence of the alternatives below,
+in any order.  E.g., these are all possible:
+	expr10[expr1].name
+	expr10.name[expr1]
+	expr10(expr1, ...)[expr1].name
+	expr10->(expr1, ...)[expr1]
+Evaluation is always from left to right.
+
+expr10[expr1]		item of String or |List|	*expr-[]* *E111*
+						*E909* *subscript* *E1062*
+In legacy Vim script:
+If expr10 is a Number or String this results in a String that contains the
+expr1'th single byte from expr10.  expr10 is used as a String (a number is
+automatically converted to a String), expr1 as a Number.  This doesn't
+recognize multibyte encodings, see `byteidx()` for an alternative, or use
+`split()` to turn the string into a list of characters.  Example, to get the
+byte under the cursor: >
+	:let c = getline(".")[col(".") - 1]
+
+In |Vim9| script:					*E1147* *E1148*
+If expr10 is a String this results in a String that contains the expr1'th
+single character (including any composing characters) from expr10.  To use byte
+indexes use |strpart()|.
+
+Index zero gives the first byte or character.  Careful: text column numbers
+start with one!
+
+If the length of the String is less than the index, the result is an empty
+String.  A negative index always results in an empty string (reason: backward
+compatibility).  Use [-1:] to get the last byte or character.
+In Vim9 script a negative index is used like with a list: count from the end.
+
+If expr10 is a |List| then it results the item at index expr1.  See |list-index|
+for possible index values.  If the index is out of range this results in an
+error.  Example: >
+	:let item = mylist[-1]		" get last item
+
+Generally, if a |List| index is equal to or higher than the length of the
+|List|, or more negative than the length of the |List|, this results in an
+error.
+
+
+expr10[expr1a : expr1b]	substring or |sublist|		*expr-[:]* *substring*
+
+If expr10 is a String this results in the substring with the bytes or
+characters from expr1a to and including expr1b.  expr10 is used as a String,
+expr1a and expr1b are used as a Number.
+
+In legacy Vim script the indexes are byte indexes.  This doesn't recognize
+multibyte encodings, see |byteidx()| for computing the indexes.  If expr10 is
+a Number it is first converted to a String.
+
+In Vim9 script the indexes are character indexes and include composing
+characters.  To use byte indexes use |strpart()|.  To use character indexes
+without including composing characters use |strcharpart()|.
+
+The item at index expr1b is included, it is inclusive.  For an exclusive index
+use the |slice()| function.
+
+If expr1a is omitted zero is used.  If expr1b is omitted the length of the
+string minus one is used.
+
+A negative number can be used to measure from the end of the string.  -1 is
+the last character, -2 the last but one, etc.
+
+If an index goes out of range for the string characters are omitted.  If
+expr1b is smaller than expr1a the result is an empty string.
+
+Examples: >
+	:let c = name[-1:]		" last byte of a string
+	:let c = name[0:-1]		" the whole string
+	:let c = name[-2:-2]		" last but one byte of a string
+	:let s = line(".")[4:]		" from the fifth byte to the end
+	:let s = s[:-3]			" remove last two bytes
+<
+							*slice*
+If expr10 is a |List| this results in a new |List| with the items indicated by
+the indexes expr1a and expr1b.  This works like with a String, as explained
+just above. Also see |sublist| below.  Examples: >
+	:let l = mylist[:3]		" first four items
+	:let l = mylist[4:4]		" List with one item
+	:let l = mylist[:]		" shallow copy of a List
+
+If expr10 is a |Blob| this results in a new |Blob| with the bytes in the
+indexes expr1a and expr1b, inclusive.  Examples: >
+	:let b = 0zDEADBEEF
+	:let bs = b[1:2]		" 0zADBE
+	:let bs = b[:]			" copy of 0zDEADBEEF
+
+Using expr10[expr1] or expr10[expr1a : expr1b] on a |Funcref| results in an
+error.
+
+Watch out for confusion between a namespace and a variable followed by a colon
+for a sublist: >
+	mylist[n:]     " uses variable n
+	mylist[s:]     " uses namespace s:, error!
+
+
+expr10.name		entry in a |Dictionary|		*expr-entry*
+							*E1203* *E1229*
+If expr10 is a |Dictionary| and it is followed by a dot, then the following
+name will be used as a key in the |Dictionary|.  This is just like:
+expr10[name].
+
+The name must consist of alphanumeric characters, just like a variable name,
+but it may start with a number.  Curly braces cannot be used.
+
+There must not be white space before or after the dot.
+
+Examples: >
+	:let dict = {"one": 1, 2: "two"}
+	:echo dict.one		" shows "1"
+	:echo dict.2		" shows "two"
+	:echo dict .2		" error because of space before the dot
+
+Note that the dot is also used for String concatenation.  To avoid confusion
+always put spaces around the dot for String concatenation.
+
+
+expr10(expr1, ...)	|Funcref| function call		*E1085*
+
+When expr10 is a |Funcref| type variable, invoke the function it refers to.
+
+
+expr10->name([args])	method call			*method* *->*
+expr10->{lambda}([args])
+							*E260* *E276* *E1265*
+For methods that are also available as global functions this is the same as: >
+	name(expr10 [, args])
+There can also be methods specifically for the type of "expr10".
+
+This allows for chaining, passing the value that one method returns to the
+next method: >
+	mylist->filter(filterexpr)->map(mapexpr)->sort()->join()
+<
+Example of using a lambda: >
+	GetPercentage()->{x -> x * 100}()->printf('%d%%')
+<
+When using -> the |expr9| operators will be applied first, thus: >
+	-1.234->string()
+Is equivalent to: >
+	(-1.234)->string()
+And NOT: >
+	-(1.234->string())
+
+What comes after "->" can be a name, a simple expression (not containing any
+parenthesis), or any expression in parentheses: >
+	base->name(args)
+	base->some.name(args)
+	base->alist[idx](args)
+	base->(getFuncRef())(args)
+Note that in the last call the base is passed to the function resulting from
+"(getFuncRef())", inserted before "args".  *E1275*
+
+							*E274*
+"->name(" must not contain white space.  There can be white space before the
+"->" and after the "(", thus you can split the lines like this: >
+	mylist
+	\ ->filter(filterexpr)
+	\ ->map(mapexpr)
+	\ ->sort()
+	\ ->join()
+
+When using the lambda form there must be no white space between the } and the
+(.
+
+
+							*expr11*
+number
+------
+number			number constant			*expr-number*
+
+			*0x* *hex-number* *0o* *octal-number* *binary-number*
+Decimal, Hexadecimal (starting with 0x or 0X), Binary (starting with 0b or 0B)
+and Octal (starting with 0, 0o or 0O).
+
+Assuming 64 bit numbers are used (see |v:numbersize|) an unsigned number is
+truncated to 0x7fffffffffffffff or 9223372036854775807.  You can use -1 to get
+0xffffffffffffffff.
+
+						*floating-point-format*
+Floating point numbers can be written in two forms:
+
+	[-+]{N}.{M}
+	[-+]{N}.{M}[eE][-+]{exp}
+
+{N} and {M} are numbers.  Both {N} and {M} must be present and can only
+contain digits, except that in |Vim9| script in {N} single quotes between
+digits are ignored.
+[-+] means there is an optional plus or minus sign.
+{exp} is the exponent, power of 10.
+Only a decimal point is accepted, not a comma.  No matter what the current
+locale is.
+
+Examples:
+	123.456
+	+0.0001
+	55.0
+	-0.123
+	1.234e03
+	1.0E-6
+	-3.1416e+88
+
+These are INVALID:
+	3.		empty {M}
+	1e40		missing .{M}
+
+Rationale:
+Before floating point was introduced, the text "123.456" was interpreted as
+the two numbers "123" and "456", both converted to a string and concatenated,
+resulting in the string "123456".  Since this was considered pointless, and we
+could not find it intentionally being used in Vim scripts, this backwards
+incompatibility was accepted in favor of being able to use the normal notation
+for floating point numbers.
+
+							*float-pi* *float-e*
+A few useful values to copy&paste: >
+	:let pi = 3.14159265359
+	:let e  = 2.71828182846
+Or, if you don't want to write them in as floating-point literals, you can
+also use functions, like the following: >
+	:let pi = acos(-1.0)
+	:let e  = exp(1.0)
+<
+						*floating-point-precision*
+The precision and range of floating points numbers depends on what "double"
+means in the library Vim was compiled with.  There is no way to change this at
+runtime.
+
+The default for displaying a |Float| is to use 6 decimal places, like using
+printf("%g", f).  You can select something else when using the |printf()|
+function.  Example: >
+	:echo printf('%.15e', atan(1))
+<	7.853981633974483e-01
+
+
+
+string					*string* *String* *expr-string* *E114*
+------
+"string"		string constant		*expr-quote*
+
+Note that double quotes are used.
+
+A string constant accepts these special characters:
+\...	three-digit octal number (e.g., "\316")
+\..	two-digit octal number (must be followed by non-digit)
+\.	one-digit octal number (must be followed by non-digit)
+\x..	byte specified with two hex numbers (e.g., "\x1f")
+\x.	byte specified with one hex number (must be followed by non-hex char)
+\X..	same as \x..
+\X.	same as \x.
+\u....	character specified with up to 4 hex numbers, stored according to the
+	current value of 'encoding' (e.g., "\u02a4")
+\U....	same as \u but allows up to 8 hex numbers.
+\b	backspace <BS>
+\e	escape <Esc>
+\f	formfeed 0x0C
+\n	newline <NL>
+\r	return <CR>
+\t	tab <Tab>
+\\	backslash
+\"	double quote
+\<xxx>	Special key named "xxx".  e.g. "\<C-W>" for CTRL-W.  This is for use
+	in mappings, the 0x80 byte is escaped.
+	To use the double quote character it must be escaped: "<M-\">".
+	Don't use <Char-xxxx> to get a UTF-8 character, use \uxxxx as
+	mentioned above.
+\<*xxx>	Like \<xxx> but prepends a modifier instead of including it in the
+	character.  E.g. "\<C-w>" is one character 0x17 while "\<*C-w>" is four
+	bytes: 3 for the CTRL modifier and then character "W".
+
+Note that "\xff" is stored as the byte 255, which may be invalid in some
+encodings.  Use "\u00ff" to store character 255 according to the current value
+of 'encoding'.
+
+Note that "\000" and "\x00" force the end of the string.
+
+
+blob-literal				*blob-literal* *E973*
+------------
+
+Hexadecimal starting with 0z or 0Z, with an arbitrary number of bytes.
+The sequence must be an even number of hex characters.  Example: >
+	:let b = 0zFF00ED015DAF
+
+
+literal-string						*literal-string* *E115*
+---------------
+'string'		string constant			*expr-'*
+
+Note that single quotes are used.
+
+This string is taken as it is.  No backslashes are removed or have a special
+meaning.  The only exception is that two quotes stand for one quote.
+
+Single quoted strings are useful for patterns, so that backslashes do not need
+to be doubled.  These two commands are equivalent: >
+	if a =~ "\\s*"
+	if a =~ '\s*'
+
+
+interpolated-string				*$quote* *interpolated-string*
+--------------------
+$"string"		interpolated string constant		*expr-$quote*
+$'string'		interpolated literal string constant	*expr-$'*
+
+Interpolated strings are an extension of the |string| and |literal-string|,
+allowing the inclusion of Vim script expressions (see |expr1|).  Any
+expression returning a value can be enclosed between curly braces.  The value
+is converted to a string.  All the text and results of the expressions
+are concatenated to make a new string.
+							*E1278* *E1279*
+To include an opening brace '{' or closing brace '}' in the string content
+double it.  For double quoted strings using a backslash also works.  A single
+closing brace '}' will result in an error.
+
+Examples: >
+	let your_name = input("What's your name? ")
+<	What's your name?  Peter ~
+>
+	echo
+	echo $"Hello, {your_name}!"
+<	Hello, Peter! ~
+>
+	echo $"The square root of {{9}} is {sqrt(9)}"
+<	The square root of {9} is 3.0 ~
+
+						*string-offset-encoding*
+A string consists of multiple characters.  How the characters are stored
+depends on 'encoding'.  Most common is UTF-8, which uses one byte for ASCII
+characters, two bytes for other latin characters and more bytes for other
+characters.
+
+A string offset can count characters or bytes.  Other programs may use
+UTF-16 encoding (16-bit words) and an offset of UTF-16 words.  Some functions
+use byte offsets, usually for UTF-8 encoding.  Other functions use character
+offsets, in which case the encoding doesn't matter.
+
+The different offsets for the string "a©😊" are below:
+
+  UTF-8 offsets:
+      [0]: 61, [1]: C2, [2]: A9, [3]: F0, [4]: 9F, [5]: 98, [6]: 8A
+  UTF-16 offsets:
+      [0]: 0061, [1]: 00A9, [2]: D83D, [3]: DE0A
+  UTF-32 (character) offsets:
+      [0]: 00000061, [1]: 000000A9, [2]: 0001F60A
+
+You can use the "g8" and "ga" commands on a character to see the
+decimal/hex/octal values.
+
+The functions |byteidx()|, |utf16idx()| and |charidx()| can be used to convert
+between these indices.  The functions |strlen()|, |strutf16len()| and
+|strcharlen()| return the number of bytes, UTF-16 code units and characters in
+a string respectively.
+
+option						*expr-option* *E112* *E113*
+------
+&option			option value, local value if possible
+&g:option		global option value
+&l:option		local option value
+
+Examples: >
+	echo "tabstop is " .. &tabstop
+	if &insertmode
+
+Any option name can be used here.  See |options|.  When using the local value
+and there is no buffer-local or window-local value, the global value is used
+anyway.
+
+
+register						*expr-register* *@r*
+--------
+@r			contents of register 'r'
+
+The result is the contents of the named register, as a single string.
+Newlines are inserted where required.  To get the contents of the unnamed
+register use @" or @@.  See |registers| for an explanation of the available
+registers.
+
+When using the '=' register you get the expression itself, not what it
+evaluates to.  Use |eval()| to evaluate it.
+
+
+nesting						*expr-nesting* *E110*
+-------
+(expr1)			nested expression
+
+
+environment variable					*expr-env*
+--------------------
+$VAR			environment variable
+
+The String value of any environment variable.  When it is not defined, the
+result is an empty string.
+
+The functions `getenv()` and `setenv()` can also be used and work for
+environment variables with non-alphanumeric names.
+The function `environ()` can be used to get a Dict with all environment
+variables.
+
+
+						*expr-env-expand*
+Note that there is a difference between using $VAR directly and using
+expand("$VAR").  Using it directly will only expand environment variables that
+are known inside the current Vim session.  Using expand() will first try using
+the environment variables known inside the current Vim session.  If that
+fails, a shell will be used to expand the variable.  This can be slow, but it
+does expand all variables that the shell knows about.  Example: >
+	:echo $shell
+	:echo expand("$shell")
+The first one probably doesn't echo anything, the second echoes the $shell
+variable (if your shell supports it).
+
+
+internal variable			*expr-variable* *E1015* *E1089*
+-----------------
+variable		internal variable
+See below |internal-variables|.
+
+
+function call		*expr-function* *E116* *E118* *E119* *E120*
+-------------
+function(expr1, ...)	function call
+See below |functions|.
+
+
+lambda expression				*expr-lambda* *lambda*
+-----------------
+{args -> expr1}		legacy lambda expression		*E451*
+(args) => expr1		|Vim9| lambda expression
+
+A lambda expression creates a new unnamed function which returns the result of
+evaluating |expr1|.  Lambda expressions differ from |user-functions| in
+the following ways:
+
+1. The body of the lambda expression is an |expr1| and not a sequence of |Ex|
+   commands.
+2. The prefix "a:" should not be used for arguments.  E.g.: >
+	:let F = {arg1, arg2 -> arg1 - arg2}
+	:echo F(5, 2)
+<	3
+
+The arguments are optional.  Example: >
+	:let F = {-> 'error function'}
+	:echo F('ignored')
+<	error function
+
+The |Vim9| lambda does not only use a different syntax, it also adds type
+checking and can be split over multiple lines, see |vim9-lambda|.
+
+							*closure*
+Lambda expressions can access outer scope variables and arguments.  This is
+often called a closure.  Example where "i" and "a:arg" are used in a lambda
+while they already exist in the function scope.  They remain valid even after
+the function returns: >
+	:function Foo(arg)
+	:  let i = 3
+	:  return {x -> x + i - a:arg}
+	:endfunction
+	:let Bar = Foo(4)
+	:echo Bar(6)
+<	5
+
+Note that the variables must exist in the outer scope before the lambda is
+defined for this to work.  See also |:func-closure|.
+
+Lambda and closure support can be checked with: >
+	if has('lambda')
+
+Examples for using a lambda expression with |sort()|, |map()| and |filter()|: >
+	:echo map([1, 2, 3], {idx, val -> val + 1})
+<	[2, 3, 4] >
+	:echo sort([3,7,2,1,4], {a, b -> a - b})
+<	[1, 2, 3, 4, 7]
+
+The lambda expression is also useful for Channel, Job and timer: >
+	:let timer = timer_start(500,
+			\ {-> execute("echo 'Handler called'", "")},
+			\ {'repeat': 3})
+<	Handler called
+	Handler called
+	Handler called
+
+Note that it is possible to cause memory to be used and not freed if the
+closure is referenced by the context it depends on: >
+	function Function()
+	   let x = 0
+	   let F = {-> x}
+	 endfunction
+The closure uses "x" from the function scope, and "F" in that same scope
+refers to the closure.  This cycle results in the memory not being freed.
+Recommendation: don't do this.
+
+Notice how execute() is used to execute an Ex command.  That's ugly though.
+In Vim9 script you can use a command block, see |inline-function|.
+
+Although you can use the loop variable of a `for` command, it must still exist
+when the closure is called, otherwise you get an error.  *E1302*
+
+Lambda expressions have internal names like '<lambda>42'.  If you get an error
+for a lambda expression, you can find what it is with the following command: >
+	:function <lambda>42
+See also: |numbered-function|
+
+==============================================================================
+3. Internal variable			*internal-variables* *E461* *E1001*
+
+An internal variable name can be made up of letters, digits and '_'.  But it
+cannot start with a digit.  In legacy script it is also possible to use curly
+braces, see |curly-braces-names|.
+
+In legacy script an internal variable is created with the ":let" command
+|:let|.  An internal variable is explicitly destroyed with the ":unlet"
+command |:unlet|.
+Using a name that is not an internal variable or refers to a variable that has
+been destroyed results in an error.
+
+In |Vim9| script `:let` is not used and variables work differently, see |:var|.
+
+						*variable-scope*
+There are several name spaces for variables.  Which one is to be used is
+specified by what is prepended:
+
+		(nothing) In a function: local to the function;
+			  in a legacy script: global;
+			  in a |Vim9|  script: local to the script
+|buffer-variable|    b:	  Local to the current buffer.
+|window-variable|    w:	  Local to the current window.
+|tabpage-variable|   t:	  Local to the current tab page.
+|global-variable|    g:	  Global.
+|local-variable|     l:	  Local to a function (only in a legacy function)
+|script-variable|    s:	  Local to a |:source|'ed Vim script.
+|function-argument|  a:	  Function argument (only in a legacy function).
+|vim-variable|       v:	  Global, predefined by Vim.
+
+The scope name by itself can be used as a |Dictionary|.  For example, to
+delete all script-local variables: >
+	:for k in keys(s:)
+	:    unlet s:[k]
+	:endfor
+
+Note: in Vim9 script variables can also be local to a block of commands, see
+|vim9-scopes|.
+						*buffer-variable* *b:var* *b:*
+A variable name that is preceded with "b:" is local to the current buffer.
+Thus you can have several "b:foo" variables, one for each buffer.
+This kind of variable is deleted when the buffer is wiped out or deleted with
+|:bdelete|.
+
+One local buffer variable is predefined:
+					*b:changedtick* *changetick*
+b:changedtick	The total number of changes to the current buffer.  It is
+		incremented for each change.  An undo command is also a change
+		in this case.  Resetting 'modified' when writing the buffer is
+		also counted.
+		This can be used to perform an action only when the buffer has
+		changed.  Example: >
+		    :if my_changedtick != b:changedtick
+		    :	let my_changedtick = b:changedtick
+		    :	call My_Update()
+		    :endif
+<		You cannot change or delete the b:changedtick variable.
+		If you need more information about the change see
+		|listener_add()|.
+
+						*window-variable* *w:var* *w:*
+A variable name that is preceded with "w:" is local to the current window.  It
+is deleted when the window is closed.
+
+						*tabpage-variable* *t:var* *t:*
+A variable name that is preceded with "t:" is local to the current tab page,
+It is deleted when the tab page is closed. {not available when compiled
+without the |+windows| feature}
+
+						*global-variable* *g:var* *g:*
+Inside functions and in |Vim9| script global variables are accessed with "g:".
+Omitting this will access a variable local to a function or script.  "g:"
+can also be used in any other place if you like.
+
+						*local-variable* *l:var* *l:*
+Inside functions local variables are accessed without prepending anything.
+But you can also prepend "l:" if you like.  However, without prepending "l:"
+you may run into reserved variable names.  For example "count".  By itself it
+refers to "v:count".  Using "l:count" you can have a local variable with the
+same name.
+
+						*script-variable* *s:var*
+In a legacy Vim script variables starting with "s:" can be used.  They cannot
+be accessed from outside of the scripts, thus are local to the script.
+In |Vim9| script the "s:" prefix can be omitted, variables are script-local by
+default.
+
+They can be used in:
+- commands executed while the script is sourced
+- functions defined in the script
+- autocommands defined in the script
+- functions and autocommands defined in functions and autocommands which were
+  defined in the script (recursively)
+- user defined commands defined in the script
+Thus not in:
+- other scripts sourced from this one
+- mappings
+- menus
+- etc.
+
+Script variables can be used to avoid conflicts with global variable names.
+Take this example: >
+
+	let s:counter = 0
+	function MyCounter()
+	  let s:counter = s:counter + 1
+	  echo s:counter
+	endfunction
+	command Tick call MyCounter()
+
+You can now invoke "Tick" from any script, and the "s:counter" variable in
+that script will not be changed, only the "s:counter" in the script where
+"Tick" was defined is used.
+
+Another example that does the same: >
+
+	let s:counter = 0
+	command Tick let s:counter = s:counter + 1 | echo s:counter
+
+When calling a function and invoking a user-defined command, the context for
+script variables is set to the script where the function or command was
+defined.
+
+The script variables are also available when a function is defined inside a
+function that is defined in a script.  Example: >
+
+	let s:counter = 0
+	function StartCounting(incr)
+	  if a:incr
+	    function MyCounter()
+	      let s:counter = s:counter + 1
+	    endfunction
+	  else
+	    function MyCounter()
+	      let s:counter = s:counter - 1
+	    endfunction
+	  endif
+	endfunction
+
+This defines the MyCounter() function either for counting up or counting down
+when calling StartCounting().  It doesn't matter from where StartCounting() is
+called, the s:counter variable will be accessible in MyCounter().
+
+When the same script is sourced again it will use the same script variables.
+They will remain valid as long as Vim is running.  This can be used to
+maintain a counter: >
+
+	if !exists("s:counter")
+	  let s:counter = 1
+	  echo "script executed for the first time"
+	else
+	  let s:counter = s:counter + 1
+	  echo "script executed " .. s:counter .. " times now"
+	endif
+
+Note that this means that filetype plugins don't get a different set of script
+variables for each buffer.  Use local buffer variables instead |b:var|.
+
+
+PREDEFINED VIM VARIABLES			*vim-variable* *v:var* *v:*
+							*E963* *E1063*
+Some variables can be set by the user, but the type cannot be changed.
+
+					*v:argv* *argv-variable*
+v:argv		The command line arguments Vim was invoked with.  This is a
+		list of strings.  The first item is the Vim command.
+		See |v:progpath| for the command with full path.
+
+					*v:beval_col* *beval_col-variable*
+v:beval_col	The number of the column, over which the mouse pointer is.
+		This is the byte index in the |v:beval_lnum| line.
+		Only valid while evaluating the 'balloonexpr' option.
+
+					*v:beval_bufnr* *beval_bufnr-variable*
+v:beval_bufnr	The number of the buffer, over which the mouse pointer is. Only
+		valid while evaluating the 'balloonexpr' option.
+
+					*v:beval_lnum* *beval_lnum-variable*
+v:beval_lnum	The number of the line, over which the mouse pointer is. Only
+		valid while evaluating the 'balloonexpr' option.
+
+					*v:beval_text* *beval_text-variable*
+v:beval_text	The text under or after the mouse pointer.  Usually a word as
+		it is useful for debugging a C program.  'iskeyword' applies,
+		but a dot and "->" before the position is included.  When on a
+		']' the text before it is used, including the matching '[' and
+		word before it.  When on a Visual area within one line the
+		highlighted text is used.  Also see |<cexpr>|.
+		Only valid while evaluating the 'balloonexpr' option.
+
+					*v:beval_winnr* *beval_winnr-variable*
+v:beval_winnr	The number of the window, over which the mouse pointer is. Only
+		valid while evaluating the 'balloonexpr' option.  The first
+		window has number zero (unlike most other places where a
+		window gets a number).
+
+					*v:beval_winid* *beval_winid-variable*
+v:beval_winid	The |window-ID| of the window, over which the mouse pointer
+		is.  Otherwise like v:beval_winnr.
+
+					*v:char* *char-variable*
+v:char		Argument for evaluating 'formatexpr' and used for the typed
+		character when using <expr> in an abbreviation |:map-<expr>|.
+		It is also used by the |InsertCharPre| and |InsertEnter| events.
+
+			*v:charconvert_from* *charconvert_from-variable*
+v:charconvert_from
+		The name of the character encoding of a file to be converted.
+		Only valid while evaluating the 'charconvert' option.
+
+			*v:charconvert_to* *charconvert_to-variable*
+v:charconvert_to
+		The name of the character encoding of a file after conversion.
+		Only valid while evaluating the 'charconvert' option.
+
+					*v:cmdarg* *cmdarg-variable*
+v:cmdarg	This variable is used for two purposes:
+		1. The extra arguments given to a file read/write command.
+		   Currently these are "++enc=" and "++ff=".  This variable is
+		   set before an autocommand event for a file read/write
+		   command is triggered.  There is a leading space to make it
+		   possible to append this variable directly after the
+		   read/write command.  Note: The "+cmd" argument isn't
+		   included here, because it will be executed anyway.
+		2. When printing a PostScript file with ":hardcopy" this is
+		   the argument for the ":hardcopy" command.  This can be used
+		   in 'printexpr'.
+
+					*v:cmdbang* *cmdbang-variable*
+v:cmdbang	Set like v:cmdarg for a file read/write command.  When a "!"
+		was used the value is 1, otherwise it is 0.  Note that this
+		can only be used in autocommands.  For user commands |<bang>|
+		can be used.
+						*v:collate* *collate-variable*
+v:collate	The current locale setting for collation order of the runtime
+		environment.  This allows Vim scripts to be aware of the
+		current locale encoding.  Technical: it's the value of
+		LC_COLLATE.  When not using a locale the value is "C".
+		This variable can not be set directly, use the |:language|
+		command.
+		See |multi-lang|.
+
+								*v:colornames*
+v:colornames    A dictionary that maps color names to hex color strings. These
+		color names can be used with the |highlight-guifg|,
+		|highlight-guibg|, and |highlight-guisp| parameters. Updating
+		an entry in v:colornames has no immediate effect on the syntax
+		highlighting. The highlight commands (probably in a
+		colorscheme script) need to be re-evaluated in order to use
+		the updated color values. For example: >
+
+		    :let v:colornames['fuscia'] = '#cf3ab4'
+		    :let v:colornames['mauve'] = '#915f6d'
+		    :highlight Normal guifg=fuscia guibg=mauve
+<
+		This cannot be used to override the |cterm-colors| but it can
+		be used to override other colors. For example, the X11 colors
+		defined in the `colors/lists/default.vim` (previously defined
+		in |rgb.txt|). When defining new color names in a plugin, the
+		recommended practice is to set a color entry only when it does
+		not already exist. For example: >
+
+		    :call extend(v:colornames, {
+			\ 'fuscia': '#cf3ab4',
+			\ 'mauve': '#915f6d,
+			\ }, 'keep')
+<
+		Using |extend()| with the 'keep' option updates each color only
+		if it did not exist in |v:colornames|. Doing so allows the
+		user to choose the precise color value for a common name
+		by setting it in their |.vimrc|.
+
+		It is possible to remove entries from this dictionary but
+		doing so is NOT recommended, because it is disruptive to
+		other scripts. It is also unlikely to achieve the desired
+		result because the |:colorscheme| and |:highlight| commands will
+		both automatically load all `colors/lists/default.vim` color
+		scripts.
+
+				*v:completed_item* *completed_item-variable*
+v:completed_item
+		|Dictionary| containing the |complete-items| for the most
+		recently completed word after |CompleteDone|.  The
+		|Dictionary| is empty if the completion failed.
+		Note: Plugins can modify the value to emulate the builtin
+		|CompleteDone| event behavior.
+
+					*v:count* *count-variable*
+v:count		The count given for the last Normal mode command.  Can be used
+		to get the count before a mapping.  Read-only.  Example: >
+	:map _x :<C-U>echo "the count is " .. v:count<CR>
+<		Note: The <C-U> is required to remove the line range that you
+		get when typing ':' after a count.
+		When there are two counts, as in "3d2w", they are multiplied,
+		just like what happens in the command, "d6w" for the example.
+		Also used for evaluating the 'formatexpr' option.
+		"count" also works, for backwards compatibility, unless
+		|scriptversion| is 3 or higher.
+
+					*v:count1* *count1-variable*
+v:count1	Just like "v:count", but defaults to one when no count is
+		used.
+
+						*v:ctype* *ctype-variable*
+v:ctype		The current locale setting for characters of the runtime
+		environment.  This allows Vim scripts to be aware of the
+		current locale encoding.  Technical: it's the value of
+		LC_CTYPE.  When not using a locale the value is "C".
+		This variable can not be set directly, use the |:language|
+		command.
+		See |multi-lang|.
+
+					*v:dying* *dying-variable*
+v:dying		Normally zero.  When a deadly signal is caught it's set to
+		one.  When multiple signals are caught the number increases.
+		Can be used in an autocommand to check if Vim didn't
+		terminate normally. {only works on Unix}
+		Example: >
+	:au VimLeave * if v:dying | echo "\nAAAAaaaarrrggghhhh!!!\n" | endif
+<		Note: if another deadly signal is caught when v:dying is one,
+		VimLeave autocommands will not be executed.
+
+					*v:exiting* *exiting-variable*
+v:exiting	Vim exit code.  Normally zero, non-zero when something went
+		wrong.  The value is v:null before invoking the |VimLeavePre|
+		and |VimLeave| autocmds.  See |:q|, |:x| and |:cquit|.
+		Example: >
+			:au VimLeave * echo "Exit value is " .. v:exiting
+<
+					*v:echospace* *echospace-variable*
+v:echospace	Number of screen cells that can be used for an `:echo` message
+		in the last screen line before causing the |hit-enter-prompt|.
+		Depends on 'showcmd', 'ruler' and 'columns'.  You need to
+		check 'cmdheight' for whether there are full-width lines
+		available above the last line.
+
+					*v:errmsg* *errmsg-variable*
+v:errmsg	Last given error message.  It's allowed to set this variable.
+		Example: >
+	:let v:errmsg = ""
+	:silent! next
+	:if v:errmsg != ""
+	:  ... handle error
+<		"errmsg" also works, for backwards compatibility, unless
+		|scriptversion| is 3 or higher.
+
+				*v:errors* *errors-variable* *assert-return*
+v:errors	Errors found by assert functions, such as |assert_true()|.
+		This is a list of strings.
+		The assert functions append an item when an assert fails.
+		The return value indicates this: a one is returned if an item
+		was added to v:errors, otherwise zero is returned.
+		To remove old results make it empty: >
+	:let v:errors = []
+<		If v:errors is set to anything but a list it is made an empty
+		list by the assert function.
+
+					*v:event* *event-variable*
+v:event		Dictionary containing information about the current
+		|autocommand|.  See the specific event for what it puts in
+		this dictionary.
+		The dictionary is emptied when the |autocommand| finishes,
+		please refer to |dict-identity| for how to get an independent
+		copy of it.  Use |deepcopy()| if you want to keep the
+		information after the event triggers.  Example: >
+			au TextYankPost * let g:foo = deepcopy(v:event)
+<
+					*v:exception* *exception-variable*
+v:exception	The value of the exception most recently caught and not
+		finished.  See also |v:throwpoint| and |throw-variables|.
+		Example: >
+	:try
+	:  throw "oops"
+	:catch /.*/
+	:  echo "caught " .. v:exception
+	:endtry
+<		Output: "caught oops".
+
+					*v:false* *false-variable*
+v:false		A Number with value zero. Used to put "false" in JSON.  See
+		|json_encode()|.
+		When used as a string this evaluates to "v:false". >
+			echo v:false
+<			v:false ~
+		That is so that eval() can parse the string back to the same
+		value.  Read-only.
+		In |Vim9| script "false" can be used which has a boolean type.
+
+					*v:fcs_reason* *fcs_reason-variable*
+v:fcs_reason	The reason why the |FileChangedShell| event was triggered.
+		Can be used in an autocommand to decide what to do and/or what
+		to set v:fcs_choice to.  Possible values:
+			deleted		file no longer exists
+			conflict	file contents, mode or timestamp was
+					changed and buffer is modified
+			changed		file contents has changed
+			mode		mode of file changed
+			time		only file timestamp changed
+
+					*v:fcs_choice* *fcs_choice-variable*
+v:fcs_choice	What should happen after a |FileChangedShell| event was
+		triggered.  Can be used in an autocommand to tell Vim what to
+		do with the affected buffer:
+			reload		Reload the buffer (does not work if
+					the file was deleted).
+			edit		Reload the buffer and detect the
+					values for options such as
+					'fileformat', 'fileencoding', 'binary'
+					(does not work if the file was
+					deleted).
+			ask		Ask the user what to do, as if there
+					was no autocommand.  Except that when
+					only the timestamp changed nothing
+					will happen.
+			<empty>		Nothing, the autocommand should do
+					everything that needs to be done.
+		The default is empty.  If another (invalid) value is used then
+		Vim behaves like it is empty, there is no warning message.
+
+					*v:fname* *fname-variable*
+v:fname		When evaluating 'includeexpr': the file name that was
+		detected.  Empty otherwise.
+
+					*v:fname_in* *fname_in-variable*
+v:fname_in	The name of the input file.  Valid while evaluating:
+			option		used for ~
+			'charconvert'	file to be converted
+			'diffexpr'	original file
+			'patchexpr'	original file
+			'printexpr'	file to be printed
+		And set to the swap file name for |SwapExists|.
+
+					*v:fname_out* *fname_out-variable*
+v:fname_out	The name of the output file.  Only valid while
+		evaluating:
+			option		used for ~
+			'charconvert'	resulting converted file (*)
+			'diffexpr'	output of diff
+			'patchexpr'	resulting patched file
+		(*) When doing conversion for a write command (e.g., ":w
+		file") it will be equal to v:fname_in.  When doing conversion
+		for a read command (e.g., ":e file") it will be a temporary
+		file and different from v:fname_in.
+
+					*v:fname_new* *fname_new-variable*
+v:fname_new	The name of the new version of the file.  Only valid while
+		evaluating 'diffexpr'.
+
+					*v:fname_diff* *fname_diff-variable*
+v:fname_diff	The name of the diff (patch) file.  Only valid while
+		evaluating 'patchexpr'.
+
+					*v:folddashes* *folddashes-variable*
+v:folddashes	Used for 'foldtext': dashes representing foldlevel of a closed
+		fold.
+		Read-only in the |sandbox|. |fold-foldtext|
+
+					*v:foldlevel* *foldlevel-variable*
+v:foldlevel	Used for 'foldtext': foldlevel of closed fold.
+		Read-only in the |sandbox|. |fold-foldtext|
+
+					*v:foldend* *foldend-variable*
+v:foldend	Used for 'foldtext': last line of closed fold.
+		Read-only in the |sandbox|. |fold-foldtext|
+
+					*v:foldstart* *foldstart-variable*
+v:foldstart	Used for 'foldtext': first line of closed fold.
+		Read-only in the |sandbox|. |fold-foldtext|
+
+					*v:hlsearch* *hlsearch-variable*
+v:hlsearch	Variable that indicates whether search highlighting is on.
+		Setting it makes sense only if 'hlsearch' is enabled which
+		requires |+extra_search|. Setting this variable to zero acts
+		like the |:nohlsearch| command, setting it to one acts like >
+			let &hlsearch = &hlsearch
+<		Note that the value is restored when returning from a
+		function. |function-search-undo|.
+
+					*v:insertmode* *insertmode-variable*
+v:insertmode	Used for the |InsertEnter| and |InsertChange| autocommand
+		events.  Values:
+			i	Insert mode
+			r	Replace mode
+			v	Virtual Replace mode
+
+						*v:key* *key-variable*
+v:key		Key of the current item of a |Dictionary|.  Only valid while
+		evaluating the expression used with |map()| and |filter()|.
+		Read-only.
+
+						*v:lang* *lang-variable*
+v:lang		The current locale setting for messages of the runtime
+		environment.  This allows Vim scripts to be aware of the
+		current language.  Technical: it's the value of LC_MESSAGES.
+		The value is system dependent.
+		This variable can not be set directly, use the |:language|
+		command.
+		It can be different from |v:ctype| when messages are desired
+		in a different language than what is used for character
+		encoding.  See |multi-lang|.
+
+						*v:lc_time* *lc_time-variable*
+v:lc_time	The current locale setting for time messages of the runtime
+		environment.  This allows Vim scripts to be aware of the
+		current language.  Technical: it's the value of LC_TIME.
+		This variable can not be set directly, use the |:language|
+		command.  See |multi-lang|.
+
+						*v:lnum* *lnum-variable*
+v:lnum		Line number for the 'foldexpr' |fold-expr|, 'formatexpr' and
+		'indentexpr' expressions, tab page number for 'guitablabel'
+		and 'guitabtooltip'.  Only valid while one of these
+		expressions is being evaluated.  Read-only when in the
+		|sandbox|.
+
+						*v:maxcol* *maxcol-variable*
+v:maxcol	Maximum line length.  Depending on where it is used it can be
+		screen columns, characters or bytes.  The value currently is
+		2147483647 on all systems.
+
+					*v:mouse_win* *mouse_win-variable*
+v:mouse_win	Window number for a mouse click obtained with |getchar()|.
+		First window has number 1, like with |winnr()|.  The value is
+		zero when there was no mouse button click.
+
+					*v:mouse_winid* *mouse_winid-variable*
+v:mouse_winid	Window ID for a mouse click obtained with |getchar()|.
+		The value is zero when there was no mouse button click.
+
+					*v:mouse_lnum* *mouse_lnum-variable*
+v:mouse_lnum	Line number for a mouse click obtained with |getchar()|.
+		This is the text line number, not the screen line number.  The
+		value is zero when there was no mouse button click.
+
+					*v:mouse_col* *mouse_col-variable*
+v:mouse_col	Column number for a mouse click obtained with |getchar()|.
+		This is the screen column number, like with |virtcol()|.  The
+		value is zero when there was no mouse button click.
+
+					*v:none* *none-variable* *None*
+v:none		An empty String. Used to put an empty item in JSON.  See
+		|json_encode()|.
+		This can also be used as a function argument to use the
+		default value, see |none-function_argument|.
+		When used as a number this evaluates to zero.
+		When used as a string this evaluates to "v:none". >
+			echo v:none
+<			v:none ~
+		That is so that eval() can parse the string back to the same
+		value.  Read-only.
+		Note that using `== v:none` and `!= v:none`  will often give
+		an error.  Instead, use `is v:none` and `isnot v:none` .
+
+					*v:null* *null-variable*
+v:null		An empty String. Used to put "null" in JSON.  See
+		|json_encode()|.
+		When used as a number this evaluates to zero.
+		When used as a string this evaluates to "v:null". >
+			echo v:null
+<			v:null ~
+		That is so that eval() can parse the string back to the same
+		value.  Read-only.
+		In |Vim9| script `null` can be used without "v:".
+		In some places `v:null` and `null` can be used for a List,
+		Dict, Job, etc. that is not set.  That is slightly different
+		than an empty List, Dict, etc.
+
+					*v:numbermax* *numbermax-variable*
+v:numbermax	Maximum value of a number.
+
+					*v:numbermin* *numbermin-variable*
+v:numbermin	Minimum value of a number (negative).
+
+					*v:numbersize* *numbersize-variable*
+v:numbersize	Number of bits in a Number.  This is normally 64, but on some
+		systems it may be 32.
+
+					*v:oldfiles* *oldfiles-variable*
+v:oldfiles	List of file names that is loaded from the |viminfo| file on
+		startup.  These are the files that Vim remembers marks for.
+		The length of the List is limited by the ' argument of the
+		'viminfo' option (default is 100).
+		When the |viminfo| file is not used the List is empty.
+		Also see |:oldfiles| and |c_#<|.
+		The List can be modified, but this has no effect on what is
+		stored in the |viminfo| file later.  If you use values other
+		than String this will cause trouble.
+		{only when compiled with the |+viminfo| feature}
+
+						    *v:option_new*
+v:option_new    New value of the option. Valid while executing an |OptionSet|
+		autocommand.
+						    *v:option_old*
+v:option_old    Old value of the option. Valid while executing an |OptionSet|
+		autocommand. Depending on the command used for setting and the
+		kind of option this is either the local old value or the
+		global old value.
+						    *v:option_oldlocal*
+v:option_oldlocal
+		Old local value of the option. Valid while executing an
+		|OptionSet| autocommand.
+						    *v:option_oldglobal*
+v:option_oldglobal
+		Old global value of the option. Valid while executing an
+		|OptionSet| autocommand.
+						    *v:option_type*
+v:option_type   Scope of the set command. Valid while executing an
+		|OptionSet| autocommand. Can be either "global" or "local"
+						    *v:option_command*
+v:option_command
+		Command used to set the option. Valid while executing an
+		|OptionSet| autocommand.
+			value		option was set via   ~
+			"setlocal"	|:setlocal| or ":let l:xxx"
+			"setglobal"	|:setglobal| or ":let g:xxx"
+			"set"		|:set| or |:let|
+			"modeline"	|modeline|
+					*v:operator* *operator-variable*
+v:operator	The last operator given in Normal mode.  This is a single
+		character except for commands starting with <g> or <z>,
+		in which case it is two characters.  Best used alongside
+		|v:prevcount| and |v:register|.  Useful if you want to cancel
+		Operator-pending mode and then use the operator, e.g.: >
+			:omap O <Esc>:call MyMotion(v:operator)<CR>
+<		The value remains set until another operator is entered, thus
+		don't expect it to be empty.
+		v:operator is not set for |:delete|, |:yank| or other Ex
+		commands.
+		Read-only.
+
+					*v:prevcount* *prevcount-variable*
+v:prevcount	The count given for the last but one Normal mode command.
+		This is the v:count value of the previous command.  Useful if
+		you want to cancel Visual or Operator-pending mode and then
+		use the count, e.g.: >
+			:vmap % <Esc>:call MyFilter(v:prevcount)<CR>
+<		Read-only.
+
+					*v:profiling* *profiling-variable*
+v:profiling	Normally zero.  Set to one after using ":profile start".
+		See |profiling|.
+
+					*v:progname* *progname-variable*
+v:progname	Contains the name (with path removed) with which Vim was
+		invoked.  Allows you to do special initialisations for |view|,
+		|evim| etc., or any other name you might symlink to Vim.
+		Read-only.
+
+					*v:progpath* *progpath-variable*
+v:progpath	Contains the command with which Vim was invoked, in a form
+		that when passed to the shell will run the same Vim executable
+		as the current one (if $PATH remains unchanged).
+		Useful if you want to message a Vim server using a
+		|--remote-expr|.
+		To get the full path use: >
+			echo exepath(v:progpath)
+<		If the command has a relative path it will be expanded to the
+		full path, so that it still works after `:cd`. Thus starting
+		"./vim" results in "/home/user/path/to/vim/src/vim".
+		On Linux and other systems it will always be the full path.
+		On Mac it may just be "vim" and using exepath() as mentioned
+		above should be used to get the full path.
+		On MS-Windows the executable may be called "vim.exe", but the
+		".exe" is not added to v:progpath.
+		Read-only.
+
+					*v:register* *register-variable*
+v:register	The name of the register in effect for the current normal mode
+		command (regardless of whether that command actually used a
+		register).  Or for the currently executing normal mode mapping
+		(use this in custom commands that take a register).
+		If none is supplied it is the default register '"', unless
+		'clipboard' contains "unnamed" or "unnamedplus", then it is
+		'*' or '+'.
+		Also see |getreg()| and |setreg()|
+
+					*v:scrollstart* *scrollstart-variable*
+v:scrollstart	String describing the script or function that caused the
+		screen to scroll up.  It's only set when it is empty, thus the
+		first reason is remembered.  It is set to "Unknown" for a
+		typed command.
+		This can be used to find out why your script causes the
+		hit-enter prompt.
+
+					*v:servername* *servername-variable*
+v:servername	The resulting registered |client-server-name| if any.
+		Read-only.
+
+
+v:searchforward			*v:searchforward* *searchforward-variable*
+		Search direction:  1 after a forward search, 0 after a
+		backward search.  It is reset to forward when directly setting
+		the last search pattern, see |quote/|.
+		Note that the value is restored when returning from a
+		function. |function-search-undo|.
+		Read-write.
+
+					*v:shell_error* *shell_error-variable*
+v:shell_error	Result of the last shell command.  When non-zero, the last
+		shell command had an error.  When zero, there was no problem.
+		This only works when the shell returns the error code to Vim.
+		The value -1 is often used when the command could not be
+		executed.  Read-only.
+		Example: >
+	:!mv foo bar
+	:if v:shell_error
+	:  echo 'could not rename "foo" to "bar"!'
+	:endif
+<		"shell_error" also works, for backwards compatibility, unless
+		|scriptversion| is 3 or higher.
+
+					*v:sizeofint* *sizeofint-variable*
+v:sizeofint	Number of bytes in an int.  Depends on how Vim was compiled.
+		This is only useful for deciding whether a test will give the
+		expected result.
+
+					*v:sizeoflong* *sizeoflong-variable*
+v:sizeoflong	Number of bytes in a long.  Depends on how Vim was compiled.
+		This is only useful for deciding whether a test will give the
+		expected result.
+
+				*v:sizeofpointer* *sizeofpointer-variable*
+v:sizeofpointer	Number of bytes in a pointer.  Depends on how Vim was compiled.
+		This is only useful for deciding whether a test will give the
+		expected result.
+
+					*v:statusmsg* *statusmsg-variable*
+v:statusmsg	Last given status message.  It's allowed to set this variable.
+
+					*v:swapname* *swapname-variable*
+v:swapname	Only valid when executing |SwapExists| autocommands: Name of
+		the swap file found.  Read-only.
+
+					*v:swapchoice* *swapchoice-variable*
+v:swapchoice	|SwapExists| autocommands can set this to the selected choice
+		for handling an existing swap file:
+			'o'	Open read-only
+			'e'	Edit anyway
+			'r'	Recover
+			'd'	Delete swapfile
+			'q'	Quit
+			'a'	Abort
+		The value should be a single-character string.  An empty value
+		results in the user being asked, as would happen when there is
+		no SwapExists autocommand.  The default is empty.
+
+					*v:swapcommand* *swapcommand-variable*
+v:swapcommand	Normal mode command to be executed after a file has been
+		opened.  Can be used for a |SwapExists| autocommand to have
+		another Vim open the file and jump to the right place.  For
+		example, when jumping to a tag the value is ":tag tagname\r".
+		For ":edit +cmd file" the value is ":cmd\r".
+
+				*v:t_TYPE* *v:t_bool* *t_bool-variable*
+v:t_bool	Value of |Boolean| type.  Read-only.  See: |type()|
+					*v:t_channel* *t_channel-variable*
+v:t_channel	Value of |Channel| type.  Read-only.  See: |type()|
+					*v:t_dict* *t_dict-variable*
+v:t_dict	Value of |Dictionary| type.  Read-only.  See: |type()|
+					*v:t_float* *t_float-variable*
+v:t_float	Value of |Float| type.  Read-only.  See: |type()|
+					*v:t_func* *t_func-variable*
+v:t_func	Value of |Funcref| type.  Read-only.  See: |type()|
+					*v:t_job* *t_job-variable*
+v:t_job		Value of |Job| type.  Read-only.  See: |type()|
+					*v:t_list* *t_list-variable*
+v:t_list	Value of |List| type.  Read-only.  See: |type()|
+					*v:t_none* *t_none-variable*
+v:t_none	Value of |None| type.  Read-only.  See: |type()|
+					*v:t_number* *t_number-variable*
+v:t_number	Value of |Number| type.  Read-only.  See: |type()|
+					*v:t_string* *t_string-variable*
+v:t_string	Value of |String| type.  Read-only.  See: |type()|
+					*v:t_blob* *t_blob-variable*
+v:t_blob	Value of |Blob| type.  Read-only.  See: |type()|
+					*v:t_class* *t_class-variable*
+v:t_class	Value of |class| type.  Read-only.  See: |type()|
+					*v:t_object* *t_object-variable*
+v:t_object	Value of |object| type.  Read-only.  See: |type()|
+
+				*v:termresponse* *termresponse-variable*
+v:termresponse	The escape sequence returned by the terminal for the |t_RV|
+		termcap entry.  It is set when Vim receives an escape sequence
+		that starts with ESC [ or CSI, then '>' or '?' and ends in a
+		'c', with only digits and ';' in between.
+		When this option is set, the TermResponse autocommand event is
+		fired, so that you can react to the response from the
+		terminal.  You can use |terminalprops()| to see what Vim
+		figured out about the terminal.
+		The response from a new xterm is: "<Esc>[> Pp ; Pv ; Pc c".  Pp
+		is the terminal type: 0 for vt100 and 1 for vt220.  Pv is the
+		patch level (since this was introduced in patch 95, it's
+		always 95 or higher).  Pc is always zero.
+		If Pv is 141 or higher then Vim will try to request terminal
+		codes.  This only works with xterm |xterm-codes|.
+		{only when compiled with |+termresponse| feature}
+
+						*v:termblinkresp*
+v:termblinkresp	The escape sequence returned by the terminal for the |t_RC|
+		termcap entry.  This is used to find out whether the terminal
+		cursor is blinking. This is used by |term_getcursor()|.
+
+						*v:termstyleresp*
+v:termstyleresp	The escape sequence returned by the terminal for the |t_RS|
+		termcap entry.  This is used to find out what the shape of the
+		cursor is.  This is used by |term_getcursor()|.
+
+						*v:termrbgresp*
+v:termrbgresp	The escape sequence returned by the terminal for the |t_RB|
+		termcap entry.  This is used to find out what the terminal
+		background color is, see 'background'.
+
+						*v:termrfgresp*
+v:termrfgresp	The escape sequence returned by the terminal for the |t_RF|
+		termcap entry.  This is used to find out what the terminal
+		foreground color is.
+
+						*v:termu7resp*
+v:termu7resp	The escape sequence returned by the terminal for the |t_u7|
+		termcap entry.  This is used to find out what the terminal
+		does with ambiguous width characters, see 'ambiwidth'.
+
+					*v:testing* *testing-variable*
+v:testing	Must be set before using `test_garbagecollect_now()`.
+		Also, when set certain error messages won't be shown for 2
+		seconds. (e.g. "'dictionary' option is empty")
+
+				*v:this_session* *this_session-variable*
+v:this_session	Full filename of the last loaded or saved session file.  See
+		|:mksession|.  It is allowed to set this variable.  When no
+		session file has been saved, this variable is empty.
+		"this_session" also works, for backwards compatibility, unless
+		|scriptversion| is 3 or higher
+
+					*v:throwpoint* *throwpoint-variable*
+v:throwpoint	The point where the exception most recently caught and not
+		finished was thrown.  Not set when commands are typed.  See
+		also |v:exception| and |throw-variables|.
+		Example: >
+	:try
+	:  throw "oops"
+	:catch /.*/
+	:  echo "Exception from" v:throwpoint
+	:endtry
+<		Output: "Exception from test.vim, line 2"
+
+						*v:true* *true-variable*
+v:true		A Number with value one. Used to put "true" in JSON.  See
+		|json_encode()|.
+		When used as a string this evaluates to "v:true". >
+			echo v:true
+<			v:true ~
+		That is so that eval() can parse the string back to the same
+		value.  Read-only.
+		In |Vim9| script "true" can be used which has a boolean type.
+						*v:val* *val-variable*
+v:val		Value of the current item of a |List| or |Dictionary|.  Only
+		valid while evaluating the expression used with |map()| and
+		|filter()|.  Read-only.
+
+					*v:version* *version-variable*
+v:version	Version number of Vim: Major version number times 100 plus
+		minor version number.  Version 5.0 is 500.  Version 5.1
+		is 501.  Read-only.  "version" also works, for backwards
+		compatibility, unless |scriptversion| is 3 or higher.
+		Use |has()| to check if a certain patch was included, e.g.: >
+			if has("patch-7.4.123")
+<		Note that patch numbers are specific to the version, thus both
+		version 5.0 and 5.1 may have a patch 123, but these are
+		completely different.
+
+					*v:versionlong* *versionlong-variable*
+v:versionlong	Like v:version, but also including the patchlevel in the last
+		four digits.  Version 8.1 with patch 123 has value 8010123.
+		This can be used like this: >
+			if v:versionlong >= 8010123
+<		However, if there are gaps in the list of patches included
+		this will not work well.  This can happen if a recent patch
+		was included into an older version, e.g. for a security fix.
+		Use the has() function to make sure the patch is actually
+		included.
+
+				*v:vim_did_enter* *vim_did_enter-variable*
+v:vim_did_enter	Zero until most of startup is done.  It is set to one just
+		before |VimEnter| autocommands are triggered.
+
+					*v:warningmsg* *warningmsg-variable*
+v:warningmsg	Last given warning message.  It's allowed to set this variable.
+
+					*v:windowid* *windowid-variable*
+v:windowid	When any X11 based GUI is running or when running in a
+		terminal and Vim connects to the X server (|-X|) this will be
+		set to the window ID.
+		When an MS-Windows GUI is running this will be set to the
+		window handle.
+		Otherwise the value is zero.
+		Note: for windows inside Vim use |winnr()| or |win_getid()|,
+		see |window-ID|.
+
+==============================================================================
+4. Builtin Functions					*functions*
+
+See |function-list| for a list grouped by what the function is used for.
+
+The alphabetic list of all builtin functions and details are in a separate
+help file: |builtin-functions|.
+
+==============================================================================
+5. Defining functions					*user-functions*
+
+New functions can be defined.  These can be called just like builtin
+functions.  The function takes arguments, executes a sequence of Ex commands
+and can return a value.
+
+You can find most information about defining functions in |userfunc.txt|.
+For Vim9 functions, which execute much faster, support type checking and more,
+see |vim9.txt|.
+
+==============================================================================
+6. Curly braces names					*curly-braces-names*
+
+In most places where you can use a variable, you can use a "curly braces name"
+variable.  This is a regular variable name with one or more expressions
+wrapped in braces {} like this: >
+	my_{adjective}_variable
+
+This only works in legacy Vim script, not in |Vim9| script.
+
+When Vim encounters this, it evaluates the expression inside the braces, puts
+that in place of the expression, and re-interprets the whole as a variable
+name.  So in the above example, if the variable "adjective" was set to
+"noisy", then the reference would be to "my_noisy_variable", whereas if
+"adjective" was set to "quiet", then it would be to "my_quiet_variable".
+
+One application for this is to create a set of variables governed by an option
+value.  For example, the statement >
+	echo my_{&background}_message
+
+would output the contents of "my_dark_message" or "my_light_message" depending
+on the current value of 'background'.
+
+You can use multiple brace pairs: >
+	echo my_{adverb}_{adjective}_message
+..or even nest them: >
+	echo my_{ad{end_of_word}}_message
+where "end_of_word" is either "verb" or "jective".
+
+However, the expression inside the braces must evaluate to a valid single
+variable name, e.g. this is invalid: >
+	:let foo='a + b'
+	:echo c{foo}d
+.. since the result of expansion is "ca + bd", which is not a variable name.
+
+						*curly-braces-function-names*
+You can call and define functions by an evaluated name in a similar way.
+Example: >
+	:let func_end='whizz'
+	:call my_func_{func_end}(parameter)
+
+This would call the function "my_func_whizz(parameter)".
+
+This does NOT work: >
+  :let i = 3
+  :let @{i} = ''  " error
+  :echo @{i}      " error
+
+==============================================================================
+7. Commands						*expression-commands*
+
+Note: in |Vim9| script `:let` is not used.  `:var` is used for variable
+declarations and assignments do not use a command.  |vim9-declaration|
+
+:let {var-name} = {expr1}				*:let* *E18*
+			Set internal variable {var-name} to the result of the
+			expression {expr1}.  The variable will get the type
+			from the {expr}.  If {var-name} didn't exist yet, it
+			is created.
+
+:let {var-name}[{idx}] = {expr1}			*E689* *E1141*
+			Set a list item to the result of the expression
+			{expr1}.  {var-name} must refer to a list and {idx}
+			must be a valid index in that list.  For nested list
+			the index can be repeated.
+			This cannot be used to add an item to a |List|.
+			This cannot be used to set a byte in a String.  You
+			can do that like this: >
+				:let var = var[0:2] .. 'X' .. var[4:]
+<			When {var-name} is a |Blob| then {idx} can be the
+			length of the blob, in which case one byte is
+			appended.
+
+					*E711* *E719* *E1165* *E1166* *E1183*
+:let {var-name}[{idx1}:{idx2}] = {expr1}		*E708* *E709* *E710*
+			Set a sequence of items in a |List| to the result of
+			the expression {expr1}, which must be a list with the
+			correct number of items.
+			{idx1} can be omitted, zero is used instead.
+			{idx2} can be omitted, meaning the end of the list.
+			When the selected range of items is partly past the
+			end of the list, items will be added.
+
+			*:let+=* *:let-=* *:letstar=* *:let/=*  *:let%=*
+			*:let.=* *:let..=* *E734* *E985* *E1019*
+:let {var} += {expr1}	Like ":let {var} = {var} + {expr1}".
+:let {var} -= {expr1}	Like ":let {var} = {var} - {expr1}".
+:let {var} *= {expr1}	Like ":let {var} = {var} * {expr1}".
+:let {var} /= {expr1}	Like ":let {var} = {var} / {expr1}".
+:let {var} %= {expr1}	Like ":let {var} = {var} % {expr1}".
+:let {var} .= {expr1}	Like ":let {var} = {var} . {expr1}".
+:let {var} ..= {expr1}	Like ":let {var} = {var} .. {expr1}".
+			These fail if {var} was not set yet and when the type
+			of {var} and {expr1} don't fit the operator.
+			`.=` is not supported with Vim script version 2 and
+			later, see |vimscript-version|.
+
+
+:let ${env-name} = {expr1}			*:let-environment* *:let-$*
+			Set environment variable {env-name} to the result of
+			the expression {expr1}.  The type is always String.
+
+			On some systems making an environment variable empty
+			causes it to be deleted.  Many systems do not make a
+			difference between an environment variable that is not
+			set and an environment variable that is empty.
+
+:let ${env-name} .= {expr1}
+			Append {expr1} to the environment variable {env-name}.
+			If the environment variable didn't exist yet this
+			works like "=".
+
+:let @{reg-name} = {expr1}			*:let-register* *:let-@*
+			Write the result of the expression {expr1} in register
+			{reg-name}.  {reg-name} must be a single letter, and
+			must be the name of a writable register (see
+			|registers|).  "@@" can be used for the unnamed
+			register, "@/" for the search pattern.
+			If the result of {expr1} ends in a <CR> or <NL>, the
+			register will be linewise, otherwise it will be set to
+			characterwise.
+			This can be used to clear the last search pattern: >
+				:let @/ = ""
+<			This is different from searching for an empty string,
+			that would match everywhere.
+
+:let @{reg-name} .= {expr1}
+			Append {expr1} to register {reg-name}.  If the
+			register was empty it's like setting it to {expr1}.
+
+:let &{option-name} = {expr1}			*:let-option* *:let-&*
+			Set option {option-name} to the result of the
+			expression {expr1}.  A String or Number value is
+			always converted to the type of the option.
+			For an option local to a window or buffer the effect
+			is just like using the |:set| command: both the local
+			value and the global value are changed.
+			Example: >
+				:let &path = &path .. ',/usr/local/include'
+<			This also works for terminal codes in the form t_xx.
+			But only for alphanumerical names.  Example: >
+				:let &t_k1 = "\<Esc>[234;"
+<			When the code does not exist yet it will be created as
+			a terminal key code, there is no error.
+
+:let &{option-name} .= {expr1}
+			For a string option: Append {expr1} to the value.
+			Does not insert a comma like |:set+=|.
+
+:let &{option-name} += {expr1}
+:let &{option-name} -= {expr1}
+			For a number or boolean option: Add or subtract
+			{expr1}.
+
+:let &l:{option-name} = {expr1}
+:let &l:{option-name} .= {expr1}
+:let &l:{option-name} += {expr1}
+:let &l:{option-name} -= {expr1}
+			Like above, but only set the local value of an option
+			(if there is one).  Works like |:setlocal|.
+
+:let &g:{option-name} = {expr1}
+:let &g:{option-name} .= {expr1}
+:let &g:{option-name} += {expr1}
+:let &g:{option-name} -= {expr1}
+			Like above, but only set the global value of an option
+			(if there is one).  Works like |:setglobal|.
+								*E1093*
+:let [{name1}, {name2}, ...] = {expr1}		*:let-unpack* *E687* *E688*
+			{expr1} must evaluate to a |List|.  The first item in
+			the list is assigned to {name1}, the second item to
+			{name2}, etc.
+			The number of names must match the number of items in
+			the |List|.
+			Each name can be one of the items of the ":let"
+			command as mentioned above.
+			Example: >
+				:let [s, item] = GetItem(s)
+<			Detail: {expr1} is evaluated first, then the
+			assignments are done in sequence.  This matters if
+			{name2} depends on {name1}.  Example: >
+				:let x = [0, 1]
+				:let i = 0
+				:let [i, x[i]] = [1, 2]
+				:echo x
+<			The result is [0, 2].
+
+:let [{name1}, {name2}, ...] .= {expr1}
+:let [{name1}, {name2}, ...] += {expr1}
+:let [{name1}, {name2}, ...] -= {expr1}
+			Like above, but append/add/subtract the value for each
+			|List| item.
+
+:let [{name}, ..., ; {lastname}] = {expr1}				*E452*
+			Like |:let-unpack| above, but the |List| may have more
+			items than there are names.  A list of the remaining
+			items is assigned to {lastname}.  If there are no
+			remaining items {lastname} is set to an empty list.
+			Example: >
+				:let [a, b; rest] = ["aval", "bval", 3, 4]
+<
+:let [{name}, ..., ; {lastname}] .= {expr1}
+:let [{name}, ..., ; {lastname}] += {expr1}
+:let [{name}, ..., ; {lastname}] -= {expr1}
+			Like above, but append/add/subtract the value for each
+			|List| item.
+
+						*:let=<<* *:let-heredoc*
+					*E990* *E991* *E172* *E221* *E1145*
+:let {var-name} =<< [trim] [eval] {endmarker}
+text...
+text...
+{endmarker}
+			Set internal variable {var-name} to a |List|
+			containing the lines of text bounded by the string
+			{endmarker}.
+
+			If "eval" is not specified, then each line of text is
+			used as a |literal-string|, except that single quotes
+			does not need to be doubled.
+			If "eval" is specified, then any Vim expression in the
+			form {expr} is evaluated and the result replaces the
+			expression, like with |interpolated-string|.
+			Example where $HOME is expanded: >
+				let lines =<< trim eval END
+				  some text
+				  See the file {$HOME}/.vimrc
+				  more text
+				END
+<			There can be multiple Vim expressions in a single line
+			but an expression cannot span multiple lines.  If any
+			expression evaluation fails, then the assignment fails.
+
+			{endmarker} must not contain white space.
+			{endmarker} cannot start with a lower case character.
+			The last line should end only with the {endmarker}
+			string without any other character.  Watch out for
+			white space after {endmarker}!
+
+			Without "trim" any white space characters in the lines
+			of text are preserved.  If "trim" is specified before
+			{endmarker}, then indentation is stripped so you can
+			do: >
+				let text =<< trim END
+				   if ok
+				     echo 'done'
+				   endif
+				END
+<			Results in: ["if ok", "  echo 'done'", "endif"]
+			The marker must line up with "let" and the indentation
+			of the first line is removed from all the text lines.
+			Specifically: all the leading indentation exactly
+			matching the leading indentation of the first
+			non-empty text line is stripped from the input lines.
+			All leading indentation exactly matching the leading
+			indentation before `let` is stripped from the line
+			containing {endmarker}.  Note that the difference
+			between space and tab matters here.
+
+			If {var-name} didn't exist yet, it is created.
+			Cannot be followed by another command, but can be
+			followed by a comment.
+
+			To avoid line continuation to be applied, consider
+			adding 'C' to 'cpoptions': >
+				set cpo+=C
+				let var =<< END
+				   \ leading backslash
+				END
+				set cpo-=C
+<
+			Examples: >
+				let var1 =<< END
+				Sample text 1
+				    Sample text 2
+				Sample text 3
+				END
+
+				let data =<< trim DATA
+					1 2 3 4
+					5 6 7 8
+				DATA
+
+				let code =<< trim eval CODE
+				   let v = {10 + 20}
+				   let h = "{$HOME}"
+				   let s = "{Str1()} abc {Str2()}"
+				   let n = {MyFunc(3, 4)}
+				CODE
+<
+								*E121*
+:let {var-name}	..	List the value of variable {var-name}.  Multiple
+			variable names may be given.  Special names recognized
+			here:				*E738*
+			  g:	global variables
+			  b:	local buffer variables
+			  w:	local window variables
+			  t:	local tab page variables
+			  s:	script-local variables
+			  l:	local function variables
+			  v:	Vim variables.
+			This does not work in Vim9 script. |vim9-declaration|
+
+:let			List the values of all variables.  The type of the
+			variable is indicated before the value:
+			    <nothing>	String
+				#	Number
+				*	Funcref
+			This does not work in Vim9 script. |vim9-declaration|
+
+:unl[et][!] {name} ...			*:unlet* *:unl* *E108* *E795* *E1081*
+			Remove the internal variable {name}.  Several variable
+			names can be given, they are all removed.  The name
+			may also be a |List| or |Dictionary| item.
+			With [!] no error message is given for non-existing
+			variables.
+			One or more items from a |List| can be removed: >
+				:unlet list[3]	  " remove fourth item
+				:unlet list[3:]   " remove fourth item to last
+<			One item from a |Dictionary| can be removed at a time: >
+				:unlet dict['two']
+				:unlet dict.two
+<			This is especially useful to clean up used global
+			variables and script-local variables (these are not
+			deleted when the script ends).  Function-local
+			variables are automatically deleted when the function
+			ends.
+			In |Vim9| script variables declared in a function or
+			script cannot be removed.
+
+:unl[et] ${env-name} ...			*:unlet-environment* *:unlet-$*
+			Remove environment variable {env-name}.
+			Can mix {name} and ${env-name} in one :unlet command.
+			No error message is given for a non-existing
+			variable, also without !.
+			If the system does not support deleting an environment
+			variable, it is made empty.
+
+						*:cons* *:const* *E1018*
+:cons[t] {var-name} = {expr1}
+:cons[t] [{name1}, {name2}, ...] = {expr1}
+:cons[t] [{name}, ..., ; {lastname}] = {expr1}
+:cons[t] {var-name} =<< [trim] {marker}
+text...
+text...
+{marker}
+			Similar to |:let|, but additionally lock the variable
+			after setting the value.  This is the same as locking
+			the variable with |:lockvar| just after |:let|, thus: >
+				:const x = 1
+<			is equivalent to: >
+				:let x = 1
+				:lockvar! x
+<			NOTE: in Vim9 script `:const` works differently, see
+			|vim9-const|
+			This is useful if you want to make sure the variable
+			is not modified.  If the value is a List or Dictionary
+			literal then the items also cannot be changed: >
+				const ll = [1, 2, 3]
+				let ll[1] = 5  " Error!
+<			Nested references are not locked: >
+				let lvar = ['a']
+				const lconst = [0, lvar]
+				let lconst[0] = 2  " Error!
+				let lconst[1][0] = 'b'  " OK
+<							*E995*
+			|:const| does not allow to for changing a variable: >
+				:let x = 1
+				:const x = 2  " Error!
+<							*E996*
+			Note that environment variables, option values and
+			register values cannot be used here, since they cannot
+			be locked.
+
+:cons[t]
+:cons[t] {var-name}
+			If no argument is given or only {var-name} is given,
+			the behavior is the same as |:let|.
+
+:lockv[ar][!] [depth] {name} ...			*:lockvar* *:lockv*
+			Lock the internal variable {name}.  Locking means that
+			it can no longer be changed (until it is unlocked).
+			A locked variable can be deleted: >
+				:lockvar v
+				:let v = 'asdf'	  " fails!
+				:unlet v	  " works
+<			*E741* *E940* *E1118* *E1119* *E1120* *E1121* *E1122*
+			If you try to change a locked variable you get an
+			error message: "E741: Value is locked: {name}".
+			If you try to lock or unlock a built-in variable you
+			get an error message: "E940: Cannot lock or unlock
+			variable {name}".
+
+			[depth] is relevant when locking a |List| or
+			|Dictionary|.  It specifies how deep the locking goes:
+				0	Lock the variable {name} but not its
+					value.
+				1	Lock the |List| or |Dictionary| itself,
+					cannot add or remove items, but can
+					still change their values.
+				2	Also lock the values, cannot change
+					the items.  If an item is a |List| or
+					|Dictionary|, cannot add or remove
+					items, but can still change the
+					values.
+				3	Like 2 but for the |List| /
+					|Dictionary| in the |List| /
+					|Dictionary|, one level deeper.
+			The default [depth] is 2, thus when {name} is a |List|
+			or |Dictionary| the values cannot be changed.
+
+			Example with [depth] 0: >
+				let mylist = [1, 2, 3]
+				lockvar 0 mylist
+				let mylist[0] = 77	" OK
+				call add(mylist, 4)	" OK
+				let mylist = [7, 8, 9]  " Error!
+<								*E743*
+			For unlimited depth use [!] and omit [depth].
+			However, there is a maximum depth of 100 to catch
+			loops.
+
+			Note that when two variables refer to the same |List|
+			and you lock one of them, the |List| will also be
+			locked when used through the other variable.
+			Example: >
+				:let l = [0, 1, 2, 3]
+				:let cl = l
+				:lockvar l
+				:let cl[1] = 99		" won't work!
+<			You may want to make a copy of a list to avoid this.
+			See |deepcopy()|.
+
+
+:unlo[ckvar][!] [depth] {name} ...		*:unlockvar* *:unlo* *E1246*
+			Unlock the internal variable {name}.  Does the
+			opposite of |:lockvar|.
+
+			If {name} does not exist:
+			- In |Vim9| script an error is given.
+			- In legacy script this is silently ignored.
+
+:if {expr1}			*:if* *:end* *:endif* *:en* *E171* *E579* *E580*
+:en[dif]		Execute the commands until the next matching `:else`
+			or `:endif` if {expr1} evaluates to non-zero.
+			Although the short forms work, it is recommended to
+			always use `:endif` to avoid confusion and to make
+			auto-indenting work properly.
+
+			From Vim version 4.5 until 5.0, every Ex command in
+			between the `:if` and `:endif` is ignored.  These two
+			commands were just to allow for future expansions in a
+			backward compatible way.  Nesting was allowed.  Note
+			that any `:else` or `:elseif` was ignored, the `else`
+			part was not executed either.
+
+			You can use this to remain compatible with older
+			versions: >
+				:if version >= 500
+				:  version-5-specific-commands
+				:endif
+<			The commands still need to be parsed to find the
+			`endif`.  Sometimes an older Vim has a problem with a
+			new command.  For example, `:silent` is recognized as
+			a `:substitute` command.  In that case `:execute` can
+			avoid problems: >
+				:if version >= 600
+				:  execute "silent 1,$delete"
+				:endif
+<
+			In |Vim9| script `:endif` cannot be shortened, to
+			improve script readability.
+			NOTE: The `:append` and `:insert` commands don't work
+			properly in between `:if` and `:endif`.
+
+						*:else* *:el* *E581* *E583*
+:el[se]			Execute the commands until the next matching `:else`
+			or `:endif` if they previously were not being
+			executed.
+			In |Vim9| script `:else` cannot be shortened, to
+			improve script readability.
+
+					*:elseif* *:elsei* *E582* *E584*
+:elsei[f] {expr1}	Short for `:else` `:if`, with the addition that there
+			is no extra `:endif`.
+			In |Vim9| script `:elseif` cannot be shortened, to
+			improve script readability.
+
+:wh[ile] {expr1}			*:while* *:endwhile* *:wh* *:endw*
+						*E170* *E585* *E588* *E733*
+:endw[hile]		Repeat the commands between `:while` and `:endwhile`,
+			as long as {expr1} evaluates to non-zero.
+			When an error is detected from a command inside the
+			loop, execution continues after the `endwhile`.
+			Example: >
+				:let lnum = 1
+				:while lnum <= line("$")
+				   :call FixLine(lnum)
+				   :let lnum = lnum + 1
+				:endwhile
+<
+			In |Vim9| script `:while`  and `:endwhile` cannot be
+			shortened, to improve script readability.
+			NOTE: The `:append` and `:insert` commands don't work
+			properly inside a `:while` and `:for` loop.
+
+:for {var} in {object}					*:for* *E690* *E732*
+:endfo[r]						*:endfo* *:endfor*
+			Repeat the commands between `:for` and `:endfor` for
+			each item in {object}.  {object} can be a |List|,
+			a |Blob| or a |String|. *E1177*
+
+			Variable {var} is set to the value of each item.
+			In |Vim9| script the loop variable must not have been
+			declared yet, unless when it is a
+			global/window/tab/buffer variable.
+
+			When an error is detected for a command inside the
+			loop, execution continues after the `endfor`.
+			Changing {object} inside the loop affects what items
+			are used.  Make a copy if this is unwanted: >
+				:for item in copy(mylist)
+<
+			When {object} is a |List| and not making a copy, in
+			legacy script Vim stores a reference to the next item
+			in the |List| before executing the commands with the
+			current item.  Thus the current item can be removed
+			without effect.  Removing any later item means it will
+			not be found.  Thus the following example works (an
+			inefficient way to make a |List| empty): >
+				for item in mylist
+				   call remove(mylist, 0)
+				endfor
+<			Note that reordering the |List| (e.g., with sort() or
+			reverse()) may have unexpected effects.
+			In |Vim9| script the index is used.  If an item before
+			the current one is deleted the next item will be
+			skipped.
+
+			When {object} is a |Blob|, Vim always makes a copy to
+			iterate over.  Unlike with |List|, modifying the
+			|Blob| does not affect the iteration.
+
+			When {object} is a |String| each item is a string with
+			one character, plus any combining characters.
+
+			In |Vim9| script `:endfor` cannot be shortened, to
+			improve script readability.
+
+:for [{var1}, {var2}, ...] in {listlist}
+:endfo[r]							*E1140*
+			Like `:for` above, but each item in {listlist} must be
+			a list, of which each item is assigned to {var1},
+			{var2}, etc.  Example: >
+				:for [lnum, col] in [[1, 3], [2, 5], [3, 8]]
+				   :echo getline(lnum)[col]
+				:endfor
+<
+						*:continue* *:con* *E586*
+:con[tinue]		When used inside a `:while` or `:for` loop, jumps back
+			to the start of the loop.
+			If it is used after a `:try` inside the loop but
+			before the matching `:finally` (if present), the
+			commands following the `:finally` up to the matching
+			`:endtry` are executed first.  This process applies to
+			all nested `:try`s inside the loop.  The outermost
+			`:endtry` then jumps back to the start of the loop.
+
+			In |Vim9| script `:cont` is the shortest form, to
+			improve script readability.
+						*:break* *:brea* *E587*
+:brea[k]		When used inside a `:while` or `:for` loop, skips to
+			the command after the matching `:endwhile` or
+			`:endfor`.
+			If it is used after a `:try` inside the loop but
+			before the matching `:finally` (if present), the
+			commands following the `:finally` up to the matching
+			`:endtry` are executed first.  This process applies to
+			all nested `:try`s inside the loop.  The outermost
+			`:endtry` then jumps to the command after the loop.
+
+			In |Vim9| script `:break` cannot be shortened, to
+			improve script readability.
+
+:try						*:try* *:endt* *:endtry*
+						*E600* *E601* *E602* *E1032*
+:endt[ry]		Change the error handling for the commands between
+			`:try` and `:endtry` including everything being
+			executed across `:source` commands, function calls,
+			or autocommand invocations.
+
+			When an error or interrupt is detected and there is
+			a `:finally` command following, execution continues
+			after the `:finally`.  Otherwise, or when the
+			`:endtry` is reached thereafter, the next
+			(dynamically) surrounding `:try` is checked for
+			a corresponding `:finally` etc.  Then the script
+			processing is terminated.  Whether a function
+			definition has an "abort" argument does not matter.
+			Example: >
+		try | call Unknown() | finally | echomsg "cleanup" | endtry
+		echomsg "not reached"
+<
+			Moreover, an error or interrupt (dynamically) inside
+			`:try` and `:endtry` is converted to an exception.  It
+			can be caught as if it were thrown by a `:throw`
+			command (see `:catch`).  In this case, the script
+			processing is not terminated.
+
+			The value "Vim:Interrupt" is used for an interrupt
+			exception.  An error in a Vim command is converted
+			to a value of the form "Vim({command}):{errmsg}",
+			other errors are converted to a value of the form
+			"Vim:{errmsg}".  {command} is the full command name,
+			and {errmsg} is the message that is displayed if the
+			error exception is not caught, always beginning with
+			the error number.
+			Examples: >
+		try | sleep 100 | catch /^Vim:Interrupt$/ | endtry
+		try | edit | catch /^Vim(edit):E\d\+/ | echo "error" | endtry
+<
+			In |Vim9| script `:endtry` cannot be shortened, to
+			improve script readability.
+
+					*:cat* *:catch*
+					*E603* *E604* *E605* *E654* *E1033*
+:cat[ch] /{pattern}/	The following commands until the next `:catch`,
+			`:finally`, or `:endtry` that belongs to the same
+			`:try` as the `:catch` are executed when an exception
+			matching {pattern} is being thrown and has not yet
+			been caught by a previous `:catch`.  Otherwise, these
+			commands are skipped.
+			When {pattern} is omitted all errors are caught.
+			Examples: >
+		:catch /^Vim:Interrupt$/	 " catch interrupts (CTRL-C)
+		:catch /^Vim\%((\a\+)\)\=:E/	 " catch all Vim errors
+		:catch /^Vim\%((\a\+)\)\=:/	 " catch errors and interrupts
+		:catch /^Vim(write):/		 " catch all errors in :write
+		:catch /^Vim\%((\a\+)\)\=:E123:/ " catch error E123
+		:catch /my-exception/		 " catch user exception
+		:catch /.*/			 " catch everything
+		:catch				 " same as /.*/
+<
+			Another character can be used instead of / around the
+			{pattern}, so long as it does not have a special
+			meaning (e.g., '|' or '"') and doesn't occur inside
+			{pattern}. *E1067*
+			Information about the exception is available in
+			|v:exception|.  Also see |throw-variables|.
+			NOTE: It is not reliable to ":catch" the TEXT of
+			an error message because it may vary in different
+			locales.
+			In |Vim9| script `:catch` cannot be shortened, to
+			improve script readability.
+
+					*:fina* *:finally* *E606* *E607*
+:fina[lly]		The following commands until the matching `:endtry`
+			are executed whenever the part between the matching
+			`:try` and the `:finally` is left:  either by falling
+			through to the `:finally` or by a `:continue`,
+			`:break`, `:finish`, or `:return`, or by an error or
+			interrupt or exception (see `:throw`).
+
+			In |Vim9| script `:finally` cannot be shortened, to
+			improve script readability and avoid confusion with
+			`:final`.
+
+						*:th* *:throw* *E608* *E1129*
+:th[row] {expr1}	The {expr1} is evaluated and thrown as an exception.
+			If the ":throw" is used after a `:try` but before the
+			first corresponding `:catch`, commands are skipped
+			until the first `:catch` matching {expr1} is reached.
+			If there is no such `:catch` or if the ":throw" is
+			used after a `:catch` but before the `:finally`, the
+			commands following the `:finally` (if present) up to
+			the matching `:endtry` are executed.  If the `:throw`
+			is after the `:finally`, commands up to the `:endtry`
+			are skipped.  At the ":endtry", this process applies
+			again for the next dynamically surrounding `:try`
+			(which may be found in a calling function or sourcing
+			script), until a matching `:catch` has been found.
+			If the exception is not caught, the command processing
+			is terminated.
+			Example: >
+		:try | throw "oops" | catch /^oo/ | echo "caught" | endtry
+<			Note that "catch" may need to be on a separate line
+			for when an error causes the parsing to skip the whole
+			line and not see the "|" that separates the commands.
+
+			In |Vim9| script `:throw` cannot be shortened, to
+			improve script readability.
+
+							*:ec* *:echo*
+:ec[ho] {expr1} ..	Echoes each {expr1}, with a space in between.  The
+			first {expr1} starts on a new line.
+			Also see |:comment|.
+			Use "\n" to start a new line.  Use "\r" to move the
+			cursor to the first column.
+			Uses the highlighting set by the `:echohl` command.
+			Cannot be followed by a comment.
+			Example: >
+		:echo "the value of 'shell' is" &shell
+<							*:echo-redraw*
+			A later redraw may make the message disappear again.
+			And since Vim mostly postpones redrawing until it's
+			finished with a sequence of commands this happens
+			quite often.  To avoid that a command from before the
+			`:echo` causes a redraw afterwards (redraws are often
+			postponed until you type something), force a redraw
+			with the `:redraw` command.  Example: >
+		:new | redraw | echo "there is a new window"
+<
+							*:echon*
+:echon {expr1} ..	Echoes each {expr1}, without anything added.  Also see
+			|:comment|.
+			Uses the highlighting set by the `:echohl` command.
+			Cannot be followed by a comment.
+			Example: >
+				:echon "the value of 'shell' is " &shell
+<
+			Note the difference between using `:echo`, which is a
+			Vim command, and `:!echo`, which is an external shell
+			command: >
+		:!echo %		--> filename
+<			The arguments of ":!" are expanded, see |:_%|. >
+		:!echo "%"		--> filename or "filename"
+<			Like the previous example.  Whether you see the double
+			quotes or not depends on your 'shell'. >
+		:echo %			--> nothing
+<			The '%' is an illegal character in an expression. >
+		:echo "%"		--> %
+<			This just echoes the '%' character. >
+		:echo expand("%")	--> filename
+<			This calls the expand() function to expand the '%'.
+
+							*:echoh* *:echohl*
+:echoh[l] {name}	Use the highlight group {name} for the following
+			`:echo`, `:echon` and `:echomsg` commands.  Also used
+			for the `input()` prompt.  Example: >
+		:echohl WarningMsg | echo "Don't panic!" | echohl None
+<			Don't forget to set the group back to "None",
+			otherwise all following echo's will be highlighted.
+
+							*:echom* *:echomsg*
+:echom[sg] {expr1} ..	Echo the expression(s) as a true message, saving the
+			message in the |message-history|.
+			Spaces are placed between the arguments as with the
+			`:echo` command.  But unprintable characters are
+			displayed, not interpreted.
+			The parsing works slightly different from `:echo`,
+			more like `:execute`.  All the expressions are first
+			evaluated and concatenated before echoing anything.
+			If expressions does not evaluate to a Number or
+			String, string() is used to turn it into a string.
+			Uses the highlighting set by the `:echohl` command.
+			Example: >
+		:echomsg "It's a Zizzer Zazzer Zuzz, as you can plainly see."
+<			See |:echo-redraw| to avoid the message disappearing
+			when the screen is redrawn.
+
+					*:echow* *:echowin* *:echowindow*
+:[N]echow[indow] {expr1} ..
+			Like |:echomsg| but when the messages popup window is
+			available the message is displayed there.  This means
+			it will show for three seconds and avoid a
+			|hit-enter| prompt.  If you want to hide it before
+			that, press Esc in Normal mode (when it would
+			otherwise beep).  If it disappears too soon you can
+			use `:messages` to see the text.
+			When [N] is given then the window will show up for
+			this number of seconds.  The last `:echowindow` with a
+			count matters, it is used once only.
+			The message window is available when Vim was compiled
+			with the +timer and the +popupwin features.
+
+							*:echoe* *:echoerr*
+:echoe[rr] {expr1} ..	Echo the expression(s) as an error message, saving the
+			message in the |message-history|.  When used in a
+			script or function the line number will be added.
+			Spaces are placed between the arguments as with the
+			`:echomsg` command.  When used inside a try conditional,
+			the message is raised as an error exception instead
+			(see |try-echoerr|).
+			Example: >
+		:echoerr "This script just failed!"
+<			If you just want a highlighted message use `:echohl`.
+			And to get a beep: >
+		:exe "normal \<Esc>"
+
+:echoc[onsole] {expr1} ..				*:echoc* *:echoconsole*
+			Intended for testing: works like `:echomsg` but when
+			running in the GUI and started from a terminal write
+			the text to stdout.
+
+							*:eval*
+:eval {expr}		Evaluate {expr} and discard the result.  Example: >
+				:eval Getlist()->Filter()->append('$')
+
+<			The expression is supposed to have a side effect,
+			since the resulting value is not used.  In the example
+			the `append()` call appends the List with text to the
+			buffer.  This is similar to `:call` but works with any
+			expression.
+			In |Vim9| script an expression without an effect will
+			result in error *E1207* .  This should help noticing
+			mistakes.
+
+			The command can be shortened to `:ev` or `:eva`, but
+			these are hard to recognize and therefore not to be
+			used.
+
+			The command cannot be followed by "|" and another
+			command, since "|" is seen as part of the expression.
+
+
+							*:exe* *:execute*
+:exe[cute] {expr1} ..	Executes the string that results from the evaluation
+			of {expr1} as an Ex command.
+			Multiple arguments are concatenated, with a space in
+			between.  To avoid the extra space use the ".."
+			operator to concatenate strings into one argument.
+			{expr1} is used as the processed command, command line
+			editing keys are not recognized.
+			Cannot be followed by a comment.
+			Examples: >
+		:execute "buffer" nextbuf
+		:execute "normal" count .. "w"
+<
+			":execute" can be used to append a command to commands
+			that don't accept a '|'.  Example: >
+		:execute '!ls' | echo "theend"
+
+<			":execute" is also a nice way to avoid having to type
+			control characters in a Vim script for a ":normal"
+			command: >
+		:execute "normal ixxx\<Esc>"
+<			This has an <Esc> character, see |expr-string|.
+
+			Be careful to correctly escape special characters in
+			file names.  The |fnameescape()| function can be used
+			for Vim commands, |shellescape()| for |:!| commands.
+			Examples: >
+		:execute "e " .. fnameescape(filename)
+		:execute "!ls " .. shellescape(filename, 1)
+<
+			Note: The executed string may be any command-line, but
+			starting or ending "if", "while" and "for" does not
+			always work, because when commands are skipped the
+			":execute" is not evaluated and Vim loses track of
+			where blocks start and end.  Also "break" and
+			"continue" should not be inside ":execute".
+			This example does not work, because the ":execute" is
+			not evaluated and Vim does not see the "while", and
+			gives an error for finding an ":endwhile": >
+		:if 0
+		: execute 'while i > 5'
+		:  echo "test"
+		: endwhile
+		:endif
+<
+			It is allowed to have a "while" or "if" command
+			completely in the executed string: >
+		:execute 'while i < 5 | echo i | let i = i + 1 | endwhile'
+<
+
+							*:exe-comment*
+			":execute", ":echo" and ":echon" cannot be followed by
+			a comment directly, because they see the '"' as the
+			start of a string.  But, you can use '|' followed by a
+			comment.  Example: >
+		:echo "foo" | "this is a comment
+
+==============================================================================
+8. Exception handling					*exception-handling*
+
+The Vim script language comprises an exception handling feature.  This section
+explains how it can be used in a Vim script.
+
+Exceptions may be raised by Vim on an error or on interrupt, see
+|catch-errors| and |catch-interrupt|.  You can also explicitly throw an
+exception by using the ":throw" command, see |throw-catch|.
+
+
+TRY CONDITIONALS					*try-conditionals*
+
+Exceptions can be caught or can cause cleanup code to be executed.  You can
+use a try conditional to specify catch clauses (that catch exceptions) and/or
+a finally clause (to be executed for cleanup).
+   A try conditional begins with a |:try| command and ends at the matching
+|:endtry| command.  In between, you can use a |:catch| command to start
+a catch clause, or a |:finally| command to start a finally clause.  There may
+be none or multiple catch clauses, but there is at most one finally clause,
+which must not be followed by any catch clauses.  The lines before the catch
+clauses and the finally clause is called a try block. >
+
+     :try
+     :	...
+     :	...				TRY BLOCK
+     :	...
+     :catch /{pattern}/
+     :	...
+     :	...				CATCH CLAUSE
+     :	...
+     :catch /{pattern}/
+     :	...
+     :	...				CATCH CLAUSE
+     :	...
+     :finally
+     :	...
+     :	...				FINALLY CLAUSE
+     :	...
+     :endtry
+
+The try conditional allows to watch code for exceptions and to take the
+appropriate actions.  Exceptions from the try block may be caught.  Exceptions
+from the try block and also the catch clauses may cause cleanup actions.
+   When no exception is thrown during execution of the try block, the control
+is transferred to the finally clause, if present.  After its execution, the
+script continues with the line following the ":endtry".
+   When an exception occurs during execution of the try block, the remaining
+lines in the try block are skipped.  The exception is matched against the
+patterns specified as arguments to the ":catch" commands.  The catch clause
+after the first matching ":catch" is taken, other catch clauses are not
+executed.  The catch clause ends when the next ":catch", ":finally", or
+":endtry" command is reached - whatever is first.  Then, the finally clause
+(if present) is executed.  When the ":endtry" is reached, the script execution
+continues in the following line as usual.
+   When an exception that does not match any of the patterns specified by the
+":catch" commands is thrown in the try block, the exception is not caught by
+that try conditional and none of the catch clauses is executed.  Only the
+finally clause, if present, is taken.  The exception pends during execution of
+the finally clause.  It is resumed at the ":endtry", so that commands after
+the ":endtry" are not executed and the exception might be caught elsewhere,
+see |try-nesting|.
+   When during execution of a catch clause another exception is thrown, the
+remaining lines in that catch clause are not executed.  The new exception is
+not matched against the patterns in any of the ":catch" commands of the same
+try conditional and none of its catch clauses is taken.  If there is, however,
+a finally clause, it is executed, and the exception pends during its
+execution.  The commands following the ":endtry" are not executed.  The new
+exception might, however, be caught elsewhere, see |try-nesting|.
+   When during execution of the finally clause (if present) an exception is
+thrown, the remaining lines in the finally clause are skipped.  If the finally
+clause has been taken because of an exception from the try block or one of the
+catch clauses, the original (pending) exception is discarded.  The commands
+following the ":endtry" are not executed, and the exception from the finally
+clause is propagated and can be caught elsewhere, see |try-nesting|.
+
+The finally clause is also executed, when a ":break" or ":continue" for
+a ":while" loop enclosing the complete try conditional is executed from the
+try block or a catch clause.  Or when a ":return" or ":finish" is executed
+from the try block or a catch clause of a try conditional in a function or
+sourced script, respectively.  The ":break", ":continue", ":return", or
+":finish" pends during execution of the finally clause and is resumed when the
+":endtry" is reached.  It is, however, discarded when an exception is thrown
+from the finally clause.
+   When a ":break" or ":continue" for a ":while" loop enclosing the complete
+try conditional or when a ":return" or ":finish" is encountered in the finally
+clause, the rest of the finally clause is skipped, and the ":break",
+":continue", ":return" or ":finish" is executed as usual.  If the finally
+clause has been taken because of an exception or an earlier ":break",
+":continue", ":return", or ":finish" from the try block or a catch clause,
+this pending exception or command is discarded.
+
+For examples see |throw-catch| and |try-finally|.
+
+
+NESTING OF TRY CONDITIONALS				*try-nesting*
+
+Try conditionals can be nested arbitrarily.  That is, a complete try
+conditional can be put into the try block, a catch clause, or the finally
+clause of another try conditional.  If the inner try conditional does not
+catch an exception thrown in its try block or throws a new exception from one
+of its catch clauses or its finally clause, the outer try conditional is
+checked according to the rules above.  If the inner try conditional is in the
+try block of the outer try conditional, its catch clauses are checked, but
+otherwise only the finally clause is executed.  It does not matter for
+nesting, whether the inner try conditional is directly contained in the outer
+one, or whether the outer one sources a script or calls a function containing
+the inner try conditional.
+
+When none of the active try conditionals catches an exception, just their
+finally clauses are executed.  Thereafter, the script processing terminates.
+An error message is displayed in case of an uncaught exception explicitly
+thrown by a ":throw" command.  For uncaught error and interrupt exceptions
+implicitly raised by Vim, the error message(s) or interrupt message are shown
+as usual.
+
+For examples see |throw-catch|.
+
+
+EXAMINING EXCEPTION HANDLING CODE			*except-examine*
+
+Exception handling code can get tricky.  If you are in doubt what happens, set
+'verbose' to 13 or use the ":13verbose" command modifier when sourcing your
+script file.  Then you see when an exception is thrown, discarded, caught, or
+finished.  When using a verbosity level of at least 14, things pending in
+a finally clause are also shown.  This information is also given in debug mode
+(see |debug-scripts|).
+
+
+THROWING AND CATCHING EXCEPTIONS			*throw-catch*
+
+You can throw any number or string as an exception.  Use the |:throw| command
+and pass the value to be thrown as argument: >
+	:throw 4711
+	:throw "string"
+<							*throw-expression*
+You can also specify an expression argument.  The expression is then evaluated
+first, and the result is thrown: >
+	:throw 4705 + strlen("string")
+	:throw strpart("strings", 0, 6)
+
+An exception might be thrown during evaluation of the argument of the ":throw"
+command.  Unless it is caught there, the expression evaluation is abandoned.
+The ":throw" command then does not throw a new exception.
+   Example: >
+
+	:function! Foo(arg)
+	:  try
+	:    throw a:arg
+	:  catch /foo/
+	:  endtry
+	:  return 1
+	:endfunction
+	:
+	:function! Bar()
+	:  echo "in Bar"
+	:  return 4710
+	:endfunction
+	:
+	:throw Foo("arrgh") + Bar()
+
+This throws "arrgh", and "in Bar" is not displayed since Bar() is not
+executed. >
+	:throw Foo("foo") + Bar()
+however displays "in Bar" and throws 4711.
+
+Any other command that takes an expression as argument might also be
+abandoned by an (uncaught) exception during the expression evaluation.  The
+exception is then propagated to the caller of the command.
+   Example: >
+
+	:if Foo("arrgh")
+	:  echo "then"
+	:else
+	:  echo "else"
+	:endif
+
+Here neither of "then" or "else" is displayed.
+
+							*catch-order*
+Exceptions can be caught by a try conditional with one or more |:catch|
+commands, see |try-conditionals|.   The values to be caught by each ":catch"
+command can be specified as a pattern argument.  The subsequent catch clause
+gets executed when a matching exception is caught.
+   Example: >
+
+	:function! Foo(value)
+	:  try
+	:    throw a:value
+	:  catch /^\d\+$/
+	:    echo "Number thrown"
+	:  catch /.*/
+	:    echo "String thrown"
+	:  endtry
+	:endfunction
+	:
+	:call Foo(0x1267)
+	:call Foo('string')
+
+The first call to Foo() displays "Number thrown", the second "String thrown".
+An exception is matched against the ":catch" commands in the order they are
+specified.  Only the first match counts.  So you should place the more
+specific ":catch" first.  The following order does not make sense: >
+
+	:  catch /.*/
+	:    echo "String thrown"
+	:  catch /^\d\+$/
+	:    echo "Number thrown"
+
+The first ":catch" here matches always, so that the second catch clause is
+never taken.
+
+							*throw-variables*
+If you catch an exception by a general pattern, you may access the exact value
+in the variable |v:exception|: >
+
+	:  catch /^\d\+$/
+	:    echo "Number thrown.  Value is" v:exception
+
+You may also be interested where an exception was thrown.  This is stored in
+|v:throwpoint|.  Note that "v:exception" and "v:throwpoint" are valid for the
+exception most recently caught as long it is not finished.
+   Example: >
+
+	:function! Caught()
+	:  if v:exception != ""
+	:    echo 'Caught "' . v:exception .. '" in ' .. v:throwpoint
+	:  else
+	:    echo 'Nothing caught'
+	:  endif
+	:endfunction
+	:
+	:function! Foo()
+	:  try
+	:    try
+	:      try
+	:	 throw 4711
+	:      finally
+	:	 call Caught()
+	:      endtry
+	:    catch /.*/
+	:      call Caught()
+	:      throw "oops"
+	:    endtry
+	:  catch /.*/
+	:    call Caught()
+	:  finally
+	:    call Caught()
+	:  endtry
+	:endfunction
+	:
+	:call Foo()
+
+This displays >
+
+	Nothing caught
+	Caught "4711" in function Foo, line 4
+	Caught "oops" in function Foo, line 10
+	Nothing caught
+
+A practical example:  The following command ":LineNumber" displays the line
+number in the script or function where it has been used: >
+
+	:function! LineNumber()
+	:    return substitute(v:throwpoint, '.*\D\(\d\+\).*', '\1', "")
+	:endfunction
+	:command! LineNumber try | throw "" | catch | echo LineNumber() | endtry
+<
+							*try-nested*
+An exception that is not caught by a try conditional can be caught by
+a surrounding try conditional: >
+
+	:try
+	:  try
+	:    throw "foo"
+	:  catch /foobar/
+	:    echo "foobar"
+	:  finally
+	:    echo "inner finally"
+	:  endtry
+	:catch /foo/
+	:  echo "foo"
+	:endtry
+
+The inner try conditional does not catch the exception, just its finally
+clause is executed.  The exception is then caught by the outer try
+conditional.  The example displays "inner finally" and then "foo".
+
+							*throw-from-catch*
+You can catch an exception and throw a new one to be caught elsewhere from the
+catch clause: >
+
+	:function! Foo()
+	:  throw "foo"
+	:endfunction
+	:
+	:function! Bar()
+	:  try
+	:    call Foo()
+	:  catch /foo/
+	:    echo "Caught foo, throw bar"
+	:    throw "bar"
+	:  endtry
+	:endfunction
+	:
+	:try
+	:  call Bar()
+	:catch /.*/
+	:  echo "Caught" v:exception
+	:endtry
+
+This displays "Caught foo, throw bar" and then "Caught bar".
+
+							*rethrow*
+There is no real rethrow in the Vim script language, but you may throw
+"v:exception" instead: >
+
+	:function! Bar()
+	:  try
+	:    call Foo()
+	:  catch /.*/
+	:    echo "Rethrow" v:exception
+	:    throw v:exception
+	:  endtry
+	:endfunction
+<							*try-echoerr*
+Note that this method cannot be used to "rethrow" Vim error or interrupt
+exceptions, because it is not possible to fake Vim internal exceptions.
+Trying so causes an error exception.  You should throw your own exception
+denoting the situation.  If you want to cause a Vim error exception containing
+the original error exception value, you can use the |:echoerr| command: >
+
+	:try
+	:  try
+	:    asdf
+	:  catch /.*/
+	:    echoerr v:exception
+	:  endtry
+	:catch /.*/
+	:  echo v:exception
+	:endtry
+
+This code displays
+
+	Vim(echoerr):Vim:E492: Not an editor command:	asdf ~
+
+
+CLEANUP CODE						*try-finally*
+
+Scripts often change global settings and restore them at their end.  If the
+user however interrupts the script by pressing CTRL-C, the settings remain in
+an inconsistent state.  The same may happen to you in the development phase of
+a script when an error occurs or you explicitly throw an exception without
+catching it.  You can solve these problems by using a try conditional with
+a finally clause for restoring the settings.  Its execution is guaranteed on
+normal control flow, on error, on an explicit ":throw", and on interrupt.
+(Note that errors and interrupts from inside the try conditional are converted
+to exceptions.  When not caught, they terminate the script after the finally
+clause has been executed.)
+Example: >
+
+	:try
+	:  let s:saved_ts = &ts
+	:  set ts=17
+	:
+	:  " Do the hard work here.
+	:
+	:finally
+	:  let &ts = s:saved_ts
+	:  unlet s:saved_ts
+	:endtry
+
+This method should be used locally whenever a function or part of a script
+changes global settings which need to be restored on failure or normal exit of
+that function or script part.
+
+							*break-finally*
+Cleanup code works also when the try block or a catch clause is left by
+a ":continue", ":break", ":return", or ":finish".
+   Example: >
+
+	:let first = 1
+	:while 1
+	:  try
+	:    if first
+	:      echo "first"
+	:      let first = 0
+	:      continue
+	:    else
+	:      throw "second"
+	:    endif
+	:  catch /.*/
+	:    echo v:exception
+	:    break
+	:  finally
+	:    echo "cleanup"
+	:  endtry
+	:  echo "still in while"
+	:endwhile
+	:echo "end"
+
+This displays "first", "cleanup", "second", "cleanup", and "end". >
+
+	:function! Foo()
+	:  try
+	:    return 4711
+	:  finally
+	:    echo "cleanup\n"
+	:  endtry
+	:  echo "Foo still active"
+	:endfunction
+	:
+	:echo Foo() "returned by Foo"
+
+This displays "cleanup" and "4711 returned by Foo".  You don't need to add an
+extra ":return" in the finally clause.  (Above all, this would override the
+return value.)
+
+							*except-from-finally*
+Using either of ":continue", ":break", ":return", ":finish", or ":throw" in
+a finally clause is possible, but not recommended since it abandons the
+cleanup actions for the try conditional.  But, of course, interrupt and error
+exceptions might get raised from a finally clause.
+   Example where an error in the finally clause stops an interrupt from
+working correctly: >
+
+	:try
+	:  try
+	:    echo "Press CTRL-C for interrupt"
+	:    while 1
+	:    endwhile
+	:  finally
+	:    unlet novar
+	:  endtry
+	:catch /novar/
+	:endtry
+	:echo "Script still running"
+	:sleep 1
+
+If you need to put commands that could fail into a finally clause, you should
+think about catching or ignoring the errors in these commands, see
+|catch-errors| and |ignore-errors|.
+
+
+CATCHING ERRORS						*catch-errors*
+
+If you want to catch specific errors, you just have to put the code to be
+watched in a try block and add a catch clause for the error message.  The
+presence of the try conditional causes all errors to be converted to an
+exception.  No message is displayed and |v:errmsg| is not set then.  To find
+the right pattern for the ":catch" command, you have to know how the format of
+the error exception is.
+   Error exceptions have the following format: >
+
+	Vim({cmdname}):{errmsg}
+or >
+	Vim:{errmsg}
+
+{cmdname} is the name of the command that failed; the second form is used when
+the command name is not known.  {errmsg} is the error message usually produced
+when the error occurs outside try conditionals.  It always begins with
+a capital "E", followed by a two or three-digit error number, a colon, and
+a space.
+
+Examples:
+
+The command >
+	:unlet novar
+normally produces the error message >
+	E108: No such variable: "novar"
+which is converted inside try conditionals to an exception >
+	Vim(unlet):E108: No such variable: "novar"
+
+The command >
+	:dwim
+normally produces the error message >
+	E492: Not an editor command: dwim
+which is converted inside try conditionals to an exception >
+	Vim:E492: Not an editor command: dwim
+
+You can catch all ":unlet" errors by a >
+	:catch /^Vim(unlet):/
+or all errors for misspelled command names by a >
+	:catch /^Vim:E492:/
+
+Some error messages may be produced by different commands: >
+	:function nofunc
+and >
+	:delfunction nofunc
+both produce the error message >
+	E128: Function name must start with a capital: nofunc
+which is converted inside try conditionals to an exception >
+	Vim(function):E128: Function name must start with a capital: nofunc
+or >
+	Vim(delfunction):E128: Function name must start with a capital: nofunc
+respectively.  You can catch the error by its number independently on the
+command that caused it if you use the following pattern: >
+	:catch /^Vim(\a\+):E128:/
+
+Some commands like >
+	:let x = novar
+produce multiple error messages, here: >
+	E121: Undefined variable: novar
+	E15: Invalid expression:  novar
+Only the first is used for the exception value, since it is the most specific
+one (see |except-several-errors|).  So you can catch it by >
+	:catch /^Vim(\a\+):E121:/
+
+You can catch all errors related to the name "nofunc" by >
+	:catch /\<nofunc\>/
+
+You can catch all Vim errors in the ":write" and ":read" commands by >
+	:catch /^Vim(\(write\|read\)):E\d\+:/
+
+You can catch all Vim errors by the pattern >
+	:catch /^Vim\((\a\+)\)\=:E\d\+:/
+<
+							*catch-text*
+NOTE: You should never catch the error message text itself: >
+	:catch /No such variable/
+only works in the English locale, but not when the user has selected
+a different language by the |:language| command.  It is however helpful to
+cite the message text in a comment: >
+	:catch /^Vim(\a\+):E108:/   " No such variable
+
+
+IGNORING ERRORS						*ignore-errors*
+
+You can ignore errors in a specific Vim command by catching them locally: >
+
+	:try
+	:  write
+	:catch
+	:endtry
+
+But you are strongly recommended NOT to use this simple form, since it could
+catch more than you want.  With the ":write" command, some autocommands could
+be executed and cause errors not related to writing, for instance: >
+
+	:au BufWritePre * unlet novar
+
+There could even be such errors you are not responsible for as a script
+writer: a user of your script might have defined such autocommands.  You would
+then hide the error from the user.
+   It is much better to use >
+
+	:try
+	:  write
+	:catch /^Vim(write):/
+	:endtry
+
+which only catches real write errors.  So catch only what you'd like to ignore
+intentionally.
+
+For a single command that does not cause execution of autocommands, you could
+even suppress the conversion of errors to exceptions by the ":silent!"
+command: >
+	:silent! nunmap k
+This works also when a try conditional is active.
+
+
+CATCHING INTERRUPTS					*catch-interrupt*
+
+When there are active try conditionals, an interrupt (CTRL-C) is converted to
+the exception "Vim:Interrupt".  You can catch it like every exception.  The
+script is not terminated, then.
+   Example: >
+
+	:function! TASK1()
+	:  sleep 10
+	:endfunction
+
+	:function! TASK2()
+	:  sleep 20
+	:endfunction
+
+	:while 1
+	:  let command = input("Type a command: ")
+	:  try
+	:    if command == ""
+	:      continue
+	:    elseif command == "END"
+	:      break
+	:    elseif command == "TASK1"
+	:      call TASK1()
+	:    elseif command == "TASK2"
+	:      call TASK2()
+	:    else
+	:      echo "\nIllegal command:" command
+	:      continue
+	:    endif
+	:  catch /^Vim:Interrupt$/
+	:    echo "\nCommand interrupted"
+	:    " Caught the interrupt.  Continue with next prompt.
+	:  endtry
+	:endwhile
+
+You can interrupt a task here by pressing CTRL-C; the script then asks for
+a new command.  If you press CTRL-C at the prompt, the script is terminated.
+
+For testing what happens when CTRL-C would be pressed on a specific line in
+your script, use the debug mode and execute the |>quit| or |>interrupt|
+command on that line.  See |debug-scripts|.
+
+
+CATCHING ALL						*catch-all*
+
+The commands >
+
+	:catch /.*/
+	:catch //
+	:catch
+
+catch everything, error exceptions, interrupt exceptions and exceptions
+explicitly thrown by the |:throw| command.  This is useful at the top level of
+a script in order to catch unexpected things.
+   Example: >
+
+	:try
+	:
+	:  " do the hard work here
+	:
+	:catch /MyException/
+	:
+	:  " handle known problem
+	:
+	:catch /^Vim:Interrupt$/
+	:    echo "Script interrupted"
+	:catch /.*/
+	:  echo "Internal error (" .. v:exception .. ")"
+	:  echo " - occurred at " .. v:throwpoint
+	:endtry
+	:" end of script
+
+Note: Catching all might catch more things than you want.  Thus, you are
+strongly encouraged to catch only for problems that you can really handle by
+specifying a pattern argument to the ":catch".
+   Example: Catching all could make it nearly impossible to interrupt a script
+by pressing CTRL-C: >
+
+	:while 1
+	:  try
+	:    sleep 1
+	:  catch
+	:  endtry
+	:endwhile
+
+
+EXCEPTIONS AND AUTOCOMMANDS				*except-autocmd*
+
+Exceptions may be used during execution of autocommands.  Example: >
+
+	:autocmd User x try
+	:autocmd User x   throw "Oops!"
+	:autocmd User x catch
+	:autocmd User x   echo v:exception
+	:autocmd User x endtry
+	:autocmd User x throw "Arrgh!"
+	:autocmd User x echo "Should not be displayed"
+	:
+	:try
+	:  doautocmd User x
+	:catch
+	:  echo v:exception
+	:endtry
+
+This displays "Oops!" and "Arrgh!".
+
+							*except-autocmd-Pre*
+For some commands, autocommands get executed before the main action of the
+command takes place.  If an exception is thrown and not caught in the sequence
+of autocommands, the sequence and the command that caused its execution are
+abandoned and the exception is propagated to the caller of the command.
+   Example: >
+
+	:autocmd BufWritePre * throw "FAIL"
+	:autocmd BufWritePre * echo "Should not be displayed"
+	:
+	:try
+	:  write
+	:catch
+	:  echo "Caught:" v:exception "from" v:throwpoint
+	:endtry
+
+Here, the ":write" command does not write the file currently being edited (as
+you can see by checking 'modified'), since the exception from the BufWritePre
+autocommand abandons the ":write".  The exception is then caught and the
+script displays: >
+
+	Caught: FAIL from BufWrite Auto commands for "*"
+<
+							*except-autocmd-Post*
+For some commands, autocommands get executed after the main action of the
+command has taken place.  If this main action fails and the command is inside
+an active try conditional, the autocommands are skipped and an error exception
+is thrown that can be caught by the caller of the command.
+   Example: >
+
+	:autocmd BufWritePost * echo "File successfully written!"
+	:
+	:try
+	:  write /i/m/p/o/s/s/i/b/l/e
+	:catch
+	:  echo v:exception
+	:endtry
+
+This just displays: >
+
+	Vim(write):E212: Can't open file for writing (/i/m/p/o/s/s/i/b/l/e)
+
+If you really need to execute the autocommands even when the main action
+fails, trigger the event from the catch clause.
+   Example: >
+
+	:autocmd BufWritePre  * set noreadonly
+	:autocmd BufWritePost * set readonly
+	:
+	:try
+	:  write /i/m/p/o/s/s/i/b/l/e
+	:catch
+	:  doautocmd BufWritePost /i/m/p/o/s/s/i/b/l/e
+	:endtry
+<
+You can also use ":silent!": >
+
+	:let x = "ok"
+	:let v:errmsg = ""
+	:autocmd BufWritePost * if v:errmsg != ""
+	:autocmd BufWritePost *   let x = "after fail"
+	:autocmd BufWritePost * endif
+	:try
+	:  silent! write /i/m/p/o/s/s/i/b/l/e
+	:catch
+	:endtry
+	:echo x
+
+This displays "after fail".
+
+If the main action of the command does not fail, exceptions from the
+autocommands will be catchable by the caller of the command:  >
+
+	:autocmd BufWritePost * throw ":-("
+	:autocmd BufWritePost * echo "Should not be displayed"
+	:
+	:try
+	:  write
+	:catch
+	:  echo v:exception
+	:endtry
+<
+							*except-autocmd-Cmd*
+For some commands, the normal action can be replaced by a sequence of
+autocommands.  Exceptions from that sequence will be catchable by the caller
+of the command.
+   Example:  For the ":write" command, the caller cannot know whether the file
+had actually been written when the exception occurred.  You need to tell it in
+some way. >
+
+	:if !exists("cnt")
+	:  let cnt = 0
+	:
+	:  autocmd BufWriteCmd * if &modified
+	:  autocmd BufWriteCmd *   let cnt = cnt + 1
+	:  autocmd BufWriteCmd *   if cnt % 3 == 2
+	:  autocmd BufWriteCmd *     throw "BufWriteCmdError"
+	:  autocmd BufWriteCmd *   endif
+	:  autocmd BufWriteCmd *   write | set nomodified
+	:  autocmd BufWriteCmd *   if cnt % 3 == 0
+	:  autocmd BufWriteCmd *     throw "BufWriteCmdError"
+	:  autocmd BufWriteCmd *   endif
+	:  autocmd BufWriteCmd *   echo "File successfully written!"
+	:  autocmd BufWriteCmd * endif
+	:endif
+	:
+	:try
+	:	write
+	:catch /^BufWriteCmdError$/
+	:  if &modified
+	:    echo "Error on writing (file contents not changed)"
+	:  else
+	:    echo "Error after writing"
+	:  endif
+	:catch /^Vim(write):/
+	:    echo "Error on writing"
+	:endtry
+
+When this script is sourced several times after making changes, it displays
+first >
+	File successfully written!
+then >
+	Error on writing (file contents not changed)
+then >
+	Error after writing
+etc.
+
+							*except-autocmd-ill*
+You cannot spread a try conditional over autocommands for different events.
+The following code is ill-formed: >
+
+	:autocmd BufWritePre  * try
+	:
+	:autocmd BufWritePost * catch
+	:autocmd BufWritePost *   echo v:exception
+	:autocmd BufWritePost * endtry
+	:
+	:write
+
+
+EXCEPTION HIERARCHIES AND PARAMETERIZED EXCEPTIONS	*except-hier-param*
+
+Some programming languages allow to use hierarchies of exception classes or to
+pass additional information with the object of an exception class.  You can do
+similar things in Vim.
+   In order to throw an exception from a hierarchy, just throw the complete
+class name with the components separated by a colon, for instance throw the
+string "EXCEPT:MATHERR:OVERFLOW" for an overflow in a mathematical library.
+   When you want to pass additional information with your exception class, add
+it in parentheses, for instance throw the string "EXCEPT:IO:WRITEERR(myfile)"
+for an error when writing "myfile".
+   With the appropriate patterns in the ":catch" command, you can catch for
+base classes or derived classes of your hierarchy.  Additional information in
+parentheses can be cut out from |v:exception| with the ":substitute" command.
+   Example: >
+
+	:function! CheckRange(a, func)
+	:  if a:a < 0
+	:    throw "EXCEPT:MATHERR:RANGE(" .. a:func .. ")"
+	:  endif
+	:endfunction
+	:
+	:function! Add(a, b)
+	:  call CheckRange(a:a, "Add")
+	:  call CheckRange(a:b, "Add")
+	:  let c = a:a + a:b
+	:  if c < 0
+	:    throw "EXCEPT:MATHERR:OVERFLOW"
+	:  endif
+	:  return c
+	:endfunction
+	:
+	:function! Div(a, b)
+	:  call CheckRange(a:a, "Div")
+	:  call CheckRange(a:b, "Div")
+	:  if (a:b == 0)
+	:    throw "EXCEPT:MATHERR:ZERODIV"
+	:  endif
+	:  return a:a / a:b
+	:endfunction
+	:
+	:function! Write(file)
+	:  try
+	:    execute "write" fnameescape(a:file)
+	:  catch /^Vim(write):/
+	:    throw "EXCEPT:IO(" .. getcwd() .. ", " .. a:file .. "):WRITEERR"
+	:  endtry
+	:endfunction
+	:
+	:try
+	:
+	:  " something with arithmetic and I/O
+	:
+	:catch /^EXCEPT:MATHERR:RANGE/
+	:  let function = substitute(v:exception, '.*(\(\a\+\)).*', '\1', "")
+	:  echo "Range error in" function
+	:
+	:catch /^EXCEPT:MATHERR/	" catches OVERFLOW and ZERODIV
+	:  echo "Math error"
+	:
+	:catch /^EXCEPT:IO/
+	:  let dir = substitute(v:exception, '.*(\(.\+\),\s*.\+).*', '\1', "")
+	:  let file = substitute(v:exception, '.*(.\+,\s*\(.\+\)).*', '\1', "")
+	:  if file !~ '^/'
+	:    let file = dir .. "/" .. file
+	:  endif
+	:  echo 'I/O error for "' .. file .. '"'
+	:
+	:catch /^EXCEPT/
+	:  echo "Unspecified error"
+	:
+	:endtry
+
+The exceptions raised by Vim itself (on error or when pressing CTRL-C) use
+a flat hierarchy:  they are all in the "Vim" class.  You cannot throw yourself
+exceptions with the "Vim" prefix; they are reserved for Vim.
+   Vim error exceptions are parameterized with the name of the command that
+failed, if known.  See |catch-errors|.
+
+
+PECULIARITIES
+							*except-compat*
+The exception handling concept requires that the command sequence causing the
+exception is aborted immediately and control is transferred to finally clauses
+and/or a catch clause.
+
+In the Vim script language there are cases where scripts and functions
+continue after an error: in functions without the "abort" flag or in a command
+after ":silent!", control flow goes to the following line, and outside
+functions, control flow goes to the line following the outermost ":endwhile"
+or ":endif".  On the other hand, errors should be catchable as exceptions
+(thus, requiring the immediate abortion).
+
+This problem has been solved by converting errors to exceptions and using
+immediate abortion (if not suppressed by ":silent!") only when a try
+conditional is active.  This is no restriction since an (error) exception can
+be caught only from an active try conditional.  If you want an immediate
+termination without catching the error, just use a try conditional without
+catch clause.  (You can cause cleanup code being executed before termination
+by specifying a finally clause.)
+
+When no try conditional is active, the usual abortion and continuation
+behavior is used instead of immediate abortion.  This ensures compatibility of
+scripts written for Vim 6.1 and earlier.
+
+However, when sourcing an existing script that does not use exception handling
+commands (or when calling one of its functions) from inside an active try
+conditional of a new script, you might change the control flow of the existing
+script on error.  You get the immediate abortion on error and can catch the
+error in the new script.  If however the sourced script suppresses error
+messages by using the ":silent!" command (checking for errors by testing
+|v:errmsg| if appropriate), its execution path is not changed.  The error is
+not converted to an exception.  (See |:silent|.)  So the only remaining cause
+where this happens is for scripts that don't care about errors and produce
+error messages.  You probably won't want to use such code from your new
+scripts.
+
+							*except-syntax-err*
+Syntax errors in the exception handling commands are never caught by any of
+the ":catch" commands of the try conditional they belong to.  Its finally
+clauses, however, is executed.
+   Example: >
+
+	:try
+	:  try
+	:    throw 4711
+	:  catch /\(/
+	:    echo "in catch with syntax error"
+	:  catch
+	:    echo "inner catch-all"
+	:  finally
+	:    echo "inner finally"
+	:  endtry
+	:catch
+	:  echo 'outer catch-all caught "' .. v:exception .. '"'
+	:  finally
+	:    echo "outer finally"
+	:endtry
+
+This displays: >
+    inner finally
+    outer catch-all caught "Vim(catch):E54: Unmatched \("
+    outer finally
+The original exception is discarded and an error exception is raised, instead.
+
+							*except-single-line*
+The ":try", ":catch", ":finally", and ":endtry" commands can be put on
+a single line, but then syntax errors may make it difficult to recognize the
+"catch" line, thus you better avoid this.
+   Example: >
+	:try | unlet! foo # | catch | endtry
+raises an error exception for the trailing characters after the ":unlet!"
+argument, but does not see the ":catch" and ":endtry" commands, so that the
+error exception is discarded and the "E488: Trailing characters" message gets
+displayed.
+
+							*except-several-errors*
+When several errors appear in a single command, the first error message is
+usually the most specific one and therefore converted to the error exception.
+   Example: >
+	echo novar
+causes >
+	E121: Undefined variable: novar
+	E15: Invalid expression: novar
+The value of the error exception inside try conditionals is: >
+	Vim(echo):E121: Undefined variable: novar
+<							*except-syntax-error*
+But when a syntax error is detected after a normal error in the same command,
+the syntax error is used for the exception being thrown.
+   Example: >
+	unlet novar #
+causes >
+	E108: No such variable: "novar"
+	E488: Trailing characters
+The value of the error exception inside try conditionals is: >
+	Vim(unlet):E488: Trailing characters
+This is done because the syntax error might change the execution path in a way
+not intended by the user.  Example: >
+	try
+	    try | unlet novar # | catch | echo v:exception | endtry
+	catch /.*/
+	    echo "outer catch:" v:exception
+	endtry
+This displays "outer catch: Vim(unlet):E488: Trailing characters", and then
+a "E600: Missing :endtry" error message is given, see |except-single-line|.
+
+==============================================================================
+9. Examples						*eval-examples*
+
+Printing in Binary ~
+>
+  :" The function Nr2Bin() returns the binary string representation of a number.
+  :func Nr2Bin(nr)
+  :  let n = a:nr
+  :  let r = ""
+  :  while n
+  :    let r = '01'[n % 2] .. r
+  :    let n = n / 2
+  :  endwhile
+  :  return r
+  :endfunc
+
+  :" The function String2Bin() converts each character in a string to a
+  :" binary string, separated with dashes.
+  :func String2Bin(str)
+  :  let out = ''
+  :  for ix in range(strlen(a:str))
+  :    let out = out .. '-' .. Nr2Bin(char2nr(a:str[ix]))
+  :  endfor
+  :  return out[1:]
+  :endfunc
+
+Example of its use: >
+  :echo Nr2Bin(32)
+result: "100000" >
+  :echo String2Bin("32")
+result: "110011-110010"
+
+
+Sorting lines ~
+
+This example sorts lines with a specific compare function. >
+
+  :func SortBuffer()
+  :  let lines = getline(1, '$')
+  :  call sort(lines, function("Strcmp"))
+  :  call setline(1, lines)
+  :endfunction
+
+As a one-liner: >
+  :call setline(1, sort(getline(1, '$'), function("Strcmp")))
+
+
+scanf() replacement ~
+							*sscanf*
+There is no sscanf() function in Vim.  If you need to extract parts from a
+line, you can use matchstr() and substitute() to do it.  This example shows
+how to get the file name, line number and column number out of a line like
+"foobar.txt, 123, 45". >
+   :" Set up the match bit
+   :let mx='\(\f\+\),\s*\(\d\+\),\s*\(\d\+\)'
+   :"get the part matching the whole expression
+   :let l = matchstr(line, mx)
+   :"get each item out of the match
+   :let file = substitute(l, mx, '\1', '')
+   :let lnum = substitute(l, mx, '\2', '')
+   :let col = substitute(l, mx, '\3', '')
+
+The input is in the variable "line", the results in the variables "file",
+"lnum" and "col". (idea from Michael Geddes)
+
+
+getting the scriptnames in a Dictionary ~
+						*scriptnames-dictionary*
+The `:scriptnames` command can be used to get a list of all script files that
+have been sourced.  There is also the `getscriptinfo()` function, but the
+information returned is not exactly the same.  In case you need to manipulate
+the list, this code can be used as a base: >
+
+    # Create or update scripts dictionary, indexed by SNR, and return it.
+    def Scripts(scripts: dict<string> = {}): dict<string>
+      for info in getscriptinfo()
+        if scripts->has_key(info.sid)
+          continue
+        endif
+        scripts[info.sid] = info.name
+      endfor
+      return scripts
+    enddef
+
+==============================================================================
+10. Vim script versions		*vimscript-version* *vimscript-versions*
+							*scriptversion*
+Over time many features have been added to Vim script.  This includes Ex
+commands, functions, variable types, etc.  Each individual feature can be
+checked with the |has()| and |exists()| functions.
+
+Sometimes old syntax of functionality gets in the way of making Vim better.
+When support is taken away this will break older Vim scripts.  To make this
+explicit the |:scriptversion| command can be used.  When a Vim script is not
+compatible with older versions of Vim this will give an explicit error,
+instead of failing in mysterious ways.
+
+When using a legacy function, defined with `:function`, in |Vim9| script then
+scriptversion 4 is used.
+
+							*scriptversion-1*  >
+ :scriptversion 1
+<	This is the original Vim script, same as not using a |:scriptversion|
+	command.  Can be used to go back to old syntax for a range of lines.
+	Test for support with: >
+		has('vimscript-1')
+
+<							*scriptversion-2*  >
+ :scriptversion 2
+<	String concatenation with "." is not supported, use ".." instead.
+	This avoids the ambiguity using "." for Dict member access and
+	floating point numbers.  Now ".5" means the number 0.5.
+
+							*scriptversion-3*  >
+ :scriptversion 3
+<	All |vim-variable|s must be prefixed by "v:".  E.g. "version" doesn't
+	work as |v:version| anymore, it can be used as a normal variable.
+	Same for some obvious names as "count" and others.
+
+	Test for support with: >
+		has('vimscript-3')
+<
+							*scriptversion-4*  >
+ :scriptversion 4
+<	Numbers with a leading zero are not recognized as octal.  "0o" or "0O"
+	is still recognized as octal.  With the
+	previous version you get: >
+		echo 017   " displays 15 (octal)
+		echo 0o17  " displays 15 (octal)
+		echo 018   " displays 18 (decimal)
+<	with script version 4: >
+		echo 017   " displays 17 (decimal)
+		echo 0o17  " displays 15 (octal)
+		echo 018   " displays 18 (decimal)
+<	Also, it is possible to use single quotes inside numbers to make them
+	easier to read: >
+		echo 1'000'000
+<	The quotes must be surrounded by digits.
+
+	Test for support with: >
+		has('vimscript-4')
+
+==============================================================================
+11. No +eval feature				*no-eval-feature*
+
+When the |+eval| feature was disabled at compile time, none of the expression
+evaluation commands are available.  To prevent this from causing Vim scripts
+to generate all kinds of errors, the ":if" and ":endif" commands are still
+recognized, though the argument of the ":if" and everything between the ":if"
+and the matching ":endif" is ignored.  Nesting of ":if" blocks is allowed, but
+only if the commands are at the start of the line.  The ":else" command is not
+recognized.
+
+Example of how to avoid executing commands when the |+eval| feature is
+missing: >
+
+	:if 1
+	:  echo "Expression evaluation is compiled in"
+	:else
+	:  echo "You will _never_ see this message"
+	:endif
+
+To execute a command only when the |+eval| feature is disabled can be done in
+two ways.  The simplest is to exit the script (or Vim) prematurely: >
+	if 1
+	   echo "commands executed with +eval"
+	   finish
+	endif
+	args  " command executed without +eval
+
+If you do not want to abort loading the script you can use a trick, as this
+example shows: >
+
+	silent! while 0
+	  set history=111
+	silent! endwhile
+
+When the |+eval| feature is available the command is skipped because of the
+"while 0".  Without the |+eval| feature the "while 0" is an error, which is
+silently ignored, and the command is executed.
+
+==============================================================================
+12. The sandbox					*eval-sandbox* *sandbox*
+
+The 'foldexpr', 'formatexpr', 'includeexpr', 'indentexpr', 'statusline' and
+'foldtext' options may be evaluated in a sandbox.  This means that you are
+protected from these expressions having nasty side effects.  This gives some
+safety for when these options are set from a modeline.  It is also used when
+the command from a tags file is executed and for CTRL-R = in the command line.
+The sandbox is also used for the |:sandbox| command.
+								*E48*
+These items are not allowed in the sandbox:
+	- changing the buffer text
+	- defining or changing mapping, autocommands, user commands
+	- setting certain options (see |option-summary|)
+	- setting certain v: variables (see |v:var|)  *E794*
+	- executing a shell command
+	- reading or writing a file
+	- jumping to another buffer or editing a file
+	- executing Python, Perl, etc. commands
+This is not guaranteed 100% secure, but it should block most attacks.
+
+							*:san* *:sandbox*
+:san[dbox] {cmd}	Execute {cmd} in the sandbox.  Useful to evaluate an
+			option that may have been set from a modeline, e.g.
+			'foldexpr'.
+
+							*sandbox-option*
+A few options contain an expression.  When this expression is evaluated it may
+have to be done in the sandbox to avoid a security risk.  But the sandbox is
+restrictive, thus this only happens when the option was set from an insecure
+location.  Insecure in this context are:
+- sourcing a .vimrc or .exrc in the current directory
+- while executing in the sandbox
+- value coming from a modeline
+- executing a function that was defined in the sandbox
+
+Note that when in the sandbox and saving an option value and restoring it, the
+option will still be marked as it was set in the sandbox.
+
+==============================================================================
+13. Textlock							*textlock*
+
+In a few situations it is not allowed to change the text in the buffer, jump
+to another window and some other things that might confuse or break what Vim
+is currently doing.  This mostly applies to things that happen when Vim is
+actually doing something else.  For example, evaluating the 'balloonexpr' may
+happen any moment the mouse cursor is resting at some position.
+
+This is not allowed when the textlock is active:
+	- changing the buffer text
+	- jumping to another buffer or window
+	- editing another file
+	- closing a window or quitting Vim
+	- etc.
+
+
+ vim:tw=78:ts=8:noet:ft=help:norl: