patch 9.1.1232: Vim script is missing the tuple data type

Problem:  Vim script is missing the tuple data type
Solution: Add support for the tuple data type
          (Yegappan Lakshmanan)

closes: #16776

Signed-off-by: Yegappan Lakshmanan <yegappan@yahoo.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
This commit is contained in:
Yegappan Lakshmanan
2025-03-23 16:42:16 +01:00
committed by Christian Brabandt
parent adb703e1b9
commit 9cb865e95b
75 changed files with 7155 additions and 691 deletions

View File

@ -1,4 +1,4 @@
*builtin.txt* For Vim version 9.1. Last change: 2025 Mar 22
*builtin.txt* For Vim version 9.1. Last change: 2025 Mar 23
VIM REFERENCE MANUAL by Bram Moolenaar
@ -207,7 +207,7 @@ foldclosedend({lnum}) Number last line of fold at {lnum} if closed
foldlevel({lnum}) Number fold level at {lnum}
foldtext() String line displayed for closed fold
foldtextresult({lnum}) String text for closed fold at {lnum}
foreach({expr1}, {expr2}) List/Dict/Blob/String
foreach({expr1}, {expr2}) List/Tuple/Dict/Blob/String
for each item in {expr1} call {expr2}
foreground() Number bring the Vim window to the foreground
fullcommand({name} [, {vim9}]) String get full command from {name}
@ -348,7 +348,7 @@ job_start({command} [, {options}])
Job start a job
job_status({job}) String get the status of {job}
job_stop({job} [, {how}]) Number stop {job}
join({list} [, {sep}]) String join {list} items into one String
join({expr} [, {sep}]) String join items in {expr} into one String
js_decode({string}) any decode JS style JSON
js_encode({expr}) String encode JS style JSON
json_decode({string}) any decode JSON
@ -364,6 +364,7 @@ line2byte({lnum}) Number byte count of line {lnum}
lispindent({lnum}) Number Lisp indent for line {lnum}
list2blob({list}) Blob turn {list} of numbers into a Blob
list2str({list} [, {utf8}]) String turn {list} of numbers into a String
list2tuple({list}) Tuple turn {list} of items into a tuple
listener_add({callback} [, {buf}])
Number add a callback to listen to changes
listener_flush([{buf}]) none invoke listener callbacks
@ -511,10 +512,10 @@ remove({blob}, {idx} [, {end}]) Number/Blob
remove bytes {idx}-{end} from {blob}
remove({dict}, {key}) any remove entry {key} from {dict}
rename({from}, {to}) Number rename (move) file from {from} to {to}
repeat({expr}, {count}) List/Blob/String
repeat({expr}, {count}) List/Tuple/Blob/String
repeat {expr} {count} times
resolve({filename}) String get filename a shortcut points to
reverse({obj}) List/Blob/String
reverse({obj}) List/Tuple/Blob/String
reverse {obj}
round({expr}) Float round off {expr}
rubyeval({expr}) any evaluate |Ruby| expression
@ -713,6 +714,7 @@ test_null_job() Job null value for testing
test_null_list() List null value for testing
test_null_partial() Funcref null value for testing
test_null_string() String null value for testing
test_null_tuple() Tuple null value for testing
test_option_not_set({name}) none reset flag indicating option was set
test_override({expr}, {val}) none test with Vim internal overrides
test_refcount({expr}) Number get the reference count of {expr}
@ -734,6 +736,7 @@ tr({src}, {fromstr}, {tostr}) String translate chars of {src} in {fromstr}
trim({text} [, {mask} [, {dir}]])
String trim characters in {mask} from {text}
trunc({expr}) Float truncate Float {expr}
tuple2list({tuple}) List turn {tuple} of items into a list
type({expr}) Number type of value {expr}
typename({expr}) String representation of the type of {expr}
undofile({name}) String undo file name for {name}
@ -2073,7 +2076,8 @@ copy({expr}) *copy()*
that the original |List| can be changed without changing the
copy, and vice versa. But the items are identical, thus
changing an item changes the contents of both |Lists|.
A |Dictionary| is copied in a similar way as a |List|.
A |Tuple| or |Dictionary| is copied in a similar way as a
|List|.
Also see |deepcopy()|.
Can also be used as a |method|: >
mylist->copy()
@ -2116,10 +2120,10 @@ cosh({expr}) *cosh()*
count({comp}, {expr} [, {ic} [, {start}]]) *count()* *E706*
Return the number of times an item with value {expr} appears
in |String|, |List| or |Dictionary| {comp}.
in |String|, |List|, |Tuple| or |Dictionary| {comp}.
If {start} is given then start with the item with this index.
{start} can only be used with a |List|.
{start} can only be used with a |List| or a |Tuple|.
When {ic} is given and it's |TRUE| then case is ignored.
@ -2239,7 +2243,8 @@ deepcopy({expr} [, {noref}]) *deepcopy()* *E698*
|Dictionary|, a copy for it is made, recursively. Thus
changing an item in the copy does not change the contents of
the original |List|.
A |Dictionary| is copied in a similar way as a |List|.
A |Tuple| or |Dictionary| is copied in a similar way as a
|List|.
When {noref} is omitted or zero a contained |List| or
|Dictionary| is only copied once. All references point to
@ -2547,8 +2552,8 @@ echoraw({string}) *echoraw()*
empty({expr}) *empty()*
Return the Number 1 if {expr} is empty, zero otherwise.
- A |List| or |Dictionary| is empty when it does not have any
items.
- A |List|, |Tuple| or |Dictionary| is empty when it does
not have any items.
- A |String| is empty when its length is zero.
- A |Number| and |Float| are empty when their value is zero.
- |v:false|, |v:none| and |v:null| are empty, |v:true| is not.
@ -3475,8 +3480,9 @@ foldtextresult({lnum}) *foldtextresult()*
Return type: |String|
foreach({expr1}, {expr2}) *foreach()*
{expr1} must be a |List|, |String|, |Blob| or |Dictionary|.
foreach({expr1}, {expr2}) *foreach()* *E1525*
{expr1} must be a |List|, |Tuple|, |String|, |Blob| or
|Dictionary|.
For each item in {expr1} execute {expr2}. {expr1} is not
modified; its values may be, as with |:lockvar| 1. |E741|
See |map()| and |filter()| to modify {expr1}.
@ -3485,10 +3491,10 @@ foreach({expr1}, {expr2}) *foreach()*
If {expr2} is a |string|, inside {expr2} |v:val| has the value
of the current item. For a |Dictionary| |v:key| has the key
of the current item and for a |List| |v:key| has the index of
the current item. For a |Blob| |v:key| has the index of the
current byte. For a |String| |v:key| has the index of the
current character.
of the current item and for a |List| or a |Tuple| |v:key| has
the index of the current item. For a |Blob| |v:key| has the
index of the current byte. For a |String| |v:key| has the
index of the current character.
Examples: >
call foreach(mylist, 'used[v:val] = true')
< This records the items that are in the {expr1} list.
@ -3514,8 +3520,8 @@ foreach({expr1}, {expr2}) *foreach()*
Can also be used as a |method|: >
mylist->foreach(expr2)
<
Return type: |String|, |Blob| list<{type}> or dict<{type}>
depending on {expr1}
Return type: |String|, |Blob|, list<{type}>, tuple<{type}> or
dict<{type}> depending on {expr1}
*foreground()*
foreground() Move the Vim window to the foreground. Useful when sent from
@ -3688,6 +3694,15 @@ get({list}, {idx} [, {default}]) *get()* *get()-list*
<
Return type: any, depending on {list}
get({tuple}, {idx} [, {default}]) *get()-tuple*
Get item {idx} from |Tuple| {tuple}. When this item is not
available return {default}. Return zero when {default} is
omitted.
Preferably used as a |method|: >
mytuple->get(idx)
<
Return type: any, depending on {tuple}
get({blob}, {idx} [, {default}]) *get()-blob*
Get byte {idx} from |Blob| {blob}. When this byte is not
available return {default}. Return -1 when {default} is
@ -5821,8 +5836,8 @@ id({item}) *id()*
< prevents {item} from being garbage collected and provides a
way to get the {item} from the `id`.
{item} may be a List, Dictionary, Object, Job, Channel or
Blob. If the item is not a permitted type, or it is a null
{item} may be a List, Tuple, Dictionary, Object, Job, Channel
or Blob. If the item is not a permitted type, or it is a null
value, then an empty String is returned.
Can also be used as a |method|: >
@ -5849,12 +5864,12 @@ index({object}, {expr} [, {start} [, {ic}]]) *index()*
Find {expr} in {object} and return its index. See
|indexof()| for using a lambda to select the item.
If {object} is a |List| return the lowest index where the item
has a value equal to {expr}. There is no automatic
conversion, so the String "4" is different from the Number 4.
And the number 4 is different from the Float 4.0. The value
of 'ignorecase' is not used here, case matters as indicated by
the {ic} argument.
If {object} is a |List| or a |Tuple| return the lowest index
where the item has a value equal to {expr}. There is no
automatic conversion, so the String "4" is different from the
Number 4. And the number 4 is different from the Float 4.0.
The value of 'ignorecase' is not used here, case matters as
indicated by the {ic} argument.
If {object} is |Blob| return the lowest index where the byte
value is equal to {expr}.
@ -5878,11 +5893,11 @@ index({object}, {expr} [, {start} [, {ic}]]) *index()*
indexof({object}, {expr} [, {opts}]) *indexof()*
Returns the index of an item in {object} where {expr} is
v:true. {object} must be a |List| or a |Blob|.
v:true. {object} must be a |List|, a |Tuple| or a |Blob|.
If {object} is a |List|, evaluate {expr} for each item in the
List until the expression is v:true and return the index of
this item.
If {object} is a |List| or a |Tuple|, evaluate {expr} for each
item in the List until the expression is v:true and return the
index of this item.
If {object} is a |Blob| evaluate {expr} for each byte in the
Blob until the expression is v:true and return the index of
@ -5890,11 +5905,11 @@ indexof({object}, {expr} [, {opts}]) *indexof()*
{expr} must be a |string| or |Funcref|.
If {expr} is a |string|: If {object} is a |List|, inside
{expr} |v:key| has the index of the current List item and
|v:val| has the value of the item. If {object} is a |Blob|,
inside {expr} |v:key| has the index of the current byte and
|v:val| has the byte value.
If {expr} is a |string|: If {object} is a |List| or a |Tuple|,
inside {expr} |v:key| has the index of the current List or
Tuple item and |v:val| has the value of the item. If {object}
is a |Blob|, inside {expr} |v:key| has the index of the
current byte and |v:val| has the byte value.
If {expr} is a |Funcref| it must take two arguments:
1. the key or the index of the current item.
@ -6204,9 +6219,9 @@ items({dict}) *items()*
echo key .. ': ' .. value
endfor
<
A List or a String argument is also supported. In these
cases, items() returns a List with the index and the value at
the index.
A |List|, a |Tuple| or a |String| argument is also supported.
In these cases, items() returns a List with the index and the
value at the index.
Can also be used as a |method|: >
mydict->items()
@ -6217,16 +6232,17 @@ items({dict}) *items()*
job_ functions are documented here: |job-functions-details|
join({list} [, {sep}]) *join()*
Join the items in {list} together into one String.
join({expr} [, {sep}]) *join()*
Join the items in {expr} together into one String. {expr} can
be a |List| or a |Tuple|.
When {sep} is specified it is put in between the items. If
{sep} is omitted a single space is used.
Note that {sep} is not added at the end. You might want to
add it there too: >
let lines = join(mylist, "\n") .. "\n"
< String items are used as-is. |Lists| and |Dictionaries| are
converted into a string like with |string()|.
The opposite function is |split()|.
< String items are used as-is. |Lists|, |Tuples| and
|Dictionaries| are converted into a string like with
|string()|. The opposite function is |split()|.
Can also be used as a |method|: >
mylist->join()
@ -6320,6 +6336,8 @@ json_encode({expr}) *json_encode()*
|Funcref| not possible, error
|List| as an array (possibly null); when
used recursively: []
|Tuple| as an array (possibly null); when
used recursively: []
|Dict| as an object (possibly null); when
used recursively: {}
|Blob| as an array of the individual bytes
@ -6368,6 +6386,8 @@ len({expr}) *len()* *E701*
used, as with |strlen()|.
When {expr} is a |List| the number of items in the |List| is
returned.
When {expr} is a |Tuple| the number of items in the |Tuple| is
returned.
When {expr} is a |Blob| the number of bytes is returned.
When {expr} is a |Dictionary| the number of entries in the
|Dictionary| is returned.
@ -6549,6 +6569,25 @@ list2str({list} [, {utf8}]) *list2str()*
Return type: |String|
list2tuple({list}) *list2tuple()*
Create a Tuple from a shallow copy of the list items.
Examples: >
list2tuple([1, 2, 3]) returns (1, 2, 3)
< |tuple2list()| does the opposite.
This function doesn't recursively convert all the List items
in {list} to a Tuple. Note that the items are identical
between the list and the tuple, changing an item changes the
contents of both the tuple and the list.
Returns an empty tuple on error.
Can also be used as a |method|: >
GetList()->list2tuple()
<
Return type: tuple<{type}> (depending on the given |List|)
listener_add({callback} [, {buf}]) *listener_add()*
Add a callback function that will be invoked when changes have
been made to buffer {buf}.
@ -7464,11 +7503,12 @@ max({expr}) *max()*
Return the maximum value of all items in {expr}. Example: >
echo max([apples, pears, oranges])
< {expr} can be a |List| or a |Dictionary|. For a Dictionary,
it returns the maximum of all values in the Dictionary.
If {expr} is neither a List nor a Dictionary, or one of the
items in {expr} cannot be used as a Number this results in
an error. An empty |List| or |Dictionary| results in zero.
< {expr} can be a |List|, a |Tuple| or a |Dictionary|. For a
Dictionary, it returns the maximum of all values in the
Dictionary. If {expr} is neither a List nor a Tuple nor a
Dictionary, or one of the items in {expr} cannot be used as a
Number this results in an error. An empty |List|, |Tuple|
or |Dictionary| results in zero.
Can also be used as a |method|: >
mylist->max()
@ -7555,11 +7595,12 @@ min({expr}) *min()*
Return the minimum value of all items in {expr}. Example: >
echo min([apples, pears, oranges])
< {expr} can be a |List| or a |Dictionary|. For a Dictionary,
it returns the minimum of all values in the Dictionary.
If {expr} is neither a List nor a Dictionary, or one of the
items in {expr} cannot be used as a Number this results in
an error. An empty |List| or |Dictionary| results in zero.
< {expr} can be a |List|, a |Tuple| or a |Dictionary|. For a
Dictionary, it returns the minimum of all values in the
Dictionary. If {expr} is neither a List nor a Tuple nor a
Dictionary, or one of the items in {expr} cannot be used as a
Number this results in an error. An empty |List|, |Tuple| or
|Dictionary| results in zero.
Can also be used as a |method|: >
mylist->min()
@ -8582,8 +8623,8 @@ readfile({fname} [, {type} [, {max}]])
reduce({object}, {func} [, {initial}]) *reduce()* *E998*
{func} is called for every item in {object}, which can be a
|String|, |List| or a |Blob|. {func} is called with two
arguments: the result so far and current item. After
|String|, |List|, |Tuple| or a |Blob|. {func} is called with
two arguments: the result so far and current item. After
processing all items the result is returned. *E1132*
{initial} is the initial result. When omitted, the first item
@ -8904,16 +8945,16 @@ repeat({expr}, {count}) *repeat()*
result. Example: >
:let separator = repeat('-', 80)
< When {count} is zero or negative the result is empty.
When {expr} is a |List| or a |Blob| the result is {expr}
concatenated {count} times. Example: >
When {expr} is a |List|, a |Tuple| or a |Blob| the result is
{expr} concatenated {count} times. Example: >
:let longlist = repeat(['a', 'b'], 3)
< Results in ['a', 'b', 'a', 'b', 'a', 'b'].
Can also be used as a |method|: >
mylist->repeat(count)
<
Return type: |String|, |Blob| or list<{type}> depending on
{expr}
Return type: |String|, |Blob|, list<{type}> or tuple<{type}>
depending on {expr}
resolve({filename}) *resolve()* *E655*
@ -8940,18 +8981,19 @@ resolve({filename}) *resolve()* *E655*
reverse({object}) *reverse()*
Reverse the order of items in {object}. {object} can be a
|List|, a |Blob| or a |String|. For a List and a Blob the
items are reversed in-place and {object} is returned.
|List|, a |Tuple|, a |Blob| or a |String|. For a List and a
Blob the items are reversed in-place and {object} is returned.
For a Tuple, a new Tuple is returned.
For a String a new String is returned.
Returns zero if {object} is not a List, Blob or a String.
If you want a List or Blob to remain unmodified make a copy
first: >
Returns zero if {object} is not a List, Tuple, Blob or a
String. If you want a List or Blob to remain unmodified make
a copy first: >
:let revlist = reverse(copy(mylist))
< Can also be used as a |method|: >
mylist->reverse()
<
Return type: |String|, |Blob| or list<{type}> depending on
{object}
Return type: |String|, |Blob|, list<{type}> or tuple<{type}>
depending on {object}
round({expr}) *round()*
@ -10304,7 +10346,7 @@ slice({expr}, {start} [, {end}]) *slice()*
Can also be used as a |method|: >
GetList()->slice(offset)
<
Return type: list<{type}>
Return type: list<{type}> or tuple<{type}>
sort({list} [, {how} [, {dict}]]) *sort()* *E702*
@ -10916,15 +10958,16 @@ string({expr}) *string()*
Funcref function('name')
Blob 0z00112233.44556677.8899
List [item, item]
Tuple (item, item)
Dictionary {key: value, key: value}
Class class SomeName
Object object of SomeName {lnum: 1, col: 3}
Enum enum EnumName
EnumValue enum name.value {name: str, ordinal: nr}
When a |List| or |Dictionary| has a recursive reference it is
replaced by "[...]" or "{...}". Using eval() on the result
will then fail.
When a |List|, |Tuple| or |Dictionary| has a recursive
reference it is replaced by "[...]" or "(...)" or "{...}".
Using eval() on the result will then fail.
For an object, invokes the string() method to get a textual
representation of the object. If the method is not present,
@ -11878,6 +11921,25 @@ trunc({expr}) *trunc()*
Return type: |Float|
tuple2list({list}) *tuple2list()*
Create a List from a shallow copy of the tuple items.
Examples: >
tuple2list((1, 2, 3)) returns [1, 2, 3]
< |list2tuple()| does the opposite.
This function doesn't recursively convert all the Tuple items
in {tuple} to a List. Note that the items are identical
between the list and the tuple, changing an item changes the
contents of both the tuple and the list.
Returns an empty list on error.
Can also be used as a |method|: >
GetTuple()->tuple2list()
<
Return type: list<{type}> (depending on the given |Tuple|)
*type()*
type({expr}) The result is a Number representing the type of {expr}.
Instead of using the number directly, it is better to use the
@ -11898,6 +11960,7 @@ type({expr}) The result is a Number representing the type of {expr}.
Typealias: 14 |v:t_typealias|
Enum: 15 |v:t_enum|
EnumValue: 16 |v:t_enumvalue|
Tuple: 17 |v:t_tuple|
For backward compatibility, this method can be used: >
:if type(myvar) == type(0)
:if type(myvar) == type("")

View File

@ -1,4 +1,4 @@
*eval.txt* For Vim version 9.1. Last change: 2025 Feb 23
*eval.txt* For Vim version 9.1. Last change: 2025 Mar 23
VIM REFERENCE MANUAL by Bram Moolenaar
@ -21,9 +21,10 @@ a remark is given.
1.1 Variable types
1.2 Function references |Funcref|
1.3 Lists |Lists|
1.4 Dictionaries |Dictionaries|
1.5 Blobs |Blobs|
1.6 More about variables |more-variables|
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|
@ -46,8 +47,8 @@ Profiling is documented at |profiling|.
1.1 Variable types ~
*E712* *E896* *E897* *E899* *E1098*
*E1107* *E1135* *E1138*
There are ten types of variables:
*E1107* *E1135* *E1138* *E1523*
There are eleven types of variables:
*Number* *Integer*
Number A 32 or 64 bit signed number. |expr-number|
@ -63,6 +64,10 @@ String A NUL terminated string of 8-bit unsigned characters (bytes).
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:
@ -165,16 +170,17 @@ A List, Dictionary or Float is not a Number or String, thus evaluate to FALSE.
*E611* *E745* *E728* *E703* *E729* *E730* *E731* *E908* *E910*
*E913* *E974* *E975* *E976* *E1319* *E1320* *E1321* *E1322*
*E1323* *E1324*
|List|, |Dictionary|, |Funcref|, |Job|, |Channel|, |Blob|, |Class| and
|object| types are not automatically converted.
*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*
*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*
@ -267,9 +273,9 @@ position in the sequence.
List creation ~
*E696* *E697*
A List is created with a comma-separated list of items in square brackets.
A List is created with a comma-separated sequence of items in square brackets.
Examples: >
:let mylist = [1, two, 3, "four"]
:let mylist = [1, "two", 3, "four"]
:let emptylist = []
An item can be any expression. Using a List for an item creates a
@ -327,13 +333,13 @@ similar to -1. >
:let otherlist = mylist[:] " make a copy of the List
Notice that the last index is inclusive. If you prefer using an exclusive
index use the |slice()| method.
index use the |slice()| function.
If the first index is beyond the last item of the List or the second item is
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 second index is equal to or greater than the length of the list the
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]
@ -463,8 +469,8 @@ Changing the order of items in a list: >
For loop ~
The |:for| loop executes commands for each item in a List, String or Blob.
A variable is set to each item in sequence. Example with a List: >
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
@ -497,6 +503,8 @@ It is also possible to put remaining items in a List variable: >
: 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
@ -527,8 +535,206 @@ 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.
1.4 Dictionaries ~
A Tuple uses less memory compared to a List and provides O(1) lookup time.
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 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
@ -537,10 +743,10 @@ ordering.
Dictionary creation ~
*E720* *E721* *E722* *E723*
A Dictionary is created with a comma-separated list of entries in curly
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 = {1: 'one', 2: 'two', 3: 'three'}
: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
@ -570,8 +776,11 @@ 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.
@ -709,7 +918,7 @@ Functions that can be used with a Dictionary: >
:call map(dict, '">> " .. v:val') " prepend ">> " to each item
1.5 Blobs ~
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.
@ -856,7 +1065,7 @@ Making a copy of a Blob is done with the |copy()| function. Using [:] also
works, as explained above.
1.6 More about variables ~
1.7 More about variables ~
*more-variables*
If you need to know the type of a variable or expression, use the |type()|
function.
@ -907,16 +1116,18 @@ Expression syntax summary, from least to most significant:
etc. As above, append ? for ignoring case, # for
matching case
expr5 is expr5 same |List|, |Dictionary| or |Blob| instance
expr5 isnot expr5 different |List|, |Dictionary| or |Blob|
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 blob concatenation
expr7 + expr7 ... number addition, list or tuple or blob
concatenation
expr7 - expr7 ... number subtraction
expr7 . expr7 ... string concatenation
expr7 .. expr7 ... string concatenation
@ -935,8 +1146,10 @@ Expression syntax summary, from least to most significant:
+ expr9 unary plus
|expr10| expr11
expr10[expr1] byte of a String or item of a |List|
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
@ -945,6 +1158,7 @@ Expression syntax summary, from least to most significant:
"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
@ -1101,10 +1315,11 @@ Examples:
"abc" == "Abc" evaluates to 1 if 'ignorecase' is set, 0 otherwise
NOTE: In |Vim9| script 'ignorecase' is not used.
*E691* *E692*
*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
@ -1124,12 +1339,13 @@ Dictionary and arguments, use |get()| to get the function name: >
if get(Part1, 'name') == get(Part2, 'name')
" Part1 and Part2 refer to the same function
< *E1037*
Using "is" or "isnot" with a |List|, |Dictionary| or |Blob| checks whether
the expressions are referring to the same |List|, |Dictionary| or |Blob|
instance. A copy of a |List| is different from the original |List|. When
using "is" without a |List|, |Dictionary| or |Blob|, it is equivalent to
using "equal", using "isnot" equivalent to using "not equal". Except that
a different type means the values are different: >
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'
@ -1147,7 +1363,7 @@ that: >
because 'x' converted to a Number is zero. However: >
echo [0] == ['x']
0
Inside a List or Dictionary this conversion is not used.
Inside a List or Tuple or Dictionary this conversion is not used.
In |Vim9| script the types must match.
@ -1191,13 +1407,14 @@ topmost bit (sometimes called the sign bit) is cleared. If the right operand
expr6 and expr7 *expr6* *expr7* *E1036* *E1051*
---------------
expr7 + expr7 Number addition, |List| or |Blob| concatenation *expr-+*
*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.
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.
@ -1295,7 +1512,8 @@ in any order. E.g., these are all possible:
expr10->(expr1, ...)[expr1]
Evaluation is always from left to right.
expr10[expr1] item of String or |List| *expr-[]* *E111*
*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
@ -1328,6 +1546,8 @@ 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*
@ -1369,6 +1589,7 @@ 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: >
@ -2615,6 +2836,8 @@ v:t_typealias Value of |typealias| type. Read-only. See: |type()|
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|
@ -2934,13 +3157,13 @@ declarations and assignments do not use a command. |vim9-declaration|
:let &g:{option-name} -= {expr1}
Like above, but only set the global value of an option
(if there is one). Works like |:setglobal|.
*E1093*
*E1093* *E1537* *E1538* *E1535*
:let [{name1}, {name2}, ...] = {expr1} *:let-unpack* *E687* *E688*
{expr1} must evaluate to a |List|. The first item in
the list is assigned to {name1}, the second item to
{name2}, etc.
{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|.
the |List| or |Tuple|.
Each name can be one of the items of the ":let"
command as mentioned above.
Example: >
@ -2957,16 +3180,22 @@ declarations and assignments do not use a command. |vim9-declaration|
:let [{name1}, {name2}, ...] .= {expr1}
:let [{name1}, {name2}, ...] += {expr1}
:let [{name1}, {name2}, ...] -= {expr1}
Like above, but append/add/subtract the value for each
|List| item.
:let [{name1}, {name2}, ...] *= {expr1}
:let [{name1}, {name2}, ...] /= {expr1}
:let [{name1}, {name2}, ...] %= {expr1}
Like above, but append, add, subtract, multiply,
divide, or modulo the value for each |List| or |Tuple|
item.
:let [{name}, ..., ; {lastname}] = {expr1} *E452*
Like |:let-unpack| above, but the |List| may have more
items than there are names. A list of the remaining
items is assigned to {lastname}. If there are no
remaining items {lastname} is set to an empty list.
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}
@ -3161,23 +3390,26 @@ text...
get an error message: "E940: Cannot lock or unlock
variable {name}".
[depth] is relevant when locking a |List| or
|Dictionary|. It specifies how deep the locking goes:
[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 |Dictionary| itself,
cannot add or remove items, but can
still change their values.
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
|Dictionary|, cannot add or remove
items, but can still change the
|Tuple| or |Dictionary|, cannot add or
remove items, but can still change the
values.
3 Like 2 but for the |List| /
|Dictionary| in the |List| /
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|
or |Dictionary| the values cannot be changed.
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]
@ -3282,7 +3514,7 @@ text...
:endfo[r] *:endfo* *:endfor*
Repeat the commands between `:for` and `:endfor` for
each item in {object}. {object} can be a |List|,
a |Blob| or a |String|. *E1177*
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

