Mercurial > vim
annotate runtime/doc/usr_52.txt @ 28956:3e6e6b4e74eb v8.2.5000
patch 8.2.5000: no patch for documentation updates
Commit: https://github.com/vim/vim/commit/835ee980eedd1aa0fa2d731312ce38697a12a897
Author: Bram Moolenaar <Bram@vim.org>
Date: Sun May 22 14:50:16 2022 +0100
patch 8.2.5000: no patch for documentation updates
Problem: No patch for documentation updates.
Solution: Update documentation files.
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Sun, 22 May 2022 16:00:02 +0200 |
parents | 57c9377b9c62 |
children | f8e9d5023bf6 |
rev | line source |
---|---|
28956
3e6e6b4e74eb
patch 8.2.5000: no patch for documentation updates
Bram Moolenaar <Bram@vim.org>
parents:
28933
diff
changeset
|
1 *usr_52.txt* For Vim version 8.2. Last change: 2022 May 21 |
20856 | 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 | |
28862
82244cfc4694
Update runtime files, new color schemes
Bram Moolenaar <Bram@vim.org>
parents:
21676
diff
changeset
|
12 |52.1| Introduction |
82244cfc4694
Update runtime files, new color schemes
Bram Moolenaar <Bram@vim.org>
parents:
21676
diff
changeset
|
13 |52.2| Variable declarations |
82244cfc4694
Update runtime files, new color schemes
Bram Moolenaar <Bram@vim.org>
parents:
21676
diff
changeset
|
14 |52.3| Functions and types |
82244cfc4694
Update runtime files, new color schemes
Bram Moolenaar <Bram@vim.org>
parents:
21676
diff
changeset
|
15 |52.4| 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 ============================================================================== | |
28862
82244cfc4694
Update runtime files, new color schemes
Bram Moolenaar <Bram@vim.org>
parents:
21676
diff
changeset
|
22 *52.1* Introduction *vim9-script-intro* |
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 | |
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 | |
21676 | 37 vim9script " This indicates a Vim9 script file. |
20856 | 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 ============================================================================== | |
28862
82244cfc4694
Update runtime files, new color schemes
Bram Moolenaar <Bram@vim.org>
parents:
21676
diff
changeset
|
72 *52.2* Variable declarations *vim9-declarations* |
20856 | 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 ============================================================================== | |
28862
82244cfc4694
Update runtime files, new color schemes
Bram Moolenaar <Bram@vim.org>
parents:
21676
diff
changeset
|
111 *52.3* Functions and types |
20856 | 112 |
28933 | 113 Legacy Vim script only checks types at runtime, when the code is executed. |
114 And it's permissive, often a computation gives an unexpected value instead of | |
115 reporting an error. Thus you can define a function and think it's fine, but | |
28956
3e6e6b4e74eb
patch 8.2.5000: no patch for documentation updates
Bram Moolenaar <Bram@vim.org>
parents:
28933
diff
changeset
|
116 notice a problem only later when the function is called: > |
3e6e6b4e74eb
patch 8.2.5000: no patch for documentation updates
Bram Moolenaar <Bram@vim.org>
parents:
28933
diff
changeset
|
117 func Concatenate(base, add) |
3e6e6b4e74eb
patch 8.2.5000: no patch for documentation updates
Bram Moolenaar <Bram@vim.org>
parents:
28933
diff
changeset
|
118 return a:base + a:add |
20856 | 119 endfunc |
120 | |
121 Can you spot the error? Try this: > | |
28956
3e6e6b4e74eb
patch 8.2.5000: no patch for documentation updates
Bram Moolenaar <Bram@vim.org>
parents:
28933
diff
changeset
|
122 echo Concatenate('base', 'text') |
3e6e6b4e74eb
patch 8.2.5000: no patch for documentation updates
Bram Moolenaar <Bram@vim.org>
parents:
28933
diff
changeset
|
123 And you'll see zero. Why? Because in legacy Vim script "+" will convert the |
3e6e6b4e74eb
patch 8.2.5000: no patch for documentation updates
Bram Moolenaar <Bram@vim.org>
parents:
28933
diff
changeset
|
124 arguments to numbers, and any string without a number results in zero! That's |
3e6e6b4e74eb
patch 8.2.5000: no patch for documentation updates
Bram Moolenaar <Bram@vim.org>
parents:
28933
diff
changeset
|
125 not what you expected. |
20856 | 126 |
28956
3e6e6b4e74eb
patch 8.2.5000: no patch for documentation updates
Bram Moolenaar <Bram@vim.org>
parents:
28933
diff
changeset
|
127 With `:def` the type checking happens when compiling the function. You need |
3e6e6b4e74eb
patch 8.2.5000: no patch for documentation updates
Bram Moolenaar <Bram@vim.org>
parents:
28933
diff
changeset
|
128 to specify the argument types and the return type to make that possible. Also |
3e6e6b4e74eb
patch 8.2.5000: no patch for documentation updates
Bram Moolenaar <Bram@vim.org>
parents:
28933
diff
changeset
|
129 notice that the argument names are used without the "a:" prefix: > |
3e6e6b4e74eb
patch 8.2.5000: no patch for documentation updates
Bram Moolenaar <Bram@vim.org>
parents:
28933
diff
changeset
|
130 def Concatenate(base: string, add: string): string |
3e6e6b4e74eb
patch 8.2.5000: no patch for documentation updates
Bram Moolenaar <Bram@vim.org>
parents:
28933
diff
changeset
|
131 return base + add |
20856 | 132 enddef |
28956
3e6e6b4e74eb
patch 8.2.5000: no patch for documentation updates
Bram Moolenaar <Bram@vim.org>
parents:
28933
diff
changeset
|
133 defcompile Concatenate |
20856 | 134 |
28956
3e6e6b4e74eb
patch 8.2.5000: no patch for documentation updates
Bram Moolenaar <Bram@vim.org>
parents:
28933
diff
changeset
|
135 Here we use `:defcompile` to do the compilation right away, without it the |
3e6e6b4e74eb
patch 8.2.5000: no patch for documentation updates
Bram Moolenaar <Bram@vim.org>
parents:
28933
diff
changeset
|
136 compilation would happen when the function is first called. Vim will tell you |
3e6e6b4e74eb
patch 8.2.5000: no patch for documentation updates
Bram Moolenaar <Bram@vim.org>
parents:
28933
diff
changeset
|
137 what you did wrong: > |
28933 | 138 E1051: Wrong argument type for + |
139 | |
28956
3e6e6b4e74eb
patch 8.2.5000: no patch for documentation updates
Bram Moolenaar <Bram@vim.org>
parents:
28933
diff
changeset
|
140 Side note: here the context is legacy script. When using Vim9 script you |
3e6e6b4e74eb
patch 8.2.5000: no patch for documentation updates
Bram Moolenaar <Bram@vim.org>
parents:
28933
diff
changeset
|
141 would put `:defcompile` at the end of the script to check for errors in all |
3e6e6b4e74eb
patch 8.2.5000: no patch for documentation updates
Bram Moolenaar <Bram@vim.org>
parents:
28933
diff
changeset
|
142 the functions defined in it. |
20856 | 143 |
144 Vim9 script is strict, it uses the "+" operator only for numbers and floats. | |
145 For string concatenation ".." must be used. This avoids mistakes and avoids | |
20965 | 146 the automatic conversion that gave a surprising result above. So you change |
20856 | 147 the first line of the function to: > |
148 s:collected ..= add | |
149 And now it works. | |
150 | |
151 If the function does not return anything, just leave out the return type: > | |
152 def ReportResult(result: string) | |
153 echo 'The result is: ' .. result | |
154 enddef | |
155 | |
156 This is also checked, if you try to return a value you'll get an error. | |
157 | |
158 In case you don't care about types or have a function that does work with | |
159 multiple types, you can use the "any" type: > | |
160 def Store(key: string, value: any) | |
161 resultDict[key] = value | |
162 enddef | |
163 | |
164 ============================================================================== | |
28862
82244cfc4694
Update runtime files, new color schemes
Bram Moolenaar <Bram@vim.org>
parents:
21676
diff
changeset
|
165 *52.4* Using a Vim9 script from legacy script *source-vim9-script* |
20856 | 166 |
167 In some cases you have a legacy Vim script where you want to use items from a | |
168 Vim9 script. For example in your .vimrc you want to initialize a plugin. The | |
169 best way to do this is to use `:import`. For example: > | |
170 | |
171 import Init as NiceInit from 'myNicePlugin.vim' | |
172 call NiceInit('today') | |
173 | |
174 This finds the exported function "Init" in the Vim9 script file and makes it | |
175 available as script-local item "NiceInit". `:import` always uses the script | |
176 namespace, even when "s:" is not given. If "myNicePlugin.vim" was already | |
177 sourced it is not sourced again. | |
178 | |
179 Besides avoiding putting any items in the global namespace (where name clashes | |
180 can cause unexpected errors), this also means the script is sourced only once, | |
181 no matter how many times items from it are imported. | |
182 | |
183 In some cases, e.g. for testing, you may just want to source the Vim9 script. | |
184 That is OK, but then only global items will be available. The Vim9 script | |
185 will have to make sure to use a unique name for these global items. Example: > | |
186 source ~/.vim/extra/myNicePlugin.vim | |
187 call g:NicePluginTest() | |
188 | |
189 ============================================================================== | |
190 | |
191 Next chapter: |usr_90.txt| Installing Vim | |
192 | |
193 Copyright: see |manual-copyright| vim:tw=78:ts=8:noet:ft=help:norl: |