To: vim_dev@googlegroups.com Subject: Patch 9.0.0727 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 9.0.0727 Problem: Help in the repository differs from patched version too much. Solution: Make a patch for a few help files. Files: runtime/doc/eval.txt, runtime/doc/userfunc.txt, runtime/doc/vim9.txt, runtime/doc/builtin.txt *** ../vim-9.0.0726/runtime/doc/eval.txt 2022-10-07 14:31:04.316852643 +0100 --- runtime/doc/eval.txt 2022-10-07 12:26:56.512246269 +0100 *************** *** 1,4 **** ! *eval.txt* For Vim version 9.0. Last change: 2022 Jun 17 VIM REFERENCE MANUAL by Bram Moolenaar --- 1,4 ---- ! *eval.txt* For Vim version 9.0. Last change: 2022 Oct 07 VIM REFERENCE MANUAL by Bram Moolenaar *************** *** 1097,1102 **** --- 1097,1103 ---- echo 0 is [] 0 "is#"/"isnot#" and "is?"/"isnot?" can be used to match and ignore case. + In |Vim9| script this doesn't work, two strings are never identical. In legacy script, when comparing a String with a Number, the String is converted to a Number, and the comparison is done on Numbers. This means *************** *** 1398,1404 **** base->alist[idx](args) base->(getFuncRef())(args) Note that in the last call the base is passed to the function resulting from ! "(getFuncRef())", inserted before "args". *E274* "->name(" must not contain white space. There can be white space before the --- 1399,1405 ---- base->alist[idx](args) base->(getFuncRef())(args) Note that in the last call the base is passed to the function resulting from ! "(getFuncRef())", inserted before "args". *E1275* *E274* "->name(" must not contain white space. There can be white space before the *************** *** 1547,1553 **** if a =~ '\s*' ! interpolated-string *$quote* *interp-string* *E256* -------------------- $"string" interpolated string constant *expr-$quote* $'string' interpolated literal string constant *expr-$'* --- 1548,1554 ---- if a =~ '\s*' ! interpolated-string *$quote* *interp-string* -------------------- $"string" interpolated string constant *expr-$quote* $'string' interpolated literal string constant *expr-$'* *************** *** 1557,1563 **** expression returning a value can be enclosed between curly braces. The value is converted to a string. All the text and results of the expressions are concatenated to make a new string. ! *E1278* To include an opening brace '{' or closing brace '}' in the string content double it. For double quoted strings using a backslash also works. A single closing brace '}' will result in an error. --- 1558,1564 ---- expression returning a value can be enclosed between curly braces. The value is converted to a string. All the text and results of the expressions are concatenated to make a new string. ! *E1278* *E1279* To include an opening brace '{' or closing brace '}' in the string content double it. For double quoted strings using a backslash also works. A single closing brace '}' will result in an error. *************** *** 1715,1720 **** --- 1716,1724 ---- Notice how execute() is used to execute an Ex command. That's ugly though. In Vim9 script you can use a command block, see |inline-function|. + Although you can use the loop variable of a `for` command, it must still exist + when the closure is called, otherwise you get an error. *E1302* + Lambda expressions have internal names like '42'. If you get an error for a lambda expression, you can find what it is with the following command: > :function 42 *************** *** 2626,3128 **** 5. Defining functions *user-functions* New functions can be defined. These can be called just like builtin ! functions. The function executes a sequence of Ex commands. Normal mode ! commands can be executed with the |:normal| command. ! ! This section is about the legacy functions. For the Vim9 functions, which ! execute much faster, support type checking and more, see |vim9.txt|. ! ! The function name must start with an uppercase letter, to avoid confusion with ! builtin functions. To prevent from using the same name in different scripts ! avoid obvious, short names. A good habit is to start the function name with ! the name of the script, e.g., "HTMLcolor()". ! ! In legacy script it is also possible to use curly braces, see ! |curly-braces-names|. ! The |autoload| facility is useful to define a function only when it's called. ! ! *local-function* ! A function local to a legacy script must start with "s:". A local script ! function can only be called from within the script and from functions, user ! commands and autocommands defined in the script. It is also possible to call ! the function from a mapping defined in the script, but then || must be ! used instead of "s:" when the mapping is expanded outside of the script. ! There are only script-local functions, no buffer-local or window-local ! functions. ! ! In |Vim9| script functions are local to the script by default, prefix "g:" to ! define a global function. ! ! *:fu* *:function* *E128* *E129* *E123* *E454* ! :fu[nction] List all functions and their arguments. ! ! :fu[nction] {name} List function {name}. ! {name} can also be a |Dictionary| entry that is a ! |Funcref|: > ! :function dict.init ! ! :fu[nction] /{pattern} List functions with a name matching {pattern}. ! Example that lists all functions ending with "File": > ! :function /File$ ! < ! *:function-verbose* ! When 'verbose' is non-zero, listing a function will also display where it was ! last defined. Example: > ! ! :verbose function SetFileTypeSH ! function SetFileTypeSH(name) ! Last set from /usr/share/vim/vim-7.0/filetype.vim ! < ! See |:verbose-cmd| for more information. ! ! *E124* *E125* *E853* *E884* ! :fu[nction][!] {name}([arguments]) [range] [abort] [dict] [closure] ! Define a new function by the name {name}. The body of ! the function follows in the next lines, until the ! matching |:endfunction|. ! ! The name must be made of alphanumeric characters and ! '_', and must start with a capital or "s:" (see ! above). Note that using "b:" or "g:" is not allowed. ! (since patch 7.4.260 E884 is given if the function ! name has a colon in the name, e.g. for "foo:bar()". ! Before that patch no error was given). ! ! {name} can also be a |Dictionary| entry that is a ! |Funcref|: > ! :function dict.init(arg) ! < "dict" must be an existing dictionary. The entry ! "init" is added if it didn't exist yet. Otherwise [!] ! is required to overwrite an existing function. The ! result is a |Funcref| to a numbered function. The ! function can only be used with a |Funcref| and will be ! deleted if there are no more references to it. ! *E127* *E122* ! When a function by this name already exists and [!] is ! not used an error message is given. There is one ! exception: When sourcing a script again, a function ! that was previously defined in that script will be ! silently replaced. ! When [!] is used, an existing function is silently ! replaced. Unless it is currently being executed, that ! is an error. ! NOTE: Use ! wisely. If used without care it can cause ! an existing function to be replaced unexpectedly, ! which is hard to debug. ! NOTE: In Vim9 script script-local functions cannot be ! deleted or redefined. ! ! For the {arguments} see |function-argument|. ! ! *:func-range* *a:firstline* *a:lastline* ! When the [range] argument is added, the function is ! expected to take care of a range itself. The range is ! passed as "a:firstline" and "a:lastline". If [range] ! is excluded, ":{range}call" will call the function for ! each line in the range, with the cursor on the start ! of each line. See |function-range-example|. ! The cursor is still moved to the first line of the ! range, as is the case with all Ex commands. ! *:func-abort* ! When the [abort] argument is added, the function will ! abort as soon as an error is detected. ! *:func-dict* ! When the [dict] argument is added, the function must ! be invoked through an entry in a |Dictionary|. The ! local variable "self" will then be set to the ! dictionary. See |Dictionary-function|. ! *:func-closure* *E932* ! When the [closure] argument is added, the function ! can access variables and arguments from the outer ! scope. This is usually called a closure. In this ! example Bar() uses "x" from the scope of Foo(). It ! remains referenced even after Foo() returns: > ! :function! Foo() ! : let x = 0 ! : function! Bar() closure ! : let x += 1 ! : return x ! : endfunction ! : return funcref('Bar') ! :endfunction ! ! :let F = Foo() ! :echo F() ! < 1 > ! :echo F() ! < 2 > ! :echo F() ! < 3 ! ! *function-search-undo* ! The last used search pattern and the redo command "." ! will not be changed by the function. This also ! implies that the effect of |:nohlsearch| is undone ! when the function returns. ! ! *:endf* *:endfunction* *E126* *E193* *W22* *E1151* ! :endf[unction] [argument] ! The end of a function definition. Best is to put it ! on a line by its own, without [argument]. ! ! [argument] can be: ! | command command to execute next ! \n command command to execute next ! " comment always ignored ! anything else ignored, warning given when ! 'verbose' is non-zero ! The support for a following command was added in Vim ! 8.0.0654, before that any argument was silently ! ignored. ! ! To be able to define a function inside an `:execute` ! command, use line breaks instead of |:bar|: > ! :exe "func Foo()\necho 'foo'\nendfunc" ! < ! *:delf* *:delfunction* *E131* *E933* *E1084* ! :delf[unction][!] {name} ! Delete function {name}. ! {name} can also be a |Dictionary| entry that is a ! |Funcref|: > ! :delfunc dict.init ! < This will remove the "init" entry from "dict". The ! function is deleted if there are no more references to ! it. ! With the ! there is no error if the function does not ! exist. ! *:retu* *:return* *E133* ! :retu[rn] [expr] Return from a function. When "[expr]" is given, it is ! evaluated and returned as the result of the function. ! If "[expr]" is not given, the number 0 is returned. ! When a function ends without an explicit ":return", ! the number 0 is returned. ! In a :def function *E1095* is given if unreachable ! code follows after the `:return`. ! In legacy script there is no check for unreachable ! lines, thus there is no warning if commands follow ! `:return`. ! ! If the ":return" is used after a |:try| but before the ! matching |:finally| (if present), the commands ! following the ":finally" up to the matching |:endtry| ! are executed first. This process applies to all ! nested ":try"s inside the function. The function ! returns at the outermost ":endtry". ! ! *function-argument* *a:var* ! An argument can be defined by giving its name. In the function this can then ! be used as "a:name" ("a:" for argument). ! *a:0* *a:1* *a:000* *E740* *...* ! Up to 20 arguments can be given, separated by commas. After the named ! arguments an argument "..." can be specified, which means that more arguments ! may optionally be following. In the function the extra arguments can be used ! as "a:1", "a:2", etc. "a:0" is set to the number of extra arguments (which ! can be 0). "a:000" is set to a |List| that contains these arguments. Note ! that "a:1" is the same as "a:000[0]". ! *E742* *E1090* ! The a: scope and the variables in it cannot be changed, they are fixed. ! However, if a composite type is used, such as |List| or |Dictionary| , you can ! change their contents. Thus you can pass a |List| to a function and have the ! function add an item to it. If you want to make sure the function cannot ! change a |List| or |Dictionary| use |:lockvar|. ! ! It is also possible to define a function without any arguments. You must ! still supply the () then. ! ! It is allowed to define another function inside a function body. ! ! *optional-function-argument* ! You can provide default values for positional named arguments. This makes ! them optional for function calls. When a positional argument is not ! specified at a call, the default expression is used to initialize it. ! This only works for functions declared with `:function` or `:def`, not for ! lambda expressions |expr-lambda|. ! ! Example: > ! function Something(key, value = 10) ! echo a:key .. ": " .. a:value ! endfunction ! call Something('empty') "empty: 10" ! call Something('key', 20) "key: 20" ! ! The argument default expressions are evaluated at the time of the function ! call, not definition. Thus it is possible to use an expression which is ! invalid the moment the function is defined. The expressions are also only ! evaluated when arguments are not specified during a call. ! *none-function_argument* ! You can pass |v:none| to use the default expression. Note that this means you ! cannot pass v:none as an ordinary value when an argument has a default ! expression. ! ! Example: > ! function Something(a = 10, b = 20, c = 30) ! endfunction ! call Something(1, v:none, 3) " b = 20 ! < ! *E989* ! Optional arguments with default expressions must occur after any mandatory ! arguments. You can use "..." after all optional named arguments. ! ! It is possible for later argument defaults to refer to prior arguments, ! but not the other way around. They must be prefixed with "a:", as with all ! arguments. ! ! Example that works: > ! :function Okay(mandatory, optional = a:mandatory) ! :endfunction ! Example that does NOT work: > ! :function NoGood(first = a:second, second = 10) ! :endfunction ! < ! When not using "...", the number of arguments in a function call must be at ! least equal to the number of mandatory named arguments. When using "...", the ! number of arguments may be larger than the total of mandatory and optional ! arguments. ! ! *local-variables* ! Inside a function local variables can be used. These will disappear when the ! function returns. Global variables need to be accessed with "g:". ! ! Example: > ! :function Table(title, ...) ! : echohl Title ! : echo a:title ! : echohl None ! : echo a:0 .. " items:" ! : for s in a:000 ! : echon ' ' .. s ! : endfor ! :endfunction ! ! This function can then be called with: > ! call Table("Table", "line1", "line2") ! call Table("Empty Table") ! ! To return more than one value, return a |List|: > ! :function Compute(n1, n2) ! : if a:n2 == 0 ! : return ["fail", 0] ! : endif ! : return ["ok", a:n1 / a:n2] ! :endfunction ! ! This function can then be called with: > ! :let [success, div] = Compute(102, 6) ! :if success == "ok" ! : echo div ! :endif ! < ! *:cal* *:call* *E107* ! :[range]cal[l] {name}([arguments]) ! Call a function. The name of the function and its arguments ! are as specified with `:function`. Up to 20 arguments can be ! used. The returned value is discarded. ! In |Vim9| script using `:call` is optional, these two lines do ! the same thing: > ! call SomeFunc(arg) ! SomeFunc(arg) ! < Without a range and for functions that accept a range, the ! function is called once. When a range is given the cursor is ! positioned at the start of the first line before executing the ! function. ! When a range is given and the function doesn't handle it ! itself, the function is executed for each line in the range, ! with the cursor in the first column of that line. The cursor ! is left at the last line (possibly moved by the last function ! call). The arguments are re-evaluated for each line. Thus ! this works: ! *function-range-example* > ! :function Mynumber(arg) ! : echo line(".") .. " " .. a:arg ! :endfunction ! :1,5call Mynumber(getline(".")) ! < ! The "a:firstline" and "a:lastline" are defined anyway, they ! can be used to do something different at the start or end of ! the range. ! Example of a function that handles the range itself: > ! ! :function Cont() range ! : execute (a:firstline + 1) .. "," .. a:lastline .. 's/^/\t\\ ' ! :endfunction ! :4,8call Cont() ! < ! This function inserts the continuation character "\" in front ! of all the lines in the range, except the first one. ! ! When the function returns a composite value it can be further ! dereferenced, but the range will not be used then. Example: > ! :4,8call GetDict().method() ! < Here GetDict() gets the range but method() does not. ! ! *E117* ! When a function cannot be found the error "E117: Unknown function" will be ! given. If the function was using an autoload path or an autoload import and ! the script is a |Vim9| script, this may also be caused by the function not ! being exported. ! ! *E132* ! The recursiveness of user functions is restricted with the |'maxfuncdepth'| ! option. ! ! It is also possible to use `:eval`. It does not support a range, but does ! allow for method chaining, e.g.: > ! eval GetList()->Filter()->append('$') ! ! A function can also be called as part of evaluating an expression or when it ! is used as a method: > ! let x = GetList() ! let y = GetList()->Filter() ! ! ! CLEANING UP IN A FUNCTION ~ ! *:defer* ! :defer {func}({args}) Call {func} when the current function is done. ! {args} are evaluated here. ! ! Quite often a command in a function has a global effect, which must be undone ! when the function finishes. Handling this in all kinds of situations can be a ! hassle. Especially when an unexpected error is encountered. This can be done ! with `try` / `finally` blocks, but this gets complicated when there is more ! than one. ! ! A much simpler solution is using `defer`. It schedules a function call when ! the function is returning, no matter if there is an error. Example: > ! func Filter(text) ! call writefile(a:text, 'Tempfile') ! call system('filter < Tempfile > Outfile') ! call Handle('Outfile') ! call delete('Tempfile') ! call delete('Outfile') ! endfunc ! ! Here 'Tempfile' and 'Outfile' will not be deleted if something causes the ! function to abort. `:defer` can be used to avoid that: > ! func Filter(text) ! call writefile(a:text, 'Tempfile') ! defer delete('Tempfile') ! defer delete('Outfile') ! call system('filter < Tempfile > Outfile') ! call Handle('Outfile') ! endfunc ! ! Note that deleting "Outfile" is scheduled before calling system(), since it ! can be created even when `system()` fails. ! ! The defered functions are called in reverse order, the last one added is ! executed first. A useless example: > ! func Useless() ! for s in range(3) ! defer execute('echomsg "number ' .. s .. '"') ! endfor ! endfunc ! ! Now `:messages` shows: ! number 2 ! number 1 ! number 0 ! ! Any return value of the deferred function is discarded. The function cannot ! be followed by anything, such as "->func" or ".member". Currently `:defer ! GetArg()->TheFunc()` does not work, it may work in a later version. ! ! Errors are reported but do not cause aborting execution of deferred functions. ! ! No range is accepted. ! ! ! AUTOMATICALLY LOADING FUNCTIONS ~ ! *autoload-functions* ! When using many or large functions, it's possible to automatically define them ! only when they are used. There are two methods: with an autocommand and with ! the "autoload" directory in 'runtimepath'. ! ! ! Using an autocommand ~ ! ! This is introduced in the user manual, section |51.4|. ! ! The autocommand is useful if you have a plugin that is a long Vim script file. ! You can define the autocommand and quickly quit the script with `:finish`. ! That makes Vim startup faster. The autocommand should then load the same file ! again, setting a variable to skip the `:finish` command. ! ! Use the FuncUndefined autocommand event with a pattern that matches the ! function(s) to be defined. Example: > ! ! :au FuncUndefined BufNet* source ~/vim/bufnetfuncs.vim ! ! The file "~/vim/bufnetfuncs.vim" should then define functions that start with ! "BufNet". Also see |FuncUndefined|. ! ! ! Using an autoload script ~ ! *autoload* *E746* ! This is introduced in the user manual, section |52.2|. ! ! Using a script in the "autoload" directory is simpler, but requires using ! exactly the right file name. A function that can be autoloaded has a name ! like this: > ! ! :call filename#funcname() ! ! These functions are always global, in Vim9 script "g:" needs to be used: > ! :call g:filename#funcname() ! ! When such a function is called, and it is not defined yet, Vim will search the ! "autoload" directories in 'runtimepath' for a script file called ! "filename.vim". For example "~/.vim/autoload/filename.vim". That file should ! then define the function like this: > ! ! function filename#funcname() ! echo "Done!" ! endfunction ! ! The file name and the name used before the # in the function must match ! exactly, and the defined function must have the name exactly as it will be ! called. In Vim9 script the "g:" prefix must be used: > ! function g:filename#funcname() ! ! or for a compiled function: > ! def g:filename#funcname() ! ! It is possible to use subdirectories. Every # in the function name works like ! a path separator. Thus when calling a function: > ! ! :call foo#bar#func() ! ! Vim will look for the file "autoload/foo/bar.vim" in 'runtimepath'. ! ! This also works when reading a variable that has not been set yet: > ! ! :let l = foo#bar#lvar ! ! However, when the autoload script was already loaded it won't be loaded again ! for an unknown variable. ! ! When assigning a value to such a variable nothing special happens. This can ! be used to pass settings to the autoload script before it's loaded: > ! ! :let foo#bar#toggle = 1 ! :call foo#bar#func() ! ! Note that when you make a mistake and call a function that is supposed to be ! defined in an autoload script, but the script doesn't actually define the ! function, you will get an error message for the missing function. If you fix ! the autoload script it won't be automatically loaded again. Either restart ! Vim or manually source the script. ! ! Also note that if you have two script files, and one calls a function in the ! other and vice versa, before the used function is defined, it won't work. ! Avoid using the autoload functionality at the toplevel. ! ! In |Vim9| script you will get error *E1263* if you define a function with ! a "#" character in the name. You should use a name without "#" and use ! `:export`. ! ! Hint: If you distribute a bunch of scripts you can pack them together with the ! |vimball| utility. Also read the user manual |distribute-script|. ============================================================================== 6. Curly braces names *curly-braces-names* --- 2630,2641 ---- 5. Defining functions *user-functions* New functions can be defined. These can be called just like builtin ! functions. The function takes arguments, executes a sequence of Ex commands ! and can return a value. ! You can find most information about defining functions in |userfunc.txt|. ! For Vim9 functions, which execute much faster, support type checking and more, ! see |vim9.txt|. ============================================================================== 6. Curly braces names *curly-braces-names* *************** *** 3661,3666 **** --- 3174,3182 ---- iterate over. Unlike with |List|, modifying the |Blob| does not affect the iteration. + When {object} is a |String| each item is a string with + one character, plus any combining characters. + In |Vim9| script `:endfor` cannot be shortened, to improve script readability. *** ../vim-9.0.0726/runtime/doc/userfunc.txt 2022-10-11 21:50:43.502084789 +0100 --- runtime/doc/userfunc.txt 2022-09-18 11:09:33.337448441 +0100 *************** *** 0 **** --- 1,531 ---- + *userfunc.txt* For Vim version 9.0. Last change: 2022 Sep 09 + + + VIM REFERENCE MANUAL by Bram Moolenaar + + + Defining and using functions. + + This is introduced in section |41.7| of the user manual. + + 1. Defining a fuction |define-function| + 2. Calling a fuction |:call| + 3. Cleaning up in a function |:defer| + 4. Automatically loading functions |autoload-functions| + + ============================================================================== + + 1. Defining a function ~ + *define-function* + New functions can be defined. These can be called just like builtin + functions. The function executes a sequence of Ex commands. Normal mode + commands can be executed with the |:normal| command. + + The function name must start with an uppercase letter, to avoid confusion with + builtin functions. To prevent from using the same name in different scripts + make them script-local. If you do use a global function then avoid obvious, + short names. A good habit is to start the function name with the name of the + script, e.g., "HTMLcolor()". + + In legacy script it is also possible to use curly braces, see + |curly-braces-names|. + + The |autoload| facility is useful to define a function only when it's called. + + *local-function* + A function local to a legacy script must start with "s:". A local script + function can only be called from within the script and from functions, user + commands and autocommands defined in the script. It is also possible to call + the function from a mapping defined in the script, but then || must be + used instead of "s:" when the mapping is expanded outside of the script. + There are only script-local functions, no buffer-local or window-local + functions. + + In |Vim9| script functions are local to the script by default, prefix "g:" to + define a global function. + + *:fu* *:function* *E128* *E129* *E123* *E454* + :fu[nction] List all functions and their arguments. + + :fu[nction] {name} List function {name}. + {name} can also be a |Dictionary| entry that is a + |Funcref|: > + :function dict.init + + :fu[nction] /{pattern} List functions with a name matching {pattern}. + Example that lists all functions ending with "File": > + :function /File$ + < + *:function-verbose* + When 'verbose' is non-zero, listing a function will also display where it was + last defined. Example: > + + :verbose function SetFileTypeSH + function SetFileTypeSH(name) + Last set from /usr/share/vim/vim-7.0/filetype.vim + < + See |:verbose-cmd| for more information. + + *E124* *E125* *E853* *E884* + :fu[nction][!] {name}([arguments]) [range] [abort] [dict] [closure] + Define a new function by the name {name}. The body of + the function follows in the next lines, until the + matching |:endfunction|. + *E1267* + The name must be made of alphanumeric characters and + '_', and must start with a capital or "s:" (see + above). Note that using "b:" or "g:" is not allowed. + (since patch 7.4.260 E884 is given if the function + name has a colon in the name, e.g. for "foo:bar()". + Before that patch no error was given). + + {name} can also be a |Dictionary| entry that is a + |Funcref|: > + :function dict.init(arg) + < "dict" must be an existing dictionary. The entry + "init" is added if it didn't exist yet. Otherwise [!] + is required to overwrite an existing function. The + result is a |Funcref| to a numbered function. The + function can only be used with a |Funcref| and will be + deleted if there are no more references to it. + *E127* *E122* + When a function by this name already exists and [!] is + not used an error message is given. There is one + exception: When sourcing a script again, a function + that was previously defined in that script will be + silently replaced. + When [!] is used, an existing function is silently + replaced. Unless it is currently being executed, that + is an error. + NOTE: Use ! wisely. If used without care it can cause + an existing function to be replaced unexpectedly, + which is hard to debug. + NOTE: In Vim9 script script-local functions cannot be + deleted or redefined. + + For the {arguments} see |function-argument|. + + *:func-range* *a:firstline* *a:lastline* + When the [range] argument is added, the function is + expected to take care of a range itself. The range is + passed as "a:firstline" and "a:lastline". If [range] + is excluded, ":{range}call" will call the function for + each line in the range, with the cursor on the start + of each line. See |function-range-example|. + The cursor is still moved to the first line of the + range, as is the case with all Ex commands. + *:func-abort* + When the [abort] argument is added, the function will + abort as soon as an error is detected. + *:func-dict* + When the [dict] argument is added, the function must + be invoked through an entry in a |Dictionary|. The + local variable "self" will then be set to the + dictionary. See |Dictionary-function|. + *:func-closure* *E932* + When the [closure] argument is added, the function + can access variables and arguments from the outer + scope. This is usually called a closure. In this + example Bar() uses "x" from the scope of Foo(). It + remains referenced even after Foo() returns: > + :function! Foo() + : let x = 0 + : function! Bar() closure + : let x += 1 + : return x + : endfunction + : return funcref('Bar') + :endfunction + + :let F = Foo() + :echo F() + < 1 > + :echo F() + < 2 > + :echo F() + < 3 + + *function-search-undo* + The last used search pattern and the redo command "." + will not be changed by the function. This also + implies that the effect of |:nohlsearch| is undone + when the function returns. + + *:endf* *:endfunction* *E126* *E193* *W22* *E1151* + :endf[unction] [argument] + The end of a function definition. Best is to put it + on a line by its own, without [argument]. + + [argument] can be: + | command command to execute next + \n command command to execute next + " comment always ignored + anything else ignored, warning given when + 'verbose' is non-zero + The support for a following command was added in Vim + 8.0.0654, before that any argument was silently + ignored. + + To be able to define a function inside an `:execute` + command, use line breaks instead of |:bar|: > + :exe "func Foo()\necho 'foo'\nendfunc" + < + *:delf* *:delfunction* *E131* *E933* *E1084* + :delf[unction][!] {name} + Delete function {name}. + {name} can also be a |Dictionary| entry that is a + |Funcref|: > + :delfunc dict.init + < This will remove the "init" entry from "dict". The + function is deleted if there are no more references to + it. + With the ! there is no error if the function does not + exist. + *:retu* *:return* *E133* + :retu[rn] [expr] Return from a function. When "[expr]" is given, it is + evaluated and returned as the result of the function. + If "[expr]" is not given, the number 0 is returned. + When a function ends without an explicit ":return", + the number 0 is returned. + In a :def function *E1095* is given if unreachable + code follows after the `:return`. + In legacy script there is no check for unreachable + lines, thus there is no warning if commands follow + `:return`. + + If the ":return" is used after a |:try| but before the + matching |:finally| (if present), the commands + following the ":finally" up to the matching |:endtry| + are executed first. This process applies to all + nested ":try"s inside the function. The function + returns at the outermost ":endtry". + + *function-argument* *a:var* + An argument can be defined by giving its name. In the function this can then + be used as "a:name" ("a:" for argument). + *a:0* *a:1* *a:000* *E740* *...* + Up to 20 arguments can be given, separated by commas. After the named + arguments an argument "..." can be specified, which means that more arguments + may optionally be following. In the function the extra arguments can be used + as "a:1", "a:2", etc. "a:0" is set to the number of extra arguments (which + can be 0). "a:000" is set to a |List| that contains these arguments. Note + that "a:1" is the same as "a:000[0]". + *E742* *E1090* + The a: scope and the variables in it cannot be changed, they are fixed. + However, if a composite type is used, such as |List| or |Dictionary| , you can + change their contents. Thus you can pass a |List| to a function and have the + function add an item to it. If you want to make sure the function cannot + change a |List| or |Dictionary| use |:lockvar|. + + It is also possible to define a function without any arguments. You must + still supply the () then. + + It is allowed to define another function inside a function body. + + *optional-function-argument* + You can provide default values for positional named arguments. This makes + them optional for function calls. When a positional argument is not + specified at a call, the default expression is used to initialize it. + This only works for functions declared with `:function` or `:def`, not for + lambda expressions |expr-lambda|. + + Example: > + function Something(key, value = 10) + echo a:key .. ": " .. a:value + endfunction + call Something('empty') "empty: 10" + call Something('key', 20) "key: 20" + + The argument default expressions are evaluated at the time of the function + call, not definition. Thus it is possible to use an expression which is + invalid the moment the function is defined. The expressions are also only + evaluated when arguments are not specified during a call. + *none-function_argument* + You can pass |v:none| to use the default expression. Note that this means you + cannot pass v:none as an ordinary value when an argument has a default + expression. + + Example: > + function Something(a = 10, b = 20, c = 30) + endfunction + call Something(1, v:none, 3) " b = 20 + < + *E989* + Optional arguments with default expressions must occur after any mandatory + arguments. You can use "..." after all optional named arguments. + + It is possible for later argument defaults to refer to prior arguments, + but not the other way around. They must be prefixed with "a:", as with all + arguments. + + Example that works: > + :function Okay(mandatory, optional = a:mandatory) + :endfunction + Example that does NOT work: > + :function NoGood(first = a:second, second = 10) + :endfunction + < + When not using "...", the number of arguments in a function call must be at + least equal to the number of mandatory named arguments. When using "...", the + number of arguments may be larger than the total of mandatory and optional + arguments. + + *local-variables* + Inside a function local variables can be used. These will disappear when the + function returns. Global variables need to be accessed with "g:". + Inside functions local variables are accessed without prepending anything. + But you can also prepend "l:" if you like. This is required for some reserved + names, such as "count". + + Example: > + :function Table(title, ...) + : echohl Title + : echo a:title + : echohl None + : echo a:0 .. " items:" + : for s in a:000 + : echon ' ' .. s + : endfor + :endfunction + + This function can then be called with: > + call Table("Table", "line1", "line2") + call Table("Empty Table") + + To return more than one value, return a |List|: > + :function Compute(n1, n2) + : if a:n2 == 0 + : return ["fail", 0] + : endif + : return ["ok", a:n1 / a:n2] + :endfunction + + This function can then be called with: > + :let [success, div] = Compute(102, 6) + :if success == "ok" + : echo div + :endif + < + ============================================================================== + + 2. Calling a function ~ + *:cal* *:call* *E107* + :[range]cal[l] {name}([arguments]) + Call a function. The name of the function and its arguments + are as specified with `:function`. Up to 20 arguments can be + used. The returned value is discarded. + In |Vim9| script using `:call` is optional, these two lines do + the same thing: > + call SomeFunc(arg) + SomeFunc(arg) + < Without a range and for functions that accept a range, the + function is called once. When a range is given the cursor is + positioned at the start of the first line before executing the + function. + When a range is given and the function doesn't handle it + itself, the function is executed for each line in the range, + with the cursor in the first column of that line. The cursor + is left at the last line (possibly moved by the last function + call). The arguments are re-evaluated for each line. Thus + this works: + *function-range-example* > + :function Mynumber(arg) + : echo line(".") .. " " .. a:arg + :endfunction + :1,5call Mynumber(getline(".")) + < + The "a:firstline" and "a:lastline" are defined anyway, they + can be used to do something different at the start or end of + the range. + + Example of a function that handles the range itself: > + + :function Cont() range + : execute (a:firstline + 1) .. "," .. a:lastline .. 's/^/\t\\ ' + :endfunction + :4,8call Cont() + < + This function inserts the continuation character "\" in front + of all the lines in the range, except the first one. + + When the function returns a composite value it can be further + dereferenced, but the range will not be used then. Example: > + :4,8call GetDict().method() + < Here GetDict() gets the range but method() does not. + + *E117* + When a function cannot be found the error "E117: Unknown function" will be + given. If the function was using an autoload path or an autoload import and + the script is a |Vim9| script, this may also be caused by the function not + being exported. + + *E132* + The recursiveness of user functions is restricted with the |'maxfuncdepth'| + option. + + It is also possible to use `:eval`. It does not support a range, but does + allow for method chaining, e.g.: > + eval GetList()->Filter()->append('$') + + A function can also be called as part of evaluating an expression or when it + is used as a method: > + let x = GetList() + let y = GetList()->Filter() + + ============================================================================== + + 3. Cleaning up in a function ~ + *:defer* + :defer {func}({args}) Call {func} when the current function is done. + {args} are evaluated here. + + Quite often a command in a function has a global effect, which must be undone + when the function finishes. Handling this in all kinds of situations can be a + hassle. Especially when an unexpected error is encountered. This can be done + with `try` / `finally` blocks, but this gets complicated when there is more + than one. + + A much simpler solution is using `defer`. It schedules a function call when + the function is returning, no matter if there is an error. Example: > + func Filter(text) abort + call writefile(a:text, 'Tempfile') + call system('filter < Tempfile > Outfile') + call Handle('Outfile') + call delete('Tempfile') + call delete('Outfile') + endfunc + + Here 'Tempfile' and 'Outfile' will not be deleted if something causes the + function to abort. `:defer` can be used to avoid that: > + func Filter(text) abort + call writefile(a:text, 'Tempfile') + defer delete('Tempfile') + defer delete('Outfile') + call system('filter < Tempfile > Outfile') + call Handle('Outfile') + endfunc + + Note that deleting "Outfile" is scheduled before calling system(), since it + can be created even when `system()` fails. + + The deferred functions are called in reverse order, the last one added is + executed first. A useless example: > + func Useless() abort + for s in range(3) + defer execute('echomsg "number ' .. s .. '"') + endfor + endfunc + + Now `:messages` shows: + number 2 + number 1 + number 0 + + Any return value of the deferred function is discarded. The function cannot + be followed by anything, such as "->func" or ".member". Currently `:defer + GetArg()->TheFunc()` does not work, it may work in a later version. + + Errors are reported but do not cause aborting execution of deferred functions. + + No range is accepted. The function can be a partial with extra arguments, but + not with a dictionary. *E1300* + + ============================================================================== + + 4. Automatically loading functions ~ + *autoload-functions* + When using many or large functions, it's possible to automatically define them + only when they are used. There are two methods: with an autocommand and with + the "autoload" directory in 'runtimepath'. + + In |Vim9| script there is also an autoload mechanism for imported scripts, see + |import-autoload|. + + + Using an autocommand ~ + + This is introduced in the user manual, section |51.4|. + + The autocommand is useful if you have a plugin that is a long Vim script file. + You can define the autocommand and quickly quit the script with `:finish`. + That makes Vim startup faster. The autocommand should then load the same file + again, setting a variable to skip the `:finish` command. + + Use the FuncUndefined autocommand event with a pattern that matches the + function(s) to be defined. Example: > + + :au FuncUndefined BufNet* source ~/vim/bufnetfuncs.vim + + The file "~/vim/bufnetfuncs.vim" should then define functions that start with + "BufNet". Also see |FuncUndefined|. + + + Using an autoload script ~ + *autoload* *E746* + This is introduced in the user manual, section |52.2|. + + Using a script in the "autoload" directory is simpler, but requires using + exactly the right file name. A function that can be autoloaded has a name + like this: > + + :call filename#funcname() + + These functions are always global, in Vim9 script "g:" needs to be used: > + :call g:filename#funcname() + + When such a function is called, and it is not defined yet, Vim will search the + "autoload" directories in 'runtimepath' for a script file called + "filename.vim". For example "~/.vim/autoload/filename.vim". That file should + then define the function like this: > + + function filename#funcname() + echo "Done!" + endfunction + + The file name and the name used before the # in the function must match + exactly, and the defined function must have the name exactly as it will be + called. In Vim9 script the "g:" prefix must be used: > + function g:filename#funcname() + + or for a compiled function: > + def g:filename#funcname() + + It is possible to use subdirectories. Every # in the function name works like + a path separator. Thus when calling a function: > + + :call foo#bar#func() + + Vim will look for the file "autoload/foo/bar.vim" in 'runtimepath'. + + This also works when reading a variable that has not been set yet: > + + :let l = foo#bar#lvar + + However, when the autoload script was already loaded it won't be loaded again + for an unknown variable. + + When assigning a value to such a variable nothing special happens. This can + be used to pass settings to the autoload script before it's loaded: > + + :let foo#bar#toggle = 1 + :call foo#bar#func() + + Note that when you make a mistake and call a function that is supposed to be + defined in an autoload script, but the script doesn't actually define the + function, you will get an error message for the missing function. If you fix + the autoload script it won't be automatically loaded again. Either restart + Vim or manually source the script. + + Also note that if you have two script files, and one calls a function in the + other and vice versa, before the used function is defined, it won't work. + Avoid using the autoload functionality at the toplevel. + + In |Vim9| script you will get error *E1263* if you define a function with + a "#" character in the name. You should use a name without "#" and use + `:export`. + + Hint: If you distribute a bunch of scripts you can pack them together with the + |vimball| utility. Also read the user manual |distribute-script|. + + + vim:tw=78:ts=8:noet:ft=help:norl: *** ../vim-9.0.0726/runtime/doc/vim9.txt 2022-10-01 15:32:42.535442251 +0100 --- runtime/doc/vim9.txt 2022-10-11 21:44:05.493858525 +0100 *************** *** 1,4 **** ! *vim9.txt* For Vim version 9.0. Last change: 2022 Jun 25 VIM REFERENCE MANUAL by Bram Moolenaar --- 1,4 ---- ! *vim9.txt* For Vim version 9.0. Last change: 2022 Oct 11 VIM REFERENCE MANUAL by Bram Moolenaar *************** *** 107,113 **** `:t` `:xit` - Some commands, especially those used for flow control, cannot be shortened. ! E.g., `:throw` cannot be written as `:th`. *E839* - You cannot use curly-braces names. - A range before a command must be prefixed with a colon: > :%s/this/that --- 107,113 ---- `:t` `:xit` - Some commands, especially those used for flow control, cannot be shortened. ! E.g., `:throw` cannot be written as `:th`. *vim9-no-shorten* - You cannot use curly-braces names. - A range before a command must be prefixed with a colon: > :%s/this/that *************** *** 145,150 **** --- 145,161 ---- and produces an error where this might be confusing. #{{ or #{{{ are OK, these can be used to start a fold. + When starting to read a script file Vim doesn't know it is |Vim9| script until + the `vim9script` command is found. Until that point you would need to use + legacy comments: > + " legacy comment + vim9script + # Vim9 comment + + That looks ugly, better put `vim9script` in the very first line: > + vim9script + # Vim9 comment + In legacy Vim script # is also used for the alternate file name. In Vim9 script you need to use %% instead. Instead of ## use %%% (stands for all arguments). *************** *** 270,276 **** script "s:funcref" could be used, because it could not be referred to with "funcref". In Vim9 script it can, therefore "s:Funcref" must be used to avoid that the name interferes with builtin functions. ! *vim9-s-namespace* The use of the "s:" prefix is not supported at the Vim9 script level. All functions and variables without a prefix are script-local. --- 281,287 ---- script "s:funcref" could be used, because it could not be referred to with "funcref". In Vim9 script it can, therefore "s:Funcref" must be used to avoid that the name interferes with builtin functions. ! *vim9-s-namespace* *E1268* The use of the "s:" prefix is not supported at the Vim9 script level. All functions and variables without a prefix are script-local. *************** *** 491,497 **** can't be assigned another value a constant. JavaScript is an example. Others also make the value immutable, thus when a constant uses a list, the list cannot be changed. In Vim9 we can use both. ! *E1021* `:const` is used for making both the variable and the value a constant. Use this for composite structures that you want to make sure will not be modified. Example: > --- 502,508 ---- can't be assigned another value a constant. JavaScript is an example. Others also make the value immutable, thus when a constant uses a list, the list cannot be changed. In Vim9 we can use both. ! *E1021* *E1307* `:const` is used for making both the variable and the value a constant. Use this for composite structures that you want to make sure will not be modified. Example: > *************** *** 846,851 **** --- 857,864 ---- Command modifiers are not ignored ~ *E1176* Using a command modifier for a command that does not use it gives an error. + *E1082* + Also, using a command modifier without a following command is now an error. Dictionary literals ~ *************** *** 900,905 **** --- 913,924 ---- The 'ignorecase' option is not used for comparators that use strings. Thus "=~" works like "=~#". + "is" and "isnot" (|expr-is| and |expr-isnot|) when used on strings now return + false. In legacy script they just compare the strings, in |Vim9| script they + check identity, and strings are copied when used, thus two strings are never + the same (this might change some day if strings are not copied but reference + counted). + Abort after error ~ *************** *** 943,948 **** --- 962,971 ---- 3 Generally, you should not change the list that is iterated over. Make a copy first if needed. + When looping over a list of lists, the nested lists can be changed. The loop + variable is "final", it cannot be changed but what its value can be changed. + *E1306* + The depth of loops, :for and :while loops added together, cannot exceed 10. Conditions and expressions ~ *************** *** 1223,1228 **** --- 1246,1254 ---- before the function is compiled. If the script the function is defined in is legacy script, then script-local variables must be accessed with the "s:" prefix if they do not exist at the time of compiling. + *E1269* + Script-local variables in a |Vim9| script must be declared at the script + level. They cannot be created in a function, also not in a legacy function. *:defc* *:defcompile* :defc[ompile] Compile functions defined in the current script that *************** *** 1289,1295 **** The "inloop" variable will exist only once, all closures put in the list refer to the same instance, which in the end will have the value 4. This is efficient, also when looping many times. If you do want a separate context ! for each closure call a function to define it: > def GetClosure(i: number): func var infunc = i return () => infunc --- 1315,1321 ---- The "inloop" variable will exist only once, all closures put in the list refer to the same instance, which in the end will have the value 4. This is efficient, also when looping many times. If you do want a separate context ! for each closure, call a function to define it: > def GetClosure(i: number): func var infunc = i return () => infunc *************** *** 1305,1310 **** --- 1331,1359 ---- In some situations, especially when calling a Vim9 closure from legacy context, the evaluation will fail. *E1248* + Note that at the script level the loop variable will be invalid after the + loop, also when used in a closure that is called later, e.g. with a timer. + This will generate error |E1302|: > + for n in range(4) + timer_start(500 * n, (_) => { + echowin n + }) + endfor + + You need to use a block and define a variable there, and use that one in the + closure: > + for n in range(4) + { + var nr = n + timer_start(500 * n, (_) => { + echowin nr + }) + } + endfor + + Using `echowindow` is useful in a timer, the messages go into a popup and will + not interfere with what the user is doing when it triggers. + Converting a function from legacy to Vim9 ~ *convert_legacy_function_to_vim9* *************** *** 1366,1376 **** Calling a function in an expr option ~ *expr-option-function* ! A few options, such as 'foldexpr', are an expresison that is evaluated to get ! a value. The evaluation can have quite a bit of overhead. One way to ! minimize the overhead, and also to keep the option value very simple, is to ! defined a compiled function and set the option to call it without arguments. ! Example: > vim9script def MyFoldFunc(): any ... compute fold level for line v:lnum --- 1415,1425 ---- Calling a function in an expr option ~ *expr-option-function* ! The value of a few options, such as 'foldexpr', is an expression that is ! evaluated to get a value. The evaluation can have quite a bit of overhead. ! One way to minimize the overhead, and also to keep the option value very ! simple, is to define a compiled function and set the option to call it ! without arguments. Example: > vim9script def MyFoldFunc(): any ... compute fold level for line v:lnum *************** *** 1496,1501 **** --- 1545,1552 ---- it to a string, use the |string()| function. Or use |str2nr()| to convert a string to a number. + If a type is given where it is not expected you can get *E1272* . + Type inference ~ *type-inference* *************** *** 1609,1615 **** *E1211* *E1217* *E1218* *E1219* *E1220* *E1221* *E1222* *E1223* *E1224* *E1225* *E1226* *E1227* *E1228* *E1238* *E1250* *E1251* *E1252* *E1253* ! *E1256* *E1297* *E1298* Types are checked for most builtin functions to make it easier to spot mistakes. --- 1660,1666 ---- *E1211* *E1217* *E1218* *E1219* *E1220* *E1221* *E1222* *E1223* *E1224* *E1225* *E1226* *E1227* *E1228* *E1238* *E1250* *E1251* *E1252* *E1253* ! *E1256* *E1297* *E1298* *E1301* Types are checked for most builtin functions to make it easier to spot mistakes. *************** *** 1651,1657 **** In Vim9 script the global "g:" namespace can still be used as before. And the "w:", "b:" and "t:" namespaces. These have in common that variables are not ! declared and they can be deleted. A side effect of `:vim9script` is that the 'cpoptions' option is set to the Vim default value, like with: > --- 1702,1708 ---- In Vim9 script the global "g:" namespace can still be used as before. And the "w:", "b:" and "t:" namespaces. These have in common that variables are not ! declared, have no specific type and they can be deleted. *E1304* A side effect of `:vim9script` is that the 'cpoptions' option is set to the Vim default value, like with: > *************** *** 1700,1722 **** Import ~ ! *:import* *:imp* *E1094* *E1047* *E1262* ! *E1048* *E1049* *E1053* *E1071* *E1236* ! The exported items can be imported in another Vim9 script: > import "myscript.vim" ! ! This makes each item available as "myscript.item". *:import-as* *E1257* *E1261* ! In case the name is long or ambiguous, another name can be specified: > ! import "thatscript.vim" as that < *E1060* *E1258* *E1259* *E1260* ! Then you can use "that.EXPORTED_CONST", "that.someValue", etc. You are free ! to choose the name "that". Use something that will be recognized as referring ! to the imported script. Avoid command names, command modifiers and builtin ! function names, because the name will shadow them. ! If the name starts with a capital letter it can also shadow global user ! commands and functions. Also, you cannot use the name for something else in ! the script, such as a function or variable name. In case the dot in the name is undesired, a local reference can be made for a function: > --- 1751,1786 ---- Import ~ ! *:import* *:imp* *E1094* *E1047* *E1262* ! *E1048* *E1049* *E1053* *E1071* *E1088* *E1236* ! The exported items can be imported in another script. The import syntax has ! two forms. The simple form: > ! import {filename} ! < ! Where {filename} is an expression that must evaluate to a string. In this ! form the filename should end in ".vim" and the portion before ".vim" will ! become the script local name of the namespace. For example: > import "myscript.vim" ! < ! This makes each exported item in "myscript.vim" available as "myscript.item". *:import-as* *E1257* *E1261* ! In case the name is long or ambiguous, this form can be used to specify ! another name: > ! import {longfilename} as {name} ! < ! In this form {name} becomes a specific script local name for the imported ! namespace. Therefore {name} must consist of letters, digits and '_', like ! |internal-variables|. The {longfilename} expression must evaluate to any ! filename. For example: > ! import "thatscript.vim.v2" as that < *E1060* *E1258* *E1259* *E1260* ! Then you can use "that.item", etc. You are free to choose the name "that". ! Use something that will be recognized as referring to the imported script. ! Avoid command names, command modifiers and builtin function names, because the ! name will shadow them. Better not start the name starts with a capital ! letter, since it can then also shadow global user commands and functions. ! Also, you cannot use the name for something else in the script, such as a ! function or variable name. In case the dot in the name is undesired, a local reference can be made for a function: > *************** *** 1729,1743 **** when changing the variable the copy will change, not the original variable. You will need to use the full name, with the dot. - The full syntax of the command is: - import {filename} [as {name}] - Where {filename} is an expression that must evaluate to a string. Without the - "as {name}" part it must end in ".vim". {name} must consist of letters, - digits and '_', like |internal-variables|. - - `:import` can also be used in legacy Vim script. The imported items still - become script-local, even when the "s:" prefix is not given. - `:import` can not be used in a function. Imported items are intended to exist at the script level and only imported once. --- 1793,1798 ---- *************** *** 1766,1780 **** name # Error! echo that .name # Error! ! ! To refer to a function in an imported script in a mapping, || can be ! used: > noremap ,a :call name.Function() When the mapping is defined "name." will be replaced with and the script ID of the imported script. An even simpler solution is using ||: > noremap ,a name.Function() < *:import-cycle* The `import` commands are executed when encountered. If script A imports --- 1821,1859 ---- name # Error! echo that .name # Error! ! < *import-map* ! When you've imported a function from one script into a vim9 script you can ! refer to the imported function in a mapping by prefixing it with ||: > noremap ,a :call name.Function() When the mapping is defined "name." will be replaced with and the script ID of the imported script. An even simpler solution is using ||: > noremap ,a name.Function() + + Note that this does not work for variables, only for functions. + + *import-legacy* *legacy-import* + `:import` can also be used in legacy Vim script. The imported namespace still + becomes script-local, even when the "s:" prefix is not given. For example: > + import "myfile.vim" + call s:myfile.MyFunc() + + And using the "as name" form: > + import "otherfile.vim9script" as that + call s:that.OtherFunc() + + However, the namespace cannot be resolved on its own: > + import "that.vim" + echo s:that + " ERROR: E1060: Expected dot after name: s:that + < + This also affects the use of || in the legacy mapping context. Since + || is only a valid prefix for a function and NOT for a namespace, you + cannot use it + to scope a function in a script local namespace. Instead of prefixing the + function with || you should use||. For example: > + noremap ,a :call s:that.OtherFunc() < *:import-cycle* The `import` commands are executed when encountered. If script A imports *************** *** 1786,1792 **** Importing an autoload script ~ ! *vim9-autoload* For optimal startup speed, loading scripts should be postponed until they are actually needed. Using the autoload mechanism is recommended: *E1264* --- 1865,1871 ---- Importing an autoload script ~ ! *vim9-autoload* *import-autoload* For optimal startup speed, loading scripts should be postponed until they are actually needed. Using the autoload mechanism is recommended: *E1264* *** ../vim-9.0.0726/runtime/doc/builtin.txt 2022-10-08 13:49:41.889378451 +0100 --- runtime/doc/builtin.txt 2022-10-10 12:27:49.502057144 +0100 *************** *** 1,4 **** ! *builtin.txt* For Vim version 9.0. Last change: 2022 Jun 27 VIM REFERENCE MANUAL by Bram Moolenaar --- 1,4 ---- ! *builtin.txt* For Vim version 9.0. Last change: 2022 Oct 10 VIM REFERENCE MANUAL by Bram Moolenaar *************** *** 6,14 **** Builtin functions *builtin-functions* ! Note: Expression evaluation can be disabled at compile time. If this has been ! done, the builtin functions are not available. See |+eval| and ! |no-eval-feature|. 1. Overview |builtin-function-list| 2. Details |builtin-function-details| --- 6,15 ---- Builtin functions *builtin-functions* ! Note: Expression evaluation can be disabled at compile time, the builtin ! functions are not available then. See |+eval| and |no-eval-feature|. ! ! For functions grouped by what they are used for see |function-list|. 1. Overview |builtin-function-list| 2. Details |builtin-function-details| *************** *** 1881,1890 **** |setcursorcharpos()|. Does not change the jumplist. ! {lnum} is used like with |getline()|. If {lnum} is greater than the number of lines in the buffer, the cursor will be positioned at the last line in the buffer. - If {lnum} is zero, the cursor will stay in the current line. If {col} is greater than the number of bytes in the line, the cursor will be positioned at the last character in the line. --- 1882,1891 ---- |setcursorcharpos()|. Does not change the jumplist. ! {lnum} is used like with |getline()|, except that if {lnum} is ! zero, the cursor will stay in the current line. If {lnum} is greater than the number of lines in the buffer, the cursor will be positioned at the last line in the buffer. If {col} is greater than the number of bytes in the line, the cursor will be positioned at the last character in the line. *************** *** 2310,2316 **** To check for a supported command always check the return value to be 2. :2match The |:2match| command. ! :3match The |:3match| command. #event autocommand defined for this event #event#pattern autocommand defined for this event and pattern (the pattern is taken --- 2311,2319 ---- To check for a supported command always check the return value to be 2. :2match The |:2match| command. ! :3match The |:3match| command (but you ! probably should not use it, it is ! reserved for internal usage) #event autocommand defined for this event #event#pattern autocommand defined for this event and pattern (the pattern is taken *************** *** 2856,2861 **** --- 2859,2868 ---- /home/user/vim/vim/src < If {mods} is empty or an unsupported modifier is used then {fname} is returned. + When {fname} is empty then with {mods} ":h" returns ".", so + that `:cd` can be used with it. This is different from + expand('%:h') without a buffer name, which returns an empty + string. Note: Environment variables don't work in {fname}, use |expand()| first then. *************** *** 3018,3027 **** Funcref. The extra arguments are appended to the list of arguments. Example: > func Callback(arg1, arg2, name) ! ... let Func = function('Callback', ['one']) let Func2 = function(Func, ['two']) ! ... call Func2('name') < Invokes the function as with: > call Callback('one', 'two', 'name') --- 3025,3034 ---- Funcref. The extra arguments are appended to the list of arguments. Example: > func Callback(arg1, arg2, name) ! "... let Func = function('Callback', ['one']) let Func2 = function(Func, ['two']) ! "... call Func2('name') < Invokes the function as with: > call Callback('one', 'two', 'name') *************** *** 3031,3052 **** function Callback() dict echo "called for " .. self.name endfunction ! ... let context = {"name": "example"} let Func = function('Callback', context) ! ... call Func() " will echo: called for example < The use of function() is not needed when there are no extra ! arguments, these two are equivalent: > let Func = function('Callback', context) let Func = context.Callback < The argument list and the Dictionary can be combined: > function Callback(arg1, count) dict ! ... let context = {"name": "example"} let Func = function('Callback', ['one'], context) ! ... call Func(500) < Invokes the function as with: > call context.Callback('one', 500) --- 3038,3060 ---- function Callback() dict echo "called for " .. self.name endfunction ! "... let context = {"name": "example"} let Func = function('Callback', context) ! "... call Func() " will echo: called for example < The use of function() is not needed when there are no extra ! arguments, these two are equivalent, if Callback() is defined ! as context.Callback(): > let Func = function('Callback', context) let Func = context.Callback < The argument list and the Dictionary can be combined: > function Callback(arg1, count) dict ! "... let context = {"name": "example"} let Func = function('Callback', ['one'], context) ! "... call Func(500) < Invokes the function as with: > call context.Callback('one', 500) *************** *** 4426,4433 **** has_key({dict}, {key}) *has_key()* The result is a Number, which is TRUE if |Dictionary| {dict} ! has an entry with key {key}. FALSE otherwise. The {key} ! argument is a string. Can also be used as a |method|: > mydict->has_key(key) --- 4434,4444 ---- has_key({dict}, {key}) *has_key()* The result is a Number, which is TRUE if |Dictionary| {dict} ! has an entry with key {key}. FALSE otherwise. ! The {key} argument is a string. In |Vim9| script a number is ! also accepted (and converted to a string) but no other types. ! In legacy script the usual automatic conversion to string is ! done. Can also be used as a |method|: > mydict->has_key(key) *************** *** 7026,7038 **** Returns the single letter name of the register being recorded. Returns an empty string when not recording. See |q|. ! reltime([{start} [, {end}]]) *reltime()* Return an item that represents a time value. The item is a list with items that depend on the system. In Vim 9 script list can be used. The item can be passed to |reltimestr()| to convert it to a ! string or |reltimefloat()| to convert to a Float. ! Without an argument reltime() returns the current time (the representation is system-dependent, it can not be used as the wall-clock time, see |localtime()| for that). --- 7037,7055 ---- Returns the single letter name of the register being recorded. Returns an empty string when not recording. See |q|. ! reltime() ! reltime({start}) ! reltime({start}, {end}) *reltime()* Return an item that represents a time value. The item is a list with items that depend on the system. In Vim 9 script list can be used. The item can be passed to |reltimestr()| to convert it to a ! string or |reltimefloat()| to convert to a Float. For ! example, to see the time spent in function Work(): > ! var startTime = reltime() ! Work() ! echo startTime->reltime()->reltimestr() ! < Without an argument reltime() returns the current time (the representation is system-dependent, it can not be used as the wall-clock time, see |localtime()| for that). *************** *** 7153,7160 **** This function is not available in the |sandbox|. {only available when compiled with the |+clientserver| feature} Examples: > ! :let repl = "" ! :echo "PEEK: " .. remote_peek(id, "repl") .. ": " .. repl < Can also be used as a |method|: > ServerId()->remote_peek() --- 7170,7177 ---- This function is not available in the |sandbox|. {only available when compiled with the |+clientserver| feature} Examples: > ! :let repl = "" ! :echo "PEEK: " .. remote_peek(id, "repl") .. ": " .. repl < Can also be used as a |method|: > ServerId()->remote_peek() *************** *** 7214,7220 **** < {only available when compiled with the |+clientserver| feature} ! remove({list}, {idx} [, {end}]) *remove()* Without {end}: Remove the item at {idx} from |List| {list} and return the item. With {end}: Remove items from {idx} to {end} (inclusive) and --- 7231,7238 ---- < {only available when compiled with the |+clientserver| feature} ! remove({list}, {idx}) ! remove({list}, {idx}, {end}) *remove()* Without {end}: Remove the item at {idx} from |List| {list} and return the item. With {end}: Remove items from {idx} to {end} (inclusive) and *************** *** 7232,7238 **** Can also be used as a |method|: > mylist->remove(idx) ! remove({blob}, {idx} [, {end}]) Without {end}: Remove the byte at {idx} from |Blob| {blob} and return the byte. With {end}: Remove bytes from {idx} to {end} (inclusive) and --- 7250,7257 ---- Can also be used as a |method|: > mylist->remove(idx) ! remove({blob}, {idx}) ! remove({blob}, {idx}, {end}) Without {end}: Remove the byte at {idx} from |Blob| {blob} and return the byte. With {end}: Remove bytes from {idx} to {end} (inclusive) and *************** *** 7478,7484 **** < When {stopline} is used and it is not zero this also implies that the search does not wrap around the end of the file. A zero value is equal to not giving the argument. ! When the {timeout} argument is given the search stops when more than this many milliseconds have passed. Thus when {timeout} is 500 the search stops after half a second. --- 7497,7503 ---- < When {stopline} is used and it is not zero this also implies that the search does not wrap around the end of the file. A zero value is equal to not giving the argument. ! *E1285* *E1286* *E1287* *E1288* *E1289* When the {timeout} argument is given the search stops when more than this many milliseconds have passed. Thus when {timeout} is 500 the search stops after half a second. *** ../vim-9.0.0726/src/version.c 2022-10-11 21:41:21.446173722 +0100 --- src/version.c 2022-10-11 21:47:18.061836284 +0100 *************** *** 701,702 **** --- 701,704 ---- { /* Add new patch number below this line */ + /**/ + 727, /**/ -- Seen on the back of a biker's vest: If you can read this, my wife fell off. /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// \\\ \\\ sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///