View File

@ -4592,9 +4592,33 @@ E1513 message.txt /*E1513*
E1514 options.txt /*E1514*
E1515 builtin.txt /*E1515*
E1516 builtin.txt /*E1516*
E1517 eval.txt /*E1517*
E1518 eval.txt /*E1518*
E1519 eval.txt /*E1519*
E152 helphelp.txt /*E152*
E1520 eval.txt /*E1520*
E1521 eval.txt /*E1521*
E1522 eval.txt /*E1522*
E1523 eval.txt /*E1523*
E1524 eval.txt /*E1524*
E1525 builtin.txt /*E1525*
E1526 eval.txt /*E1526*
E1527 eval.txt /*E1527*
E1528 vim9.txt /*E1528*
E1529 vim9.txt /*E1529*
E153 helphelp.txt /*E153*
E1530 vim9.txt /*E1530*
E1531 vim9.txt /*E1531*
E1532 eval.txt /*E1532*
E1533 eval.txt /*E1533*
E1534 vim9.txt /*E1534*
E1535 eval.txt /*E1535*
E1536 eval.txt /*E1536*
E1537 eval.txt /*E1537*
E1538 eval.txt /*E1538*
E1539 vim9.txt /*E1539*
E154 helphelp.txt /*E154*
E1540 eval.txt /*E1540*
E155 sign.txt /*E155*
E156 sign.txt /*E156*
E157 sign.txt /*E157*
@ -5785,6 +5809,8 @@ TextChangedP autocmd.txt /*TextChangedP*
TextChangedT autocmd.txt /*TextChangedT*
TextYankPost autocmd.txt /*TextYankPost*
Transact-SQL ft_sql.txt /*Transact-SQL*
Tuple eval.txt /*Tuple*
Tuples eval.txt /*Tuples*
U undo.txt /*U*
UTF-8 mbyte.txt /*UTF-8*
UTF8-xterm mbyte.txt /*UTF8-xterm*
@ -7872,6 +7898,7 @@ get()-blob builtin.txt /*get()-blob*
get()-dict builtin.txt /*get()-dict*
get()-func builtin.txt /*get()-func*
get()-list builtin.txt /*get()-list*
get()-tuple builtin.txt /*get()-tuple*
get-ms-debuggers debug.txt /*get-ms-debuggers*
getbufinfo() builtin.txt /*getbufinfo()*
getbufline() builtin.txt /*getbufline()*
@ -8652,6 +8679,7 @@ list-modification eval.txt /*list-modification*
list-repeat windows.txt /*list-repeat*
list2blob() builtin.txt /*list2blob()*
list2str() builtin.txt /*list2str()*
list2tuple() builtin.txt /*list2tuple()*
listener_add() builtin.txt /*listener_add()*
listener_flush() builtin.txt /*listener_flush()*
listener_remove() builtin.txt /*listener_remove()*
@ -10325,6 +10353,7 @@ subscript eval.txt /*subscript*
substitute() builtin.txt /*substitute()*
substitute-CR version6.txt /*substitute-CR*
substring eval.txt /*substring*
subtuple eval.txt /*subtuple*
suffixes cmdline.txt /*suffixes*
suspend starting.txt /*suspend*
swap-exists-choices usr_11.txt /*swap-exists-choices*
@ -10574,6 +10603,7 @@ t_ti term.txt /*t_ti*
t_tp version4.txt /*t_tp*
t_ts term.txt /*t_ts*
t_ts_old version4.txt /*t_ts_old*
t_tuple-variable eval.txt /*t_tuple-variable*
t_typealias-variable eval.txt /*t_typealias-variable*
t_u7 term.txt /*t_u7*
t_ue term.txt /*t_ue*
@ -10810,6 +10840,7 @@ test_null_job() testing.txt /*test_null_job()*
test_null_list() testing.txt /*test_null_list()*
test_null_partial() testing.txt /*test_null_partial()*
test_null_string() testing.txt /*test_null_string()*
test_null_tuple() testing.txt /*test_null_tuple()*
test_option_not_set() testing.txt /*test_option_not_set()*
test_override() testing.txt /*test_override()*
test_refcount() testing.txt /*test_refcount()*
@ -10895,6 +10926,13 @@ try-echoerr eval.txt /*try-echoerr*
try-finally eval.txt /*try-finally*
try-nested eval.txt /*try-nested*
try-nesting eval.txt /*try-nesting*
tuple eval.txt /*tuple*
tuple-concatenation eval.txt /*tuple-concatenation*
tuple-functions usr_41.txt /*tuple-functions*
tuple-identity eval.txt /*tuple-identity*
tuple-index eval.txt /*tuple-index*
tuple-type vim9.txt /*tuple-type*
tuple2list() builtin.txt /*tuple2list()*
tutor usr_01.txt /*tutor*
two-engines pattern.txt /*two-engines*
type() builtin.txt /*type()*
@ -11091,6 +11129,7 @@ v:t_none eval.txt /*v:t_none*
v:t_number eval.txt /*v:t_number*
v:t_object eval.txt /*v:t_object*
v:t_string eval.txt /*v:t_string*
v:t_tuple eval.txt /*v:t_tuple*
v:t_typealias eval.txt /*v:t_typealias*
v:termblinkresp eval.txt /*v:termblinkresp*
v:termrbgresp eval.txt /*v:termrbgresp*
@ -11230,6 +11269,7 @@ variable-categories vim9.txt /*variable-categories*
variable-scope eval.txt /*variable-scope*
variable-types vim9.txt /*variable-types*
variables eval.txt /*variables*
variadic-tuple vim9.txt /*variadic-tuple*
various various.txt /*various*
various-cmds various.txt /*various-cmds*
various-functions usr_41.txt /*various-functions*

View File

@ -1,4 +1,4 @@
*testing.txt* For Vim version 9.1. Last change: 2024 Jul 18
*testing.txt* For Vim version 9.1. Last change: 2025 Mar 23
VIM REFERENCE MANUAL by Bram Moolenaar
@ -364,6 +364,11 @@ test_null_string() *test_null_string()*
Return type: |String|
test_null_tuple() *test_null_tuple()*
Return a |Tuple| that is null. Only useful for testing.
Return type: |Tuple|
test_option_not_set({name}) *test_option_not_set()*
Reset the flag that indicates option {name} was set. Thus it
looks like it still has the default value. Use like this: >

View File

@ -1,4 +1,4 @@
*usr_41.txt* For Vim version 9.1. Last change: 2025 Feb 01
*usr_41.txt* For Vim version 9.1. Last change: 2025 Mar 23
VIM USER MANUAL - by Bram Moolenaar
@ -839,6 +839,30 @@ List manipulation: *list-functions*
repeat() repeat a List multiple times
flatten() flatten a List
flattennew() flatten a copy of a List
items() get List of List index-value pairs
Tuple manipulation: *tuple-functions*
copy() make a shallow copy of a Tuple
count() count number of times a value appears in a
Tuple
deepcopy() make a full copy of a Tuple
empty() check if Tuple is empty
foreach() apply function to Tuple items
get() get an item without error for wrong index
index() index of a value in a Tuple
indexof() index in a Tuple where an expression is true
items() get List of Tuple index-value pairs
join() join Tuple items into a String
len() number of items in a Tuple
list2tuple() convert a list of items into a Tuple
max() maximum value in a Tuple
min() minimum value in a Tuple
reduce() reduce a Tuple to a value
repeat() repeat a Tuple multiple times
reverse() reverse the order of items in a Tuple
slice() take a slice of a Tuple
string() string representation of a Tuple
tuple2list() convert a Tuple of items into a list
Dictionary manipulation: *dict-functions*
get() get an entry without an error for a wrong key
@ -1234,6 +1258,7 @@ Testing: *test-functions*
test_null_list() return a null List
test_null_partial() return a null Partial function
test_null_string() return a null String
test_null_tuple() return a null Tuple
test_settime() set the time Vim uses internally
test_setmouse() set the mouse position
test_feedinput() add key sequence to input buffer
@ -1649,8 +1674,8 @@ More information about defining your own functions here: |user-functions|.
==============================================================================
*41.8* Lists and Dictionaries
So far we have used the basic types String and Number. Vim also supports two
composite types: List and Dictionary.
So far we have used the basic types String and Number. Vim also supports
three composite types: List, Tuple and Dictionary.
A List is an ordered sequence of items. The items can be any kind of value,
thus you can make a List of numbers, a List of Lists and even a List of mixed
@ -1751,6 +1776,23 @@ This looks into lines 1 to 50 (inclusive) and echoes any date found in there.
For further reading see |Lists|.
TUPLE
A Tuple is an immutable ordered sequence of items. An item can be of any
type. Items can be accessed by their index number. To create a Tuple with
three strings: >
var atuple = ('one', 'two', 'three')
The Tuple items are enclosed in parenthesis and separated by commas. To
create an empty Tuple: >
var atuple = ()
The |:for| loop can be used to iterate over the items in a Tuple similar to a
List.
For further reading see |Tuples|.
DICTIONARIES

View File

@ -1,4 +1,4 @@
*version9.txt* For Vim version 9.1. Last change: 2025 Mar 21
*version9.txt* For Vim version 9.1. Last change: 2025 Mar 23
VIM REFERENCE MANUAL by Bram Moolenaar
@ -41574,6 +41574,8 @@ Include the "linematch" algorithm for the 'diffopt' setting. This aligns
changes between buffers on similar lines improving the diff highlighting in
Vim
Support for the |Tuple| data type in Vim script and Vim9 script.
*changed-9.2*
Changed~
-------
@ -41677,11 +41679,14 @@ Functions: ~
|getstacktrace()| get current stack trace of Vim scripts
|id()| get unique identifier for a Dict, List, Object,
Channel or Blob variable
|list2tuple()| turn a List of items into a Tuple
|matchbufline()| all the matches of a pattern in a buffer
|matchstrlist()| all the matches of a pattern in a List of strings
|ngettext()| lookup single/plural message translation
|popup_setbuf()| switch to a different buffer in a popup
|str2blob()| convert a List of strings into a blob
|test_null_tuple()| return a null tuple
|tuple2list()| turn a Tuple of items into a List
Autocommands: ~

View File

@ -1,4 +1,4 @@
*vim9.txt* For Vim version 9.1. Last change: 2025 Mar 06
*vim9.txt* For Vim version 9.1. Last change: 2025 Mar 23
VIM REFERENCE MANUAL by Bram Moolenaar
@ -1001,6 +1001,7 @@ empty list and dict is falsy:
string non-empty
blob non-empty
list non-empty (different from JavaScript)
tuple non-empty (different from JavaScript)
dictionary non-empty (different from JavaScript)
func when there is a function name
special true or v:true
@ -1048,6 +1049,7 @@ In Vim9 script one can use the following predefined values: >
null_function
null_job
null_list
null_tuple
null_object
null_partial
null_string
@ -1467,15 +1469,16 @@ The following builtin types are supported:
dict<{type}>
job
channel
tuple<{type}>
tuple<{type}, {type}, ...>
tuple<...list<{type}>>
tuple<{type}, ...list<{type}>>
func
func: {type}
func({type}, ...)
func({type}, ...): {type}
void
Not supported yet:
tuple<a: {type}, b: {type}, ...>
These types can be used in declarations, but no simple value will actually
have the "void" type. Trying to use a void (e.g. a function without a
return value) results in error *E1031* *E1186* .
@ -1483,6 +1486,32 @@ return value) results in error *E1031* *E1186* .
There is no array type, use list<{type}> instead. For a list constant an
efficient implementation is used that avoids allocating a lot of small pieces
of memory.
*tuple-type*
A tuple type can be declared in more or less specific ways:
tuple<number> a tuple with a single item of type |Number|
tuple<number, string> a tuple with two items of type |Number| and
|String|
tuple<number, float, bool> a tuple with three items of type |Number|,
|Float| and |Boolean|.
tuple<...list<number>> a variadic tuple with zero or more items of
type |Number|.
tuple<number, ...list<string>> a tuple with an item of type |Number| followed
by zero or more items of type |String|.
Examples: >
var myTuple: tuple<number> = (20,)
var myTuple: tuple<number, string> = (30, 'vim')
var myTuple: tuple<number, float, bool> = (40, 1.1, true)
var myTuple: tuple<...list<string>> = ('a', 'b', 'c')
var myTuple: tuple<number, ...list<string>> = (3, 'a', 'b', 'c')
<
*variadic-tuple* *E1539*
A variadic tuple has zero or more items of the same type. The type of a
variadic tuple must end with a list type. Examples: >
var myTuple: tuple<...list<number>> = (1, 2, 3)
var myTuple: tuple<...list<string>> = ('a', 'b', 'c')
var myTuple: tuple<...list<bool>> = ()
<
*vim9-func-declaration* *E1005* *E1007*
A partial and function can be declared in more or less specific ways:
func any kind of function reference, no type
@ -1707,7 +1736,8 @@ argument type checking: >
*E1211* *E1217* *E1218* *E1219* *E1220* *E1221*
*E1222* *E1223* *E1224* *E1225* *E1226* *E1227*
*E1228* *E1238* *E1250* *E1251* *E1252* *E1256*
*E1297* *E1298* *E1301*
*E1297* *E1298* *E1301* *E1528* *E1529* *E1530*
*E1531* *E1534*
Types are checked for most builtin functions to make it easier to spot
mistakes.
@ -1715,7 +1745,7 @@ Categories of variables, defaults and null handling ~
*variable-categories* *null-variables*
There are categories of variables:
primitive number, float, boolean
container string, blob, list, dict
container string, blob, list, tuple, dict
specialized function, job, channel, user-defined-object
When declaring a variable without an initializer, an explicit type must be
@ -1845,6 +1875,7 @@ An uninitialized variable is usually equal to null; it depends on its type:
var s: string s == null
var b: blob b != null ***
var l: list<any> l != null ***
var t: tuple<any> t != null ***
var d: dict<any> d != null ***
var f: func f == null
var j: job j == null
@ -1855,6 +1886,7 @@ A variable initialized to empty equals null_<type>; but not null:
var s2: string = "" == null_string != null
var b2: blob = 0z == null_blob != null
var l2: list<any> = [] == null_list != null
var t2: tuple<any> = () == null_tuple != null
var d2: dict<any> = {} == null_dict != null
NOTE: the specialized variables, like job, default to null value and have no