related: #18380 closes: #18388 Signed-off-by: zeertzjq <zeertzjq@outlook.com> Signed-off-by: Christian Brabandt <cb@256bit.org>
		
			
				
	
	
		
			5266 lines
		
	
	
		
			184 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			5266 lines
		
	
	
		
			184 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
| *eval.txt*	For Vim version 9.1.  Last change: 2025 Sep 25
 | |
| 
 | |
| 
 | |
| 		  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 Tuples				|Tuples|
 | |
|     1.5 Dictionaries			|Dictionaries|
 | |
|     1.6 Blobs				|Blobs|
 | |
|     1.7 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|
 | |
| 14. Vim script library		|vim-script-library|
 | |
| 
 | |
| 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* *E1523*
 | |
| There are eleven 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']]
 | |
| 
 | |
| Tuple		An ordered immutable sequence of items, see |Tuple| 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* *E1520* *E1522*
 | |
| |List|, |Tuple|, |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* *E1521*
 | |
| 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 sequence 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 longlist = [5, 6] + mylist
 | |
| To prepend or append an item, turn it into a list by putting [] around it.
 | |
| 
 | |
| A list can be concatenated with another one in-place using |:let+=| or
 | |
| |extend()|: >
 | |
| 	:let mylist += [7, 8]
 | |
| 	:call extend(mylist, [7, 8])
 | |
| <
 | |
| See |list-modification| below for more about changing a list in-place.
 | |
| 
 | |
| 
 | |
| 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()| function.
 | |
| 
 | |
| If the first index is beyond the last item of the List or the last index is
 | |
| before the first item, the result is an empty list.  There is no error
 | |
| message.
 | |
| 
 | |
| If the last 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]
 | |
| 
 | |
| To add items to a List in-place, you can use |:let+=| (|list-concatenation|): >
 | |
| 	:let listA = [1, 2]
 | |
| 	:let listA += [3, 4]
 | |
| <
 | |
| When two variables refer to the same List, changing one List in-place will
 | |
| cause the referenced List to be changed in-place: >
 | |
| 	:let listA = [1, 2]
 | |
| 	:let listB = listA
 | |
| 	:let listB += [3, 4]
 | |
| 	:echo listA
 | |
| 	[1, 2, 3, 4]
 | |
| <
 | |
| 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, Tuple, 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 Tuple one tuple item at a time is used.
 | |
| 
 | |
| 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 Tuples ~
 | |
| 						*tuple* *Tuple* *Tuples*
 | |
| 						*E1532* *E1533*
 | |
| A Tuple is an ordered sequence of items.  An item can be of any type.  Items
 | |
| can be accessed by their index number.  A Tuple is immutable.
 | |
| 
 | |
| A Tuple is similar to a List but uses less memory and provides O(1) lookup
 | |
| time for an item.
 | |
| 
 | |
| Tuple creation ~
 | |
| 						*E1526* *E1527*
 | |
| A Tuple is created with a comma-separated sequence of items in parentheses.
 | |
| Examples: >
 | |
| 	:let mytuple = (1, "two", 3, "four")
 | |
| 	:let tuple = (5,)
 | |
| 	:let emptytuple = ()
 | |
| 
 | |
| An item can be any expression.  If there is only one item in the tuple, then
 | |
| the item must be followed by a comma.
 | |
| 
 | |
| Using a Tuple for an item creates a Tuple of Tuples: >
 | |
| 	:let nesttuple = ((11, 12), (21, 22), (31, 32))
 | |
| 
 | |
| 
 | |
| Tuple index ~
 | |
| 							*tuple-index* *E1519*
 | |
| An item in the Tuple can be accessed by putting the index in square brackets
 | |
| after the Tuple.  Indexes are zero-based, thus the first item has index zero.
 | |
| >
 | |
| 	:let item = mytuple[0]		" get the first item: 1
 | |
| 	:let item = mytuple[2]		" get the third item: 3
 | |
| 
 | |
| When the resulting item is a tuple this can be repeated: >
 | |
| 	:let item = nesttuple[0][1]	" get the first tuple, second item: 12
 | |
| <
 | |
| A negative index is counted from the end.  Index -1 refers to the last item in
 | |
| the Tuple, -2 to the last but one item, etc. >
 | |
| 	:let last = mytuple[-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(mytuple, idx)
 | |
| 	:echo get(mytuple, idx, "NONE")
 | |
| 
 | |
| 
 | |
| Tuple modification ~
 | |
| 							*tuple-modification*
 | |
| A tuple is immutable and items cannot be added or removed from a tuple.  But
 | |
| List and Dict items within a tuple can be modified: >
 | |
| 	:let tuple = (1, [2, 3], {'a': 4})
 | |
| 	:let tuple[1][0] = 10
 | |
| 	:let tuple[2]['a'] = 20
 | |
| 
 | |
| 
 | |
| Tuple concatenation ~
 | |
| 							*tuple-concatenation*
 | |
| Two tuples can be concatenated with the "+" operator: >
 | |
| 	:let longtuple = mytuple + (5, 6)
 | |
| 	:let longtuple = (5, 6) + mytuple
 | |
| To prepend or append an item, turn it into a tuple by putting () around it.
 | |
| The item must be followed by a comma.
 | |
| 
 | |
| 							*E1540*
 | |
| Two variadic tuples with same item type can be concatenated but with different
 | |
| item types cannot be concatenated.  Examples: >
 | |
|     var a: tuple<...list<number>> = (1, 2)
 | |
|     var b: tuple<...list<string>> = ('a', 'b')
 | |
|     echo a + b		# not allowed
 | |
| 
 | |
|     var a: tuple<number, number> = (1, 2)
 | |
|     var b: tuple<...list<string>> = ('a', 'b')
 | |
|     echo a + b		# allowed
 | |
| 
 | |
|     var a: tuple<...list<number>> = (1, 2)
 | |
|     var b: tuple<number, number> = (3, 4)
 | |
|     echo a + b		# not allowed
 | |
| 
 | |
|     var a: tuple<...list<number>> = (1, 2)
 | |
|     var b: tuple<number, ...list<number>> = (3, 4)
 | |
|     echo a + b		# not allowed
 | |
| <
 | |
| Note that a tuple is immutable and items cannot be added or removed from a
 | |
| tuple.
 | |
| 
 | |
| 
 | |
| Subtuple ~
 | |
| 							*subtuple*
 | |
| A part of the Tuple can be obtained by specifying the first and last index,
 | |
| separated by a colon in square brackets: >
 | |
| 	:let shorttuple = mytuple[2:-1]	" get Tuple (3, "four")
 | |
| 
 | |
| Omitting the first index is similar to zero.  Omitting the last index is
 | |
| similar to -1. >
 | |
| 	:let endtuple = mytuple[2:]	" from item 2 to the end: (3, "four")
 | |
| 	:let shorttuple = mytuple[2:2]	" Tuple with one item: (3,)
 | |
| 	:let othertuple = mytuple[:]	" make a copy of the Tuple
 | |
| 
 | |
| Notice that the last index is inclusive.  If you prefer using an exclusive
 | |
| index, use the |slice()| function.
 | |
| 
 | |
| If the first index is beyond the last item of the Tuple or the last index is
 | |
| before the first item, the result is an empty tuple.  There is no error
 | |
| message.
 | |
| 
 | |
| If the last index is equal to or greater than the length of the tuple, the
 | |
| length minus one is used: >
 | |
| 	:let mytuple = (0, 1, 2, 3)
 | |
| 	:echo mytuple[2:8]		" result: (2, 3)
 | |
| 
 | |
| NOTE: mytuple[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:
 | |
| mytuple[s : e].
 | |
| 
 | |
| 
 | |
| Tuple identity ~
 | |
| 							*tuple-identity*
 | |
| When variable "aa" is a tuple and you assign it to another variable "bb", both
 | |
| variables refer to the same tuple: >
 | |
| 	:let aa = (1, 2, 3)
 | |
| 	:let bb = aa
 | |
| <
 | |
| 
 | |
| Making a copy of a tuple is done with the |copy()| function.  Using [:] also
 | |
| works, as explained above.  This creates a shallow copy of the tuple: For
 | |
| example, changing a list item in the tuple will also change the item in the
 | |
| copied tuple: >
 | |
| 	:let aa = ([1, 'a'], 2, 3)
 | |
| 	:let bb = copy(aa)
 | |
| 	:let aa[0][1] = 'aaa'
 | |
| 	:echo aa
 | |
| <	([1, aaa], 2, 3) >
 | |
| 	:echo bb
 | |
| <	([1, aaa], 2, 3)
 | |
| 
 | |
| To make a completely independent tuple, use |deepcopy()|.  This also makes a
 | |
| copy of the values in the tuple, recursively.  Up to a hundred levels deep.
 | |
| 
 | |
| The operator "is" can be used to check if two variables refer to the same
 | |
| Tuple.  "isnot" does the opposite.  In contrast, "==" compares if two tuples
 | |
| have the same value. >
 | |
| 	:let atuple = (1, 2, 3)
 | |
| 	:let btuple = (1, 2, 3)
 | |
| 	:echo atuple is btuple
 | |
| <	0 >
 | |
| 	:echo atuple == btuple
 | |
| <	1
 | |
| 
 | |
| Note about comparing tuples: Two tuples 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 Tuples is more strict than comparing numbers and strings.  You
 | |
| can compare simple values this way too by putting them in a tuple: >
 | |
| 
 | |
| 	:let a = 5
 | |
| 	:let b = "5"
 | |
| 	:echo a == b
 | |
| <	1 >
 | |
| 	:echo (a,) == (b,)
 | |
| <	0
 | |
| 
 | |
| 
 | |
| Tuple unpack ~
 | |
| 
 | |
| To unpack the items in a tuple to individual variables, put the variables in
 | |
| square brackets, like list items: >
 | |
| 	:let [var1, var2] = mytuple
 | |
| 
 | |
| When the number of variables does not match the number of items in the tuple
 | |
| this produces an error.  To handle any extra items from the tuple, append ";"
 | |
| and a variable name (which will then be of type tuple): >
 | |
| 	:let [var1, var2; rest] = mytuple
 | |
| 
 | |
| This works like: >
 | |
| 	:let var1 = mytuple[0]
 | |
| 	:let var2 = mytuple[1]
 | |
| 	:let rest = mytuple[2:]
 | |
| 
 | |
| Except that there is no error if there are only two items.  "rest" will be an
 | |
| empty tuple then.
 | |
| 
 | |
| 
 | |
| Tuple functions ~
 | |
| 						*E1536*
 | |
| Functions that are useful with a Tuple: >
 | |
| 	:let xs = count(tuple, 'x')	" count number of 'x's in tuple
 | |
| 	:if empty(tuple)		" check if tuple is empty
 | |
| 	:let i = index(tuple, 'x')	" index of first 'x' in tuple
 | |
| 	:let l = items(tuple)		" list of items in a tuple
 | |
| 	:let string = join(tuple, ', ')	" create string from tuple items
 | |
| 	:let l = len(tuple)		" number of items in tuple
 | |
| 	:let big = max(tuple)		" maximum value in tuple
 | |
| 	:let small = min(tuple)		" minimum value in tuple
 | |
| 	:let r = repeat(tuple, n)	" repeat a tuple n times
 | |
| 	:let r = reverse(tuple)		" reverse a tuple
 | |
| 	:let s = slice(tuple, n1, n2)	" slice a tuple
 | |
| 	:let s = string(tuple)		" String representation of tuple
 | |
| 	:let l = tuple2list(tuple)	" convert a tuple to list
 | |
| 	:let t = list2tuple(list)	" convert a list to tuple
 | |
| <
 | |
| 						*E1524*
 | |
| A tuple cannot be used with the |map()|, |mapnew()| and |filter()| functions.
 | |
| 
 | |
| 1.5 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 sequence 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 = {'one': 1, 'two': 2, 'three': 3}
 | |
| 	: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 mydict = {'one': 1, 'two': 2, 'three': 3}
 | |
| 	:let val = mydict["one"]
 | |
| 	:let mydict["four"] = 4
 | |
| 	: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.6 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 ~
 | |
| 							*blob-concatenation*
 | |
| Two blobs can be concatenated with the "+" operator: >
 | |
| 	:let longblob = myblob + 0z4455
 | |
| 	:let longblob = 0z4455 + myblob
 | |
| <
 | |
| A blob can be concatenated with another one in-place using |:let+=|: >
 | |
| 	:let myblob += 0z6677
 | |
| <
 | |
| See |blob-modification| below for more about changing a blob in-place.
 | |
| 
 | |
| 
 | |
| 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* *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
 | |
| 
 | |
| To add items to a Blob in-place, you can use |:let+=| (|blob-concatenation|): >
 | |
| 	:let blobA = 0z1122
 | |
| 	:let blobA += 0z3344
 | |
| <
 | |
| When two variables refer to the same Blob, changing one Blob in-place will
 | |
| cause the referenced Blob to be changed in-place: >
 | |
| 	:let blobA = 0z1122
 | |
| 	:let blobB = blobA
 | |
| 	:let blobB += 0z3344
 | |
| 	:echo blobA
 | |
| 	0z11223344
 | |
| <
 | |
| 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.7 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|, |Tuple|, |Dictionary| or |Blob|
 | |
| 				instance
 | |
| 	expr5 isnot expr5	different |List|, |Tuple|, |Dictionary| or
 | |
| 				|Blob| instance
 | |
| 
 | |
| |expr5|	expr6
 | |
| 	expr6 << expr6		bitwise left shift
 | |
| 	expr6 >> expr6		bitwise right shift
 | |
| 
 | |
| |expr6|	expr7
 | |
| 	expr7 +	 expr7 ...	number addition, list or tuple 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| or
 | |
| 				|Tuple|
 | |
| 	expr10[expr1 : expr1]	substring of a String or sublist of a |List|
 | |
| 				or a slice of a |Tuple|
 | |
| 	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, ...)		|Tuple|
 | |
| 	{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* *E1517* *E1518*
 | |
| 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.
 | |
| Same applies for a |Tuple|.
 | |
| 
 | |
| 							*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|, |Tuple|, |Dictionary| or |Blob| checks
 | |
| whether the expressions are referring to the same |List|, |Tuple|,
 | |
| |Dictionary| or |Blob| instance.  A copy of a |List| or |Tuple| is different
 | |
| from the original |List| or |Tuple|.  When using "is" without a |List|,
 | |
| |Tuple|, |Dictionary| or |Blob|, it is equivalent to using "equal", using
 | |
| "isnot" is 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 Tuple 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*
 | |
| ---------------
 | |
| 								*expr-+*
 | |
| expr7 + expr7   Number addition, |List| or |Tuple| or |Blob| concatenation
 | |
| 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.  Same for a |Tuple|.
 | |
| 
 | |
| 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.
 | |
| 
 | |
| 							*expr-[]* *E111*
 | |
| expr10[expr1]		item of String or |List| or |Tuple|
 | |
| 						*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.
 | |
| 
 | |
| A |Tuple| index is similar to a |List| index as explained above.
 | |
| 
 | |
| 
 | |
| 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
 | |
| A |Tuple| slice is similar to a |List| slice.
 | |
| 
 | |
| 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*
 | |
| Most variables are read-only, when a variable can be set by the user, it will
 | |
| be mentioned at the variable description below. 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|, |InsertEnter|,
 | |
| 		|KeyInputPre|, |CmdlineLeave| and |CmdlineLeavePre| 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:clipmethod*
 | |
| v:clipmethod	The current method of accessing the clipboard that is being
 | |
| 		used.  Can either have the value of:
 | |
| 			wayland		The Wayland protocol is being used.
 | |
| 			x11		X11 selections are being used.
 | |
| 			gui		GUI specific method is being used
 | |
| 			other		Some other method is being used
 | |
| 			none		Clipboard functionality is disabled or
 | |
| 					unavailable.
 | |
| 		See 'clipmethod' for more details.
 | |
| 
 | |
| 					*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.
 | |
| 
 | |
| 		The key values in the dictionary (the color names) should be
 | |
| 		lower cased, because Vim looks up a color by its lower case
 | |
| 		name.
 | |
| 
 | |
| 		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.
 | |
| 
 | |
| 		You can make changes to that file, but make sure to add new
 | |
| 		keys instead of updating existing ones, otherwise Vim will skip
 | |
| 		loading the file (thinking it hasn't been changed).
 | |
| 
 | |
| 				*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:stacktrace|, |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:python3_version* *python3-version-variable*
 | |
| v:python3_version
 | |
| 		Version of Python 3 that Vim was built against.  When
 | |
| 		Python is loaded dynamically (|python-dynamic|), this version
 | |
| 		should exactly match the Python library up to the minor
 | |
| 		version (e.g.  3.10.2 and 3.10.3 are compatible as the minor
 | |
| 		version is "10", whereas 3.9.4 and 3.10.3 are not compatible).
 | |
| 		When |python-stable-abi| is used, this will be the minimum
 | |
| 		Python version that you can use instead. (e.g. if
 | |
| 		v:python3_version indicates 3.9, you can use 3.9, 3.10, or
 | |
| 		anything above).
 | |
| 
 | |
| 		This number is encoded as a hex number following Python ABI
 | |
| 		versioning conventions.  Do the following to have a
 | |
| 		human-readable full version in hex: >
 | |
| 			echo printf("%08X", v:python3_version)
 | |
| <		You can obtain only the minor version by doing: >
 | |
| 			echo and(v:python3_version>>16,0xff)
 | |
| <		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:stacktrace* *stacktrace-variable*
 | |
| v:stacktrace	The stack trace of the exception most recently caught and
 | |
| 		not finished.  Refer to |getstacktrace()| for the structure of
 | |
| 		stack trace.  See also |v:exception|, |v:throwpoint|, and
 | |
| 		|throw-variables|.
 | |
| 
 | |
| 					*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:t_typealias* *t_typealias-variable*
 | |
| v:t_typealias	Value of |typealias| type.  Read-only.  See: |type()|
 | |
| 					*v:t_enum* *t_enum-variable*
 | |
| v:t_enum	Value of |enum| type.  Read-only.  See: |type()|
 | |
| 					*v:t_enumvalue* *t_enumvalue-variable*
 | |
| v:t_enumvalue	Value of |enumvalue| type.  Read-only.  See: |type()|
 | |
| 					*v:t_tuple* *t_tuple-variable*
 | |
| v:t_tuple	Value of |Tuple| 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 variable is set, the TermResponse autocommand event
 | |
| 		is fired, so that you can react to the response from the
 | |
| 		terminal.  The TermResponseAll event is also fired, with
 | |
| 		<amatch> set to "version".  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* *termblinkresp-variable*
 | |
| 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()|.  When
 | |
| 		this variable is set, the TermResponseAll autocommand event is
 | |
| 		fired, with <amatch> set to "cursorblink".
 | |
| 
 | |
| 				    *v:termstyleresp* *termstyleresp-variable*
 | |
| 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()|.  When this
 | |
| 		variable is set, the TermResponseAll autocommand event is
 | |
| 		fired, with <amatch> set to "cursorshape".
 | |
| 
 | |
| 					*v:termrbgresp* *termrbgresp-variable*
 | |
| 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'.  When this variable is
 | |
| 		set, the TermResponseAll autocommand event is fired, with
 | |
| 		<amatch> set to "background".
 | |
| 
 | |
| 					*v:termrfgresp* *termrfgresp-variable*
 | |
| 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.  When this variable is set, the
 | |
| 		TermResponseAll autocommand event is fired, with <amatch> set
 | |
| 		to "foreground".
 | |
| 
 | |
| 					*v:termu7resp* *termu7resp-variable*
 | |
| 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'.  When
 | |
| 		this variable is set, the TermResponseAll autocommand event is
 | |
| 		fired, with <amatch> set to "ambiguouswidth".
 | |
| 
 | |
| 					*v:termda1* *termda1-variable*
 | |
| v:termda1	The escape sequence returned by a primary device attributes
 | |
| 		(DA1) query from the terminal.  When this variable is set, the
 | |
| 		TermResponseAll autocommand event is fired, with <amatch> set
 | |
| 		to "da1".  Can be used to detect OSC 52 support in a terminal.
 | |
| 
 | |
| 					*v:termosc* *termosc-variable*
 | |
| v:termosc	The escape sequence of the most recent OSC response received
 | |
| 		from the terminal.  When this variable is set, the
 | |
| 		|TermResponseAll| autocommand event is fired, with <amatch>
 | |
| 		set to "osc".
 | |
| 
 | |
| 					*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|, |v:stacktrace|, 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:wayland_display* *wayland_display-variable*
 | |
| v:wayland_display
 | |
| 		The name of the Wayland display that Vim is connected to.
 | |
| 		Equivalent to the $WAYLAND_DISPLAY environment variable.
 | |
| 		If this is empty, then Vim is not connected to any display.
 | |
| 
 | |
| 					*v:windowid* *windowid-variable*
 | |
| v:windowid	When any X11/Wayland 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.
 | |
| 			`+=` modifies a |List| or a |Blob| in-place instead of
 | |
| 			creating a new one.
 | |
| 			`.=` 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}
 | |
| :let ${env-name} ..= {expr1}
 | |
| 			Append {expr1} to the environment variable {env-name}.
 | |
| 			If the environment variable didn't exist yet this
 | |
| 			works like "=".
 | |
| 			`.=` is not supported with Vim script version 2 and
 | |
| 			later, see |vimscript-version|.
 | |
| 
 | |
| :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}
 | |
| :let @{reg-name} ..= {expr1}
 | |
| 			Append {expr1} to register {reg-name}.  If the
 | |
| 			register was empty it's like setting it to {expr1}.
 | |
| 			`.=` is not supported with Vim script version 2 and
 | |
| 			later, see |vimscript-version|.
 | |
| 
 | |
| :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}
 | |
| :let &{option-name} ..= {expr1}
 | |
| 			For a string option: Append {expr1} to the value.
 | |
| 			Does not insert a comma like |:set+=|.
 | |
| 			`.=` is not supported with Vim script version 2 and
 | |
| 			later, see |vimscript-version|.
 | |
| 
 | |
| :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}
 | |
| :let &l:{option-name} ..= {expr1}
 | |
| 			Like above, but only set the local value of an option
 | |
| 			(if there is one).  Works like |:setlocal|.
 | |
| 			`.=` is not supported with Vim script version 2 and
 | |
| 			later, see |vimscript-version|.
 | |
| 
 | |
| :let &g:{option-name} = {expr1}
 | |
| :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|.
 | |
| 			`.=` is not supported with Vim script version 2 and
 | |
| 			later, see |vimscript-version|.
 | |
| 
 | |
| 						*E1093* *E1537* *E1538* *E1535*
 | |
| :let [{name1}, {name2}, ...] = {expr1}		*:let-unpack* *E687* *E688*
 | |
| 			{expr1} must evaluate to a |List| or a |Tuple|.  The
 | |
| 			first item in the list or tuple is assigned to
 | |
| 			{name1}, the second item to {name2}, etc.
 | |
| 			The number of names must match the number of items in
 | |
