In this “part 1”, several global changes and improvements are made to vim9.txt (except for sections 2 and 8, which will be addressed in “part 2”). “Part 2” is written already, but is large. So it is better separated from this PR.
The changes are:
>vim9 on the blank line that separates the text from the code block. (This makes maintenance easier too with fewer lines getting wrapped unnecessarily when using gq.)Notes: blocks are reformatted. They now have no indent, as discussed and agreed in PR19250.Locations of changes are indicated by reference to *tag* in the updated file.
vim9.txt being a very large, comprehensive help file, shorter introductions probably are worth referencing. This aligns with other references, e.g., https://github.com/lacygoill/wiki/blob/master/vim/vim9.md, which at one point appeared in several places.:def function is defined in is a Vim9...”: The paragraph and example are extended and qualified to cover exists_compiled().exists() versus exists_compiled() difference.*tuple-type*
*variadic-tuple*
*vim9-func-declaration*
Tags *E1005* and *E1007* are moved to the end of the passage on the func type as they are specific func related errors.
Regarding the func list in the current help:
func({type}, ?{type}, ...list<{type}>): {type}, is sufficiently problematic to warrant it being omitted. Although it can “work” in some scenarios, the danger is that it is interpreted as meaning the optional parameter 2 always may be omitted when parameter 3 is provided. It (or more correctly, they, if the [: void] variant was also included) could be reverted, and included as the last examples: func({type}, ?{type}, ...list<{type}>)[: void]
- typed mandatory argument
- typed optional argument
- typed list for variable number of arguments
- does not return a value
func({type}, ?{type}, ...list<{type}>): {type}
- typed mandatory argument
- typed optional argument
- typed list for variable number of arguments
- returns a typed value
However, doing so would need to come with warnings regarding unintended consequences and errors. A mostly “working” example is this (echoing 9 for all output except the last line):
vim9script
def D(n: number, o: float = 0.1, ...l: list<number>): number
return (n + o + max(sort(l, (x, y) => x + y)))->float2nr()
enddef
const F: func(number, ?float, ...list<number>): number = D->function()
echo F(9)
echo F(8, 1.0)
echo F(7, 1.0, 0, 1)
echo F(6, 2.0, 1)
echo F(5, 3, 1)
echo F(4, 5)
echo F(8, 1) # E1013
The problem with this example is that, although it appears to be successfully skipping the float, that’s not what it’s doing. What is happening is that the number (3 in the third-to-last echo, then 5 in the penultimate echo) is being coerced to a float. This can be proven by adding an echo l[0] to D():
vim9script
def D(n: number, o: float = 0.1, ...l: list<number>): number
echo $'({l[0]} is the first list item)'
return (n + o + max(sort(l, (x, y) => x + y)))->float2nr()
enddef
const F: func(number, ?float, ...list<number>): number = D->function()
echo F(1, 2.0, 1, 6)
echo F(1, 2, 6)
This shows that 6 is the first list item in the second echo, not 2, which it would be if the optional float was truly being skipped.
It feels wrong to be documenting a questionable “way”: As this example shows, the optional parameter cannot actually be skipped. It is always filled positionally, either by coercion or error. So, it does not feel helpful suggesting this “way”.
func(?{type}): {type}func(...list<{type}>): {type}func({type}, ...list<{type}>)[: void]func({type}, ...list<{type}>): {type}[: void] for the implicit/explicit indicator of no typed return value.*E1005*
*E1005* is distinctly addressed. It was not stated anywhere what this is relates to. Providing an example of, “No more than 19 argument types may be used...”, takes only a few lines to illustrate the point. A working, extreme example with precisely 19 arguments (for anyone who wants it 😀️) is:
vim9script
var X: func
X = (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s) => 0
# The lambda X() can have up to 20 arguments (19 are shown here):
echo X(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 19)
# The Funcref F() can have up to 19 arguments:
var F: func(any, any, any, any, any, any, any, any, any, any, any,
\ any, any, any, any, any, any, any, any): any = X->function()
echo F(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 19)
*E1007*
*E1007* is treated separately too. It is another specific error related to Funcrefs - i.e., trying to use a mandatory argument after an optional argument. (Incidental: It has some parallels to the removed, problematic, func({type}, ?{type}, ...list<{type}>): {type}.)This section receives the same global changes applied elsewhere (2-space body indent, standalone >vim9 syntax blocks, trailing-comment condensation, “Note:” treatment, etc.); there are no substantive content changes.
*E1304*
*:export*
*:exp* is removed because using that invalid shortened form gives E1065.final someValue/const somevalue is removed. Also,function is added: legacy functions, not just :def functions, can be exported.*E1043*
*E1042*
:export can only be used in a Vim9 script scope.” This is more accurate than the current help, which says, “at the script level”, which is inaccurate. For example, this script will export a constant, and it is not at the script level:
vim9script
b:tmp = $'{tempname()}.vim'->substitute('\\', '/', 'g')
['vim9script',
'export def D(): void',
' export const C = "C is exported!"',
'enddef']->writefile(b:tmp)
import b:tmp as imported
imported.D()
echo $"Exported constant 'C' in 'imported' ({b:tmp}):\n" .. imported.C
*E1044*
*:import*
*:imp* is relocated because, like tag *:exp*, it is not helpful implying :imp is allowed in Vim9 script (it gives E1065, which is “command cannot be shortened”). It is relocated to the *import-legacy* passage, thought, because it is permitted in legacy Vim script.*:import* are relocated to their own distinct places, along with explanations and examples.*E1094*
*E1053* *E1071*
*:import-as*
*E1257* and *E1261* are relocated later with distinct explanations and examples.:export and :import-as. It is helpful because, from personal experience, trying to understand the nuances of exporting and importing is not easy using the current help. Hopefully, providing working examples and more detailed explanations will make it easier.*E1047* to *E1262*
ccomplete.vim in Vim's $VIMRUNTIME path or temporarily write a Vim9 script to tempname(), then import it.*import-map*
Note sentence, a self-contained example of using <ScriptCmd> is provided.*import-legacy* *legacy-import* *:imp*
:imp is moved here since the shortened form, :imp, is only valid in a legacy Vim script.vim9.txt are generally more detailed than those in vim9class.txt, so it is worth pointing users to them.https://github.com/vim/vim/pull/20706
(1 file)
—
Reply to this email directly, view it on GitHub, or unsubscribe.
Triage notifications, keep track of coding agent tasks and review pull requests on the go with GitHub Mobile for iOS and Android. Download it today!
You are receiving this because you are subscribed to this thread.![]()