From da086246b1aec40dbc932a48b0c27486e290cfdd Mon Sep 17 00:00:00 2001 From: Kyoichiro Yamada Date: Tue, 26 Jan 2021 19:57:01 +0900 Subject: [PATCH 01/14] update en/vim9.txt --- en/vim9.txt | 355 +++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 270 insertions(+), 85 deletions(-) diff --git a/en/vim9.txt b/en/vim9.txt index 085e4453e..7246ff87a 100644 --- a/en/vim9.txt +++ b/en/vim9.txt @@ -1,4 +1,4 @@ -*vim9.txt* For Vim version 8.2. Last change: 2020 Nov 25 +*vim9.txt* For Vim version 8.2. Last change: 2021 Jan 23 VIM REFERENCE MANUAL by Bram Moolenaar @@ -6,7 +6,7 @@ THIS IS STILL UNDER DEVELOPMENT - ANYTHING CAN BREAK - ANYTHING CAN CHANGE -Vim9 script commands and expressions. *vim9* +Vim9 script commands and expressions. *Vim9* *vim9* Most expression help is in |eval.txt|. This file is about the new syntax and features in Vim9 script. @@ -14,7 +14,7 @@ features in Vim9 script. THIS IS STILL UNDER DEVELOPMENT - ANYTHING CAN BREAK - ANYTHING CAN CHANGE -1. What is Vim9 script? |vim9-script| +1. What is Vim9 script? |Vim9-script| 2. Differences |vim9-differences| 3. New style functions |fast-functions| 4. Types |vim9-types| @@ -25,7 +25,7 @@ THIS IS STILL UNDER DEVELOPMENT - ANYTHING CAN BREAK - ANYTHING CAN CHANGE ============================================================================== -1. What is Vim9 script? *vim9-script* +1. What is Vim9 script? *Vim9-script* THIS IS STILL UNDER DEVELOPMENT - ANYTHING CAN BREAK - ANYTHING CAN CHANGE @@ -52,8 +52,9 @@ The Vim9 script syntax and semantics are used in: - a script file where the first command is `vim9script` - an autocommand defined in the context of the above -When using `:function` in a Vim9 script file the legacy syntax is used. -However, this can be confusing and is therefore discouraged. +When using `:function` in a Vim9 script file the legacy syntax is used, with +the highest |scriptversion|. However, this can be confusing and is therefore +discouraged. Vim9 script and legacy Vim script can be mixed. There is no requirement to rewrite old scripts, they keep working as before. You may want to use a few @@ -70,28 +71,29 @@ Overview ~ Brief summary of the differences you will most often encounter when using Vim9 script and `:def` functions; details are below: - Comments start with #, not ": > - echo "hello" # comment + echo "hello" # comment - Using a backslash for line continuation is hardly ever needed: > - echo "hello " + echo "hello " .. yourName .. ", how are you?" - White space is required in many places. - Assign values without `:let`, declare variables with `:var`: > - var count = 0 + var count = 0 count += 3 - Constants can be declared with `:final` and `:const`: > - final matches = [] # add matches + final matches = [] # add matches const names = ['Betty', 'Peter'] # cannot be changed - `:final` cannot be used as an abbreviation of `:finally`. - Variables and functions are script-local by default. - Functions are declared with argument types and return type: > def CallMe(count: number, message: string): bool - Call functions without `:call`: > - writefile(['done'], 'file.txt') + writefile(['done'], 'file.txt') - You cannot use `:xit`, `:t`, `:append`, `:change`, `:insert` or curly-braces names. - A range before a command must be prefixed with a colon: > - :%s/this/that + :%s/this/that +- Unless mentioned specifically, the highest |scriptversion| is used. Comments starting with # ~ @@ -112,7 +114,13 @@ In Vi # is a command to list text with numbers. In Vim9 script you can use 101 number To improve readability there must be a space between a command and the # -that starts a comment. +that starts a comment: > + var name = value # comment + var name = value# error! + +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). Vim9 functions ~ @@ -123,8 +131,8 @@ often 10x to 100x times. Many errors are already found when compiling, before the function is executed. The syntax is strict, to enforce code that is easy to read and understand. -Compilation is done when: -- the function is first called +Compilation is done when either of these is encountered: +- the first time the function is called - when the `:defcompile` command is encountered in the script where the function was defined - `:disassemble` is used for the function. @@ -132,8 +140,9 @@ Compilation is done when: reference `:def` has no options like `:function` does: "range", "abort", "dict" or -"closure". A `:def` function always aborts on an error, does not get a range -passed and cannot be a "dict" function. +"closure". A `:def` function always aborts on an error (unless `:silent!` was +used for the command or inside a `:try` block), does not get a range passed +cannot be a "dict" function, and can always be a closure. The argument types and return type need to be specified. The "any" type can be used, type checking will then be done at runtime, like with legacy @@ -186,6 +195,33 @@ Global functions can still be defined and deleted at nearly any time. In Vim9 script script-local functions are defined once when the script is sourced and cannot be deleted or replaced. +When compiling a function and a function call is encountered for a function +that is not (yet) defined, the |FuncUndefined| autocommand is not triggered. +You can use an autoload function if needed, or call a legacy function and have +|FuncUndefined| triggered there. + + +Reloading a Vim9 script clears functions and variables by default ~ + *vim9-reload* +When loading a legacy Vim script a second time nothing is removed, the +commands will replace existing variables and functions and create new ones. + +When loading a Vim9 script a second time all existing script-local functions +and variables are deleted, thus you start with a clean slate. This is useful +if you are developing a plugin and want to try a new version. If you renamed +something you don't have to worry about the old name still hanging around. + +If you do want to keep items, use: > + vim9script noclear + +You want to use this in scripts that use a `finish` command to bail out at +some point when loaded again. E.g. when a buffer local option is set: > + vim9script noclear + setlocal completefunc=SomeFunc + if exists('*g:SomeFunc') | finish | endif + def g:SomeFunc() + .... + Variable declarations with :var, :final and :const ~ *vim9-declaration* *:var* @@ -281,7 +317,7 @@ The constant only applies to the value itself, not what it refers to. > NAMES[0] = ["Jack"] # Error! NAMES[0][0] = "Jack" # Error! NAMES[1] = ["Emma"] # Error! - Names[1][0] = "Emma" # OK, now females[0] == "Emma" + NAMES[1][0] = "Emma" # OK, now females[0] == "Emma" < *E1092* Declaring more than one variable at a time, using the unpack notation, is @@ -334,11 +370,55 @@ When using `function()` the resulting type is "func", a function with any number of arguments and any return type. The function can be defined later. +Lambda using => instead of -> ~ + +In legacy script there can be confusion between using "->" for a method call +and for a lambda. Also, when a "{" is found the parser needs to figure out if +it is the start of a lambda or a dictionary, which is now more complicated +because of the use of argument types. + +To avoid these problems Vim9 script uses a different syntax for a lambda, +which is similar to Javascript: > + var Lambda = (arg) => expression + +No line break is allowed in the arguments of a lambda up to and including the +"=>". This is OK: > + filter(list, (k, v) => + v > 0) +This does not work: > + filter(list, (k, v) + => v > 0) +This also does not work: > + filter(list, (k, + v) => v > 0) +But you can use a backslash to concatenate the lines before parsing: > + filter(list, (k, + \ v) + \ => v > 0) + +Additionally, a lambda can contain statements in {}: > + var Lambda = (arg) => { + g:was_called = 'yes' + return expression + } +NOT IMPLEMENTED YET + + *vim9-curly* +To avoid the "{" of a dictionary literal to be recognized as a statement block +wrap it in parenthesis: > + var Lambda = (arg) => ({key: 42}) + +Also when confused with the start of a command block: > + ({ + key: value + })->method() + + Automatic line continuation ~ In many cases it is obvious that an expression continues on the next line. In -those cases there is no need to prefix the line with a backslash -|line-continuation|. For example, when a list spans multiple lines: > +those cases there is no need to prefix the line with a backslash (see +|line-continuation|). For example, when a list spans multiple lines: > var mylist = [ 'one', 'two', @@ -360,7 +440,7 @@ possible just before or after the operator. For example: > .. middle .. end var total = start + - end - + end - correction var result = positive ? PosFunc(arg) @@ -375,6 +455,12 @@ before it: > var result = MyDict .member +For commands that have an argument that is a list of commands, the | character +at the start of the line indicates line continuation: > + autocmd BufNewFile *.match if condition + | echo 'match' + | endif + < *E1050* To make it possible for the operator at the start of the line to be recognized, it is required to put a colon before a range. This will add @@ -398,6 +484,19 @@ arguments: > separator = '-' ): string +Since a continuation line cannot be easily recognized the parsing of commands +has been made stricter. E.g., because of the error in the first line, the +second line is seen as a separate command: > + popup_create(some invalid expression, { + exit_cb: Func}) +Now "exit_cb: Func})" is actually a valid command: save any changes to the +file "_cb: Func})" and exit. To avoid this kind of mistake in Vim9 script +there must be white space between most command names and the argument. + +However, the argument of a command that is a command won't be recognized. For +example, after "windo echo expr" a line break inside "expr" will not be seen. + + Notes: - "enddef" cannot be used at the start of a continuation line, it ends the current function. @@ -417,14 +516,6 @@ Notes: < This does not work: > echo [1, 2] [3, 4] -- No line break is allowed in the arguments of a lambda, between the "{" and - "->". This is OK: > - filter(list, {k, v -> - v > 0}) -< This does not work: > - filter(list, {k, - v -> v > 0}) - No curly braces expansion ~ @@ -436,20 +527,26 @@ Dictionary literals ~ Traditionally Vim has supported dictionary literals with a {} syntax: > let dict = {'key': value} -Later it became clear that using a simple key name is very common, thus -literally dictionaries were introduced in a backwards compatible way: > +Later it became clear that using a simple text key is very common, thus +literal dictionaries were introduced in a backwards compatible way: > let dict = #{key: value} -However, this #{} syntax is unlike any existing language. As it appears that -using a literal key is much more common than using an expression, and +However, this #{} syntax is unlike any existing language. As it turns out +that using a literal key is much more common than using an expression, and considering that JavaScript uses this syntax, using the {} form for dictionary -literals was considered a much more useful syntax. In Vim9 script the {} form +literals is considered a much more useful syntax. In Vim9 script the {} form uses literal keys: > - let dict = {key: value} + var dict = {key: value} + +This works for alphanumeric characters, underscore and dash. If you want to +use another character, use a single or double quoted string: > + var dict = {'key with space': value} + var dict = {"key\twith\ttabs": value} + var dict = {'': value} # empty key -In case an expression needs to be used for the key, square brackets can be -used, just like in JavaScript: > - let dict = {["key" .. nr]: value} +In case the key needs to be an expression, square brackets can be used, just +like in JavaScript: > + var dict = {["key" .. nr]: value} No :xit, :t, :append, :change or :insert ~ @@ -464,6 +561,29 @@ Comparators ~ The 'ignorecase' option is not used for comparators that use strings. +For loop ~ + +Legacy Vim script has some tricks to make a for loop over a list handle +deleting items at the current or previous item. In Vim9 script it just uses +the index, if items are deleted then items in the list will be skipped. +Example legacy script: > + let l = [1, 2, 3, 4] + for i in l + echo i + call remove(l, index(l, i)) + endfor +Would echo: + 1 + 2 + 3 + 4 +In compiled Vim9 script you get: + 1 + 3 +Generally, you should not change the list that is iterated over. Make a copy +first if needed. + + White space ~ Vim9 script enforces proper use of white space. This is no longer allowed: > @@ -479,17 +599,26 @@ command: > White space is required around most operators. +White space is required in a sublist (list slice) around the ":", except at +the start and end: > + otherlist = mylist[v : count] # v:count has a different meaning + otherlist = mylist[:] # make a copy of the List + otherlist = mylist[v :] + otherlist = mylist[: v] + White space is not allowed: - Between a function name and the "(": > - call Func (arg) # Error! - call Func + Func (arg) # Error! + Func \ (arg) # Error! - call Func(arg) # OK - call Func( - \ arg) # OK - call Func( - \ arg # OK - \ ) + Func + (arg) # Error! + Func(arg) # OK + Func( + arg) # OK + Func( + arg # OK + ) Conditions and expressions ~ @@ -509,7 +638,7 @@ is either falsy or truthy. This is mostly like JavaScript, except that an empty list and dict is falsy: type truthy when ~ - bool v:true or 1 + bool true, v:true or 1 number non-zero float non-zero string non-empty @@ -517,11 +646,11 @@ empty list and dict is falsy: list non-empty (different from JavaScript) dictionary non-empty (different from JavaScript) func when there is a function name - special v:true + special true or v:true job when not NULL channel when not NULL class when not NULL - object when not NULL (TODO: when isTrue() returns v:true) + object when not NULL (TODO: when isTrue() returns true) The boolean operators "||" and "&&" expect the values to be boolean, zero or one: > @@ -536,25 +665,37 @@ one: > When using "!" for inverting, there is no error for using any type and the result is a boolean. "!!" can be used to turn any value into boolean: > - !'yes' == false + !'yes' == false !![] == false - !![1, 2, 3] == true + !![1, 2, 3] == true When using "`.."` for string concatenation arguments of simple types are always converted to string: > 'hello ' .. 123 == 'hello 123' - 'hello ' .. v:true == 'hello v:true' + 'hello ' .. v:true == 'hello true' Simple types are string, float, special and bool. For other types |string()| can be used. - *false* *true* -In Vim9 script one can use "true" for v:true and "false" for v:false. + *false* *true* *null* +In Vim9 script one can use "true" for v:true, "false" for v:false and "null" +for v:null. When converting a boolean to a string "false" and "true" are +used, not "v:false" and "v:true" like in legacy script. "v:none" is not +changed, it is only used in JSON and has no equivalent in other languages. -Indexing a string with [idx] or [idx, idx] uses character indexes instead of +Indexing a string with [idx] or [idx : idx] uses character indexes instead of byte indexes. Example: > echo 'bár'[1] In legacy script this results in the character 0xc3 (an illegal byte), in Vim9 script this results in the string 'á'. +A negative index is counting from the end, "[-1]" is the last character. +To exclude the last character use |slice()|. +If the index is out of range then an empty string results. + +In legacy script "++var" and "--var" would be silently accepted and have no +effect. This is an error in Vim9 script. + +Numbers starting with zero are not considered to be octal, only numbers +starting with "0o" are octal: "0o744". |scriptversion-4| What to watch out for ~ @@ -564,21 +705,22 @@ same time tries to support the legacy Vim commands. Some compromises had to be made. Here is a summary of what might be unexpected. Ex command ranges need to be prefixed with a colon. > - -> # legacy Vim: shifts the previous line to the right - ->func() # Vim9: method call in continuation line - :-> # Vim9: shifts the previous line to the right + -> legacy Vim: shifts the previous line to the right + ->func() Vim9: method call in a continuation line + :-> Vim9: shifts the previous line to the right - %s/a/b # legacy Vim: substitute on all lines + %s/a/b legacy Vim: substitute on all lines x = alongname - % another # Vim9: line continuation without a backslash - :%s/a/b # Vim9: substitute on all lines - 'text'->func() # Vim9: method call - :'t # legacy Vim: jump to mark m + % another Vim9: modulo operator in a continuation line + :%s/a/b Vim9: substitute on all lines + 't legacy Vim: jump to mark t + 'text'->func() Vim9: method call + :'t Vim9: jump to mark t Some Ex commands can be confused with assignments in Vim9 script: > - g:name = value # assignment - g:pattern:cmd # invalid command - ERROR - :g:pattern:cmd # :global command + g:name = value # assignment + g:pattern:cmd # invalid command - ERROR + :g:pattern:cmd # :global command Functions defined with `:def` compile the whole function. Legacy functions can bail out, and the following lines are not parsed: > @@ -593,12 +735,12 @@ Vim9 functions are compiled as a whole: > if !has('feature') return endif - use-feature # May give compilation error + use-feature # May give a compilation error enddef For a workaround, split it in two functions: > func Maybe() if has('feature') - call MaybyInner() + call MaybeInner() endif endfunc if has('feature') @@ -613,12 +755,38 @@ evaluates to false: > use-feature endif enddef +< *vim9-user-command* +Another side effect of compiling a function is that the presence of a user +command is checked at compile time. If the user command is defined later an +error will result. This works: > + command -nargs=1 MyCommand echom + def Works() + MyCommand 123 + enddef +This will give an error for "MyCommand" not being defined: > + def Works() + command -nargs=1 MyCommand echom + MyCommand 123 + enddef +A workaround is to invoke the command indirectly with `:execute`: > + def Works() + command -nargs=1 MyCommand echom + execute 'MyCommand 123' + enddef + Note that for unrecognized commands there is no check for "|" and a following command. This will give an error for missing `endif`: > def Maybe() if has('feature') | use-feature | endif enddef +Other differences ~ + +Patterns are used like 'magic' is set, unless explicitly overruled. +The 'edcompatible' option value is not used. +The 'gdefault' option value is not used. + + ============================================================================== 3. New style functions *fast-functions* @@ -679,21 +847,30 @@ prefix and they do not need to exist (they can be deleted any time). Note that for command line completion of {func} you can prepend "s:" to find script-local functions. +:disa[ssemble]! {func} Like `:disassemble` but with the instructions used for + profiling. + Limitations ~ Local variables will not be visible to string evaluation. For example: > - def EvalString(): list + def MapList(): list var list = ['aa', 'bb', 'cc', 'dd'] return range(1, 2)->map('list[v:val]') enddef The map argument is a string expression, which is evaluated without the function scope. Instead, use a lambda: > - def EvalString(): list + def MapList(): list var list = ['aa', 'bb', 'cc', 'dd'] - return range(1, 2)->map({ _, v -> list[v] }) + return range(1, 2)->map(( _, v) => list[v]) enddef +The same is true for commands that are not compiled, such as `:global`. +For these the backtick expansion can be used. Example: > + def Replace() + var newText = 'blah' + g/pattern/s/^/`=newText`/ + enddef ============================================================================== @@ -788,12 +965,14 @@ compiled code the "any" type is assumed. This can be a problem when the "any" type is undesired and the actual type is expected to always be the same. For example, when declaring a list: > var l: list = [1, g:two] -This will give an error, because "g:two" has type "any". To avoid this, use a -type cast: > +At compile time Vim doesn't know the type of "g:two" and the expression type +becomes list. An instruction is generated to check the list type before +doing the assignment, which is a bit inefficient. + *type-casting* +To avoid this, use a type cast: > var l: list = [1, g:two] -< *type-casting* -The compiled code will then check that "g:two" is a number at runtime and give -an error if it isn't. This is called type casting. +The compiled code will then only check that "g:two" is a number and give an +error if it isn't. This is called type casting. The syntax of a type cast is: "<" {type} ">". There cannot be white space after the "<" or before the ">" (to avoid them being confused with @@ -835,6 +1014,12 @@ an error, thus breaking backwards compatibility. For example: - Using a string value when setting a number options. - Using a number where a string is expected. *E1024* +One consequence is that the item type of a list or dict given to map() must +not change. This will give an error in compiled code: > + map([1, 2, 3], (i, v) => 'item ' .. i) + E1012: Type mismatch; expected list but got list +Instead use |mapnew()|. + ============================================================================== 5. Namespace, Import and Export @@ -851,7 +1036,7 @@ that you don't do that. Namespace ~ - *:vim9script* *:vim9* + *vim9-namespace* To recognize a file that can be imported the `vim9script` statement must appear as the first statement in the file. It tells Vim to interpret the script in its own namespace, instead of the global namespace. If a file @@ -944,14 +1129,14 @@ actually needed. A recommended mechanism: 1. In the plugin define user commands, functions and/or mappings that refer to an autoload script. > - command -nargs=1 SearchForStuff call searchfor#Stuff() + command -nargs=1 SearchForStuff searchfor#Stuff() < This goes in .../plugin/anyname.vim. "anyname.vim" can be freely chosen. 2. In the autoload script do the actual work. You can import items from other files to split up functionality in appropriate pieces. > vim9script - import FilterFunc from "../import/someother.vim" + import FilterFunc from "../import/someother.vim" def searchfor#Stuff(arg: string) var filtered = FilterFunc(arg) ... @@ -1037,12 +1222,12 @@ When compiling lines of Vim commands into instructions as much as possible should be done at compile time. Postponing it to runtime makes the execution slower and means mistakes are found only later. For example, when encountering the "+" character and compiling this into a generic add -instruction, at execution time the instruction would have to inspect the type -of the arguments and decide what kind of addition to do. And when the -type is dictionary throw an error. If the types are known to be numbers then -an "add number" instruction can be used, which is faster. The error can be -given at compile time, no error handling is needed at runtime, since adding -two numbers cannot fail. +instruction, at runtime the instruction would have to inspect the type of the +arguments and decide what kind of addition to do. And when the type is +dictionary throw an error. If the types are known to be numbers then an "add +number" instruction can be used, which is faster. The error can be given at +compile time, no error handling is needed at runtime, since adding two numbers +cannot fail. The syntax for types, using for compound types, is similar to Java. It is easy to understand and widely used. The type names are what were used in From bac545a0cc41878c47a84c35aa0a20e11c9ef649 Mon Sep 17 00:00:00 2001 From: Kyoichiro Yamada Date: Tue, 26 Jan 2021 20:55:08 +0900 Subject: [PATCH 02/14] update for en/vim9.txt#145 --- doc/vim9.jax | 39 +++++++++++++++++++++++---------------- 1 file changed, 23 insertions(+), 16 deletions(-) diff --git a/doc/vim9.jax b/doc/vim9.jax index 3cbb35093..4957066d3 100644 --- a/doc/vim9.jax +++ b/doc/vim9.jax @@ -1,4 +1,4 @@ -*vim9.txt* For Vim バージョン 8.2. Last change: 2020 Nov 25 +*vim9.txt* For Vim バージョン 8.2. Last change: 2021 Jan 23 VIMリファレンスマニュアル by Bram Moolenaar @@ -6,7 +6,7 @@ THIS IS STILL UNDER DEVELOPMENT - ANYTHING CAN BREAK - ANYTHING CAN CHANGE -Vim9 script のコマンドと文法 *vim9* +Vim9 script のコマンドと文法 *Vim9* *vim9* ほとんどの文法については |eval.txt| で解説されています。このファイルには Vim9 script の新しい文法と機能について書かれています。 @@ -14,7 +14,7 @@ script の新しい文法と機能について書かれています。 THIS IS STILL UNDER DEVELOPMENT - ANYTHING CAN BREAK - ANYTHING CAN CHANGE -1. Vim9 script とは |vim9-script| +1. Vim9 script とは |Vim9-script| 2. 変更点 |vim9-differences| 3. 新しいスタイルの関数 |fast-functions| 4. 型 |vim9-types| @@ -25,7 +25,7 @@ THIS IS STILL UNDER DEVELOPMENT - ANYTHING CAN BREAK - ANYTHING CAN CHANGE ============================================================================== -1. Vim9 script とは *vim9-script* +1. Vim9 script とは *Vim9-script* THIS IS STILL UNDER DEVELOPMENT - ANYTHING CAN BREAK - ANYTHING CAN CHANGE @@ -53,7 +53,7 @@ Vim9 script は以下の場所で使用することができます: - 上記のコンテキストで定義された自動コマンド Vim9 スクリプトファイルの中でコマンド `:function` で関数を定義すると、その中で -は旧来の Vim script の記法が有効になります。 +は旧来の Vim script の記法が、最新の |scriptversion| とともに有効になります。 しかし、これは混乱を招く可能性があるため、推奨できません。 Vim9 script と旧来の Vim script は同時に利用できます。古いスクリプトを書き換え @@ -71,28 +71,28 @@ THIS IS STILL UNDER DEVELOPMENT - ANYTHING CAN BREAK - ANYTHING CAN CHANGE Vim9 script と `:def` で定義する関数を使用する際に最もよく遭遇する変更点の概要 をまとめると以下のとおりです: - コメントは " ではなく、# で始めます: > - echo "hello" # コメント + echo "hello" # コメント - 行継続文字 (\) はほとんどの場合、必要ありません: > - echo "hello " + echo "hello " .. yourName .. ", how are you?" - 多くの場所にスペースが必要になります。 - 値の代入には `:let` を使用せず、変数の宣言には `:var` を使用します: > - var count = 0 + var count = 0 count += 3 - `:final` と `:const` を使用して、定数を宣言できます: > - final matches = [] # matches を追加 + final matches = [] # matches を追加 const names = ['Betty', 'Peter'] # 変更できない - `:final` は `:finally` の略語として使用することはできません。 - 変数と関数のスコープは、明示しない限りスクリプトローカルです。 - 関数を引数の型、戻り値の型とともに宣言します: > def CallMe(count: number, message: string): bool - 関数は `:call` なしで呼び出します: > - writefile(['done'], 'file.txt') + writefile(['done'], 'file.txt') - `:xit`、`:t`、`:append`、`:change`、`:insert` と波括弧変数は使用できません。 - コマンドの前に範囲指定を置くときは、コロン (:) を前置しなくてはなりません: > - :%s/this/that - + :%s/this/that +- 特に指定しない限り、最新の |scriptversion| が使われます。 # から始まるコメント ~ @@ -112,7 +112,13 @@ Vi において # は行番号付きでテキストを表示します。Vim9 scr 101 number 可読性を向上するために、コマンドと #、コメント文の間にはスペースをおいてくださ -い。 +い: > + var name = value # コメント + var name = value# エラー! + +旧来の Vim script では # は代替バッファのファイル名として使います。Vim9 script +では、代わりに %% を使う必要があります。 ## の代わりに %%% を使います。(すべて +の引数を意味します) Vim9 関数 ~ @@ -123,15 +129,16 @@ Vim9 関数 ~ 多くのエラーは関数が実行される前に、コンパイルされる段階で検出されます。読みや すく理解しやすいコードを強制するために、構文は厳密に定められています。 -コンパイルは以下のタイミングで実行されます: +コンパイルは以下のいずれかのタイミングで実行されます: - 関数が最初に呼び出されるとき - 関数の定義されたスクリプトの中で、コマンド `:defcompile` に出会ったとき - 関数に対してコマンド `:disassemble` が実行されたとき - コンパイルされた関数から呼び出されたり、関数リファレンスとして使用されたとき `:def` には `:function` の "range"、"abort"、"dict" や "closure" といったオプ -ションがありません。`:def` で定義する関数は常にエラー時は処理を中断 (abort) -し、範囲を受け取らず、辞書関数にすることはできません。 +ションがありません。`:def` で定義する関数はエラー時は常に (ただし、`:silent!` +が指定されたコマンドか、`:try` ブロックの中は除く) 処理を中断 (abort) し、範囲 +を受け取らず、辞書関数にすることはできず、常にクロージャとすることができます。 引数の型と戻り値の型を指定する必要があります。型には "any" を指定することがで き、型のチェックは旧来の関数と同様に実行時に行われます。 From ebc13b74fb2a6d5690903b66f0fd1c183e3acbc6 Mon Sep 17 00:00:00 2001 From: Kyoichiro Yamada Date: Tue, 26 Jan 2021 22:10:49 +0900 Subject: [PATCH 03/14] update for vim9.txt#417 --- doc/vim9.jax | 72 +++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 71 insertions(+), 1 deletion(-) diff --git a/doc/vim9.jax b/doc/vim9.jax index 4957066d3..2c04882a0 100644 --- a/doc/vim9.jax +++ b/doc/vim9.jax @@ -194,6 +194,33 @@ Vim9 script でスクリプト直下に `:function` や `:def` を使って関 script でのスクリプトローカル関数は、スクリプトが読み込まれたときに一度定義さ れたきり、削除や置き換えはできません。 +関数のコンパイルや、関数の呼び出しが未定義の関数に遭遇したとき、自動コマンド +|FuncUndefined| は呼び出されません。必要であればオートロード関数を使用したり、 +旧来の関数を呼び出すことで |FuncUndefined| イベントが発生します。 + + +デフォルトでは Vim9 script の再読み込みにより関数と変数がクリアされる ~ + *vim9-reload* +旧来の Vim script を2回目に読み込んだときは、何も削除されることはなく、コマン +ドはすでにある変数や関数を置き換えて新しいものを作ります。 + +Vim9 script を2回目に読み込んだときは、存在するすべてのスクリプトローカルの関 +数や変数は削除され、クリーンな状態から開始します。これはプラグインを開発中に、 +新しいバージョンを試す際には便利です。いずれかの名前を変えたとしても、古い名前 +が宙に浮いて残る心配はありません。 + +消さずに残すには、以下を使用します: > + vim9script noclear + +これは、`finish` コマンドを使っているスクリプトで、再読み込みの際にある時点で +脱出するために使用することができます。たとえば、バッファローカルオプションを設 +定するときです: > + vim9script noclear + setlocal completefunc=SomeFunc + if exists('*g:SomeFunc') | finish | endif + def g:SomeFunc() + .... + :var、:final や :const で宣言する変数 ~ *vim9-declaration* *:var* @@ -288,7 +315,7 @@ Vim9ではこのどちらも定義することができます。 NAMES[0] = ["Jack"] # エラー! NAMES[0][0] = "Jack" # エラー! NAMES[1] = ["Emma"] # エラー! - Names[1][0] = "Emma" # OK, females[0] == "Emma" + NAMES[1][0] = "Emma" # OK, females[0] == "Emma" < *E1092* 変数を複数一度に宣言し、同時にアンパックする記法は現在サポートされていません: > @@ -339,6 +366,49 @@ function() は不要に ~ す。 +ラムダ式には -> の代わりに => を使う ~ + +旧来のスクリプトでは "->" はメソッド呼び出しとラムダ式で混乱をきたすおそれがあ +ります。また、"{" が見つかったとき、パーサはラムダ式と辞書の開始どちらかを見分 +けねばならず、そしてそれは引数の型指定によりより複雑になっています。 + +この問題を回避するため、Vim9 script ではラムダ式のために違う書式を使用し、それ +は Javascript に似ています: > + var Lambda = (arg) => expression + +"=>" まで含めて、ラムダ式の引数の定義の中では改行することはできません。以下は +問題のない例です: > + filter(list, (k, v) => + v > 0) +以下のように記述することはできません: > + filter(list, (k, v) + => v > 0) +以下のように記述することもできません: > + filter(list, (k, + v) => v > 0) +ただし、バックスラッシュを使ってパースする前に行をつなげることができます: > + filter(list, (k, + \ v) + \ => v > 0) + +加えて、ラムダ式には {} に複数のステートメントを含むことができます: > + var Lambda = (arg) => { + g:was_called = 'yes' + return expression + } +NOT IMPLEMENTED YET + + *vim9-curly* +辞書リテラルの "{" がステートメントブロックと認識されてしまうのを回避するため +には、括弧で包みます: > + var Lambda = (arg) => ({key: 42}) + +コマンドブロックの開始と混同してしまう場合も同様です: > + ({ + key: value + })->method() + + 自動行継続 ~ 多くの場合、式が次の行に続くことは明らかです。継続行の先頭に行継続のためのバッ From 9b967129fcf9dd92f0432ed14e99574a53c3db8c Mon Sep 17 00:00:00 2001 From: Kyoichiro Yamada Date: Tue, 26 Jan 2021 22:47:16 +0900 Subject: [PATCH 04/14] update for vim9.txt#550 --- doc/vim9.jax | 37 +++++++++++++++++++++++++++---------- 1 file changed, 27 insertions(+), 10 deletions(-) diff --git a/doc/vim9.jax b/doc/vim9.jax index 2c04882a0..391541127 100644 --- a/doc/vim9.jax +++ b/doc/vim9.jax @@ -403,7 +403,7 @@ NOT IMPLEMENTED YET には、括弧で包みます: > var Lambda = (arg) => ({key: 42}) -コマンドブロックの開始と混同してしまう場合も同様です: > +さらに、コマンドブロックの開始と混同してしまう場合: > ({ key: value })->method() @@ -412,7 +412,7 @@ NOT IMPLEMENTED YET 自動行継続 ~ 多くの場合、式が次の行に続くことは明らかです。継続行の先頭に行継続のためのバッ -クスラッシュ |line-continuation| を置く必要はありません。たとえば、複数行にま +クスラッシュ (|line-continuation|参照) を置く必要はありません。たとえば、複数行にま たぐリストの場合: > var mylist = [ 'one', @@ -450,6 +450,12 @@ NOT IMPLEMENTED YET var result = MyDict .member +複数のコマンドのリストを引数に持つコマンドでは、行の先頭に置かれた文字 | は行 +継続を表します: > + autocmd BufNewFile *.match if condition + | echo 'match' + | endif + < *E1050* 行頭の演算子と識別できるようにするために、範囲指定の前にはコロンを置きま す。"start" と print をつなげる例: > @@ -471,6 +477,18 @@ Note |+cmd| の引数にはコロンは不要です: > separator = '-' ): string +継続行を識別することは容易ではないため、コマンドの解析はより厳格化されていま +す。たとえば、一行目のエラーにより、2行目は別のコマンドとみなされます: > + popup_create(some invalid expression, { + exit_cb: Func}) +ここで "exit_cb: Func})" は実際に有効なコマンドです: 変更をファイル +"_cb: Func})" に保存して閉じます。Vim9 script の中ではこの種のミスを回避するた +めに、コマンド名と引数の間には空白を置かなくてはなりません。 + +However, the argument of a command that is a command won't be recognized. For +example, after "windo echo expr" a line break inside "expr" will not be seen. + + Notes: - "enddef" は継続行の先頭に置くことはできません。それは関数の終端を意味します。 - 代入式の左辺を複数の行に分割できません。特にリストのアンパック |:let-unpack| @@ -489,13 +507,6 @@ Notes: < 以下のように記述することはできません: > echo [1, 2] [3, 4] -- ラムダ関数の引数、"{" と "->" の間は複数の行に分割できません。以下は問題のな - い例です: > - filter(list, {k, v -> - v > 0}) -< 以下のように記述することはできません: > - filter(list, {k, - v -> v > 0}) 波括弧変数の廃止 ~ @@ -518,9 +529,15 @@ Notes: ラルに {} の表記を使うほうがずっと便利です: > let dict = {key: value} +これは英数字、アンダースコアとダッシュのキーで利用できます。異なる文字を使用す +る場合は、シングルクォートまたはダブルクォートで囲まれた文字列を使用します: > + var dict = {'key with space': value} + var dict = {"key\twith\ttabs": value} + var dict = {'': value} # 空のキー + キーに式を使用する必要がある場合は、JavaScript と同様に角括弧を使用することが できます: > - let dict = {["key" .. nr]: value} + var dict = {["key" .. nr]: value} :xit、:t、:append、:change、:insert の廃止 ~ From 120bdcb004626f695a2d8815ad5a01741d632e56 Mon Sep 17 00:00:00 2001 From: Kyoichiro Yamada Date: Tue, 26 Jan 2021 23:09:48 +0900 Subject: [PATCH 05/14] update for vim9.txt#678 --- doc/vim9.jax | 57 ++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 44 insertions(+), 13 deletions(-) diff --git a/doc/vim9.jax b/doc/vim9.jax index 391541127..19fc24348 100644 --- a/doc/vim9.jax +++ b/doc/vim9.jax @@ -483,7 +483,7 @@ Note |+cmd| の引数にはコロンは不要です: > exit_cb: Func}) ここで "exit_cb: Func})" は実際に有効なコマンドです: 変更をファイル "_cb: Func})" に保存して閉じます。Vim9 script の中ではこの種のミスを回避するた -めに、コマンド名と引数の間には空白を置かなくてはなりません。 +めに、コマンド名と引数の間にはスペースを置かなくてはなりません。 However, the argument of a command that is a command won't be recognized. For example, after "windo echo expr" a line break inside "expr" will not be seen. @@ -552,6 +552,29 @@ Notes: オプション 'ignorecase' は文字列の比較には作用しません。 +For ループ~ + +旧来の Vim script では、リストのループ内で現在または前の項目を削除するための +for ループをつくるために幾つかのトリックがあります。Vim9 script では、単純にイ +ンデックスを使用することで、リストから削除された場合はスキップされます。 +旧来のスクリプトの例: > + let l = [1, 2, 3, 4] + for i in l + echo i + call remove(l, index(l, i)) + endfor +出力は以下の通り: + 1 + 2 + 3 + 4 +コンパイルされた Vim9 スクリプトでの出力は以下の通り: + 1 + 3 +一般的に、反復しているリストを変更してはいけません。必要であれば最初にコピーを +作ります。 + + スペース ~ Vim9 script ではスペースの適切な使用を推奨しています。以下のような記述はできま @@ -567,17 +590,25 @@ Vim9 script ではスペースの適切な使用を推奨しています。以 多くの演算子の前後にはスペースが必要です。 +部分リストの ":" の前後には、先頭と末尾の場合を除いてはスペースが必要です: > + otherlist = mylist[v : count] # v:count は違う意味になる + otherlist = mylist[:] # リストのコピーを作る + otherlist = mylist[v :] + otherlist = mylist[: v] + スペースをおいてはいけない場合: - 関数の名前と "(" の間: > - call Func (arg) # エラー! - call Func + Func (arg) # エラー! + Func \ (arg) # エラー! - call Func(arg) # OK - call Func( - \ arg) # OK - call Func( - \ arg # OK - \ ) + Func + (arg) # エラー! + Func(arg) # OK + Func( + arg) # OK + Func( + arg # OK + ) 条件と式 ~ @@ -597,7 +628,7 @@ falsy か truthy として評価されます。これは JavaScript とほぼ同 リストと辞書は falsy として評価されます: 型 真と評価される値 ~ - bool v:true または 1 + bool true, v:true または 1 number 非0 float 非0 string 空文字列以外 @@ -605,11 +636,11 @@ falsy か truthy として評価されます。これは JavaScript とほぼ同 list 空リスト以外 (JavaScript とは異なります) dictionary 空辞書以外 (JavaScript とは異なります) func when there is a function name - special v:true + special true or v:true job 非 NULL channel 非 NULL class 非 NULL - object 非 NULL (TODO: isTrue() が v:true を返すとき) + object 非 NULL (TODO: isTrue() が true を返すとき) 真偽値演算子 "||" と "&&" は、値が真偽値、0または1であることを期待します: > @@ -631,7 +662,7 @@ falsy か truthy として評価されます。これは JavaScript とほぼ同 文字列の結合に `..` を使用すると、すべての単純型の被演算子は常に文字列に変換さ れます: > 'hello ' .. 123 == 'hello 123' - 'hello ' .. v:true == 'hello v:true' + 'hello ' .. v:true == 'hello true' 単純型とは、文字列 (string)、数値 (float)、特殊値 (special) と真偽値 (bool) で す。他の型では |string()| が使用できます。 From e3ceb2602f4ad2542dd98838a8571e29b92eaae8 Mon Sep 17 00:00:00 2001 From: Kyoichiro Yamada Date: Tue, 26 Jan 2021 23:39:39 +0900 Subject: [PATCH 06/14] update for vim9.txt#782 --- doc/vim9.jax | 116 ++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 86 insertions(+), 30 deletions(-) diff --git a/doc/vim9.jax b/doc/vim9.jax index 19fc24348..fa3dbbfbf 100644 --- a/doc/vim9.jax +++ b/doc/vim9.jax @@ -667,15 +667,27 @@ falsy か truthy として評価されます。これは JavaScript とほぼ同 単純型とは、文字列 (string)、数値 (float)、特殊値 (special) と真偽値 (bool) で す。他の型では |string()| が使用できます。 - *false* *true* -Vim9 script では "true" を v:true として、"false" を v:false として使うことが -できます。 + *false* *true* *null* +Vim9 script では "true" を v:true として、"false" を v:false と "null" として +使うことができます。真偽値を文字列に変換するとき、旧来のスクリプトのような +"v:false" と "v:true" ではなく、"false" と "true" を使用します。"v:none" は変 +わらず、JSONでのみ使用され、他の言語に相当するものはありません -文字列に対してインデックス [idx] や [idx, idx] を使用すると、バイト単位ではな +文字列に対してインデックス [idx] や [idx : idx] を使用すると、バイト単位ではな く文字単位のインデックスとして扱われます。例: > echo 'bár'[1] 旧来の Vim script ではこれは文字 0xc3 (不正な文字) となりますが、Vim9 script では文字列 'á' が得られます。 +負のインデックスを指定すると、文字列の末尾から数えられます。"[-1]" は最後の文 +字です。 +最後の文字を除外するには |slice()| を使用します。 +インデックスが範囲外の場合は、空文字列になります。 + +旧来のスクリプトでは "++var" と "--var" は寡黙に処理され、何の効果ももたらしま +せん。これは Vim9 script ではエラーになります。 + +ゼロから始まる数値は8進数とはみなされません、"0o" から始まる数値だけが8進数と +みなされます: "0o744"。 |scriptversion-4| 気をつけるべきこと ~ @@ -685,16 +697,17 @@ Vim9 は、一般的なプログラミング言語に近づくように設計さ ければなりませんでした。ここでは、意外と知られていないことをまとめてみました。 Exコマンドの範囲指定にはコロンを前置する必要があります。 > - -> # 旧来の Vim: 前の行を右にシフト - ->func() # Vim9: 継続行におけるメソッド呼び出し - :-> # Vim9: 前の行を右にシフト + -> 旧来の Vim: 前の行を右にシフト + ->func() Vim9: 継続行におけるメソッド呼び出し + :-> Vim9: 前の行を右にシフト - %s/a/b # 旧来の Vim: すべての行を置換 + %s/a/b 旧来の Vim: すべての行を置換 x = alongname - % another # Vim9: バックスラッシュなしの行継続 - :%s/a/b # Vim9: すべての行を置換 - 'text'->func() # Vim9: メソッド呼び出し - :'t # 旧来の Vim: マーク t へのジャンプ + % another Vim9: 継続行の剰余演算 + :%s/a/b Vim9: すべての行を置換 + 't 旧来の Vim: マーク t へのジャンプ + 'text'->func() Vim9: メソッド呼び出し + :'t Vim9: マーク t へのジャンプ いくつかのExコマンドは Vim9 script の代入式と紛らわしくなります: > g:name = value # 代入 @@ -719,7 +732,7 @@ Vim9 関数はすべてコンパイルされます: > 応急的に、2つの関数に分けることができます: > func Maybe() if has('feature') - call MaybyInner() + call MaybeInner() endif endfunc if has('feature') @@ -734,12 +747,38 @@ Vim9 関数はすべてコンパイルされます: > use-feature endif enddef +< *vim9-user-command* +関数のコンパイルによる他の副作用として、ユーザーコマンドの存在がコンパイルの時 +点でチェックされます。ユーザーコマンドが後で定義されている場合、エラーとなりま +す。以下は問題のない例です: > + command -nargs=1 MyCommand echom + def Works() + MyCommand 123 + enddef +以下の例では "MyCommand" が定義されていないというエラーが発生します: > + def Works() + command -nargs=1 MyCommand echom + MyCommand 123 + enddef +ワークアラウンドとして、`:execute` を使用して間接的にコマンドを呼び出せます: > + def Works() + command -nargs=1 MyCommand echom + execute 'MyCommand 123' + enddef + Note 認識されていないコマンドを "|" でつなぐと、その後のコマンドは認識されませ ん。次のような記述は `endif` がないというエラーになります: > def Maybe() if has('feature') | use-feature | endif enddef +その他の変更点 ~ + +Patterns are used like 'magic' is set, unless explicitly overruled. +The 'edcompatible' option value is not used. +The 'gdefault' option value is not used. + + ============================================================================== 3. New style functions *fast-functions* @@ -800,21 +839,30 @@ prefix and they do not need to exist (they can be deleted any time). Note that for command line completion of {func} you can prepend "s:" to find script-local functions. +:disa[ssemble]! {func} Like `:disassemble` but with the instructions used for + profiling. + Limitations ~ Local variables will not be visible to string evaluation. For example: > - def EvalString(): list + def MapList(): list var list = ['aa', 'bb', 'cc', 'dd'] return range(1, 2)->map('list[v:val]') enddef The map argument is a string expression, which is evaluated without the function scope. Instead, use a lambda: > - def EvalString(): list + def MapList(): list var list = ['aa', 'bb', 'cc', 'dd'] - return range(1, 2)->map({ _, v -> list[v] }) + return range(1, 2)->map(( _, v) => list[v]) enddef +The same is true for commands that are not compiled, such as `:global`. +For these the backtick expansion can be used. Example: > + def Replace() + var newText = 'blah' + g/pattern/s/^/`=newText`/ + enddef ============================================================================== @@ -909,12 +957,14 @@ compiled code the "any" type is assumed. This can be a problem when the "any" type is undesired and the actual type is expected to always be the same. For example, when declaring a list: > var l: list = [1, g:two] -This will give an error, because "g:two" has type "any". To avoid this, use a -type cast: > +At compile time Vim doesn't know the type of "g:two" and the expression type +becomes list. An instruction is generated to check the list type before +doing the assignment, which is a bit inefficient. + *type-casting* +To avoid this, use a type cast: > var l: list = [1, g:two] -< *type-casting* -The compiled code will then check that "g:two" is a number at runtime and give -an error if it isn't. This is called type casting. +The compiled code will then only check that "g:two" is a number and give an +error if it isn't. This is called type casting. The syntax of a type cast is: "<" {type} ">". There cannot be white space after the "<" or before the ">" (to avoid them being confused with @@ -956,6 +1006,12 @@ an error, thus breaking backwards compatibility. For example: - Using a string value when setting a number options. - Using a number where a string is expected. *E1024* +One consequence is that the item type of a list or dict given to map() must +not change. This will give an error in compiled code: > + map([1, 2, 3], (i, v) => 'item ' .. i) + E1012: Type mismatch; expected list but got list +Instead use |mapnew()|. + ============================================================================== 5. Namespace, Import and Export @@ -972,7 +1028,7 @@ that you don't do that. Namespace ~ - *:vim9script* *:vim9* + *vim9-namespace* To recognize a file that can be imported the `vim9script` statement must appear as the first statement in the file. It tells Vim to interpret the script in its own namespace, instead of the global namespace. If a file @@ -1065,14 +1121,14 @@ actually needed. A recommended mechanism: 1. In the plugin define user commands, functions and/or mappings that refer to an autoload script. > - command -nargs=1 SearchForStuff call searchfor#Stuff() + command -nargs=1 SearchForStuff searchfor#Stuff() < This goes in .../plugin/anyname.vim. "anyname.vim" can be freely chosen. 2. In the autoload script do the actual work. You can import items from other files to split up functionality in appropriate pieces. > vim9script - import FilterFunc from "../import/someother.vim" + import FilterFunc from "../import/someother.vim" def searchfor#Stuff(arg: string) var filtered = FilterFunc(arg) ... @@ -1158,12 +1214,12 @@ When compiling lines of Vim commands into instructions as much as possible should be done at compile time. Postponing it to runtime makes the execution slower and means mistakes are found only later. For example, when encountering the "+" character and compiling this into a generic add -instruction, at execution time the instruction would have to inspect the type -of the arguments and decide what kind of addition to do. And when the -type is dictionary throw an error. If the types are known to be numbers then -an "add number" instruction can be used, which is faster. The error can be -given at compile time, no error handling is needed at runtime, since adding -two numbers cannot fail. +instruction, at runtime the instruction would have to inspect the type of the +arguments and decide what kind of addition to do. And when the type is +dictionary throw an error. If the types are known to be numbers then an "add +number" instruction can be used, which is faster. The error can be given at +compile time, no error handling is needed at runtime, since adding two numbers +cannot fail. The syntax for types, using for compound types, is similar to Java. It is easy to understand and widely used. The type names are what were used in From 458c17c596289ef8b676ae756ca68944d7fdff50 Mon Sep 17 00:00:00 2001 From: Kyoichiro Yamada Date: Tue, 26 Jan 2021 23:43:22 +0900 Subject: [PATCH 07/14] update for limit --- doc/vim9.jax | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/doc/vim9.jax b/doc/vim9.jax index fa3dbbfbf..7225b4337 100644 --- a/doc/vim9.jax +++ b/doc/vim9.jax @@ -774,9 +774,10 @@ Note 認識されていないコマンドを "|" でつなぐと、その後の その他の変更点 ~ -Patterns are used like 'magic' is set, unless explicitly overruled. -The 'edcompatible' option value is not used. -The 'gdefault' option value is not used. +パターンは、明示的に上書きされない限り 'magic' が設定されている状態と同様に作 +用します。 +オプション 'edcompatible' の値は使用されません。 +オプション 'gdefault' の値は使用されません。 ============================================================================== From c23981dc159e5b415770f1e696582c5bc75267bd Mon Sep 17 00:00:00 2001 From: Kyoichiro Yamada Date: Tue, 26 Jan 2021 23:52:10 +0900 Subject: [PATCH 08/14] fix following update --- doc/vim9.jax | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/doc/vim9.jax b/doc/vim9.jax index 7225b4337..a6e410eef 100644 --- a/doc/vim9.jax +++ b/doc/vim9.jax @@ -117,8 +117,8 @@ Vi において # は行番号付きでテキストを表示します。Vim9 scr var name = value# エラー! 旧来の Vim script では # は代替バッファのファイル名として使います。Vim9 script -では、代わりに %% を使う必要があります。 ## の代わりに %%% を使います。(すべて -の引数を意味します) +では、代わりに %% を使う必要があります。 ## の代わりに %%% を使います。(すべ +ての引数を意味します) Vim9 関数 ~ @@ -136,8 +136,8 @@ Vim9 関数 ~ - コンパイルされた関数から呼び出されたり、関数リファレンスとして使用されたとき `:def` には `:function` の "range"、"abort"、"dict" や "closure" といったオプ -ションがありません。`:def` で定義する関数はエラー時は常に (ただし、`:silent!` -が指定されたコマンドか、`:try` ブロックの中は除く) 処理を中断 (abort) し、範囲 +ションがありません。`:def` で定義する関数はエラー時は常に(ただし、`:silent!` +が指定されたコマンドか、`:try` ブロックの中は除く)処理を中断 (abort) し、範囲 を受け取らず、辞書関数にすることはできず、常にクロージャとすることができます。 引数の型と戻り値の型を指定する必要があります。型には "any" を指定することがで @@ -369,8 +369,8 @@ function() は不要に ~ ラムダ式には -> の代わりに => を使う ~ 旧来のスクリプトでは "->" はメソッド呼び出しとラムダ式で混乱をきたすおそれがあ -ります。また、"{" が見つかったとき、パーサはラムダ式と辞書の開始どちらかを見分 -けねばならず、そしてそれは引数の型指定によりより複雑になっています。 +ります。また、"{" が見つかったとき、パーサーはラムダ式と辞書の開始どちらかを見 +分けねばならず、そしてそれは引数の型指定によりより複雑になっています。 この問題を回避するため、Vim9 script ではラムダ式のために違う書式を使用し、それ は Javascript に似ています: > @@ -412,8 +412,8 @@ NOT IMPLEMENTED YET 自動行継続 ~ 多くの場合、式が次の行に続くことは明らかです。継続行の先頭に行継続のためのバッ -クスラッシュ (|line-continuation|参照) を置く必要はありません。たとえば、複数行にま -たぐリストの場合: > +クスラッシュ (|line-continuation| 参照) を置く必要はありません。たとえば、複数 +行にまたぐリストの場合: > var mylist = [ 'one', 'two', @@ -485,8 +485,8 @@ Note |+cmd| の引数にはコロンは不要です: > "_cb: Func})" に保存して閉じます。Vim9 script の中ではこの種のミスを回避するた めに、コマンド名と引数の間にはスペースを置かなくてはなりません。 -However, the argument of a command that is a command won't be recognized. For -example, after "windo echo expr" a line break inside "expr" will not be seen. +ただし、コマンドの引数に置いたコマンドは認識されません。たとえば、 +"windo echo expr" に続く "expr" の式の中で改行しても認識されません。 Notes: From 7a62b330cb3a0e39607ac7a28e721e062697e953 Mon Sep 17 00:00:00 2001 From: Kyoichiro Yamada Date: Wed, 27 Jan 2021 00:14:37 +0900 Subject: [PATCH 09/14] fix description of usage of `vim9script noclear` --- doc/vim9.jax | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/doc/vim9.jax b/doc/vim9.jax index a6e410eef..0c460a6c1 100644 --- a/doc/vim9.jax +++ b/doc/vim9.jax @@ -212,9 +212,8 @@ Vim9 script を2回目に読み込んだときは、存在するすべてのス 消さずに残すには、以下を使用します: > vim9script noclear -これは、`finish` コマンドを使っているスクリプトで、再読み込みの際にある時点で -脱出するために使用することができます。たとえば、バッファローカルオプションを設 -定するときです: > +これを使用することで、再読み込みの際に任意の場所で `finish` コマンドにより脱出 +することができます。たとえば、バッファローカルオプションが設定されているとき: > vim9script noclear setlocal completefunc=SomeFunc if exists('*g:SomeFunc') | finish | endif From 2f4b381b0e8303e1d5ae19071f844c7ae49afe02 Mon Sep 17 00:00:00 2001 From: Kyoichiro Yamada Date: Wed, 27 Jan 2021 00:19:22 +0900 Subject: [PATCH 10/14] fix description of the lambda differences --- doc/vim9.jax | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/vim9.jax b/doc/vim9.jax index 0c460a6c1..07cec6caf 100644 --- a/doc/vim9.jax +++ b/doc/vim9.jax @@ -367,9 +367,9 @@ function() は不要に ~ ラムダ式には -> の代わりに => を使う ~ -旧来のスクリプトでは "->" はメソッド呼び出しとラムダ式で混乱をきたすおそれがあ -ります。また、"{" が見つかったとき、パーサーはラムダ式と辞書の開始どちらかを見 -分けねばならず、そしてそれは引数の型指定によりより複雑になっています。 +旧来のスクリプトでは "->" はメソッド呼び出しとラムダ式で混同するおそれがありま +す。また、"{" が見つかったとき、パーサーはラムダ式と辞書の開始を見分けねばなら +ず、そしてそれは引数の型指定により複雑になっています。 この問題を回避するため、Vim9 script ではラムダ式のために違う書式を使用し、それ は Javascript に似ています: > From 96b4cefee196ae2406c23f0576562f2c0b437130 Mon Sep 17 00:00:00 2001 From: Kyoichiro Yamada Date: Mon, 1 Feb 2021 10:16:25 +0900 Subject: [PATCH 11/14] =?UTF-8?q?=E5=AE=99=E3=81=AB=E6=B5=AE=E3=81=84?= =?UTF-8?q?=E3=81=A6=E6=AE=8B=E3=82=8B=20=E2=86=92=20=E6=AE=8B=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- doc/vim9.jax | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/vim9.jax b/doc/vim9.jax index 07cec6caf..075350746 100644 --- a/doc/vim9.jax +++ b/doc/vim9.jax @@ -207,7 +207,7 @@ script でのスクリプトローカル関数は、スクリプトが読み込 Vim9 script を2回目に読み込んだときは、存在するすべてのスクリプトローカルの関 数や変数は削除され、クリーンな状態から開始します。これはプラグインを開発中に、 新しいバージョンを試す際には便利です。いずれかの名前を変えたとしても、古い名前 -が宙に浮いて残る心配はありません。 +が残る心配はありません。 消さずに残すには、以下を使用します: > vim9script noclear From 1fd5ed5df4c093997ef899957de2709eb56e8b71 Mon Sep 17 00:00:00 2001 From: Kyoichiro Yamada Date: Wed, 3 Feb 2021 07:28:17 +0900 Subject: [PATCH 12/14] Apply suggestions from code review Co-authored-by: h_east --- doc/vim9.jax | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/doc/vim9.jax b/doc/vim9.jax index 075350746..ad06d9aef 100644 --- a/doc/vim9.jax +++ b/doc/vim9.jax @@ -113,12 +113,12 @@ Vi において # は行番号付きでテキストを表示します。Vim9 scr 可読性を向上するために、コマンドと #、コメント文の間にはスペースをおいてくださ い: > - var name = value # コメント - var name = value# エラー! + var name = value # コメント + var name = value# エラー! -旧来の Vim script では # は代替バッファのファイル名として使います。Vim9 script -では、代わりに %% を使う必要があります。 ## の代わりに %%% を使います。(すべ -ての引数を意味します) +旧来の Vim script では # は代替ファイル名としても使われます。Vim9 scriptでは、 +代わりに %% を使う必要があります。## の代わりに %%% を使います。(すべての引数 +を意味します) Vim9 関数 ~ @@ -136,9 +136,9 @@ Vim9 関数 ~ - コンパイルされた関数から呼び出されたり、関数リファレンスとして使用されたとき `:def` には `:function` の "range"、"abort"、"dict" や "closure" といったオプ -ションがありません。`:def` で定義する関数はエラー時は常に(ただし、`:silent!` -が指定されたコマンドか、`:try` ブロックの中は除く)処理を中断 (abort) し、範囲 -を受け取らず、辞書関数にすることはできず、常にクロージャとすることができます。 +ションがありません。`:def` で定義する関数はエラー時は常に(ただし、`:silent!`が +指定されたコマンドか、`:try` ブロックの中は除く)処理を中断し、渡される範囲を受 +け取らない "dict" 関数にすることはできず、常にクロージャとすることができます。 引数の型と戻り値の型を指定する必要があります。型には "any" を指定することがで き、型のチェックは旧来の関数と同様に実行時に行われます。 @@ -526,7 +526,7 @@ Notes: しかし、この #{} という表記は他の言語に比べて異色なものです。キーには式よりも リテラルを使うほうが一般的で、JavaScript が使っている構文を考えると、辞書リテ ラルに {} の表記を使うほうがずっと便利です: > - let dict = {key: value} + var dict = {key: value} これは英数字、アンダースコアとダッシュのキーで利用できます。異なる文字を使用す る場合は、シングルクォートまたはダブルクォートで囲まれた文字列を使用します: > @@ -551,7 +551,7 @@ Notes: オプション 'ignorecase' は文字列の比較には作用しません。 -For ループ~ +For ループ ~ 旧来の Vim script では、リストのループ内で現在または前の項目を削除するための for ループをつくるために幾つかのトリックがあります。Vim9 script では、単純にイ @@ -635,7 +635,7 @@ falsy か truthy として評価されます。これは JavaScript とほぼ同 list 空リスト以外 (JavaScript とは異なります) dictionary 空辞書以外 (JavaScript とは異なります) func when there is a function name - special true or v:true + special true または v:true job 非 NULL channel 非 NULL class 非 NULL @@ -686,7 +686,7 @@ Vim9 script では "true" を v:true として、"false" を v:false と "null" せん。これは Vim9 script ではエラーになります。 ゼロから始まる数値は8進数とはみなされません、"0o" から始まる数値だけが8進数と -みなされます: "0o744"。 |scriptversion-4| +みなされます: "0o744"。|scriptversion-4| 気をつけるべきこと ~ @@ -759,7 +759,7 @@ Vim9 関数はすべてコンパイルされます: > command -nargs=1 MyCommand echom MyCommand 123 enddef -ワークアラウンドとして、`:execute` を使用して間接的にコマンドを呼び出せます: > +回避策は、`:execute` を使用して間接的にコマンドを呼び出すことです: > def Works() command -nargs=1 MyCommand echom execute 'MyCommand 123' From d200067c9e2ad2a1cd3f0309238eabd1ffadc194 Mon Sep 17 00:00:00 2001 From: Kyoichiro Yamada Date: Thu, 4 Feb 2021 13:32:00 +0900 Subject: [PATCH 13/14] fix points from review https://github.com/vim-jp/vimdoc-ja-working/pull/880#discussion_r568001063 --- doc/vim9.jax | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/doc/vim9.jax b/doc/vim9.jax index ad06d9aef..f2284bde2 100644 --- a/doc/vim9.jax +++ b/doc/vim9.jax @@ -375,8 +375,8 @@ function() は不要に ~ は Javascript に似ています: > var Lambda = (arg) => expression -"=>" まで含めて、ラムダ式の引数の定義の中では改行することはできません。以下は -問題のない例です: > +"=>" まで含めて、ラムダ式の引数の定義の中では改行することはできません。これは +OKです: > filter(list, (k, v) => v > 0) 以下のように記述することはできません: > @@ -491,15 +491,15 @@ Note |+cmd| の引数にはコロンは不要です: > Notes: - "enddef" は継続行の先頭に置くことはできません。それは関数の終端を意味します。 - 代入式の左辺を複数の行に分割できません。特にリストのアンパック |:let-unpack| - を使用する場合は注意が必要です。以下は問題のない例です: > + を使用する場合は注意が必要です。これはOKです: > [var1, var2] = Func() < 以下のように記述することはできません: > [var1, var2] = Func() -- `:echo` や `:execute` のようなコマンドの引数は複数の行に分割できません。以下 - は問題のない例です: > +- `:echo` や `:execute` のようなコマンドの引数は複数の行に分割できません。これ + はOKです: > echo [1, 2] [3, 4] @@ -749,12 +749,12 @@ Vim9 関数はすべてコンパイルされます: > < *vim9-user-command* 関数のコンパイルによる他の副作用として、ユーザーコマンドの存在がコンパイルの時 点でチェックされます。ユーザーコマンドが後で定義されている場合、エラーとなりま -す。以下は問題のない例です: > +す。これはOKです: > command -nargs=1 MyCommand echom def Works() MyCommand 123 enddef -以下の例では "MyCommand" が定義されていないというエラーが発生します: > +これは "MyCommand" が定義されていないというエラーが発生します: > def Works() command -nargs=1 MyCommand echom MyCommand 123 From 1506b7cb69d8f012a1c7e38c796235b13f0bd35d Mon Sep 17 00:00:00 2001 From: Kyoichiro Yamada Date: Thu, 4 Feb 2021 13:33:57 +0900 Subject: [PATCH 14/14] fix a point from review https://github.com/vim-jp/vimdoc-ja-working/pull/880#discussion_r568027833 --- doc/vim9.jax | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/vim9.jax b/doc/vim9.jax index f2284bde2..19da9fb35 100644 --- a/doc/vim9.jax +++ b/doc/vim9.jax @@ -709,9 +709,9 @@ Exコマンドの範囲指定にはコロンを前置する必要があります :'t Vim9: マーク t へのジャンプ いくつかのExコマンドは Vim9 script の代入式と紛らわしくなります: > - g:name = value # 代入 - g:pattern:cmd # 不正なコマンド - エラー - :g:pattern:cmd # :グローバルコマンド + g:name = value # 代入 + g:pattern:cmd # 不正なコマンド - エラー + :g:pattern:cmd # :グローバルコマンド `:def` で定義した関数はすべてコンパイルされます。旧来の関数は途中で脱出するこ とができ、それ以降の行はパースされません: >