summaryrefslogtreecommitdiffstats
path: root/runtime/doc/usr_46.txt
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-27 13:18:03 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-27 13:18:03 +0000
commitafce081b90c1e2c50c3507758c7558a0dfa1f33e (patch)
tree3fb840f0bd9de41b463443ddf17131a0ad77f226 /runtime/doc/usr_46.txt
parentInitial commit. (diff)
downloadvim-afce081b90c1e2c50c3507758c7558a0dfa1f33e.tar.xz
vim-afce081b90c1e2c50c3507758c7558a0dfa1f33e.zip
Adding upstream version 2:8.2.2434.upstream/2%8.2.2434upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'runtime/doc/usr_46.txt')
-rw-r--r--runtime/doc/usr_46.txt192
1 files changed, 192 insertions, 0 deletions
diff --git a/runtime/doc/usr_46.txt b/runtime/doc/usr_46.txt
new file mode 100644
index 0000000..0986ba1
--- /dev/null
+++ b/runtime/doc/usr_46.txt
@@ -0,0 +1,192 @@
+*usr_46.txt* For Vim version 8.2. Last change: 2020 Jun 14
+
+ VIM USER MANUAL - by Bram Moolenaar
+
+ Write plugins using Vim9 script
+
+
+The Vim9 script language is used for writing plugins, especially larger ones
+that use multiple files. This chapter explains how to split up a plugin into
+modules, import and export items and keep the rest local.
+
+|46.1| Introduction
+|46.2| Variable declarations
+|46.3| Functions and types
+|46.?| Using a Vim9 script from legacy script
+
+ Next chapter: |usr_90.txt| Installing Vim
+ Previous chapter: |usr_45.txt| Select your language (locale)
+Table of contents: |usr_toc.txt|
+
+==============================================================================
+*46.1* Introduction *vim9-script-intro*
+
+Vim9 script was designed to make it easier to write large Vim scripts. It
+looks more like other script languages, especially Typescript. Also,
+functions are compiled into instructions that can be executed quickly. This
+makes Vim9 script a lot faster, up to a 100 times.
+
+The basic idea is that a script file has items that are private, only used
+inside the script file, and items that are exported, used outside of the
+script file. The exported items can then be used by scripts that import them.
+That makes very clear what is defined where.
+
+Let's start with an example, a script that exports one function and has one
+private function: >
+
+ vim9script " This indicates a Vim9 script file.
+
+ export def GetMessage(): string
+ let result = ''
+ ...
+ result = GetPart(count)
+ ...
+ return result
+ enddef
+
+ def GetPart(nr: number): string
+ if nr == 4
+ return 'yes'
+ else
+ return 'no'
+ endif
+ enddef
+
+The `vim9script` command must be the very first command in the file. Without
+it Vim will assume legacy script syntax.
+
+The `export def GetMessage(): string` line starts with `export`, meaning that
+this function can be imported and called by other scripts. The line
+`def GetPart(...` does not start with `export`, this is a script-local
+function, it can only be used inside this script file.
+
+In the `export def GetMessage(): string` line you will notice the colon and
+the return type. Vim9 functions, defined with `def`, require specifying the
+type of arguments and the return type. That way Vim can compile the code
+efficiently. The GetPart function defines an argument "nr" of type "number".
+
+Notice that the assignment `result = GetPart(count)` does not use the `let`
+command. That is explained in the next section.
+
+==============================================================================
+*46.2* Variable declarations *vim9-declarations*
+
+In Vim9 script variables are declared once with a `:let` or `:const` command.
+Assigning a value is done without `:let` and it is not possible to `:unlet`
+the variable.
+
+In most cases you will want to declare the variable and initialize it at the
+same time: >
+ let myText = 'some text'
+ ...
+ myText = 'other text'
+
+The type of the variable will be inferred from the expression. In this case
+it is a string. If you initialize with a number, then the type is number: >
+ let myNumber = 1234
+ ...
+ myNumber = 0
+
+If you try to assign a string to this variable, you will get an error: >
+ let myNumber = 'this fails!'
+
+In the rare case you want a variable that can take values of any type, you
+have to specify the type: >
+ let myVar: any = 1234
+ myVar = 'text also works'
+
+You can also declare a variable without assigning a value. In that case Vim
+will initialize it to zero or empty: >
+ let word: string
+ if condition
+ word = 'yes'
+ else
+ word = 'no'
+ endif
+
+Although it's shorter to do: >
+ let word = condition ? 'yes' : 'no'
+
+==============================================================================
+*46.3* Functions and types
+
+Legacy Vim script does have type checking, but this happens at runtime, when
+the code is executed. And it's permissive, often a computation gives an
+unexpected value instead of reporting an error. Thus you can define a
+function and think it's fine, but see a problem only later when it is called: >
+ let s:collected = ''
+ func ExtendAndReturn(add)
+ let s:collected += a:add
+ return s:collected
+ endfunc
+
+Can you spot the error? Try this: >
+ echo ExtendAndReturn('text')
+And you'll see zero. Why? Because in legacy Vim script "+=" will convert the
+arguments to numbers, and any string without a number results in zero!
+
+With `:def` the type checking happens when compiling the function. For that
+you need to specify the argument types and the return type. Also notice that
+the argument is used without the "a:" prefix: >
+ let s:collected = ''
+ def ExtendAndReturn(add: string): string
+ s:collected += add
+ return s:collected
+ enddef
+ defcompile
+
+Here we use `:defcompile` to do the compilation right away, without it the
+compilation would happen when the function is called. Vim will tell you what
+you did wrong: >
+ E1013: type mismatch, expected number but got string
+
+Vim9 script is strict, it uses the "+" operator only for numbers and floats.
+For string concatenation ".." must be used. This avoids mistakes and avoids
+the automatic conversion that gave a surprising result above. So you change
+the first line of the function to: >
+ s:collected ..= add
+And now it works.
+
+If the function does not return anything, just leave out the return type: >
+ def ReportResult(result: string)
+ echo 'The result is: ' .. result
+ enddef
+
+This is also checked, if you try to return a value you'll get an error.
+
+In case you don't care about types or have a function that does work with
+multiple types, you can use the "any" type: >
+ def Store(key: string, value: any)
+ resultDict[key] = value
+ enddef
+
+==============================================================================
+*46.?* Using a Vim9 script from legacy script *source-vim9-script*
+
+In some cases you have a legacy Vim script where you want to use items from a
+Vim9 script. For example in your .vimrc you want to initialize a plugin. The
+best way to do this is to use `:import`. For example: >
+
+ import Init as NiceInit from 'myNicePlugin.vim'
+ call NiceInit('today')
+
+This finds the exported function "Init" in the Vim9 script file and makes it
+available as script-local item "NiceInit". `:import` always uses the script
+namespace, even when "s:" is not given. If "myNicePlugin.vim" was already
+sourced it is not sourced again.
+
+Besides avoiding putting any items in the global namespace (where name clashes
+can cause unexpected errors), this also means the script is sourced only once,
+no matter how many times items from it are imported.
+
+In some cases, e.g. for testing, you may just want to source the Vim9 script.
+That is OK, but then only global items will be available. The Vim9 script
+will have to make sure to use a unique name for these global items. Example: >
+ source ~/.vim/extra/myNicePlugin.vim
+ call g:NicePluginTest()
+
+==============================================================================
+
+Next chapter: |usr_90.txt| Installing Vim
+
+Copyright: see |manual-copyright| vim:tw=78:ts=8:noet:ft=help:norl: