Mercurial > vim
annotate runtime/doc/usr_52.txt @ 29202:b6c284c1f095 v8.2.5120
patch 8.2.5120: searching for quotes may go over the end of the line
Commit: https://github.com/vim/vim/commit/2f074f4685897ab7212e25931eeeb0212292829f
Author: Bram Moolenaar <Bram@vim.org>
Date: Sat Jun 18 11:22:40 2022 +0100
patch 8.2.5120: searching for quotes may go over the end of the line
Problem: Searching for quotes may go over the end of the line.
Solution: Check for running into the NUL.
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Sat, 18 Jun 2022 12:30:05 +0200 |
parents | 1e9e9d89f0ee |
children | f8116058ca76 |
rev | line source |
---|---|
29087 | 1 *usr_52.txt* For Vim version 8.2. Last change: 2022 Jun 04 |
20856 | 2 |
3 VIM USER MANUAL - by Bram Moolenaar | |
4 | |
29066 | 5 Write larger plugins |
20856 | 6 |
29066 | 7 When plugins do more than simple things, they tend to grow big. This file |
8 explains how to make sure they still load fast and how to split them up in | |
29087 | 9 smaller parts. |
20856 | 10 |
29066 | 11 |52.1| Export and import |
12 |52.2| Autoloading | |
13 |52.3| Autoloading without import/export | |
14 |52.4| Other mechanisms to use | |
15 |52.5| Using a Vim9 script from legacy script | |
20856 | 16 |
17 Next chapter: |usr_90.txt| Installing Vim | |
28862
82244cfc4694
Update runtime files, new color schemes
Bram Moolenaar <Bram@vim.org>
parents:
21676
diff
changeset
|
18 Previous chapter: |usr_51.txt| Create a plugin |
20856 | 19 Table of contents: |usr_toc.txt| |
20 | |
21 ============================================================================== | |
29066 | 22 *52.1* Export and import |
20856 | 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 | |
29087 | 30 inside the script file, and items that are exported, which can be used by |
31 scripts that import them. That makes very clear what is defined where. | |
20856 | 32 |
33 Let's start with an example, a script that exports one function and has one | |
34 private function: > | |
35 | |
29087 | 36 vim9script |
20856 | 37 |
29087 | 38 export def GetMessage(count: string): string |
39 var nr = str2nr(count) | |
40 var result = $'To {nr} we say ' | |
41 result ..= GetReply(nr) | |
20856 | 42 return result |
43 enddef | |
44 | |
29087 | 45 def GetReply(nr: number): string |
46 if nr == 42 | |
20856 | 47 return 'yes' |
29087 | 48 elseif nr = 22 |
49 return 'maybe' | |
20856 | 50 else |
51 return 'no' | |
52 endif | |
53 enddef | |
54 | |
29087 | 55 The `vim9script` command is required, `export` only works in a |Vim9| script. |
56 | |
57 The `export def GetMessage(...` line starts with `export`, meaning that this | |
58 function can be called by other scripts. The line `def GetReply(...` does not | |
59 start with `export`, this is a script-local function, it can only be used | |
60 inside this script file. | |
61 | |
62 Now about the script where this is imported. In this example we use this | |
63 layout, which works well for a plugin below the "pack" directory: | |
64 .../plugin/theplugin.vim | |
65 .../lib/getmessage.vim | |
66 | |
67 Assuming the "..." directory has been added to 'runtimepath', Vim will look | |
68 for plugins in the "plugin" directory and source "theplugin.vim". Vim does | |
69 not recognize the "lib" directory, you can put any scripts there. | |
70 | |
71 The above script that exports GetMessage() goes in lib/getmessage.vim. The | |
72 GetMessage() function is used in plugin/theplugin.vim: > | |
73 | |
74 vim9script | |
75 | |
76 import "../lib/getmessage.vim" | |
77 command -nargs=1 ShowMessage echomsg getmessage.GetMessage(<f-args>) | |
78 | |
79 The `import` command uses a relative path, it starts with "../", which means | |
80 to go one directory up. For other kinds of paths see the `:import` command. | |
20856 | 81 |
29087 | 82 How we can try out the command that the plugin provides: > |
83 ShowMessage 1 | |
84 < To 1 we say no ~ | |
85 > | |
86 ShowMessage 22 | |
87 < To 22 we say maybe ~ | |
88 | |
89 Notice that the function GetMessage() is prefixed with the imported script | |
90 name "getmessage". That way, for every imported function used, you know what | |
91 script it was imported from. If you import several scripts each of them could | |
92 define a GetMessage() function: > | |
93 | |
94 vim9script | |
95 | |
96 import "../lib/getmessage.vim" | |
97 import "../lib/getother.vim" | |
98 command -nargs=1 ShowMessage echomsg getmessage.GetMessage(<f-args>) | |
99 command -nargs=1 ShowOther echomsg getother.GetMessage(<f-args>) | |
20856 | 100 |
29087 | 101 If the imported script name is long or you use it in many places, you can |
102 shorten it by adding an "as" argument: > | |
103 import "../lib/getmessage.vim" as msg | |
104 command -nargs=1 ShowMessage echomsg msg.GetMessage(<f-args>) | |
105 | |
106 | |
107 RELOADING | |
20856 | 108 |
29087 | 109 One thing to keep in mind: the imported "lib/getmessage.vim" script will be |
110 sourced only once. When it is imported a second time sourcing it will be | |
111 skipped, since the items in it have already been created. It does not matter | |
112 if this import command is in another script, or in the same script that is | |
113 sourced again. | |
114 | |
115 This is efficient when using a plugin, but when still developing a plugin it | |
116 means that changing "lib/getmessage.vim" after it has been imported will have | |
117 no effect. You need to quit Vim and start it again. (Rationale: the items | |
118 defined in the script could be used in a compiled function, sourcing the | |
119 script again may break those functions). | |
120 | |
29066 | 121 |
122 USING GLOBALS | |
123 | |
124 Sometimes you will want to use global variables or functions, so that they can | |
125 be used anywhere. A good example is a global variable that passes a | |
126 preference to a plugin. To avoid other scripts using the same name, use a | |
127 prefix that is very unlikely to be used elsewhere. For example, if you have a | |
128 "mytags" plugin, you could use: > | |
129 | |
130 g:mytags_location = '$HOME/project' | |
131 g:mytags_style = 'fast' | |
20856 | 132 |
133 ============================================================================== | |
29066 | 134 *52.2* Autoloading |
20856 | 135 |
29066 | 136 After splitting your large script into pieces, all the lines will still be |
137 loaded and executed the moment the script is used. Every `import` loads the | |
138 imported script to find the items defined there. Although that is good for | |
139 finding errors early, it also takes time. Which is wasted if the | |
140 functionality is not often used. | |
20856 | 141 |
29066 | 142 Instead of having `import` load the script immediately, it can be postponed |
29087 | 143 until needed. Using the example above, only one change needs to be made in |
144 the plugin/theplugin.vim script: > | |
145 import autoload "../lib/getmessage.vim" | |
20856 | 146 |
29087 | 147 Nothing in the rest of the script needs to change. However, the types will |
148 not be checked. Not even the existence of the GetMessage() function is | |
149 checked until it is used. You will have to decide what is more important for | |
150 your script: fast startup or getting errors early. You can also add the | |
151 "autoload" argument later, after you have checked everything works. | |
20856 | 152 |
29087 | 153 |
154 AUTOLOAD DIRECTORY | |
155 | |
156 Another form is to use autoload with a script name that is not an absolute or | |
157 relative path: > | |
29066 | 158 import autload "monthlib.vim" |
20856 | 159 |
29066 | 160 This will search for the script "monthlib.vim" in the autoload directories of |
29087 | 161 'runtimepath'. With Unix one of the directories often is "~/.vim/autoload". |
29066 | 162 |
29087 | 163 The main advantage of this is that this script can be easily shared with other |
29066 | 164 scripts. You do need to make sure that the script name is unique, since Vim |
165 will search all the "autoload" directories in 'runtimepath', and if you are | |
29087 | 166 using several plugins with a plugin manager, it may add a directory to |
167 'runtimepath', each of which might have an "autoload" directory. | |
168 | |
169 Without autoload: > | |
170 import "monthlib.vim" | |
171 | |
172 Vim will search for the script "monthlib.vim" in the import directories of | |
173 'runtimepath'. Note that in this case adding or removing "autoload" changes | |
174 where the script is found. With a relative or absolute path the location does | |
175 not change. | |
20856 | 176 |
177 ============================================================================== | |
29066 | 178 *52.3* Autoloading without import/export |
179 | |
180 *write-library-script* | |
181 A mechanism from before import/export is still useful and some users may find | |
182 it a bit simpler. The idea is that you call a function with a special name. | |
183 That function is then in an autoload script. We will call that one script a | |
184 library script. | |
20856 | 185 |
29193 | 186 The autoload mechanism is based on a function name that has "#" characters: > |
29066 | 187 |
188 mylib#myfunction(arg) | |
20856 | 189 |
29066 | 190 Vim will recognize the function name by the embedded "#" character and when |
191 it is not defined yet search for the script "autoload/mylib.vim" in | |
192 'runtimepath'. That script must define the "mylib#myfunction()" function. | |
193 Obviously the name "mylib" is the part before the "#" and is used as the name | |
194 of the script, adding ".vim". | |
20856 | 195 |
29066 | 196 You can put many other functions in the mylib.vim script, you are free to |
197 organize your functions in library scripts. But you must use function names | |
198 where the part before the '#' matches the script name. Otherwise Vim would | |
199 not know what script to load. This is where it differs from the import/export | |
200 mechanism. | |
20856 | 201 |
29066 | 202 If you get really enthusiastic and write lots of library scripts, you may |
203 want to use subdirectories. Example: > | |
204 | |
205 netlib#ftp#read('somefile') | |
28933 | 206 |
29066 | 207 Here the script name is taken from the function name up to the last "#". The |
208 "#" in the middle are replaced by a slash, the last one by ".vim". Thus you | |
209 get "netlib/ftp.vim". For Unix the library script used for this could be: | |
20856 | 210 |
29066 | 211 ~/.vim/autoload/netlib/ftp.vim |
20856 | 212 |
29066 | 213 Where the function is defined like this: > |
214 | |
215 def netlib#ftp#read(fname: string) | |
216 # Read the file fname through ftp | |
20856 | 217 enddef |
218 | |
29066 | 219 Notice that the name the function is defined with is exactly the same as the |
220 name used for calling the function. And the part before the last '#' | |
221 exactly matches the subdirectory and script name. | |
222 | |
223 You can use the same mechanism for variables: > | |
224 | |
225 var weekdays = dutch#weekdays | |
20856 | 226 |
29066 | 227 This will load the script "autoload/dutch.vim", which should contain something |
228 like: > | |
229 | |
230 var dutch#weekdays = ['zondag', 'maandag', 'dinsdag', 'woensdag', | |
231 \ 'donderdag', 'vrijdag', 'zaterdag'] | |
232 | |
233 Further reading: |autoload|. | |
20856 | 234 |
235 ============================================================================== | |
29066 | 236 *52.4* Other mechanisms to use |
237 | |
238 Some may find the use of several files a hassle and prefer to keep everything | |
239 together in one script. To avoid this resulting in slow startup there is a | |
240 mechanism that only defines a small part and postpones the rest to when it is | |
241 actually used. *write-plugin-quickload* | |
242 | |
243 The basic idea is that the plugin is loaded twice. The first time user | |
244 commands and mappings are defined that offer the functionality. The second | |
245 time the functions that implement the functionality are defined. | |
246 | |
247 It may sound surprising that quickload means loading a script twice. What we | |
248 mean is that it loads quickly the first time, postponing the bulk of the | |
249 script to the second time, which only happens when you actually use it. When | |
250 you always use the functionality it actually gets slower! | |
251 | |
252 This uses a FuncUndefined autocommand. This works differently from the | |
253 |autoload| functionality explained above. | |
254 | |
255 The following example shows how it's done: > | |
256 | |
257 " Vim global plugin for demonstrating quick loading | |
258 " Last Change: 2005 Feb 25 | |
259 " Maintainer: Bram Moolenaar <Bram@vim.org> | |
260 " License: This file is placed in the public domain. | |
261 | |
262 if !exists("s:did_load") | |
263 command -nargs=* BNRead call BufNetRead(<f-args>) | |
264 map <F19> :call BufNetWrite('something')<CR> | |
265 | |
266 let s:did_load = 1 | |
267 exe 'au FuncUndefined BufNet* source ' .. expand('<sfile>') | |
268 finish | |
269 endif | |
270 | |
271 function BufNetRead(...) | |
272 echo 'BufNetRead(' .. string(a:000) .. ')' | |
273 " read functionality here | |
274 endfunction | |
275 | |
276 function BufNetWrite(...) | |
277 echo 'BufNetWrite(' .. string(a:000) .. ')' | |
278 " write functionality here | |
279 endfunction | |
280 | |
281 When the script is first loaded "s:did_load" is not set. The commands between | |
282 the "if" and "endif" will be executed. This ends in a |:finish| command, thus | |
283 the rest of the script is not executed. | |
284 | |
285 The second time the script is loaded "s:did_load" exists and the commands | |
286 after the "endif" are executed. This defines the (possible long) | |
287 BufNetRead() and BufNetWrite() functions. | |
288 | |
289 If you drop this script in your plugin directory Vim will execute it on | |
290 startup. This is the sequence of events that happens: | |
291 | |
292 1. The "BNRead" command is defined and the <F19> key is mapped when the script | |
293 is sourced at startup. A |FuncUndefined| autocommand is defined. The | |
294 ":finish" command causes the script to terminate early. | |
295 | |
296 2. The user types the BNRead command or presses the <F19> key. The | |
297 BufNetRead() or BufNetWrite() function will be called. | |
298 | |
299 3. Vim can't find the function and triggers the |FuncUndefined| autocommand | |
300 event. Since the pattern "BufNet*" matches the invoked function, the | |
301 command "source fname" will be executed. "fname" will be equal to the name | |
302 of the script, no matter where it is located, because it comes from | |
303 expanding "<sfile>" (see |expand()|). | |
304 | |
305 4. The script is sourced again, the "s:did_load" variable exists and the | |
306 functions are defined. | |
307 | |
308 Notice that the functions that are loaded afterwards match the pattern in the | |
309 |FuncUndefined| autocommand. You must make sure that no other plugin defines | |
310 functions that match this pattern. | |
311 | |
312 ============================================================================== | |
313 *52.5* Using a Vim9 script from legacy script *source-vim9-script* | |
20856 | 314 |
315 In some cases you have a legacy Vim script where you want to use items from a | |
316 Vim9 script. For example in your .vimrc you want to initialize a plugin. The | |
317 best way to do this is to use `:import`. For example: > | |
318 | |
29087 | 319 import 'myNicePlugin.vim' |
320 call myNicePlugin.NiceInit('today') | |
20856 | 321 |
29087 | 322 This finds the exported function "NiceInit" in the Vim9 script file and makes |
323 it available as script-local item "myNicePlugin.NiceInit". `:import` always | |
324 uses the script namespace, even when "s:" is not given. If "myNicePlugin.vim" | |
325 was already sourced it is not sourced again. | |
20856 | 326 |
327 Besides avoiding putting any items in the global namespace (where name clashes | |
328 can cause unexpected errors), this also means the script is sourced only once, | |
329 no matter how many times items from it are imported. | |
330 | |
331 In some cases, e.g. for testing, you may just want to source the Vim9 script. | |
332 That is OK, but then only global items will be available. The Vim9 script | |
333 will have to make sure to use a unique name for these global items. Example: > | |
334 source ~/.vim/extra/myNicePlugin.vim | |
335 call g:NicePluginTest() | |
336 | |
337 ============================================================================== | |
338 | |
339 Next chapter: |usr_90.txt| Installing Vim | |
340 | |
29066 | 341 |
20856 | 342 Copyright: see |manual-copyright| vim:tw=78:ts=8:noet:ft=help:norl: |