| 			the |List| or |Tuple|.
 | |
| 			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}
 | |
| :let [{name1}, {name2}, ...] /= {expr1}
 | |
| :let [{name1}, {name2}, ...] %= {expr1}
 | |
| :let [{name1}, {name2}, ...] .= {expr1}
 | |
| :let [{name1}, {name2}, ...] ..= {expr1}
 | |
| 			Like above, but add, subtract, multiply, divide,
 | |
| 			modulo, or append the value for each |List| or |Tuple|
 | |
| 			item.
 | |
| 			`.=` is not supported with Vim script version 2 and
 | |
| 			later, see |vimscript-version|.
 | |
| 
 | |
| :let [{name}, ..., ; {lastname}] = {expr1}				*E452*
 | |
| 			Like |:let-unpack| above, but the |List| or |Tuple|
 | |
| 			may have more items than there are names.  A list or a
 | |
| 			tuple of the remaining items is assigned to
 | |
| 			{lastname}.  If there are no remaining items,
 | |
| 			{lastname} is set to an empty list or tuple.
 | |
| 			Example: >
 | |
| 				:let [a, b; rest] = ["aval", "bval", 3, 4]
 | |
| 				:let [a, b; rest] = ("aval", "bval", 3, 4)
 | |
| <
 | |
| :let [{name}, ..., ; {lastname}] += {expr1}
 | |
| :let [{name}, ..., ; {lastname}] -= {expr1}
 | |
| :let [{name}, ..., ; {lastname}] .= {expr1}
 | |
| :let [{name}, ..., ; {lastname}] ..= {expr1}
 | |
| 			Like above, but add/subtract/append the value for each
 | |
| 			|List| item.
 | |
| 			`.=` is not supported with Vim script version 2 and
 | |
| 			later, see |vimscript-version|.
 | |
| 
 | |
| 						*: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] [eval] {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*
 | |
| 			It is an error to specify an existing variable with
 | |
| 			|:const|. >
 | |
| 				:let x = 1
 | |
| 				:const x = 1  " 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|, a |Tuple|
 | |
| 			or a |Dictionary|.  It specifies how deep the locking
 | |
| 			goes:
 | |
| 				0	Lock the variable {name} but not its
 | |
| 					value.
 | |
| 				1	Lock the |List| or |Tuple| 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
 | |
| 					|Tuple| or |Dictionary|, cannot add or
 | |
| 					remove items, but can still change the
 | |
| 					values.
 | |
| 				3	Like 2 but for the |List| / |Tuple| /
 | |
| 					|Dictionary| in the |List| / |Tuple| /
 | |
| 					|Dictionary|, one level deeper.
 | |
| 			The default [depth] is 2, thus when {name} is a
 | |
| 			|List|, a |Tuple| or a |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()|.
 | |
| 
 | |
| 							*E1391* *E1392*
 | |
| 			Locking and unlocking object and class variables is
 | |
| 			currently NOT supported.
 | |
| 
 | |
| 
 | |
| :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 |Tuple|, 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|.  And you can obtain the stack trace from |v:stacktrace|.
 | |
| Note that "v:exception", "v:stacktrace" 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.
 | |
| 
 | |
| ==============================================================================
 | |
| 14. Vim script library					*vim-script-library*
 | |
| 
 | |
| Vim comes bundled with a Vim script library, that can be used by runtime,
 | |
| script authors.  Currently, it only includes very few functions, but it may
 | |
| grow over time.
 | |
| 
 | |
| The functions are available as |Vim9-script| as well as using legacy Vim
 | |
| script (to be used for non Vim 9.0 versions and Neovim).
 | |
| 
 | |
| 							*dist#vim* *dist#vim9*
 | |
| The functions make use of the autoloaded prefix "dist#vim" (for legacy Vim
 | |
| script and Neovim) and "dist#vim9" for Vim9 script.
 | |
| 
 | |
| The following functions are available:
 | |
| 
 | |
| dist#vim#IsSafeExecutable(filetype, executable) ~
 | |
| dist#vim9#IsSafeExecutable(filetype:string, executable:string): bool ~
 | |
| 
 | |
| This function takes a filetype and an executable and checks whether it is safe
 | |
| to execute the given executable.  For security reasons users may not want to
 | |
| have Vim execute random executables or may have forbidden to do so for
 | |
| specific filetypes by setting the "<filetype>_exec" variable (|plugin_exec|).
 | |
| 
 | |
| It returns |true| or |false| to indicate whether the plugin should run the
 | |
| given executable.  It takes the following arguments:
 | |
| 
 | |
| 	argument	type ~
 | |
| 
 | |
| 	filetype	string
 | |
| 	executable	string
 | |
| 
 | |
| 							*package-open*
 | |
| The |:Open| and |:Launch| command are provided by the included plugin
 | |
| $VIMRUNTIME/plugin/openPlugin.vim
 | |
| 
 | |
| 					*dist#vim9#Open()* *:Open* *:URLOpen*
 | |
| 						      *g:Openprg* *gx*
 | |
| dist#vim9#Open(file: string) ~
 | |
| 
 | |
| Opens `path` with the system default handler (macOS `open`, Windows
 | |
| `explorer.exe`, Linux `xdg-open`, …). If the variable |g:Openprg| exists the
 | |
| string specified in the variable is used instead.
 | |
| 
 | |
| The |:Open| user command uses file completion for its argument.
 | |
| 
 | |
| The |:URLOpen| user command works the same but does not perform file
 | |
| completion and therefore does not expand special characters |cmdline-special|.
 | |
| 
 | |
| This function is by default called using the gx mapping.  In visual mode
 | |
| tries to open the visually selected text.
 | |
| 
 | |
| Associated setting variables:
 | |
| `g:gx_word`: control how gx picks up the text under the cursor. Uses
 | |
| 	     `g:netrw_gx` as a fallback for backward compatibility.
 | |
| 	     (default: `<cfile>`)
 | |
| 
 | |
| `g:nogx`: disables the gx mapping. Uses `g:netrw_nogx` as a fallback for
 | |
| 	  backward compatibility. (default: `unset`)
 | |
| 
 | |
| 
 | |
| NOTE: Escaping of the path is automatically applied.
 | |
| 
 | |
| Usage: >vim
 | |
| 	:call dist#vim9#Open(<path>)
 | |
| 	:Open <path>
 | |
| 	:URLOpen <path>
 | |
| <
 | |
| 						*dist#vim9#Launch()* *:Launch*
 | |
| dist#vim9#Launch(file: string) ~
 | |
| 
 | |
| Launches <args> with the appropriate system programs. Intended for launching
 | |
| GUI programs within Vim.
 | |
| 
 | |
| The |:Launch| user command uses shell completion for its first argument.
 | |
| 
 | |
| NOTE: escaping of <args> is left to the user
 | |
| 
 | |
| Examples: >
 | |
| 	vim9script
 | |
| 
 | |
| 	import autoload 'dist/vim9.vim'
 | |
| 	# Execute 'makeprg' into another xterm window
 | |
| 	vim9.Launch('xterm ' .. expandcmd(&makeprg))
 | |
| <
 | |
| 
 | |
| Usage: >vim
 | |
| 	:call dist#vim9#Launch(<args>)
 | |
| 	:Launch <app> <args>.
 | |
| <
 | |
| 
 | |
|  vim:tw=78:ts=8:noet:ft=help:norl:
 |