Mercurial > vim
comparison runtime/doc/usr_46.txt @ 20856:83cfa1ef1bf2
Update runtime files
Commit: https://github.com/vim/vim/commit/65e0d77a66b7e50beb562ad554ace46c32ef8f0f
Author: Bram Moolenaar <Bram@vim.org>
Date: Sun Jun 14 17:29:55 2020 +0200
Update runtime files
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Sun, 14 Jun 2020 17:45:04 +0200 |
parents | |
children | 59f93c2d2551 |
comparison
equal
deleted
inserted
replaced
20855:6390b8b611fb | 20856:83cfa1ef1bf2 |
---|---|
1 *usr_46.txt* For Vim version 8.2. Last change: 2020 Jun 14 | |
2 | |
3 VIM USER MANUAL - by Bram Moolenaar | |
4 | |
5 Write plugins using Vim9 script | |
6 | |
7 | |
8 The Vim9 script language is used for writing plugins, especially larger ones | |
9 that use multiple files. This chapter explains how to split up a plugin into | |
10 modules, import and export items and keep the rest local. | |
11 | |
12 |46.1| Introduction | |
13 |46.2| Variable declarations | |
14 |46.3| Functions and types | |
15 |46.?| Using a Vim9 script from legacy script | |
16 | |
17 Next chapter: |usr_90.txt| Installing Vim | |
18 Previous chapter: |usr_45.txt| Select your language (locale) | |
19 Table of contents: |usr_toc.txt| | |
20 | |
21 ============================================================================== | |
22 *46.1* Introduction *vim9-script-intro* | |
23 | |
24 Vim9 script was designed to make it easier to write large Vim scripts. It | |
25 looks more like other script languages, especially Typescript. Also, | |
26 functions are compiled into instructions that can be executed quickly. This | |
27 makes Vim9 script a lot faster, up to a 100 times. | |
28 | |
29 The basic idea is that a script file has items that are private, only used | |
30 inside the script file, and items that are exported, used outside of the | |
31 script file. The exported items can then be used by scripts that import them. | |
32 That makes very clear what is defined where. | |
33 | |
34 Let's start with an example, a script that exports one function and has one | |
35 private function: > | |
36 | |
37 vim9script " This indicates a Vim9 script file, | |
38 | |
39 export def GetMessage(): string | |
40 let result = '' | |
41 ... | |
42 result = GetPart(count) | |
43 ... | |
44 return result | |
45 enddef | |
46 | |
47 def GetPart(nr: number): string | |
48 if nr == 4 | |
49 return 'yes' | |
50 else | |
51 return 'no' | |
52 endif | |
53 enddef | |
54 | |
55 The `vim9script` command must be the very first command in the file. Without | |
56 it Vim will assume legacy script syntax. | |
57 | |
58 The `export def GetMessage(): string` line starts with `export`, meaning that | |
59 this function can be imported and called by other scripts. The line | |
60 `def GetPart(...` does not start with `export`, this is a script-local | |
61 function, it can only be used inside this script file. | |
62 | |
63 In the `export def GetMessage(): string` line you will notice the colon and | |
64 the return type. Vim9 functions, defined with `def`, require specifying the | |
65 type of arguments and the return type. That way Vim can compile the code | |
66 efficiently. The GetPart function defines an argument "nr" of type "number". | |
67 | |
68 Notice that the assignment `result = GetPart(count)` does not use the `let` | |
69 command. That is explained in the next section. | |
70 | |
71 ============================================================================== | |
72 *46.2* Variable declarations *vim9-declarations* | |
73 | |
74 In Vim9 script variables are declared once with a `:let` or `:const` command. | |
75 Assigning a value is done without `:let` and it is not possible to `:unlet` | |
76 the variable. | |
77 | |
78 In most cases you will want to declare the variable and initialize it at the | |
79 same time: > | |
80 let myText = 'some text' | |
81 ... | |
82 myText = 'other text' | |
83 | |
84 The type of the variable will be inferred from the expression. In this case | |
85 it is a string. If you initialize with a number, then the type is number: > | |
86 let myNumber = 1234 | |
87 ... | |
88 myNumber = 0 | |
89 | |
90 If you try to assign a string to this variable, you will get an error: > | |
91 let myNumber = 'this fails!' | |
92 | |
93 In the rare case you want a variable that can take values of any type, you | |
94 have to specify the type: > | |
95 let myVar: any = 1234 | |
96 myVar = 'text also works' | |
97 | |
98 You can also declare a variable without assigning a value. In that case Vim | |
99 will initialize it to zero or empty: > | |
100 let word: string | |
101 if condition | |
102 word = 'yes' | |
103 else | |
104 word = 'no' | |
105 endif | |
106 | |
107 Although it's shorter to do: > | |
108 let word = condition ? 'yes' : 'no' | |
109 | |
110 ============================================================================== | |
111 *46.3* Functions and types | |
112 | |
113 Legacy Vim script does have type checking, but this happens at runtime, when | |
114 the code is executed. And it's permissive, often a computation gives an | |
115 unexpected value instead of reporting an error . Thus you can define a | |
116 function and think it's fine, but see a problem only later when it is called: > | |
117 let s:collected = '' | |
118 func ExtendAndReturn(add) | |
119 let s:collected += a:add | |
120 return s:collected | |
121 endfunc | |
122 | |
123 Can you spot the error? Try this: > | |
124 echo ExtendAndReturn('text') | |
125 And you'll see zero. Why? Because in legacy Vim script "+=" will convert the | |
126 arguments to numbers, and any string without a number results in zero! | |
127 | |
128 With `:def` the type checking happens when compiling the function. For that | |
129 you need to specify the argument types and the return type. Also notice that | |
130 the argument is used without the "a:" prefix: > | |
131 let s:collected = '' | |
132 def ExtendAndReturn(add: string): string | |
133 s:collected += add | |
134 return s:collected | |
135 enddef | |
136 defcompile | |
137 | |
138 Here we use `:defcompile` to do the compilation right away, without it the | |
139 compilation would happen when the function is called. Vim will tell you what | |
140 you did wrong: > | |
141 E1013: type mismatch, expected number but got string | |
142 | |
143 Vim9 script is strict, it uses the "+" operator only for numbers and floats. | |
144 For string concatenation ".." must be used. This avoids mistakes and avoids | |
145 the automatic conversion that gave a suprising result above. So you change | |
146 the first line of the function to: > | |
147 s:collected ..= add | |
148 And now it works. | |
149 | |
150 If the function does not return anything, just leave out the return type: > | |
151 def ReportResult(result: string) | |
152 echo 'The result is: ' .. result | |
153 enddef | |
154 | |
155 This is also checked, if you try to return a value you'll get an error. | |
156 | |
157 In case you don't care about types or have a function that does work with | |
158 multiple types, you can use the "any" type: > | |
159 def Store(key: string, value: any) | |
160 resultDict[key] = value | |
161 enddef | |
162 | |
163 ============================================================================== | |
164 *46.?* Using a Vim9 script from legacy script *source-vim9-script* | |
165 | |
166 In some cases you have a legacy Vim script where you want to use items from a | |
167 Vim9 script. For example in your .vimrc you want to initialize a plugin. The | |
168 best way to do this is to use `:import`. For example: > | |
169 | |
170 import Init as NiceInit from 'myNicePlugin.vim' | |
171 call NiceInit('today') | |
172 | |
173 This finds the exported function "Init" in the Vim9 script file and makes it | |
174 available as script-local item "NiceInit". `:import` always uses the script | |
175 namespace, even when "s:" is not given. If "myNicePlugin.vim" was already | |
176 sourced it is not sourced again. | |
177 | |
178 Besides avoiding putting any items in the global namespace (where name clashes | |
179 can cause unexpected errors), this also means the script is sourced only once, | |
180 no matter how many times items from it are imported. | |
181 | |
182 In some cases, e.g. for testing, you may just want to source the Vim9 script. | |
183 That is OK, but then only global items will be available. The Vim9 script | |
184 will have to make sure to use a unique name for these global items. Example: > | |
185 source ~/.vim/extra/myNicePlugin.vim | |
186 call g:NicePluginTest() | |
187 | |
188 ============================================================================== | |
189 | |
190 Next chapter: |usr_90.txt| Installing Vim | |
191 | |
192 Copyright: see |manual-copyright| vim:tw=78:ts=8:noet:ft=help:norl: |