From fcc0a89e2dafbf6788b41a63be16af2c45c94ed4 Mon Sep 17 00:00:00 2001 From: Kyoichiro Yamada Date: Fri, 4 Dec 2020 23:43:57 +0900 Subject: [PATCH 01/43] copy vim9.txt from vim/vim --- en/vim9.txt | 1302 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1302 insertions(+) create mode 100644 en/vim9.txt diff --git a/en/vim9.txt b/en/vim9.txt new file mode 100644 index 000000000..085e4453e --- /dev/null +++ b/en/vim9.txt @@ -0,0 +1,1302 @@ +*vim9.txt* For Vim version 8.2. Last change: 2020 Nov 25 + + + VIM REFERENCE MANUAL by Bram Moolenaar + + +THIS IS STILL UNDER DEVELOPMENT - ANYTHING CAN BREAK - ANYTHING CAN CHANGE + +Vim9 script commands and expressions. *vim9* + +Most expression help is in |eval.txt|. This file is about the new syntax and +features in Vim9 script. + +THIS IS STILL UNDER DEVELOPMENT - ANYTHING CAN BREAK - ANYTHING CAN CHANGE + + +1. What is Vim9 script? |vim9-script| +2. Differences |vim9-differences| +3. New style functions |fast-functions| +4. Types |vim9-types| +5. Namespace, Import and Export |vim9script| +6. Future work: classes |vim9-classes| + +9. Rationale |vim9-rationale| + +============================================================================== + +1. What is Vim9 script? *vim9-script* + +THIS IS STILL UNDER DEVELOPMENT - ANYTHING CAN BREAK - ANYTHING CAN CHANGE + +Vim script has been growing over time, while preserving backwards +compatibility. That means bad choices from the past often can't be changed +and compatibility with Vi restricts possible solutions. Execution is quite +slow, each line is parsed every time it is executed. + +The main goal of Vim9 script is to drastically improve performance. This is +accomplished by compiling commands into instructions that can be efficiently +executed. An increase in execution speed of 10 to 100 times can be expected. + +A secondary goal is to avoid Vim-specific constructs and get closer to +commonly used programming languages, such as JavaScript, TypeScript and Java. + +The performance improvements can only be achieved by not being 100% backwards +compatible. For example, making function arguments available in the +"a:" dictionary adds quite a lot of overhead. In a Vim9 function this +dictionary is not available. Other differences are more subtle, such as how +errors are handled. + +The Vim9 script syntax and semantics are used in: +- a function defined with the `:def` command +- 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. + +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 +`:def` functions for code that needs to be fast. + +============================================================================== + +2. Differences from legacy Vim script *vim9-differences* + +THIS IS STILL UNDER DEVELOPMENT - ANYTHING CAN BREAK - ANYTHING CAN CHANGE + +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 +- Using a backslash for line continuation is hardly ever needed: > + echo "hello " + .. yourName + .. ", how are you?" +- White space is required in many places. +- Assign values without `:let`, declare variables with `:var`: > + var count = 0 + count += 3 +- Constants can be declared with `:final` and `:const`: > + 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') +- 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 + + +Comments starting with # ~ + +In legacy Vim script comments start with double quote. In Vim9 script +comments start with #. > + # declarations + var count = 0 # number of occurrences + +The reason is that a double quote can also be the start of a string. In many +places, especially halfway through an expression with a line break, it's hard +to tell what the meaning is, since both a string and a comment can be followed +by arbitrary text. To avoid confusion only # comments are recognized. This +is the same as in shell scripts and Python programs. + +In Vi # is a command to list text with numbers. In Vim9 script you can use +`:number` for that. > + 101 number + +To improve readability there must be a space between a command and the # +that starts a comment. + + +Vim9 functions ~ + +A function defined with `:def` is compiled. Execution is many times faster, +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 +- when the `:defcompile` command is encountered in the script where the + function was defined +- `:disassemble` is used for the function. +- a function that is compiled calls the function or uses it as a function + 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. + +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 +functions. + +Arguments are accessed by name, without "a:", just like any other language. +There is no "a:" dictionary or "a:000" list. + +Variable arguments are defined as the last argument, with a name and have a +list type, similar to TypeScript. For example, a list of numbers: > + def MyFunc(...itemlist: list) + for item in itemlist + ... + + +Functions and variables are script-local by default ~ + *vim9-scopes* +When using `:function` or `:def` to specify a new function at the script level +in a Vim9 script, the function is local to the script, as if "s:" was +prefixed. Using the "s:" prefix is optional. To define a global function or +variable the "g:" prefix must be used. For functions in an autoload script +the "name#" prefix is sufficient. > + def ThisFunction() # script-local + def s:ThisFunction() # script-local + def g:ThatFunction() # global + def scriptname#function() # autoload + +When using `:function` or `:def` to specify a nested function inside a `:def` +function, this nested function is local to the code block it is defined in. +In a `:def` function it is not possible to define a script-local function. It +is possible to define a global function by using the "g:" prefix. + +When referring to a function and no "s:" or "g:" prefix is used, Vim will +search for the function: +- in the function scope, in block scopes +- in the script scope, possibly imported +- in the list of global functions +However, it is recommended to always use "g:" to refer to a global function +for clarity. + +In all cases the function must be defined before used. That is when it is +called, when `:defcompile` causes it to be compiled, or when code that calls +it is being compiled (to figure out the return type). + +The result is that functions and variables without a namespace can usually be +found in the script, either defined there or imported. Global functions and +variables could be defined anywhere (good luck finding out where!). + +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. + + +Variable declarations with :var, :final and :const ~ + *vim9-declaration* *:var* +Local variables need to be declared with `:var`. Local constants need to be +declared with `:final` or `:const`. We refer to both as "variables" in this +section. + +Variables can be local to a script, function or code block: > + vim9script + var script_var = 123 + def SomeFunc() + var func_var = script_var + if cond + var block_var = func_var + ... + +The variables are only visible in the block where they are defined and nested +blocks. Once the block ends the variable is no longer accessible: > + if cond + var inner = 5 + else + var inner = 0 + endif + echo inner # Error! + +The declaration must be done earlier: > + var inner: number + if cond + inner = 5 + else + inner = 0 + endif + echo inner + +To intentionally hide a variable from code that follows, a block can be +used: > + { + var temp = 'temp' + ... + } + echo temp # Error! + +Declaring a variable with a type but without an initializer will initialize to +zero, false or empty. + +In Vim9 script `:let` cannot be used. An existing variable is assigned to +without any command. The same for global, window, tab, buffer and Vim +variables, because they are not really declared. They can also be deleted +with `:unlet`. + +Variables and functions cannot shadow previously defined or imported variables +and functions. +Variables may shadow Ex commands, rename the variable if needed. + +Global variables and user defined functions must be prefixed with "g:", also +at the script level. > + vim9script + var script_local = 'text' + g:global = 'value' + var Funcref = g:ThatFunction + +Since `&opt = value` is now assigning a value to option "opt", ":&" cannot be +used to repeat a `:substitute` command. + + +Constants ~ + *vim9-const* *vim9-final* +How constants work varies between languages. Some consider a variable that +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. + +`: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: > + const myList = [1, 2] + myList = [3, 4] # Error! + myList[0] = 9 # Error! + muList->add(3) # Error! +< *:final* +`:final` is used for making only the variable a constant, the value can be +changed. This is well known from Java. Example: > + final myList = [1, 2] + myList = [3, 4] # Error! + myList[0] = 9 # OK + muList->add(3) # OK + +It is common to write constants as ALL_CAPS, but you don't have to. + +The constant only applies to the value itself, not what it refers to. > + final females = ["Mary"] + const NAMES = [["John", "Peter"], females] + NAMES[0] = ["Jack"] # Error! + NAMES[0][0] = "Jack" # Error! + NAMES[1] = ["Emma"] # Error! + Names[1][0] = "Emma" # OK, now females[0] == "Emma" + +< *E1092* +Declaring more than one variable at a time, using the unpack notation, is +currently not supported: > + var [v1, v2] = GetValues() # Error! +That is because the type needs to be inferred from the list item type, which +isn't that easy. + + +Omitting :call and :eval ~ + +Functions can be called without `:call`: > + writefile(lines, 'file') +Using `:call` is still possible, but this is discouraged. + +A method call without `eval` is possible, so long as the start is an +identifier or can't be an Ex command. Examples: > + myList->add(123) + g:myList->add(123) + [1, 2, 3]->Process() + {a: 1, b: 2}->Process() + "foobar"->Process() + ("foobar")->Process() + 'foobar'->Process() + ('foobar')->Process() + +In the rare case there is ambiguity between a function name and an Ex command, +prepend ":" to make clear you want to use the Ex command. For example, there +is both the `:substitute` command and the `substitute()` function. When the +line starts with `substitute(` this will use the function. Prepend a colon to +use the command instead: > + :substitute(pattern (replacement ( + +Note that while variables need to be defined before they can be used, +functions can be called before being defined. This is required to allow +for cyclic dependencies between functions. It is slightly less efficient, +since the function has to be looked up by name. And a typo in the function +name will only be found when the function is called. + + +Omitting function() ~ + +A user defined function can be used as a function reference in an expression +without `function()`. The argument types and return type will then be checked. +The function must already have been defined. > + + var Funcref = MyFunction + +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. + + +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: > + var mylist = [ + 'one', + 'two', + ] +And when a dict spans multiple lines: > + var mydict = { + one: 1, + two: 2, + } +Function call: > + var result = Func( + arg1, + arg2 + ) + +For binary operators in expressions not in [], {} or () a line break is +possible just before or after the operator. For example: > + var text = lead + .. middle + .. end + var total = start + + end - + correction + var result = positive + ? PosFunc(arg) + : NegFunc(arg) + +For a method call using "->" and a member using a dot, a line break is allowed +before it: > + var result = GetBuilder() + ->BuilderSetWidth(333) + ->BuilderSetHeight(777) + ->BuilderBuild() + var result = MyDict + .member + +< *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 +"start" and print: > + var result = start + + print +Like this: > + var result = start + print + +This will assign "start" and print a line: > + var result = start + :+ print + +Note that the colon is not required for the |+cmd| argument: > + edit +6 fname + +It is also possible to split a function header over multiple lines, in between +arguments: > + def MyFunc( + text: string, + separator = '-' + ): string + +Notes: +- "enddef" cannot be used at the start of a continuation line, it ends the + current function. +- No line break is allowed in the LHS of an assignment. Specifically when + unpacking a list |:let-unpack|. This is OK: > + [var1, var2] = + Func() +< This does not work: > + [var1, + var2] = + Func() +- No line break is allowed in between arguments of an `:echo`, `:execute` and + similar commands. This is OK: > + echo [1, + 2] [3, + 4] +< 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 ~ + +|curly-braces-names| cannot be used. + + +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: > + 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 +considering that JavaScript uses this syntax, using the {} form for dictionary +literals was considered a much more useful syntax. In Vim9 script the {} form +uses literal keys: > + let dict = {key: value} + +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} + + +No :xit, :t, :append, :change or :insert ~ + +These commands are too easily confused with local variable names. +Instead of `:x` or `:xit` you can use `:exit`. +Instead of `:t` you can use `:copy`. + + +Comparators ~ + +The 'ignorecase' option is not used for comparators that use strings. + + +White space ~ + +Vim9 script enforces proper use of white space. This is no longer allowed: > + var name=234 # Error! + var name= 234 # Error! + var name =234 # Error! +There must be white space before and after the "=": > + var name = 234 # OK +White space must also be put before the # that starts a comment after a +command: > + var name = 234# Error! + var name = 234 # OK + +White space is required around most operators. + +White space is not allowed: +- Between a function name and the "(": > + call Func (arg) # Error! + call Func + \ (arg) # Error! + call Func(arg) # OK + call Func( + \ arg) # OK + call Func( + \ arg # OK + \ ) + + +Conditions and expressions ~ + +Conditions and expressions are mostly working like they do in other languages. +Some values are different from legacy Vim script: + value legacy Vim script Vim9 script ~ + 0 falsy falsy + 1 truthy truthy + 99 truthy Error! + "0" falsy Error! + "99" truthy Error! + "text" falsy Error! + +For the "??" operator and when using "!" then there is no error, every value +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 + number non-zero + float non-zero + string non-empty + blob non-empty + list non-empty (different from JavaScript) + dictionary non-empty (different from JavaScript) + func when there is a function name + special v:true + job when not NULL + channel when not NULL + class when not NULL + object when not NULL (TODO: when isTrue() returns v:true) + +The boolean operators "||" and "&&" expect the values to be boolean, zero or +one: > + 1 || false == true + 0 || 1 == true + 0 || false == false + 1 && true == true + 0 && 1 == false + 8 || 0 Error! + 'yes' && 0 Error! + [] || 99 Error! + +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 + !![] == false + !![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' + +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. + +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 'á'. + + +What to watch out for ~ + *vim9-gotchas* +Vim9 was designed to be closer to often used programming languages, but at the +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 + + %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 + +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 + +Functions defined with `:def` compile the whole function. Legacy functions +can bail out, and the following lines are not parsed: > + func Maybe() + if !has('feature') + return + endif + use-feature + endfunc +Vim9 functions are compiled as a whole: > + def Maybe() + if !has('feature') + return + endif + use-feature # May give compilation error + enddef +For a workaround, split it in two functions: > + func Maybe() + if has('feature') + call MaybyInner() + endif + endfunc + if has('feature') + def MaybeInner() + use-feature + enddef + endif +Or put the unsupported code inside an `if` with a constant expression that +evaluates to false: > + def Maybe() + if has('feature') + use-feature + endif + 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 + +============================================================================== + +3. New style functions *fast-functions* + +THIS IS STILL UNDER DEVELOPMENT - ANYTHING CAN BREAK - ANYTHING CAN CHANGE + + *:def* +:def[!] {name}([arguments])[: {return-type}] + Define a new function by the name {name}. The body of + the function follows in the next lines, until the + matching `:enddef`. + + When {return-type} is omitted or is "void" the + function is not expected to return anything. + + {arguments} is a sequence of zero or more argument + declarations. There are three forms: + {name}: {type} + {name} = {value} + {name}: {type} = {value} + The first form is a mandatory argument, the caller + must always provide them. + The second and third form are optional arguments. + When the caller omits an argument the {value} is used. + + The function will be compiled into instructions when + called, or when `:disassemble` or `:defcompile` is + used. Syntax and type errors will be produced at that + time. + + It is possible to nest `:def` inside another `:def` or + `:function` up to about 50 levels deep. + + [!] is used as with `:function`. Note that + script-local functions cannot be deleted or redefined + later in Vim9 script. They can only be removed by + reloading the same script. + + *:enddef* +:enddef End of a function defined with `:def`. It should be on + a line by its own. + + +If the script the function is defined in is Vim9 script, then script-local +variables can be accessed without the "s:" prefix. They must be defined +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 and they do not need to exist (they can be deleted any time). + + *:defc* *:defcompile* +:defc[ompile] Compile functions defined in the current script that + were not compiled yet. + This will report errors found during the compilation. + + *:disa* *:disassemble* +:disa[ssemble] {func} Show the instructions generated for {func}. + This is for debugging and testing. + Note that for command line completion of {func} you + can prepend "s:" to find script-local functions. + +Limitations ~ + +Local variables will not be visible to string evaluation. For example: > + def EvalString(): 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 + var list = ['aa', 'bb', 'cc', 'dd'] + return range(1, 2)->map({ _, v -> list[v] }) + enddef + + +============================================================================== + +4. Types *vim9-types* + +THIS IS STILL UNDER DEVELOPMENT - ANYTHING CAN BREAK - ANYTHING CAN CHANGE + +The following builtin types are supported: + bool + number + float + string + blob + list<{type}> + dict<{type}> + job + channel + func + func: {type} + func({type}, ...) + func({type}, ...): {type} + +Not supported yet: + tuple + +These types can be used in declarations, but no value will have this type: + {type}|{type} {not implemented yet} + void + any + +There is no array type, use list<{type}> instead. For a list constant an +efficient implementation is used that avoids allocating lot of small pieces of +memory. + +A partial and function can be declared in more or less specific ways: +func any kind of function reference, no type + checking for arguments or return value +func: {type} any number and type of arguments with specific + return type +func({type}) function with argument type, does not return + a value +func({type}): {type} function with argument type and return type +func(?{type}) function with type of optional argument, does + not return a value +func(...{type}) function with type of variable number of + arguments, does not return a value +func({type}, ?{type}, ...{type}): {type} + function with: + - type of mandatory argument + - type of optional argument + - type of variable number of arguments + - return type + +If the return type is "void" the function does not return a value. + +The reference can also be a |Partial|, in which case it stores extra arguments +and/or a dictionary, which are not visible to the caller. Since they are +called in the same way the declaration is the same. + +Custom types can be defined with `:type`: > + :type MyList list +Custom types must start with a capital letter, to avoid name clashes with +builtin types added later, similarly to user functions. +{not implemented yet} + +And classes and interfaces can be used as types: > + :class MyClass + :var mine: MyClass + + :interface MyInterface + :var mine: MyInterface + + :class MyTemplate + :var mine: MyTemplate + :var mine: MyTemplate + + :class MyInterface + :var mine: MyInterface + :var mine: MyInterface +{not implemented yet} + + +Variable types and type casting ~ + *variable-types* +Variables declared in Vim9 script or in a `:def` function have a type, either +specified explicitly or inferred from the initialization. + +Global, buffer, window and tab page variables do not have a specific type, the +value can be changed at any time, possibly changing the type. Therefore, in +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: > + 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 syntax of a type cast is: "<" {type} ">". There cannot be white space +after the "<" or before the ">" (to avoid them being confused with +smaller-than and bigger-than operators). + +The semantics is that, if needed, a runtime type check is performed. The +value is not actually changed. If you need to change the type, e.g. to change +it to a string, use the |string()| function. Or use |str2nr()| to convert a +string to a number. + + +Type inference ~ + *type-inference* +In general: Whenever the type is clear it can be omitted. For example, when +declaring a variable and giving it a value: > + var name = 0 # infers number type + var name = 'hello' # infers string type + +The type of a list and dictionary comes from the common type of the values. +If the values all have the same type, that type is used for the list or +dictionary. If there is a mix of types, the "any" type is used. > + [1, 2, 3] list + ['a', 'b', 'c'] list + [1, 'x', 3] list + + +Stricter type checking ~ + *type-checking* +In legacy Vim script, where a number was expected, a string would be +automatically converted to a number. This was convenient for an actual number +such as "123", but leads to unexpected problems (but no error message) if the +string doesn't start with a number. Quite often this leads to hard-to-find +bugs. + +In Vim9 script this has been made stricter. In most places it works just as +before, if the value used matches the expected type. There will sometimes be +an error, thus breaking backwards compatibility. For example: +- Using a number other than 0 or 1 where a boolean is expected. *E1023* +- Using a string value when setting a number options. +- Using a number where a string is expected. *E1024* + +============================================================================== + +5. Namespace, Import and Export + *vim9script* *vim9-export* *vim9-import* + +THIS IS STILL UNDER DEVELOPMENT - ANYTHING CAN BREAK - ANYTHING CAN CHANGE + +A Vim9 script can be written to be imported. This means that everything in +the script is local, unless exported. Those exported items, and only those +items, can then be imported in another script. + +You can cheat by using the global namespace explicitly. We will assume here +that you don't do that. + + +Namespace ~ + *:vim9script* *:vim9* +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 +starts with: > + vim9script + var myvar = 'yes' +Then "myvar" will only exist in this file. While without `vim9script` it would +be available as `g:myvar` from any other script and function. + +The variables at the file level are very much like the script-local "s:" +variables in legacy Vim script, but the "s:" is omitted. And they cannot be +deleted. + +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: > + :set cpo&vim +One of the effects is that |line-continuation| is always enabled. +The original value of 'cpoptions' is restored at the end of the script. + + +Export ~ + *:export* *:exp* +Exporting an item can be written as: > + export const EXPORTED_CONST = 1234 + export var someValue = ... + export final someValue = ... + export const someValue = ... + export def MyFunc() ... + export class MyClass ... + +As this suggests, only constants, variables, `:def` functions and classes can +be exported. {classes are not implemented yet} + + *E1042* +`:export` can only be used in Vim9 script, at the script level. + + +Import ~ + *:import* *:imp* *E1094* +The exported items can be imported individually in another Vim9 script: > + import EXPORTED_CONST from "thatscript.vim" + import MyClass from "myclass.vim" + +To import multiple items at the same time: > + import {someValue, MyClass} from "thatscript.vim" + +In case the name is ambiguous, another name can be specified: > + import MyClass as ThatClass from "myclass.vim" + import {someValue, MyClass as ThatClass} from "myclass.vim" + +To import all exported items under a specific identifier: > + import * as That from 'thatscript.vim' + +{not implemented yet: using "This as That"} + +Then you can use "That.EXPORTED_CONST", "That.someValue", etc. You are free +to choose the name "That", but it is highly recommended to use the name of the +script file to avoid confusion. + +`:import` can also be used in legacy Vim script. The imported items still +become script-local, even when the "s:" prefix is not given. + +The script name after `import` can be: +- A relative path, starting "." or "..". This finds a file relative to the + location of the script file itself. This is useful to split up a large + plugin into several files. +- An absolute path, starting with "/" on Unix or "D:/" on MS-Windows. This + will rarely be used. +- A path not being relative or absolute. This will be found in the + "import" subdirectories of 'runtimepath' entries. The name will usually be + longer and unique, to avoid loading the wrong file. + +Once a vim9 script file has been imported, the result is cached and used the +next time the same script is imported. It will not be read again. + *:import-cycle* +The `import` commands are executed when encountered. If that script (directly +or indirectly) imports the current script, then items defined after the +`import` won't be processed yet. Therefore cyclic imports can exist, but may +result in undefined items. + + +Import in an autoload script ~ + +For optimal startup speed, loading scripts should be postponed until they are +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() + +< 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" + def searchfor#Stuff(arg: string) + var filtered = FilterFunc(arg) + ... +< This goes in .../autoload/searchfor.vim. "searchfor" in the file name + must be exactly the same as the prefix for the function name, that is how + Vim finds the file. + +3. Other functionality, possibly shared between plugins, contains the exported + items and any private items. > + vim9script + var localVar = 'local' + export def FilterFunc(arg: string): string + ... +< This goes in .../import/someother.vim. + +When compiling a `:def` function and a function in an autoload script is +encountered, the script is not loaded until the `:def` function is called. + + +Import in legacy Vim script ~ + +If an `import` statement is used in legacy Vim script, the script-local "s:" +namespace will be used for the imported item, even when "s:" is not specified. + + +============================================================================== + +6. Future work: classes *vim9-classes* + +Above "class" was mentioned a few times, but it has not been implemented yet. +Most of Vim9 script can be created without this functionality, and since +implementing classes is going to be a lot of work, it is left for the future. +For now we'll just make sure classes can be added later. + +Thoughts: +- `class` / `endclass`, everything in one file +- Class names are always CamelCase +- Single constructor +- Single inheritance with `class ThisClass extends BaseClass` +- `abstract class` +- `interface` (Abstract class without any implementation) +- `class SomeClass implements SomeInterface` +- Generics for class: `class ` +- Generics for function: `def GetLast(key: Tkey)` + +Again, much of this is from TypeScript. + +Some things that look like good additions: +- Use a class as an interface (like Dart) +- Extend a class with methods, using an import (like Dart) + +An important class that will be provided is "Promise". Since Vim is single +threaded, connecting asynchronous operations is a natural way of allowing +plugins to do their work without blocking the user. It's a uniform way to +invoke callbacks and handle timeouts and errors. + +============================================================================== + +9. Rationale *vim9-rationale* + +The :def command ~ + +Plugin writers have asked for much faster Vim script. Investigations have +shown that keeping the existing semantics of function calls make this close to +impossible, because of the overhead involved with calling a function, setting +up the local function scope and executing lines. There are many details that +need to be handled, such as error messages and exceptions. The need to create +a dictionary for a: and l: scopes, the a:000 list and several others add too +much overhead that cannot be avoided. + +Therefore the `:def` method to define a new-style function had to be added, +which allows for a function with different semantics. Most things still work +as before, but some parts do not. A new way to define a function was +considered the best way to separate the legacy style code from Vim9 style code. + +Using "def" to define a function comes from Python. Other languages use +"function" which clashes with legacy Vim script. + + +Type checking ~ + +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. + +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 +Vim before, with some additions such as "void" and "bool". + + +Removing clutter and weirdness ~ + +Once decided that `:def` functions have different syntax than legacy functions, +we are free to add improvements to make the code more familiar for users who +know popular programming languages. In other words: remove weird things that +only Vim does. + +We can also remove clutter, mainly things that were done to make Vim script +backwards compatible with the good old Vi commands. + +Examples: +- Drop `:call` for calling a function and `:eval` for manipulating data. +- Drop using a leading backslash for line continuation, automatically figure + out where an expression ends. + +However, this does require that some things need to change: +- Comments start with # instead of ", to avoid confusing them with strings. + This is good anyway, it is known from several popular languages. +- Ex command ranges need to be prefixed with a colon, to avoid confusion with + expressions (single quote can be a string or a mark, "/" can be divide or a + search command, etc.). + +Goal is to limit the differences. A good criteria is that when the old syntax +is accidentally used you are very likely to get an error message. + + +Syntax and semantics from popular languages ~ + +Script writers have complained that the Vim script syntax is unexpectedly +different from what they are used to. To reduce this complaint popular +languages are used as an example. At the same time, we do not want to abandon +the well-known parts of legacy Vim script. + +For many things TypeScript is followed. It's a recent language that is +gaining popularity and has similarities with Vim script. It also has a +mix of static typing (a variable always has a known value type) and dynamic +typing (a variable can have different types, this changes at runtime). Since +legacy Vim script is dynamically typed and a lot of existing functionality +(esp. builtin functions) depends on that, while static typing allows for much +faster execution, we need to have this mix in Vim9 script. + +There is no intention to completely match TypeScript syntax and semantics. We +just want to take those parts that we can use for Vim and we expect Vim users +will be happy with. TypeScript is a complex language with its own history, +advantages and disadvantages. To get an idea of the disadvantages read the +book: "JavaScript: The Good Parts". Or find the article "TypeScript: the good +parts" and read the "Things to avoid" section. + +People familiar with other languages (Java, Python, etc.) will also find +things in TypeScript that they do not like or do not understand. We'll try to +avoid those things. + +Specific items from TypeScript we avoid: +- Overloading "+", using it both for addition and string concatenation. This + goes against legacy Vim script and often leads to mistakes. For that reason + we will keep using ".." for string concatenation. Lua also uses ".." this + way. And it allows for conversion to string for more values. +- TypeScript can use an expression like "99 || 'yes'" in a condition, but + cannot assign the value to a boolean. That is inconsistent and can be + annoying. Vim recognizes an expression with && or || and allows using the + result as a bool. TODO: to be reconsidered +- TypeScript considers an empty string as Falsy, but an empty list or dict as + Truthy. That is inconsistent. In Vim an empty list and dict are also + Falsy. +- TypeScript has various "Readonly" types, which have limited usefulness, + since a type cast can remove the immutable nature. Vim locks the value, + which is more flexible, but is only checked at runtime. + + +Declarations ~ + +Legacy Vim script uses `:let` for every assignment, while in Vim9 declarations +are used. That is different, thus it's good to use a different command: +`:var`. This is used in many languages. The semantics might be slightly +different, but it's easily recognized as a declaration. + +Using `:const` for constants is common, but the semantics varies. Some +languages only make the variable immutable, others also make the value +immutable. Since "final" is well known from Java for only making the variable +immutable we decided to use that. And then `:const` can be used for making +both immutable. This was also used in legacy Vim script and the meaning is +almost the same. + +What we end up with is very similar to Dart: > + :var name # mutable variable and value + :final name # immutable variable, mutable value + :const name # immutable variable and value + +Since legacy and Vim9 script will be mixed and global variables will be +shared, optional type checking is desirable. Also, type inference will avoid +the need for specifying the type in many cases. The TypeScript syntax fits +best for adding types to declarations: > + var name: string # string type is specified + ... + name = 'John' + const greeting = 'hello' # string type is inferred + +This is how we put types in a declaration: > + var mylist: list + final mylist: list = ['foo'] + def Func(arg1: number, arg2: string): bool + +Two alternatives were considered: +1. Put the type before the name, like Dart: > + var list mylist + final list mylist = ['foo'] + def Func(number arg1, string arg2) bool +2. Put the type after the variable name, but do not use a colon, like Go: > + var mylist list + final mylist list = ['foo'] + def Func(arg1 number, arg2 string) bool + +The first is more familiar for anyone used to C or Java. The second one +doesn't really have an advantage over the first, so let's discard the second. + +Since we use type inference the type can be left out when it can be inferred +from the value. This means that after `var` we don't know if a type or a name +follows. That makes parsing harder, not only for Vim but also for humans. +Also, it will not be allowed to use a variable name that could be a type name, +using `var string string` is too confusing. + +The chosen syntax, using a colon to separate the name from the type, adds +punctuation, but it actually makes it easier to recognize the parts of a +declaration. + + +Expressions ~ + +Expression evaluation was already close to what other languages are doing. +Some details are unexpected and can be improved. For example a boolean +condition would accept a string, convert it to a number and check if the +number is non-zero. This is unexpected and often leads to mistakes, since +text not starting with a number would be converted to zero, which is +considered false. Thus using a string for a condition would often not give an +error and be considered false. That is confusing. + +In Vim9 type checking is stricter to avoid mistakes. Where a condition is +used, e.g. with the `:if` command and the `||` operator, only boolean-like +values are accepted: + true: `true`, `v:true`, `1`, `0 < 9` + false: `false`, `v:false`, `0`, `0 > 9` +Note that the number zero is false and the number one is true. This is more +permissive than most other languages. It was done because many builtin +functions return these values. + +If you have any type of value and want to use it as a boolean, use the `!!` +operator: + true: !`!'text'`, `!![99]`, `!!{'x': 1}`, `!!99` + false: `!!''`, `!![]`, `!!{}` + +From a language like JavaScript we have this handy construct: > + GetName() || 'unknown' +However, this conflicts with only allowing a boolean for a condition. +Therefore the "??" operator was added: > + GetName() ?? 'unknown' +Here you can explicitly express your intention to use the value as-is and not +result in a boolean. This is called the |falsy-operator|. + + +Import and Export ~ + +A problem of legacy Vim script is that by default all functions and variables +are global. It is possible to make them script-local, but then they are not +available in other scripts. This defies the concept of a package that only +exports selected items and keeps the rest local. + +In Vim9 script a mechanism very similar to the JavaScript import and export +mechanism is supported. It is a variant to the existing `:source` command +that works like one would expect: +- Instead of making everything global by default, everything is script-local, + unless exported. +- When importing a script the symbols that are imported are explicitly listed, + avoiding name conflicts and failures if functionality is added later. +- The mechanism allows for writing a big, long script with a very clear API: + the exported function(s) and class(es). +- By using relative paths loading can be much faster for an import inside of a + package, no need to search many directories. +- Once an import has been used, it can be cached and loading it again can be + avoided. +- The Vim-specific use of "s:" to make things script-local can be dropped. + +When sourcing a Vim9 script from a legacy script, only the items defined +globally can be used, not the exported items. Alternatives considered: +- All the exported items become available as script-local items. This makes + it uncontrollable what items get defined and likely soon leads to trouble. +- Use the exported items and make them global. Disadvantage is that it's then + not possible to avoid name clashes in the global namespace. +- Completely disallow sourcing a Vim9 script, require using `:import`. That + makes it difficult to use scripts for testing, or sourcing them from the + command line to try them out. +Note that you can also use `:import` in legacy Vim script, see above. + + +Compiling functions early ~ + +Functions are compiled when called or when `:defcompile` is used. Why not +compile them early, so that syntax and type errors are reported early? + +The functions can't be compiled right away when encountered, because there may +be forward references to functions defined later. Consider defining functions +A, B and C, where A calls B, B calls C, and C calls A again. It's impossible +to reorder the functions to avoid forward references. + +An alternative would be to first scan through the file to locate items and +figure out their type, so that forward references are found, and only then +execute the script and compile the functions. This means the script has to be +parsed twice, which is slower, and some conditions at the script level, such +as checking if a feature is supported, are hard to use. An attempt was made +to see if it works, but it turned out to be impossible to make work nicely. + +It would be possible to compile all the functions at the end of the script. +The drawback is that if a function never gets called, the overhead of +compiling it counts anyway. Since startup speed is very important, in most +cases it's better to do it later and accept that syntax and type errors are +only reported then. In case these errors should be found early, e.g. when +testing, the `:defcompile` command will help out. + + +Why not use an embedded language? ~ + +Vim supports interfaces to Perl, Python, Lua, Tcl and a few others. But +these interfaces have never become widely used, for various reasons. When +Vim9 was designed a decision was made to make these interfaces lower priority +and concentrate on Vim script. + +Still, plugin writers may find other languages more familiar, want to use +existing libraries or see a performance benefit. We encourage plugin authors +to write code in any language and run it as an external tool, using jobs and +channels. We can try to make this easier somehow. + +Using an external tool also has disadvantages. An alternative is to convert +the tool into Vim script. For that to be possible without too much +translation, and keeping the code fast at the same time, the constructs of the +tool need to be supported. Since most languages support classes the lack of +support for classes in Vim is then a problem. + + +Classes ~ + +Vim supports a kind-of object oriented programming by adding methods to a +dictionary. With some care this can be made to work, but it does not look +like real classes. On top of that, it's quite slow, because of the use of +dictionaries. + +The support of classes in Vim9 script is a "minimal common functionality" of +class support in most languages. It works much like Java, which is the most +popular programming language. + + + + vim:tw=78:ts=8:noet:ft=help:norl: From 6e991c30f61af09c11abef3fda4b47877f30ea03 Mon Sep 17 00:00:00 2001 From: Kyoichiro Yamada Date: Sat, 5 Dec 2020 00:39:33 +0900 Subject: [PATCH 02/43] =?UTF-8?q?wip:=20=E5=B0=8E=E5=85=A5=E9=83=A8?= =?UTF-8?q?=E5=88=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- doc/vim9.jax | 1308 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1308 insertions(+) create mode 100644 doc/vim9.jax diff --git a/doc/vim9.jax b/doc/vim9.jax new file mode 100644 index 000000000..2bdf9d4a5 --- /dev/null +++ b/doc/vim9.jax @@ -0,0 +1,1308 @@ +*vim9.txt* For Vim version 8.2. Last change: 2020 Nov 03 + + + VIMリファレンスマニュアル by Bram Moolenaar + + + +注意: この内容は開発中の内容を含んでいます。予告なく破壊的変更が行われるおそれ +があります。 + +Vim9 スクリプトのコマンドと文法 *vim9* + +ほとんどの文法については |eval.txt| で解説されています。このファイルには Vim9 +スクリプトの新しい文法と機能について書かれています。 + +注意: この内容は開発中の内容を含んでいます。予告なく破壊的変更が行われるおそれ +があります。 + + +1. Vim9 スクリプトとは |vim9-script| +2. 古い Vim スクリプトからの変更点 |vim9-differences| +3. 新しい関数 |fast-functions| +4. 型 |vim9-types| +5. 名前空間と Import / Export |vim9script| +6. 将来的な変更: クラス |vim9-classes| + +9. 言語設計の背景 |vim9-rationale| + +============================================================================== + +1. Vim9 スクリプトとは *vim9-script* + +注意: この内容は開発中の内容を含んでいます。予告なく破壊的変更が行われるおそれ +があります。 + + +Vim スクリプトは、互換性の維持に気を配りながら成長してきました。そのため、古い +悪しき仕様を変更できないことが多いほか、 Vi との互換性に制約を受けて、より良い +解決策を採用できなくなっています。処理は遅く、実行するたびに各行のパースが行わ +れています。 + +Vim9 スクリプトの主な目的は劇的な性能の向上です。これは、コマンドをより効率よ +く実行できる命令にコンパイルすることで実現しています。これにより、10倍から100 +倍の実行速度の向上が期待できます。 + +第2の目的は、Vim スクリプト特有の文法を見直し、より一般的に使われる JavaScript +や TypeScript、 Java のようなプログラミング言語に近づけることです。 + +パフォーマンスの向上は、下位互換性を犠牲にせずには達成できません。たとえば、関 +数の引数を辞書 "a:" から利用できるようにするためには、かなりのオーバーヘッドが +必要になります。そのため、Vim9 スクリプトでは、この辞書が利用できなくなりまし +た。その他の違いは、エラーの処理方法など、より微細なものです。 + +Vim9 スクリプトは以下の場所で使用することができます。 +- コマンド `:def` で定義された関数の中 +- コマンド `vim9script` で始まるスクリプトファイルの中 +- 上記のコンテキストで定義された autocommand + +Vim9 スクリプトファイルの中でコマンド `:function` で関数を定義すると、その中で +は古い Vim スクリプトの記法が有効になります。 +しかし、これは混乱を招く可能性があるため、推奨できません。 + +Vim9 スクリプトと 古い Vim スクリプトは同時に利用できます。古いスクリプトを書 +き換えなくとも、以前と同様に実行することが可能です。高速化が必要なコードには、 +`:def` 関数を使ったほうが良いかもしれません。 + +============================================================================== + +2. 古い Vim スクリプトからの変更点 *vim9-differences* + +注意: この内容は開発中の内容を含んでいます。予告なく破壊的変更が行われるおそれ +があります。 + +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 +- Using a backslash for line continuation is hardly ever needed: > + echo "hello " + .. yourName + .. ", how are you?" +- White space is required in many places. +- Assign values without `:let`, declare variables with `:var`: > + var count = 0 + count += 3 +- Constants can be declared with `:final` and `:const`: > + 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') +- 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 + + +Comments starting with # ~ + +In legacy Vim script comments start with double quote. In Vim9 script +comments start with #. > + # declarations + var count = 0 # number of occurrences + +The reason is that a double quote can also be the start of a string. In many +places, especially halfway through an expression with a line break, it's hard +to tell what the meaning is, since both a string and a comment can be followed +by arbitrary text. To avoid confusion only # comments are recognized. This +is the same as in shell scripts and Python programs. + +In Vi # is a command to list text with numbers. In Vim9 script you can use +`:number` for that. > + 101 number + +To improve readability there must be a space between a command and the # +that starts a comment. + + +Vim9 functions ~ + +A function defined with `:def` is compiled. Execution is many times faster, +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 +- when the `:defcompile` command is encountered in the script where the + function was defined +- `:disassemble` is used for the function. +- a function that is compiled calls the function or uses it as a function + 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. + +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 +functions. + +Arguments are accessed by name, without "a:", just like any other language. +There is no "a:" dictionary or "a:000" list. + +Variable arguments are defined as the last argument, with a name and have a +list type, similar to TypeScript. For example, a list of numbers: > + def MyFunc(...itemlist: list) + for item in itemlist + ... + + +Functions and variables are script-local by default ~ + *vim9-scopes* +When using `:function` or `:def` to specify a new function at the script level +in a Vim9 script, the function is local to the script, as if "s:" was +prefixed. Using the "s:" prefix is optional. To define a global function or +variable the "g:" prefix must be used. For functions in an autoload script +the "name#" prefix is sufficient. > + def ThisFunction() # script-local + def s:ThisFunction() # script-local + def g:ThatFunction() # global + def scriptname#function() # autoload + +When using `:function` or `:def` to specify a nested function inside a `:def` +function, this nested function is local to the code block it is defined in. +In a `:def` function it is not possible to define a script-local function. It +is possible to define a global function by using the "g:" prefix. + +When referring to a function and no "s:" or "g:" prefix is used, Vim will +search for the function: +- in the function scope, in block scopes +- in the script scope, possibly imported +- in the list of global functions +However, it is recommended to always use "g:" to refer to a global function +for clarity. + +In all cases the function must be defined before used. That is when it is +called, when `:defcompile` causes it to be compiled, or when code that calls +it is being compiled (to figure out the return type). + +The result is that functions and variables without a namespace can usually be +found in the script, either defined there or imported. Global functions and +variables could be defined anywhere (good luck finding out where!). + +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. + + +Variable declarations with :var, :final and :const ~ + *vim9-declaration* *:var* +Local variables need to be declared with `:var`. Local constants need to be +declared with `:final` or `:const`. We refer to both as "variables" in this +section. + +Variables can be local to a script, function or code block: > + vim9script + var script_var = 123 + def SomeFunc() + var func_var = script_var + if cond + var block_var = func_var + ... + +The variables are only visible in the block where they are defined and nested +blocks. Once the block ends the variable is no longer accessible: > + if cond + var inner = 5 + else + var inner = 0 + endif + echo inner # Error! + +The declaration must be done earlier: > + var inner: number + if cond + inner = 5 + else + inner = 0 + endif + echo inner + +To intentionally hide a variable from code that follows, a block can be +used: > + { + var temp = 'temp' + ... + } + echo temp # Error! + +Declaring a variable with a type but without an initializer will initialize to +zero, false or empty. + +In Vim9 script `:let` cannot be used. An existing variable is assigned to +without any command. The same for global, window, tab, buffer and Vim +variables, because they are not really declared. They can also be deleted +with `:unlet`. + +Variables and functions cannot shadow previously defined or imported variables +and functions. +Variables may shadow Ex commands, rename the variable if needed. + +Global variables and user defined functions must be prefixed with "g:", also +at the script level. > + vim9script + var script_local = 'text' + g:global = 'value' + var Funcref = g:ThatFunction + +Since `&opt = value` is now assigning a value to option "opt", ":&" cannot be +used to repeat a `:substitute` command. + + +Constants ~ + *vim9-const* *vim9-final* +How constants work varies between languages. Some consider a variable that +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. + +`: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: > + const myList = [1, 2] + myList = [3, 4] # Error! + myList[0] = 9 # Error! + muList->add(3) # Error! +< *:final* +`:final` is used for making only the variable a constant, the value can be +changed. This is well known from Java. Example: > + final myList = [1, 2] + myList = [3, 4] # Error! + myList[0] = 9 # OK + muList->add(3) # OK + +It is common to write constants as ALL_CAPS, but you don't have to. + +The constant only applies to the value itself, not what it refers to. > + final females = ["Mary"] + const NAMES = [["John", "Peter"], females] + NAMES[0] = ["Jack"] # Error! + NAMES[0][0] = "Jack" # Error! + NAMES[1] = ["Emma"] # Error! + Names[1][0] = "Emma" # OK, now females[0] == "Emma" + +< *E1092* +Declaring more than one variable at a time, using the unpack notation, is +currently not supported: > + var [v1, v2] = GetValues() # Error! +That is because the type needs to be inferred from the list item type, which +isn't that easy. + + +Omitting :call and :eval ~ + +Functions can be called without `:call`: > + writefile(lines, 'file') +Using `:call` is still possible, but this is discouraged. + +A method call without `eval` is possible, so long as the start is an +identifier or can't be an Ex command. Examples: > + myList->add(123) + g:myList->add(123) + [1, 2, 3]->Process() + {a: 1, b: 2}->Process() + "foobar"->Process() + ("foobar")->Process() + 'foobar'->Process() + ('foobar')->Process() + +In the rare case there is ambiguity between a function name and an Ex command, +prepend ":" to make clear you want to use the Ex command. For example, there +is both the `:substitute` command and the `substitute()` function. When the +line starts with `substitute(` this will use the function. Prepend a colon to +use the command instead: > + :substitute(pattern (replacement ( + +Note that while variables need to be defined before they can be used, +functions can be called before being defined. This is required to allow +for cyclic dependencies between functions. It is slightly less efficient, +since the function has to be looked up by name. And a typo in the function +name will only be found when the function is called. + + +Omitting function() ~ + +A user defined function can be used as a function reference in an expression +without `function()`. The argument types and return type will then be checked. +The function must already have been defined. > + + var Funcref = MyFunction + +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. + + +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: > + var mylist = [ + 'one', + 'two', + ] +And when a dict spans multiple lines: > + var mydict = { + one: 1, + two: 2, + } +Function call: > + var result = Func( + arg1, + arg2 + ) + +For binary operators in expressions not in [], {} or () a line break is +possible just before or after the operator. For example: > + var text = lead + .. middle + .. end + var total = start + + end - + correction + var result = positive + ? PosFunc(arg) + : NegFunc(arg) + +For a method call using "->" and a member using a dot, a line break is allowed +before it: > + var result = GetBuilder() + ->BuilderSetWidth(333) + ->BuilderSetHeight(777) + ->BuilderBuild() + var result = MyDict + .member + +< *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 +"start" and print: > + var result = start + + print +Like this: > + var result = start + print + +This will assign "start" and print a line: > + var result = start + :+ print + +Note that the colon is not required for the |+cmd| argument: > + edit +6 fname + +It is also possible to split a function header over multiple lines, in between +arguments: > + def MyFunc( + text: string, + separator = '-' + ): string + +Notes: +- "enddef" cannot be used at the start of a continuation line, it ends the + current function. +- No line break is allowed in the LHS of an assignment. Specifically when + unpacking a list |:let-unpack|. This is OK: > + [var1, var2] = + Func() +< This does not work: > + [var1, + var2] = + Func() +- No line break is allowed in between arguments of an `:echo`, `:execute` and + similar commands. This is OK: > + echo [1, + 2] [3, + 4] +< 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 ~ + +|curly-braces-names| cannot be used. + + +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: > + 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 +considering that JavaScript uses this syntax, using the {} form for dictionary +literals was considered a much more useful syntax. In Vim9 script the {} form +uses literal keys: > + let dict = {key: value} + +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} + + +No :xit, :t, :append, :change or :insert ~ + +These commands are too easily confused with local variable names. +Instead of `:x` or `:xit` you can use `:exit`. +Instead of `:t` you can use `:copy`. + + +Comparators ~ + +The 'ignorecase' option is not used for comparators that use strings. + + +White space ~ + +Vim9 script enforces proper use of white space. This is no longer allowed: > + var name=234 # Error! + var name= 234 # Error! + var name =234 # Error! +There must be white space before and after the "=": > + var name = 234 # OK +White space must also be put before the # that starts a comment after a +command: > + var name = 234# Error! + var name = 234 # OK + +White space is required around most operators. + +White space is not allowed: +- Between a function name and the "(": > + call Func (arg) # Error! + call Func + \ (arg) # Error! + call Func(arg) # OK + call Func( + \ arg) # OK + call Func( + \ arg # OK + \ ) + + +Conditions and expressions ~ + +Conditions and expressions are mostly working like they do in other languages. +Some values are different from legacy Vim script: + value legacy Vim script Vim9 script ~ + 0 falsy falsy + 1 truthy truthy + 99 truthy Error! + "0" falsy Error! + "99" truthy Error! + "text" falsy Error! + +For the "??" operator and when using "!" then there is no error, every value +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 + number non-zero + float non-zero + string non-empty + blob non-empty + list non-empty (different from JavaScript) + dictionary non-empty (different from JavaScript) + func when there is a function name + special v:true + job when not NULL + channel when not NULL + class when not NULL + object when not NULL (TODO: when isTrue() returns v:true) + +The boolean operators "||" and "&&" expect the values to be boolean, zero or +one: > + 1 || false == true + 0 || 1 == true + 0 || false == false + 1 && true == true + 0 && 1 == false + 8 || 0 Error! + 'yes' && 0 Error! + [] || 99 Error! + +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 + !![] == false + !![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' + +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. + +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 'á'. + + +What to watch out for ~ + *vim9-gotchas* +Vim9 was designed to be closer to often used programming languages, but at the +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 + + %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 + +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 + +Functions defined with `:def` compile the whole function. Legacy functions +can bail out, and the following lines are not parsed: > + func Maybe() + if !has('feature') + return + endif + use-feature + endfunc +Vim9 functions are compiled as a whole: > + def Maybe() + if !has('feature') + return + endif + use-feature # May give compilation error + enddef +For a workaround, split it in two functions: > + func Maybe() + if has('feature') + call MaybyInner() + endif + endfunc + if has('feature') + def MaybeInner() + use-feature + enddef + endif +Or put the unsupported code inside an `if` with a constant expression that +evaluates to false: > + def Maybe() + if has('feature') + use-feature + endif + 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 + +============================================================================== + +3. New style functions *fast-functions* + +THIS IS STILL UNDER DEVELOPMENT - ANYTHING CAN BREAK - ANYTHING CAN CHANGE + + *:def* +:def[!] {name}([arguments])[: {return-type}] + Define a new function by the name {name}. The body of + the function follows in the next lines, until the + matching `:enddef`. + + When {return-type} is omitted or is "void" the + function is not expected to return anything. + + {arguments} is a sequence of zero or more argument + declarations. There are three forms: + {name}: {type} + {name} = {value} + {name}: {type} = {value} + The first form is a mandatory argument, the caller + must always provide them. + The second and third form are optional arguments. + When the caller omits an argument the {value} is used. + + The function will be compiled into instructions when + called, or when `:disassemble` or `:defcompile` is + used. Syntax and type errors will be produced at that + time. + + It is possible to nest `:def` inside another `:def` or + `:function` up to about 50 levels deep. + + [!] is used as with `:function`. Note that + script-local functions cannot be deleted or redefined + later in Vim9 script. They can only be removed by + reloading the same script. + + *:enddef* +:enddef End of a function defined with `:def`. It should be on + a line by its own. + + +If the script the function is defined in is Vim9 script, then script-local +variables can be accessed without the "s:" prefix. They must be defined +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 and they do not need to exist (they can be deleted any time). + + *:defc* *:defcompile* +:defc[ompile] Compile functions defined in the current script that + were not compiled yet. + This will report errors found during the compilation. + + *:disa* *:disassemble* +:disa[ssemble] {func} Show the instructions generated for {func}. + This is for debugging and testing. + Note that for command line completion of {func} you + can prepend "s:" to find script-local functions. + +Limitations ~ + +Local variables will not be visible to string evaluation. For example: > + def EvalString(): 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 + var list = ['aa', 'bb', 'cc', 'dd'] + return range(1, 2)->map({ _, v -> list[v] }) + enddef + + +============================================================================== + +4. Types *vim9-types* + +THIS IS STILL UNDER DEVELOPMENT - ANYTHING CAN BREAK - ANYTHING CAN CHANGE + +The following builtin types are supported: + bool + number + float + string + blob + list<{type}> + dict<{type}> + job + channel + func + func: {type} + func({type}, ...) + func({type}, ...): {type} + +Not supported yet: + tuple + +These types can be used in declarations, but no value will have this type: + {type}|{type} {not implemented yet} + void + any + +There is no array type, use list<{type}> instead. For a list constant an +efficient implementation is used that avoids allocating lot of small pieces of +memory. + +A partial and function can be declared in more or less specific ways: +func any kind of function reference, no type + checking for arguments or return value +func: {type} any number and type of arguments with specific + return type +func({type}) function with argument type, does not return + a value +func({type}): {type} function with argument type and return type +func(?{type}) function with type of optional argument, does + not return a value +func(...{type}) function with type of variable number of + arguments, does not return a value +func({type}, ?{type}, ...{type}): {type} + function with: + - type of mandatory argument + - type of optional argument + - type of variable number of arguments + - return type + +If the return type is "void" the function does not return a value. + +The reference can also be a |Partial|, in which case it stores extra arguments +and/or a dictionary, which are not visible to the caller. Since they are +called in the same way the declaration is the same. + +Custom types can be defined with `:type`: > + :type MyList list +Custom types must start with a capital letter, to avoid name clashes with +builtin types added later, similarly to user functions. +{not implemented yet} + +And classes and interfaces can be used as types: > + :class MyClass + :var mine: MyClass + + :interface MyInterface + :var mine: MyInterface + + :class MyTemplate + :var mine: MyTemplate + :var mine: MyTemplate + + :class MyInterface + :var mine: MyInterface + :var mine: MyInterface +{not implemented yet} + + +Variable types and type casting ~ + *variable-types* +Variables declared in Vim9 script or in a `:def` function have a type, either +specified explicitly or inferred from the initialization. + +Global, buffer, window and tab page variables do not have a specific type, the +value can be changed at any time, possibly changing the type. Therefore, in +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: > + 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 syntax of a type cast is: "<" {type} ">". There cannot be white space +after the "<" or before the ">" (to avoid them being confused with +smaller-than and bigger-than operators). + +The semantics is that, if needed, a runtime type check is performed. The +value is not actually changed. If you need to change the type, e.g. to change +it to a string, use the |string()| function. Or use |str2nr()| to convert a +string to a number. + + +Type inference ~ + *type-inference* +In general: Whenever the type is clear it can be omitted. For example, when +declaring a variable and giving it a value: > + var name = 0 # infers number type + var name = 'hello' # infers string type + +The type of a list and dictionary comes from the common type of the values. +If the values all have the same type, that type is used for the list or +dictionary. If there is a mix of types, the "any" type is used. > + [1, 2, 3] list + ['a', 'b', 'c'] list + [1, 'x', 3] list + + +Stricter type checking ~ + *type-checking* +In legacy Vim script, where a number was expected, a string would be +automatically converted to a number. This was convenient for an actual number +such as "123", but leads to unexpected problems (but no error message) if the +string doesn't start with a number. Quite often this leads to hard-to-find +bugs. + +In Vim9 script this has been made stricter. In most places it works just as +before, if the value used matches the expected type. There will sometimes be +an error, thus breaking backwards compatibility. For example: +- Using a number other than 0 or 1 where a boolean is expected. *E1023* +- Using a string value when setting a number options. +- Using a number where a string is expected. *E1024* + +============================================================================== + +5. Namespace, Import and Export + *vim9script* *vim9-export* *vim9-import* + +THIS IS STILL UNDER DEVELOPMENT - ANYTHING CAN BREAK - ANYTHING CAN CHANGE + +A Vim9 script can be written to be imported. This means that everything in +the script is local, unless exported. Those exported items, and only those +items, can then be imported in another script. + +You can cheat by using the global namespace explicitly. We will assume here +that you don't do that. + + +Namespace ~ + *:vim9script* *:vim9* +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 +starts with: > + vim9script + var myvar = 'yes' +Then "myvar" will only exist in this file. While without `vim9script` it would +be available as `g:myvar` from any other script and function. + +The variables at the file level are very much like the script-local "s:" +variables in legacy Vim script, but the "s:" is omitted. And they cannot be +deleted. + +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: > + :set cpo&vim +One of the effects is that |line-continuation| is always enabled. +The original value of 'cpoptions' is restored at the end of the script. + + +Export ~ + *:export* *:exp* +Exporting an item can be written as: > + export const EXPORTED_CONST = 1234 + export var someValue = ... + export final someValue = ... + export const someValue = ... + export def MyFunc() ... + export class MyClass ... + +As this suggests, only constants, variables, `:def` functions and classes can +be exported. {classes are not implemented yet} + + *E1042* +`:export` can only be used in Vim9 script, at the script level. + + +Import ~ + *:import* *:imp* *E1094* +The exported items can be imported individually in another Vim9 script: > + import EXPORTED_CONST from "thatscript.vim" + import MyClass from "myclass.vim" + +To import multiple items at the same time: > + import {someValue, MyClass} from "thatscript.vim" + +In case the name is ambiguous, another name can be specified: > + import MyClass as ThatClass from "myclass.vim" + import {someValue, MyClass as ThatClass} from "myclass.vim" + +To import all exported items under a specific identifier: > + import * as That from 'thatscript.vim' + +{not implemented yet: using "This as That"} + +Then you can use "That.EXPORTED_CONST", "That.someValue", etc. You are free +to choose the name "That", but it is highly recommended to use the name of the +script file to avoid confusion. + +`:import` can also be used in legacy Vim script. The imported items still +become script-local, even when the "s:" prefix is not given. + +The script name after `import` can be: +- A relative path, starting "." or "..". This finds a file relative to the + location of the script file itself. This is useful to split up a large + plugin into several files. +- An absolute path, starting with "/" on Unix or "D:/" on MS-Windows. This + will rarely be used. +- A path not being relative or absolute. This will be found in the + "import" subdirectories of 'runtimepath' entries. The name will usually be + longer and unique, to avoid loading the wrong file. + +Once a vim9 script file has been imported, the result is cached and used the +next time the same script is imported. It will not be read again. + *:import-cycle* +The `import` commands are executed when encountered. If that script (directly +or indirectly) imports the current script, then items defined after the +`import` won't be processed yet. Therefore cyclic imports can exist, but may +result in undefined items. + + +Import in an autoload script ~ + +For optimal startup speed, loading scripts should be postponed until they are +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() + +< 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" + def searchfor#Stuff(arg: string) + var filtered = FilterFunc(arg) + ... +< This goes in .../autoload/searchfor.vim. "searchfor" in the file name + must be exactly the same as the prefix for the function name, that is how + Vim finds the file. + +3. Other functionality, possibly shared between plugins, contains the exported + items and any private items. > + vim9script + var localVar = 'local' + export def FilterFunc(arg: string): string + ... +< This goes in .../import/someother.vim. + +When compiling a `:def` function and a function in an autoload script is +encountered, the script is not loaded until the `:def` function is called. + + +Import in legacy Vim script ~ + +If an `import` statement is used in legacy Vim script, the script-local "s:" +namespace will be used for the imported item, even when "s:" is not specified. + + +============================================================================== + +6. Future work: classes *vim9-classes* + +Above "class" was mentioned a few times, but it has not been implemented yet. +Most of Vim9 script can be created without this functionality, and since +implementing classes is going to be a lot of work, it is left for the future. +For now we'll just make sure classes can be added later. + +Thoughts: +- `class` / `endclass`, everything in one file +- Class names are always CamelCase +- Single constructor +- Single inheritance with `class ThisClass extends BaseClass` +- `abstract class` +- `interface` (Abstract class without any implementation) +- `class SomeClass implements SomeInterface` +- Generics for class: `class ` +- Generics for function: `def GetLast(key: Tkey)` + +Again, much of this is from TypeScript. + +Some things that look like good additions: +- Use a class as an interface (like Dart) +- Extend a class with methods, using an import (like Dart) + +An important class that will be provided is "Promise". Since Vim is single +threaded, connecting asynchronous operations is a natural way of allowing +plugins to do their work without blocking the user. It's a uniform way to +invoke callbacks and handle timeouts and errors. + +============================================================================== + +9. Rationale *vim9-rationale* + +The :def command ~ + +Plugin writers have asked for much faster Vim script. Investigations have +shown that keeping the existing semantics of function calls make this close to +impossible, because of the overhead involved with calling a function, setting +up the local function scope and executing lines. There are many details that +need to be handled, such as error messages and exceptions. The need to create +a dictionary for a: and l: scopes, the a:000 list and several others add too +much overhead that cannot be avoided. + +Therefore the `:def` method to define a new-style function had to be added, +which allows for a function with different semantics. Most things still work +as before, but some parts do not. A new way to define a function was +considered the best way to separate the legacy style code from Vim9 style code. + +Using "def" to define a function comes from Python. Other languages use +"function" which clashes with legacy Vim script. + + +Type checking ~ + +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. + +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 +Vim before, with some additions such as "void" and "bool". + + +Removing clutter and weirdness ~ + +Once decided that `:def` functions have different syntax than legacy functions, +we are free to add improvements to make the code more familiar for users who +know popular programming languages. In other words: remove weird things that +only Vim does. + +We can also remove clutter, mainly things that were done to make Vim script +backwards compatible with the good old Vi commands. + +Examples: +- Drop `:call` for calling a function and `:eval` for manipulating data. +- Drop using a leading backslash for line continuation, automatically figure + out where an expression ends. + +However, this does require that some things need to change: +- Comments start with # instead of ", to avoid confusing them with strings. + This is good anyway, it is known from several popular languages. +- Ex command ranges need to be prefixed with a colon, to avoid confusion with + expressions (single quote can be a string or a mark, "/" can be divide or a + search command, etc.). + +Goal is to limit the differences. A good criteria is that when the old syntax +is accidentally used you are very likely to get an error message. + + +Syntax and semantics from popular languages ~ + +Script writers have complained that the Vim script syntax is unexpectedly +different from what they are used to. To reduce this complaint popular +languages are used as an example. At the same time, we do not want to abandon +the well-known parts of legacy Vim script. + +For many things TypeScript is followed. It's a recent language that is +gaining popularity and has similarities with Vim script. It also has a +mix of static typing (a variable always has a known value type) and dynamic +typing (a variable can have different types, this changes at runtime). Since +legacy Vim script is dynamically typed and a lot of existing functionality +(esp. builtin functions) depends on that, while static typing allows for much +faster execution, we need to have this mix in Vim9 script. + +There is no intention to completely match TypeScript syntax and semantics. We +just want to take those parts that we can use for Vim and we expect Vim users +will be happy with. TypeScript is a complex language with its own history, +advantages and disadvantages. To get an idea of the disadvantages read the +book: "JavaScript: The Good Parts". Or find the article "TypeScript: the good +parts" and read the "Things to avoid" section. + +People familiar with other languages (Java, Python, etc.) will also find +things in TypeScript that they do not like or do not understand. We'll try to +avoid those things. + +Specific items from TypeScript we avoid: +- Overloading "+", using it both for addition and string concatenation. This + goes against legacy Vim script and often leads to mistakes. For that reason + we will keep using ".." for string concatenation. Lua also uses ".." this + way. And it allows for conversion to string for more values. +- TypeScript can use an expression like "99 || 'yes'" in a condition, but + cannot assign the value to a boolean. That is inconsistent and can be + annoying. Vim recognizes an expression with && or || and allows using the + result as a bool. TODO: to be reconsidered +- TypeScript considers an empty string as Falsy, but an empty list or dict as + Truthy. That is inconsistent. In Vim an empty list and dict are also + Falsy. +- TypeScript has various "Readonly" types, which have limited usefulness, + since a type cast can remove the immutable nature. Vim locks the value, + which is more flexible, but is only checked at runtime. + + +Declarations ~ + +Legacy Vim script uses `:let` for every assignment, while in Vim9 declarations +are used. That is different, thus it's good to use a different command: +`:var`. This is used in many languages. The semantics might be slightly +different, but it's easily recognized as a declaration. + +Using `:const` for constants is common, but the semantics varies. Some +languages only make the variable immutable, others also make the value +immutable. Since "final" is well known from Java for only making the variable +immutable we decided to use that. And then `:const` can be used for making +both immutable. This was also used in legacy Vim script and the meaning is +almost the same. + +What we end up with is very similar to Dart: > + :var name # mutable variable and value + :final name # immutable variable, mutable value + :const name # immutable variable and value + +Since legacy and Vim9 script will be mixed and global variables will be +shared, optional type checking is desirable. Also, type inference will avoid +the need for specifying the type in many cases. The TypeScript syntax fits +best for adding types to declarations: > + var name: string # string type is specified + ... + name = 'John' + const greeting = 'hello' # string type is inferred + +This is how we put types in a declaration: > + var mylist: list + final mylist: list = ['foo'] + def Func(arg1: number, arg2: string): bool + +Two alternatives were considered: +1. Put the type before the name, like Dart: > + var list mylist + final list mylist = ['foo'] + def Func(number arg1, string arg2) bool +2. Put the type after the variable name, but do not use a colon, like Go: > + var mylist list + final mylist list = ['foo'] + def Func(arg1 number, arg2 string) bool + +The first is more familiar for anyone used to C or Java. The second one +doesn't really have an advantage over the first, so let's discard the second. + +Since we use type inference the type can be left out when it can be inferred +from the value. This means that after `var` we don't know if a type or a name +follows. That makes parsing harder, not only for Vim but also for humans. +Also, it will not be allowed to use a variable name that could be a type name, +using `var string string` is too confusing. + +The chosen syntax, using a colon to separate the name from the type, adds +punctuation, but it actually makes it easier to recognize the parts of a +declaration. + + +Expressions ~ + +Expression evaluation was already close to what other languages are doing. +Some details are unexpected and can be improved. For example a boolean +condition would accept a string, convert it to a number and check if the +number is non-zero. This is unexpected and often leads to mistakes, since +text not starting with a number would be converted to zero, which is +considered false. Thus using a string for a condition would often not give an +error and be considered false. That is confusing. + +In Vim9 type checking is stricter to avoid mistakes. Where a condition is +used, e.g. with the `:if` command and the `||` operator, only boolean-like +values are accepted: + true: `true`, `v:true`, `1`, `0 < 9` + false: `false`, `v:false`, `0`, `0 > 9` +Note that the number zero is false and the number one is true. This is more +permissive than most other languages. It was done because many builtin +functions return these values. + +If you have any type of value and want to use it as a boolean, use the `!!` +operator: + true: !`!'text'`, `!![99]`, `!!{'x': 1}`, `!!99` + false: `!!''`, `!![]`, `!!{}` + +From a language like JavaScript we have this handy construct: > + GetName() || 'unknown' +However, this conflicts with only allowing a boolean for a condition. +Therefore the "??" operator was added: > + GetName() ?? 'unknown' +Here you can explicitly express your intention to use the value as-is and not +result in a boolean. This is called the |falsy-operator|. + + +Import and Export ~ + +A problem of legacy Vim script is that by default all functions and variables +are global. It is possible to make them script-local, but then they are not +available in other scripts. This defies the concept of a package that only +exports selected items and keeps the rest local. + +In Vim9 script a mechanism very similar to the JavaScript import and export +mechanism is supported. It is a variant to the existing `:source` command +that works like one would expect: +- Instead of making everything global by default, everything is script-local, + unless exported. +- When importing a script the symbols that are imported are explicitly listed, + avoiding name conflicts and failures if functionality is added later. +- The mechanism allows for writing a big, long script with a very clear API: + the exported function(s) and class(es). +- By using relative paths loading can be much faster for an import inside of a + package, no need to search many directories. +- Once an import has been used, it can be cached and loading it again can be + avoided. +- The Vim-specific use of "s:" to make things script-local can be dropped. + +When sourcing a Vim9 script from a legacy script, only the items defined +globally can be used, not the exported items. Alternatives considered: +- All the exported items become available as script-local items. This makes + it uncontrollable what items get defined and likely soon leads to trouble. +- Use the exported items and make them global. Disadvantage is that it's then + not possible to avoid name clashes in the global namespace. +- Completely disallow sourcing a Vim9 script, require using `:import`. That + makes it difficult to use scripts for testing, or sourcing them from the + command line to try them out. +Note that you can also use `:import` in legacy Vim script, see above. + + +Compiling functions early ~ + +Functions are compiled when called or when `:defcompile` is used. Why not +compile them early, so that syntax and type errors are reported early? + +The functions can't be compiled right away when encountered, because there may +be forward references to functions defined later. Consider defining functions +A, B and C, where A calls B, B calls C, and C calls A again. It's impossible +to reorder the functions to avoid forward references. + +An alternative would be to first scan through the file to locate items and +figure out their type, so that forward references are found, and only then +execute the script and compile the functions. This means the script has to be +parsed twice, which is slower, and some conditions at the script level, such +as checking if a feature is supported, are hard to use. An attempt was made +to see if it works, but it turned out to be impossible to make work nicely. + +It would be possible to compile all the functions at the end of the script. +The drawback is that if a function never gets called, the overhead of +compiling it counts anyway. Since startup speed is very important, in most +cases it's better to do it later and accept that syntax and type errors are +only reported then. In case these errors should be found early, e.g. when +testing, the `:defcompile` command will help out. + + +Why not use an embedded language? ~ + +Vim supports interfaces to Perl, Python, Lua, Tcl and a few others. But +these interfaces have never become widely used, for various reasons. When +Vim9 was designed a decision was made to make these interfaces lower priority +and concentrate on Vim script. + +Still, plugin writers may find other languages more familiar, want to use +existing libraries or see a performance benefit. We encourage plugin authors +to write code in any language and run it as an external tool, using jobs and +channels. We can try to make this easier somehow. + +Using an external tool also has disadvantages. An alternative is to convert +the tool into Vim script. For that to be possible without too much +translation, and keeping the code fast at the same time, the constructs of the +tool need to be supported. Since most languages support classes the lack of +support for classes in Vim is then a problem. + + +Classes ~ + +Vim supports a kind-of object oriented programming by adding methods to a +dictionary. With some care this can be made to work, but it does not look +like real classes. On top of that, it's quite slow, because of the use of +dictionaries. + +The support of classes in Vim9 script is a "minimal common functionality" of +class support in most languages. It works much like Java, which is the most +popular programming language. + + + + vim:tw=78:ts=8:noet:ft=help:norl: From ee7ac8c85d8ac2a3442a491311ec2784f131b829 Mon Sep 17 00:00:00 2001 From: Kyoichiro Yamada Date: Sat, 5 Dec 2020 00:40:09 +0900 Subject: [PATCH 03/43] =?UTF-8?q?autocommand=20->=20=E8=87=AA=E5=8B=95?= =?UTF-8?q?=E3=82=B3=E3=83=9E=E3=83=B3=E3=83=89?= 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 2bdf9d4a5..615f666fe 100644 --- a/doc/vim9.jax +++ b/doc/vim9.jax @@ -54,7 +54,7 @@ Vim9 スクリプトの主な目的は劇的な性能の向上です。これは Vim9 スクリプトは以下の場所で使用することができます。 - コマンド `:def` で定義された関数の中 - コマンド `vim9script` で始まるスクリプトファイルの中 -- 上記のコンテキストで定義された autocommand +- 上記のコンテキストで定義された自動コマンド Vim9 スクリプトファイルの中でコマンド `:function` で関数を定義すると、その中で は古い Vim スクリプトの記法が有効になります。 From da7edc507442367bd8a7e00a67fa11f2abbab308 Mon Sep 17 00:00:00 2001 From: Kyoichiro Yamada Date: Sat, 5 Dec 2020 01:58:33 +0900 Subject: [PATCH 04/43] wip: change overview --- doc/vim9.jax | 31 +++++++++++++++---------------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/doc/vim9.jax b/doc/vim9.jax index 615f666fe..f128b713a 100644 --- a/doc/vim9.jax +++ b/doc/vim9.jax @@ -71,32 +71,31 @@ Vim9 スクリプトと 古い Vim スクリプトは同時に利用できます 注意: この内容は開発中の内容を含んでいます。予告なく破壊的変更が行われるおそれ があります。 -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 -- Using a backslash for line continuation is hardly ever needed: > +Vim9 スクリプトと `:def` 関数を使用する際に最もよく遭遇する変更点を簡単にまと +めると以下のとおりです。 +- コメントは " ではなく # で始めます。 > + echo "hello" # コメント +- 行継続文字 (\) はほとんどの場合、必要ありません。 > echo "hello " .. yourName .. ", how are you?" -- White space is required in many places. -- Assign values without `:let`, declare variables with `:var`: > +- 多くの場所に空白が必要になります。 +- 値の代入には `:let` を使用せず、変数の宣言には `:var` を使用します。 > var count = 0 count += 3 -- Constants can be declared with `:final` and `:const`: > +- `:final` と `:const` を使用して、定数を宣言できます。 > 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: > +- `:final` は `:finally` の略語として使用することはできません。 +- 変数と関数のスコープは、明示しない限りスクリプトローカルです。 +- 関数を引数の型、戻り値の型とともに宣言します。 > def CallMe(count: number, message: string): bool -- Call functions without `:call`: > +- 関数は `:call` なしで呼び出します。 > 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: > +- `:xit`、`:t`、`:append`、`:change`、`:insert`と波括弧変数は使用できません。 +- コマンドの前に範囲指定を置くときは、コロン (:) を前置しなくてはなりません。 > :%s/this/that From 238a3b2a17d34d8019622cec8cbde5791f4a4139 Mon Sep 17 00:00:00 2001 From: Kyoichiro Yamada Date: Sat, 5 Dec 2020 01:59:59 +0900 Subject: [PATCH 05/43] =?UTF-8?q?vim9=3F=20=E3=82=B9=E3=82=AF=E3=83=AA?= =?UTF-8?q?=E3=83=97=E3=83=88=20->=20vim9=3F=20script?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- doc/vim9.jax | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/doc/vim9.jax b/doc/vim9.jax index f128b713a..63822fb08 100644 --- a/doc/vim9.jax +++ b/doc/vim9.jax @@ -8,17 +8,17 @@ 注意: この内容は開発中の内容を含んでいます。予告なく破壊的変更が行われるおそれ があります。 -Vim9 スクリプトのコマンドと文法 *vim9* +Vim9 script のコマンドと文法 *vim9* ほとんどの文法については |eval.txt| で解説されています。このファイルには Vim9 -スクリプトの新しい文法と機能について書かれています。 +script の新しい文法と機能について書かれています。 注意: この内容は開発中の内容を含んでいます。予告なく破壊的変更が行われるおそれ があります。 -1. Vim9 スクリプトとは |vim9-script| -2. 古い Vim スクリプトからの変更点 |vim9-differences| +1. Vim9 script とは |vim9-script| +2. 古い Vim script からの変更点 |vim9-differences| 3. 新しい関数 |fast-functions| 4. 型 |vim9-types| 5. 名前空間と Import / Export |vim9script| @@ -28,52 +28,52 @@ Vim9 スクリプトのコマンドと文法 *vim9* ============================================================================== -1. Vim9 スクリプトとは *vim9-script* +1. Vim9 script とは *vim9-script* 注意: この内容は開発中の内容を含んでいます。予告なく破壊的変更が行われるおそれ があります。 -Vim スクリプトは、互換性の維持に気を配りながら成長してきました。そのため、古い +Vim script は、互換性の維持に気を配りながら成長してきました。そのため、古い 悪しき仕様を変更できないことが多いほか、 Vi との互換性に制約を受けて、より良い 解決策を採用できなくなっています。処理は遅く、実行するたびに各行のパースが行わ れています。 -Vim9 スクリプトの主な目的は劇的な性能の向上です。これは、コマンドをより効率よ +Vim9 script の主な目的は劇的な性能の向上です。これは、コマンドをより効率よ く実行できる命令にコンパイルすることで実現しています。これにより、10倍から100 倍の実行速度の向上が期待できます。 -第2の目的は、Vim スクリプト特有の文法を見直し、より一般的に使われる JavaScript +第2の目的は、Vim script 特有の文法を見直し、より一般的に使われる JavaScript や TypeScript、 Java のようなプログラミング言語に近づけることです。 パフォーマンスの向上は、下位互換性を犠牲にせずには達成できません。たとえば、関 数の引数を辞書 "a:" から利用できるようにするためには、かなりのオーバーヘッドが -必要になります。そのため、Vim9 スクリプトでは、この辞書が利用できなくなりまし +必要になります。そのため、Vim9 script では、この辞書が利用できなくなりまし た。その他の違いは、エラーの処理方法など、より微細なものです。 -Vim9 スクリプトは以下の場所で使用することができます。 +Vim9 script は以下の場所で使用することができます。 - コマンド `:def` で定義された関数の中 - コマンド `vim9script` で始まるスクリプトファイルの中 - 上記のコンテキストで定義された自動コマンド Vim9 スクリプトファイルの中でコマンド `:function` で関数を定義すると、その中で -は古い Vim スクリプトの記法が有効になります。 +は古い Vim script の記法が有効になります。 しかし、これは混乱を招く可能性があるため、推奨できません。 -Vim9 スクリプトと 古い Vim スクリプトは同時に利用できます。古いスクリプトを書 +Vim9 script と 古い Vim script は同時に利用できます。古いスクリプトを書 き換えなくとも、以前と同様に実行することが可能です。高速化が必要なコードには、 `:def` 関数を使ったほうが良いかもしれません。 ============================================================================== -2. 古い Vim スクリプトからの変更点 *vim9-differences* +2. 古い Vim script からの変更点 *vim9-differences* 注意: この内容は開発中の内容を含んでいます。予告なく破壊的変更が行われるおそれ があります。 概要 ~ -Vim9 スクリプトと `:def` 関数を使用する際に最もよく遭遇する変更点を簡単にまと +Vim9 script と `:def` 関数を使用する際に最もよく遭遇する変更点を簡単にまと めると以下のとおりです。 - コメントは " ではなく # で始めます。 > echo "hello" # コメント From 98256f570bb989186ea63563b6bf2ec9321cc587 Mon Sep 17 00:00:00 2001 From: Kyoichiro Yamada Date: Sat, 5 Dec 2020 02:36:24 +0900 Subject: [PATCH 06/43] =?UTF-8?q?=E9=96=A2=E6=95=B0=E3=81=AE=E7=AF=80?= =?UTF-8?q?=E3=81=BE=E3=81=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- doc/vim9.jax | 73 ++++++++++++++++++++++++++-------------------------- 1 file changed, 36 insertions(+), 37 deletions(-) diff --git a/doc/vim9.jax b/doc/vim9.jax index 63822fb08..cc4b9fce8 100644 --- a/doc/vim9.jax +++ b/doc/vim9.jax @@ -62,7 +62,7 @@ Vim9 スクリプトファイルの中でコマンド `:function` で関数を Vim9 script と 古い Vim script は同時に利用できます。古いスクリプトを書 き換えなくとも、以前と同様に実行することが可能です。高速化が必要なコードには、 -`:def` 関数を使ったほうが良いかもしれません。 +`:def` で定義する関数を使ったほうが良いかもしれません。 ============================================================================== @@ -73,9 +73,9 @@ Vim9 script と 古い Vim script は同時に利用できます。古いスク 概要 ~ -Vim9 script と `:def` 関数を使用する際に最もよく遭遇する変更点を簡単にまと -めると以下のとおりです。 -- コメントは " ではなく # で始めます。 > +Vim9 script と `:def` で定義する関数を使用する際に最もよく遭遇する変更点を簡単 +にまとめると以下のとおりです。 +- コメントはダブルクォーテーション (") ではなく、ハッシュ (#) で始めます。 > echo "hello" # コメント - 行継続文字 (\) はほとんどの場合、必要ありません。 > echo "hello " @@ -99,56 +99,55 @@ Vim9 script と `:def` 関数を使用する際に最もよく遭遇する変更 :%s/this/that -Comments starting with # ~ +ハッシュ (#) から始まるコメント ~ -In legacy Vim script comments start with double quote. In Vim9 script -comments start with #. > +古い Vim script のコメントは、ダブルクォーテーション (") で始めます。Vim9 +scriptのコメントはハッシュ (#) で始めます。 > # declarations var count = 0 # number of occurrences -The reason is that a double quote can also be the start of a string. In many -places, especially halfway through an expression with a line break, it's hard -to tell what the meaning is, since both a string and a comment can be followed -by arbitrary text. To avoid confusion only # comments are recognized. This -is the same as in shell scripts and Python programs. +これは、ダブルクォーテーションは文字列の開始を表す文字でもあるからです。多くの +場所、特に改行を含む式の途中では、文字列とコメントの両方が現れるため、どちらを +意味しているのかわかりにくくなってしまいます。この混乱を避けるために、Vim9 +script では、ハッシュ (#) のみをコメントとして認識します。このコメント形式はシ +ェルスクリプトやPythonのコードと同じです。 -In Vi # is a command to list text with numbers. In Vim9 script you can use -`:number` for that. > +Vi においてハッシュ (#) は行番号付きでテキストを表示します。Vim9 script では、 +代わりに `:number` を使用します。 > 101 number -To improve readability there must be a space between a command and the # -that starts a comment. +可読性を向上するために、コマンドとハッシュ (#)、コメント文の間にはスペースをお +いてください。 -Vim9 functions ~ +Vim9 関数 ~ -A function defined with `:def` is compiled. Execution is many times faster, -often 10x to 100x times. +`:def` で定義された関数はコンパイルされます。処理の実行は多くの場合、通常の関 +数に比べて10倍から100倍ほど速くなります。 -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 -- when the `:defcompile` command is encountered in the script where the - function was defined -- `:disassemble` is used for the function. -- a function that is compiled calls the function or uses it as a function - reference +コンパイルは以下のタイミングで実行されます。 +- 関数が最初に呼び出されるとき +- 関数の定義されたスクリプトの中で、コマンド `:defcompile` に出会ったとき +- 関数に対してコマンド `:disassemble` が実行されたとき +- コンパイルされた関数から呼び出されたり、関数リファレンスとして使用されたとき -`: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. +`:def` で定義する関数には `:function` の "range"、"abort"、"dict" や "closure" +といったオプションがありません。`:def` で定義する関数は常にエラー時は処理を中 +断 (abort) し、範囲を受け取らず、辞書関数にすることはできません。 -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 -functions. +引数の型と戻り値の型を指定する必要があります。型には "any" を指定することがで +き、型のチェックは古い関数と同様に実行時に行われます。 Arguments are accessed by name, without "a:", just like any other language. -There is no "a:" dictionary or "a:000" list. +引数を参照する際は、他のプログラミング言語と同様、"a:" をつけずに名前だけで指定 +することができます。 +引数辞書 "a:" と 引数リスト "a:000" はありません。 -Variable arguments are defined as the last argument, with a name and have a -list type, similar to TypeScript. For example, a list of numbers: > +可変長引数を定義する場合は TypeScript のように、最後の引数として名前とlist型で +定義します。たとえば、数値の可変長引数の例は以下のとおりです。 > def MyFunc(...itemlist: list) for item in itemlist ... From d448d55a61ec80cd35f4672837b7949b62701c5b Mon Sep 17 00:00:00 2001 From: Kyoichiro Yamada Date: Sat, 5 Dec 2020 02:37:46 +0900 Subject: [PATCH 07/43] remove untranslated textt --- doc/vim9.jax | 1 - 1 file changed, 1 deletion(-) diff --git a/doc/vim9.jax b/doc/vim9.jax index cc4b9fce8..466a428b9 100644 --- a/doc/vim9.jax +++ b/doc/vim9.jax @@ -141,7 +141,6 @@ Vim9 関数 ~ 引数の型と戻り値の型を指定する必要があります。型には "any" を指定することがで き、型のチェックは古い関数と同様に実行時に行われます。 -Arguments are accessed by name, without "a:", just like any other language. 引数を参照する際は、他のプログラミング言語と同様、"a:" をつけずに名前だけで指定 することができます。 引数辞書 "a:" と 引数リスト "a:000" はありません。 From f6fa72ab18f85d9129b932a504d965230b0138d9 Mon Sep 17 00:00:00 2001 From: Kyoichiro Yamada Date: Sat, 5 Dec 2020 02:38:33 +0900 Subject: [PATCH 08/43] =?UTF-8?q?fix=20"=E3=81=A7=E5=AE=9A=E7=BE=A9?= =?UTF-8?q?=E3=81=95=E3=82=8C=E3=82=8B=E9=96=A2=E6=95=B0"?= 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 466a428b9..b0b07fde0 100644 --- a/doc/vim9.jax +++ b/doc/vim9.jax @@ -134,7 +134,7 @@ Vim9 関数 ~ - 関数に対してコマンド `:disassemble` が実行されたとき - コンパイルされた関数から呼び出されたり、関数リファレンスとして使用されたとき -`:def` で定義する関数には `:function` の "range"、"abort"、"dict" や "closure" +`:def` には `:function` の "range"、"abort"、"dict" や "closure" といったオプションがありません。`:def` で定義する関数は常にエラー時は処理を中 断 (abort) し、範囲を受け取らず、辞書関数にすることはできません。 From 895c2cd46f872c20a200bb919115f353263be1ee Mon Sep 17 00:00:00 2001 From: Kyoichiro Yamada Date: Sat, 5 Dec 2020 02:38:55 +0900 Subject: [PATCH 09/43] fix newlines --- doc/vim9.jax | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/vim9.jax b/doc/vim9.jax index b0b07fde0..3cf6319be 100644 --- a/doc/vim9.jax +++ b/doc/vim9.jax @@ -134,9 +134,9 @@ Vim9 関数 ~ - 関数に対してコマンド `:disassemble` が実行されたとき - コンパイルされた関数から呼び出されたり、関数リファレンスとして使用されたとき -`:def` には `:function` の "range"、"abort"、"dict" や "closure" -といったオプションがありません。`:def` で定義する関数は常にエラー時は処理を中 -断 (abort) し、範囲を受け取らず、辞書関数にすることはできません。 +`:def` には `:function` の "range"、"abort"、"dict" や "closure" といったオプ +ションがありません。`:def` で定義する関数は常にエラー時は処理を中断 (abort) し、 +範囲を受け取らず、辞書関数にすることはできません。 引数の型と戻り値の型を指定する必要があります。型には "any" を指定することがで き、型のチェックは古い関数と同様に実行時に行われます。 From a60b6e7d4a7b9bd77b9393b41b0cbed2eb8c758b Mon Sep 17 00:00:00 2001 From: Kyoichiro Yamada Date: Sat, 5 Dec 2020 13:40:53 +0900 Subject: [PATCH 10/43] =?UTF-8?q?=E3=82=B9=E3=82=AF=E3=83=AA=E3=83=97?= =?UTF-8?q?=E3=83=88=E3=83=AD=E3=83=BC=E3=82=AB=E3=83=AB=E3=82=B9=E3=82=B3?= =?UTF-8?q?=E3=83=BC=E3=83=97=E3=81=A7=E5=AE=9A=E7=BE=A9=E3=81=95=E3=82=8C?= =?UTF-8?q?=E3=82=8B=E9=96=A2=E6=95=B0=E3=81=A8=E5=A4=89=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- doc/vim9.jax | 63 +++++++++++++++++++++++++++------------------------- 1 file changed, 33 insertions(+), 30 deletions(-) diff --git a/doc/vim9.jax b/doc/vim9.jax index 3cf6319be..722ae3633 100644 --- a/doc/vim9.jax +++ b/doc/vim9.jax @@ -152,42 +152,45 @@ Vim9 関数 ~ ... -Functions and variables are script-local by default ~ +明示しない限りスクリプトローカルになる変数と関数のスコープ ~ *vim9-scopes* -When using `:function` or `:def` to specify a new function at the script level -in a Vim9 script, the function is local to the script, as if "s:" was -prefixed. Using the "s:" prefix is optional. To define a global function or -variable the "g:" prefix must be used. For functions in an autoload script -the "name#" prefix is sufficient. > +Vim9 script でスクリプト直下に `:function` や `:def` を使って関数を定義すると、 +関数はプレフィックス "s:" をつけた際のように、スクリプトローカルで定義されます。 +"s:" を明示することもできます。グローバルスコープの関数や変数を定義するにはプ +レフィックス "g:" をつける必要があります。autoload scriptで定義する場合は、 +"name#" をつけます。 > def ThisFunction() # script-local def s:ThisFunction() # script-local def g:ThatFunction() # global def scriptname#function() # autoload -When using `:function` or `:def` to specify a nested function inside a `:def` -function, this nested function is local to the code block it is defined in. -In a `:def` function it is not possible to define a script-local function. It -is possible to define a global function by using the "g:" prefix. - -When referring to a function and no "s:" or "g:" prefix is used, Vim will -search for the function: -- in the function scope, in block scopes -- in the script scope, possibly imported -- in the list of global functions -However, it is recommended to always use "g:" to refer to a global function -for clarity. - -In all cases the function must be defined before used. That is when it is -called, when `:defcompile` causes it to be compiled, or when code that calls -it is being compiled (to figure out the return type). - -The result is that functions and variables without a namespace can usually be -found in the script, either defined there or imported. Global functions and -variables could be defined anywhere (good luck finding out where!). - -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. +`:def` で定義した関数の中で `:function` や `:def` でネストした関数を定義するこ +とができ、定義されたブロックローカルのスコープになります。 +`:def` で定義した関数の中では、スクリプトのスコープで関数を定義することはでき +ません。プレフィックス "g:" を使ってグローバルスコープの関数を定義することはで +きます。 + +関数をプレフィックス "s:" や "g:" をつけずに参照した場合、Vim は関数を次のよう +に探します: +- 同じ関数の中、ブロックスコープの中 +- スクリプトスコープの中、インポートされたもの +- グローバル関数のリスト +しかし、明瞭にするためにもグローバル関数を参照する際はプレフィックス "g:" を付 +けることを推奨します。 + +いずれの場合でも、関数は使用されるよりも前に定義されていなくてはなりません。 +使用されるタイミングは、コマンド `:defcompile` によってコンパイルされるとき、ま +たは同コマンドを呼び出す関数がコンパイルされているとき(戻り値の型を確認するた +め)です。 + +その結果として、名前空間を持たない関数や変数は通常、スクリプト内で定義されてい +るか、インポートされたものかのどちらかで見つけることができます。グローバルな関 +数や変数はどこでも定義できます(どこで定義されているか、見つかるといいです +ね!)。 + +グローバル関数は引き続き、ほとんどいつでも定義し、削除することができます。Vim9 +script でのスクリプトローカル関数は、スクリプトが読み込まれたときに一度定義さ +れたきり、削除や置き換えはできません。 Variable declarations with :var, :final and :const ~ From 6e7b17b824049c398f55d9b7cc66692d46d7d499 Mon Sep 17 00:00:00 2001 From: Kyoichiro Yamada Date: Sat, 5 Dec 2020 13:43:44 +0900 Subject: [PATCH 11/43] =?UTF-8?q?=E3=82=B3=E3=83=9E=E3=83=B3=E3=83=89?= =?UTF-8?q?=E3=82=92=E5=91=BC=E3=81=B3=E5=87=BA=E3=81=99=E3=81=A8=E3=81=8D?= =?UTF-8?q?=E3=81=A7=E3=81=AF=E3=81=AA=E3=81=8F=E3=80=81=E9=96=A2=E6=95=B0?= =?UTF-8?q?=E3=82=92=E5=91=BC=E3=81=B3=E5=87=BA=E3=81=99=E3=81=A8=E3=81=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- doc/vim9.jax | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/vim9.jax b/doc/vim9.jax index 722ae3633..815e0d272 100644 --- a/doc/vim9.jax +++ b/doc/vim9.jax @@ -180,8 +180,8 @@ Vim9 script でスクリプト直下に `:function` や `:def` を使って関 いずれの場合でも、関数は使用されるよりも前に定義されていなくてはなりません。 使用されるタイミングは、コマンド `:defcompile` によってコンパイルされるとき、ま -たは同コマンドを呼び出す関数がコンパイルされているとき(戻り値の型を確認するた -め)です。 +たは関数を呼び出す関数がコンパイルされているとき(戻り値の型を確認するため)で +す。 その結果として、名前空間を持たない関数や変数は通常、スクリプト内で定義されてい るか、インポートされたものかのどちらかで見つけることができます。グローバルな関 From 163ec3d7990275147e805d5b44aaa606dc1b217b Mon Sep 17 00:00:00 2001 From: Kyoichiro Yamada Date: Sat, 5 Dec 2020 15:41:06 +0900 Subject: [PATCH 12/43] =?UTF-8?q?=E5=AE=9A=E6=95=B0=E5=AE=A3=E8=A8=80?= =?UTF-8?q?=E3=80=81:call=20=E3=81=A8=20:eval=E3=81=8C=E4=B8=8D=E8=A6=81?= =?UTF-8?q?=E3=81=AB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- doc/vim9.jax | 108 +++++++++++++++++++++++++-------------------------- 1 file changed, 52 insertions(+), 56 deletions(-) diff --git a/doc/vim9.jax b/doc/vim9.jax index 815e0d272..5542dc05e 100644 --- a/doc/vim9.jax +++ b/doc/vim9.jax @@ -193,13 +193,13 @@ script でのスクリプトローカル関数は、スクリプトが読み込 れたきり、削除や置き換えはできません。 -Variable declarations with :var, :final and :const ~ +:var、:final や :const で定義する変数 ~ *vim9-declaration* *:var* -Local variables need to be declared with `:var`. Local constants need to be -declared with `:final` or `:const`. We refer to both as "variables" in this -section. +ローカル変数は `:var` で定義する必要があります。ローカル定数は `:final` または +`:const` で定義する必要があります。このセクションでは、両者を "変数" と呼ぶこ +とにします。 -Variables can be local to a script, function or code block: > +変数はスクリプトローカルや、関数、コードブロックのスコープで定義できます。 > vim9script var script_var = 123 def SomeFunc() @@ -208,8 +208,8 @@ Variables can be local to a script, function or code block: > var block_var = func_var ... -The variables are only visible in the block where they are defined and nested -blocks. Once the block ends the variable is no longer accessible: > +変数は、定義されたコードブロックか、ネストされた配下のブロックで参照することが +できます。コードブロックが終わったあとの処理から参照することはできません。 > if cond var inner = 5 else @@ -217,7 +217,7 @@ blocks. Once the block ends the variable is no longer accessible: > endif echo inner # Error! -The declaration must be done earlier: > +参照したい場合には、ブロックよりも前で宣言しなくてはなりません。 > var inner: number if cond inner = 5 @@ -226,62 +226,61 @@ The declaration must be done earlier: > endif echo inner -To intentionally hide a variable from code that follows, a block can be -used: > +意図的に続く処理から変数を隠したいとき、ブロックを使うことができます。 > { var temp = 'temp' ... } echo temp # Error! -Declaring a variable with a type but without an initializer will initialize to -zero, false or empty. +変数を型つきで、かつ初期値なしで宣言した場合、その値はゼロ、False、または空で +初期化されます。 -In Vim9 script `:let` cannot be used. An existing variable is assigned to -without any command. The same for global, window, tab, buffer and Vim -variables, because they are not really declared. They can also be deleted -with `:unlet`. +Vim9 script では `:let` は使用できません。すでに存在する変数に題してはコマンド +を使用せずに代入します。グローバル変数、ウィンドウ変数、タブ変数、バッファ変数、 +そして Vim 変数についてもどうようです。 +変数は `:unlet` によって削除することもできます。 -Variables and functions cannot shadow previously defined or imported variables -and functions. -Variables may shadow Ex commands, rename the variable if needed. +変数と関数は、すでに定義された、またはインポートされた変数と関数をシャドーイン +グすることはできません。一方で変数は Ex コマンドをシャドーイングするので、必要 +であれば変数の名前を変更してください。 -Global variables and user defined functions must be prefixed with "g:", also -at the script level. > +グローバル変数やユーザ定義関数の前には、スクリプトレベルでも "g: "を付けなけれ +ばなりません。 > vim9script var script_local = 'text' g:global = 'value' var Funcref = g:ThatFunction -Since `&opt = value` is now assigning a value to option "opt", ":&" cannot be -used to repeat a `:substitute` command. +現在、`&opt = value` は "opt" オプションに値を設定する目的で使用されているため、 +`:substitute` コマンドをリピートする目的 ":&" を使用することはできません。 -Constants ~ +定数 ~ *vim9-const* *vim9-final* -How constants work varies between languages. Some consider a variable that -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. - -`: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: > +定数の働きは言語によって異なります。別の値を代入できない変数を定数とする場合も +あります。JavaScript がその一例です。また、値そのものを不変にすることもあり、 +たとえばリスト定数の内容を変更することができないとしている場合もあります。 +Vim9ではこのどちらも定義することができます。 + +変数とその値、両方を定数とするには、`:const` を使用します。何らかの複合的な値が +変更できないようにする際に使用します。例: > const myList = [1, 2] myList = [3, 4] # Error! myList[0] = 9 # Error! muList->add(3) # Error! < *:final* -`:final` is used for making only the variable a constant, the value can be -changed. This is well known from Java. Example: > +変数の変更のみを禁止するには、`:final` を使用します。この場合は、中の値自体を +変えることはできます。Java でよく知られるものです。例: > final myList = [1, 2] myList = [3, 4] # Error! myList[0] = 9 # OK muList->add(3) # OK -It is common to write constants as ALL_CAPS, but you don't have to. +一般に、定数はすべて大文字 (例: ALL_CAPS) で書かれますが、必ずしもそうしなくて +も構いません。 -The constant only applies to the value itself, not what it refers to. > +定数宣言は値そのものにのみ適用され、参照先の変数には影響しません。 > final females = ["Mary"] const NAMES = [["John", "Peter"], females] NAMES[0] = ["Jack"] # Error! @@ -290,21 +289,20 @@ The constant only applies to the value itself, not what it refers to. > Names[1][0] = "Emma" # OK, now females[0] == "Emma" < *E1092* -Declaring more than one variable at a time, using the unpack notation, is -currently not supported: > +変数を複数一度に宣言し、同時にアンパックする記法は現在サポートされていません。 +> var [v1, v2] = GetValues() # Error! -That is because the type needs to be inferred from the list item type, which -isn't that easy. +これは、リストの要素から型を推定せねばならず、現在はそれが容易ではないからです。 -Omitting :call and :eval ~ +:call と :eval は不要に ~ -Functions can be called without `:call`: > +関数は `:call` なしで呼ぶことができます。 > writefile(lines, 'file') -Using `:call` is still possible, but this is discouraged. +`:call` は引き続き使用できますが。やめたほうが良いでしょう。 -A method call without `eval` is possible, so long as the start is an -identifier or can't be an Ex command. Examples: > +メソッド呼び出しには `eval` は必要ありません。Exコマンドと同名の識別子ではない +かぎり、直接に識別子から呼び出すことができます。例: > myList->add(123) g:myList->add(123) [1, 2, 3]->Process() @@ -314,21 +312,19 @@ identifier or can't be an Ex command. Examples: > 'foobar'->Process() ('foobar')->Process() -In the rare case there is ambiguity between a function name and an Ex command, -prepend ":" to make clear you want to use the Ex command. For example, there -is both the `:substitute` command and the `substitute()` function. When the -line starts with `substitute(` this will use the function. Prepend a colon to -use the command instead: > +一部の関数と Ex コマンドが紛らわしい場合、コロン (:) を前置することでそれが Ex コマ +ンドであることを明示することができます。たとえば、`:substitute` コマンドと +`substitute()` が該当します。`substitute(` で始まる場合は関数呼び出しですが、 +コロンを前置することでコマンドを代わりに使用することができます。 > :substitute(pattern (replacement ( -Note that while variables need to be defined before they can be used, -functions can be called before being defined. This is required to allow -for cyclic dependencies between functions. It is slightly less efficient, -since the function has to be looked up by name. And a typo in the function -name will only be found when the function is called. +注意: 変数は使用する前に宣言する必要がありますが、関数は宣言するより前に使用で +きる点に注意してください。これは関数の循環参照を可能にするためです。関数を名前 +で探さなければならないので、少し効率が悪いです。また、関数名のタイプミスは、関 +数が呼び出されるときまで見つかりません。 -Omitting function() ~ +function() は不要に ~ A user defined function can be used as a function reference in an expression without `function()`. The argument types and return type will then be checked. From 4163cf8561f0e3ceb3baf68456b54a2daab3b3e7 Mon Sep 17 00:00:00 2001 From: Kyoichiro Yamada Date: Sat, 5 Dec 2020 15:52:24 +0900 Subject: [PATCH 13/43] =?UTF-8?q?=E8=87=AA=E5=8B=95=E8=A1=8C=E7=B6=99?= =?UTF-8?q?=E7=B6=9A=E3=81=AE=E9=80=94=E4=B8=AD=E3=81=BE=E3=81=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- doc/vim9.jax | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/doc/vim9.jax b/doc/vim9.jax index 5542dc05e..c16061c9b 100644 --- a/doc/vim9.jax +++ b/doc/vim9.jax @@ -326,38 +326,39 @@ Vim9ではこのどちらも定義することができます。 function() は不要に ~ -A user defined function can be used as a function reference in an expression -without `function()`. The argument types and return type will then be checked. -The function must already have been defined. > +ユーザー定義の関数は、 `function()` を使わずとも関数リファレンスとして使用する +ことができます。引数の型と戻り値の型がチェックされます。関数はすでに定義されて +いる必要があります。 > var Funcref = MyFunction -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. +`function()` を使って "func" 型のリファレンスを得た場合、その関数は任意の個数 +の引数と任意の戻り値の型を持つものとされます。この場合、関数は後から宣言できま +す。 -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: > +多くの場合、式が次の行に続くことは明らかです。継続業の先頭に行継続のためのバッ +クスラッシュ |line-continuation| を置く必要はありません。たとえば、複数行にま +たぐリストの場合: > var mylist = [ 'one', 'two', ] -And when a dict spans multiple lines: > +辞書の場合: > var mydict = { one: 1, two: 2, } -Function call: > +関数の呼び出し: > var result = Func( arg1, arg2 ) -For binary operators in expressions not in [], {} or () a line break is -possible just before or after the operator. For example: > +角カッコ []、波カッコ {}、または丸カッコの中‘以外で’二項演算子御使用する場合、 +その前後で改行することができます。例: > var text = lead .. middle .. end @@ -368,8 +369,8 @@ possible just before or after the operator. For example: > ? PosFunc(arg) : NegFunc(arg) -For a method call using "->" and a member using a dot, a line break is allowed -before it: > +"->" を使用したメソッド呼び出し、そしてドット (.) を使用したメンバー参照の場合、 +その前に改行を置くことができます。 > var result = GetBuilder() ->BuilderSetWidth(333) ->BuilderSetHeight(777) From ee207d97be6715aa6c36d6c524def3c9c7658658 Mon Sep 17 00:00:00 2001 From: Kyoichiro Yamada Date: Sun, 6 Dec 2020 01:23:54 +0900 Subject: [PATCH 14/43] =?UTF-8?q?=E3=82=B9=E3=83=9A=E3=83=BC=E3=82=B9?= =?UTF-8?q?=E3=81=BE=E3=81=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- doc/vim9.jax | 94 +++++++++++++++++++++++++--------------------------- 1 file changed, 45 insertions(+), 49 deletions(-) diff --git a/doc/vim9.jax b/doc/vim9.jax index c16061c9b..5dfd1ab92 100644 --- a/doc/vim9.jax +++ b/doc/vim9.jax @@ -81,7 +81,7 @@ Vim9 script と `:def` で定義する関数を使用する際に最もよく遭 echo "hello " .. yourName .. ", how are you?" -- 多くの場所に空白が必要になります。 +- 多くの場所にスペースが必要になります。 - 値の代入には `:let` を使用せず、変数の宣言には `:var` を使用します。 > var count = 0 count += 3 @@ -339,7 +339,7 @@ function() は不要に ~ 自動行継続 ~ -多くの場合、式が次の行に続くことは明らかです。継続業の先頭に行継続のためのバッ +多くの場合、式が次の行に続くことは明らかです。継続行の先頭に行継続のためのバッ クスラッシュ |line-continuation| を置く必要はありません。たとえば、複数行にま たぐリストの場合: > var mylist = [ @@ -379,111 +379,107 @@ function() は不要に ~ .member < *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 -"start" and print: > +行頭の演算子と識別できるようにするために、範囲指定の前にはコロンを置きます。 +"start" と "print" をつなげる例: > var result = start + print -Like this: > +これは以下の記述と同じです。 > var result = start + print -This will assign "start" and print a line: > +次のように書くと、 "start" を代入して、1行表示します。 > var result = start :+ print -Note that the colon is not required for the |+cmd| argument: > +|+cmd| の引数にはコロンは不要な点に注意してください。 > edit +6 fname -It is also possible to split a function header over multiple lines, in between -arguments: > +関数の定義部においても、引数の間で改行をおくことができます。 > def MyFunc( text: string, separator = '-' ): string -Notes: -- "enddef" cannot be used at the start of a continuation line, it ends the - current function. -- No line break is allowed in the LHS of an assignment. Specifically when - unpacking a list |:let-unpack|. This is OK: > +注意: +- "enddef" は継続行の先頭に置くことはできません。それは関数の終端を意味します。 +- 代入式の左辺を複数の行に分割できません。特にリストのアンパック |:let-unpack| + を使用する場合は注意が必要です。以下は問題のない例です。 > [var1, var2] = Func() -< This does not work: > +< 以下のように記述することはできません。 > [var1, var2] = Func() -- No line break is allowed in between arguments of an `:echo`, `:execute` and - similar commands. This is OK: > +- `:echo` や `:execute` のようなコマンドの引数は複数の行に分割できません。以下 + は問題のない例です。 > echo [1, 2] [3, 4] -< 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 ~ +波括弧変数の廃止 ~ -|curly-braces-names| cannot be used. +波括弧変数 |curly-braces-names| は使用できません。 -Dictionary literals ~ +辞書リテラル ~ -Traditionally Vim has supported dictionary literals with a {} syntax: > +従来、 Vim は波括弧 {} で辞書リテラルの表記をサポートしてきました。 > 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: > +後に、辞書にシンプルなキーを使用することが非常に一般的であることが明らかになっ +たため、キーをクォーテーションなしで指定できる表記が後方互換的に導入されました。 +> 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 -considering that JavaScript uses this syntax, using the {} form for dictionary -literals was considered a much more useful syntax. In Vim9 script the {} form -uses literal keys: > +しかし、この #{} という表記は他の言語に比べて異色なものです。キーには式よりも +リテラルを使うほうが一般的で、JavaScript が使っている構文を考えると、辞書リテ +ラルに {} の表記を使うほうがずっと便利です。 > let dict = {key: value} -In case an expression needs to be used for the key, square brackets can be -used, just like in JavaScript: > +キーに式を使用する必要がある場合は、JavaScript と同様に角括弧を使用することが +できます。 > let dict = {["key" .. nr]: value} -No :xit, :t, :append, :change or :insert ~ +:xit、:t、:append、:change、:insert の廃止 ~ -These commands are too easily confused with local variable names. -Instead of `:x` or `:xit` you can use `:exit`. -Instead of `:t` you can use `:copy`. +これらのコマンドは容易にローカル変数の名前と混同します。 +`:x` や `:xit` の代わりに `:exit` を使用できます。 +`:t` の代わりに `:copy` を使用できます。 -Comparators ~ +比較 ~ -The 'ignorecase' option is not used for comparators that use strings. +オプション 'ignorecase' は文字列の比較には作用しません。 -White space ~ +スペース ~ -Vim9 script enforces proper use of white space. This is no longer allowed: > +Vim9 script ではスペースの適切な使用を推奨しています。以下のような記述はできま +せん。 > var name=234 # Error! var name= 234 # Error! var name =234 # Error! -There must be white space before and after the "=": > +"=" の前後にはスペースを置く必要があります。 > var name = 234 # OK -White space must also be put before the # that starts a comment after a -command: > +コメント先頭のハッシュ (#) の前にもスペースが必要です。 > var name = 234# Error! var name = 234 # OK -White space is required around most operators. +多くの演算子の前後にはスペースが必要です。 -White space is not allowed: -- Between a function name and the "(": > +スペースをおいてはいけない場合: +- 関数の名前と "(" の間: > call Func (arg) # Error! call Func \ (arg) # Error! From 94e4f5c410607cfa017d3d9130f0e2d46c04e6bb Mon Sep 17 00:00:00 2001 From: Kyoichiro Yamada Date: Sun, 6 Dec 2020 03:10:46 +0900 Subject: [PATCH 15/43] =?UTF-8?q?2=E7=AB=A0=E3=81=BE=E3=81=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- doc/vim9.jax | 69 ++++++++++++++++++++++++++-------------------------- 1 file changed, 35 insertions(+), 34 deletions(-) diff --git a/doc/vim9.jax b/doc/vim9.jax index 5dfd1ab92..70a726f43 100644 --- a/doc/vim9.jax +++ b/doc/vim9.jax @@ -491,10 +491,10 @@ Vim9 script ではスペースの適切な使用を推奨しています。以 \ ) -Conditions and expressions ~ +条件と式 ~ -Conditions and expressions are mostly working like they do in other languages. -Some values are different from legacy Vim script: +条件と式は、他の言語とおよそ同じように扱われます。いくつかの値は古い Vim +script と扱いが異なります。 value legacy Vim script Vim9 script ~ 0 falsy falsy 1 truthy truthy @@ -503,11 +503,11 @@ Some values are different from legacy Vim script: "99" truthy Error! "text" falsy Error! -For the "??" operator and when using "!" then there is no error, every value -is either falsy or truthy. This is mostly like JavaScript, except that an -empty list and dict is falsy: +"??" 演算子か "!" を使用している場合はエラーとなることはなく、すべての値は真ま +たは偽として評価されます。真偽の評価方法は JavaScripot とほぼ同じですが、空のリ +ストと辞書は偽として評価されます。 - type truthy when ~ + 型 真と評価される値 ~ bool v:true or 1 number non-zero float non-zero @@ -522,8 +522,7 @@ empty list and dict is falsy: class when not NULL object when not NULL (TODO: when isTrue() returns v:true) -The boolean operators "||" and "&&" expect the values to be boolean, zero or -one: > +真偽値演算子 "||" と "&&" は、値が真偽値、ゼロまたは1であることを期待します。 > 1 || false == true 0 || 1 == true 0 || false == false @@ -533,36 +532,38 @@ one: > 'yes' && 0 Error! [] || 99 Error! -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 !![] == false !![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' -Simple types are string, float, special and bool. For other types |string()| -can be used. +単純型とは、文字列 (string)、数値 (float)、special {訳注: このspecialが何を指し +ているのか不明} と真偽値 (bool) です。他の型では |string()| が使用できます。 + *false* *true* -In Vim9 script one can use "true" for v:true and "false" for v:false. +Vim9 script では "true" を v:true として、"false" を v:false として使うことが +できます。 -Indexing a string with [idx] or [idx, idx] uses character indexes instead of -byte indexes. Example: > +文字列に対してインデックス [idx] や [idx, idx] を使用すると、バイト単位ではなく +文字単位のインデックスとして扱われます。例: > echo 'bár'[1] -In legacy script this results in the character 0xc3 (an illegal byte), in Vim9 -script this results in the string 'á'. +古い Vim script ではこれは文字 0xc3 (不正な文字) となりますが、Vim9 script では +文字列 'á' が得られます。 -What to watch out for ~ +気をつけるべきこと ~ *vim9-gotchas* -Vim9 was designed to be closer to often used programming languages, but at the -same time tries to support the legacy Vim commands. Some compromises had to -be made. Here is a summary of what might be unexpected. +Vim9 は、一般的なプログラミング言語に近づくように設計されていますが、同時にレガ +シーな Vim コマンドをサポートしようとしています。そのため、いくつかの妥協をしな +ければなりませんでした。ここでは、意外と知られていないことをまとめてみました。 -Ex command ranges need to be prefixed with a colon. > +Exコマンドの範囲指定にはコロンを前置する必要があります。 > -> # legacy Vim: shifts the previous line to the right ->func() # Vim9: method call in continuation line :-> # Vim9: shifts the previous line to the right @@ -574,27 +575,27 @@ Ex command ranges need to be prefixed with a colon. > 'text'->func() # Vim9: method call :'t # legacy Vim: jump to mark m -Some Ex commands can be confused with assignments in Vim9 script: > +いくつかのExコマンドは Vim9 script の代入式と紛らわしくなります。 > 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: > +`:def` で定義した関数はすべてコンパイルされます。古い関数によってベイルアウト +することができ、以下の行はコンパイルされません。 > func Maybe() if !has('feature') return endif use-feature endfunc -Vim9 functions are compiled as a whole: > +Vim9 関数はすべてコンパイルされます。 > def Maybe() if !has('feature') return endif use-feature # May give compilation error enddef -For a workaround, split it in two functions: > +応急的に、2つの関数に分けることができます。 > func Maybe() if has('feature') call MaybyInner() @@ -605,15 +606,15 @@ For a workaround, split it in two functions: > use-feature enddef endif -Or put the unsupported code inside an `if` with a constant expression that -evaluates to false: > +また、偽として評価される定数式の条件をもった `if` の配下でにサポート外のコード +を置くことができます。 > def Maybe() if has('feature') use-feature endif enddef -Note that for unrecognized commands there is no check for "|" and a following -command. This will give an error for missing `endif`: > +認識されていないコマンドを "|" でつなぐと、その後のコマンドは認識されないこと +に注意してください。次のような記述は `endif` がないというエラーになります。 > def Maybe() if has('feature') | use-feature | endif enddef From d2218f113994f7b07703dfb131dd2704c24e562d Mon Sep 17 00:00:00 2001 From: Kyoichiro Yamada Date: Sun, 6 Dec 2020 03:13:43 +0900 Subject: [PATCH 16/43] =?UTF-8?q?=E8=A1=A8=E8=A8=98=E3=82=86=E3=82=8C?= =?UTF-8?q?=E3=82=92=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- doc/vim9.jax | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/doc/vim9.jax b/doc/vim9.jax index 70a726f43..4b5bb4631 100644 --- a/doc/vim9.jax +++ b/doc/vim9.jax @@ -155,9 +155,9 @@ Vim9 関数 ~ 明示しない限りスクリプトローカルになる変数と関数のスコープ ~ *vim9-scopes* Vim9 script でスクリプト直下に `:function` や `:def` を使って関数を定義すると、 -関数はプレフィックス "s:" をつけた際のように、スクリプトローカルで定義されます。 +関数はプリフィックス "s:" をつけた際のように、スクリプトローカルで定義されます。 "s:" を明示することもできます。グローバルスコープの関数や変数を定義するにはプ -レフィックス "g:" をつける必要があります。autoload scriptで定義する場合は、 +リフィックス "g:" をつける必要があります。autoload scriptで定義する場合は、 "name#" をつけます。 > def ThisFunction() # script-local def s:ThisFunction() # script-local @@ -167,15 +167,15 @@ Vim9 script でスクリプト直下に `:function` や `:def` を使って関 `:def` で定義した関数の中で `:function` や `:def` でネストした関数を定義するこ とができ、定義されたブロックローカルのスコープになります。 `:def` で定義した関数の中では、スクリプトのスコープで関数を定義することはでき -ません。プレフィックス "g:" を使ってグローバルスコープの関数を定義することはで +ません。プリフィックス "g:" を使ってグローバルスコープの関数を定義することはで きます。 -関数をプレフィックス "s:" や "g:" をつけずに参照した場合、Vim は関数を次のよう +関数をプリフィックス "s:" や "g:" をつけずに参照した場合、Vim は関数を次のよう に探します: - 同じ関数の中、ブロックスコープの中 - スクリプトスコープの中、インポートされたもの - グローバル関数のリスト -しかし、明瞭にするためにもグローバル関数を参照する際はプレフィックス "g:" を付 +しかし、明瞭にするためにもグローバル関数を参照する際はプリフィックス "g:" を付 けることを推奨します。 いずれの場合でも、関数は使用されるよりも前に定義されていなくてはなりません。 @@ -245,8 +245,8 @@ Vim9 script では `:let` は使用できません。すでに存在する変数 グすることはできません。一方で変数は Ex コマンドをシャドーイングするので、必要 であれば変数の名前を変更してください。 -グローバル変数やユーザ定義関数の前には、スクリプトレベルでも "g: "を付けなけれ -ばなりません。 > +グローバル変数やユーザー定義関数の前には、スクリプトレベルでも "g: "を付けなけ +ればなりません。 > vim9script var script_local = 'text' g:global = 'value' From e228c356aa6ea78568f752fd9f02f32e4e3418ce Mon Sep 17 00:00:00 2001 From: Kyoichiro Yamada Date: Sun, 6 Dec 2020 03:22:31 +0900 Subject: [PATCH 17/43] fix title --- doc/vim9.jax | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/doc/vim9.jax b/doc/vim9.jax index 4b5bb4631..1254a3006 100644 --- a/doc/vim9.jax +++ b/doc/vim9.jax @@ -1,5 +1,4 @@ -*vim9.txt* For Vim version 8.2. Last change: 2020 Nov 03 - +*vim9.txt* For Vim バージョン 8.2. Last change: 2020 Nov 03 VIMリファレンスマニュアル by Bram Moolenaar From 24eef49be4bf01447deee97d4484648bfda9e949 Mon Sep 17 00:00:00 2001 From: Kyoichiro Yamada Date: Sun, 6 Dec 2020 03:27:00 +0900 Subject: [PATCH 18/43] fix typo --- doc/vim9.jax | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/vim9.jax b/doc/vim9.jax index 1254a3006..ba3d16aa9 100644 --- a/doc/vim9.jax +++ b/doc/vim9.jax @@ -605,8 +605,8 @@ Vim9 関数はすべてコンパイルされます。 > use-feature enddef endif -また、偽として評価される定数式の条件をもった `if` の配下でにサポート外のコード -を置くことができます。 > +また、偽として評価される定数式の条件をもった `if` の配下にサポート外のコードを +置くことができます。 > def Maybe() if has('feature') use-feature From 1ecf6d939301308f55d43bfa4c0106b0e04bbf70 Mon Sep 17 00:00:00 2001 From: Kyoichiro Yamada Date: Sat, 12 Dec 2020 10:16:31 +0900 Subject: [PATCH 19/43] fix the points in the review --- doc/vim9.jax | 221 ++++++++++++++++++++++++++------------------------- 1 file changed, 111 insertions(+), 110 deletions(-) diff --git a/doc/vim9.jax b/doc/vim9.jax index ba3d16aa9..d5a6831d7 100644 --- a/doc/vim9.jax +++ b/doc/vim9.jax @@ -1,26 +1,24 @@ -*vim9.txt* For Vim バージョン 8.2. Last change: 2020 Nov 03 +*vim9.txt* For Vim バージョン 8.2. Last change: 2020 Nov 25 VIMリファレンスマニュアル by Bram Moolenaar -注意: この内容は開発中の内容を含んでいます。予告なく破壊的変更が行われるおそれ -があります。 +THIS IS STILL UNDER DEVELOPMENT - ANYTHING CAN BREAK - ANYTHING CAN CHANGE Vim9 script のコマンドと文法 *vim9* ほとんどの文法については |eval.txt| で解説されています。このファイルには Vim9 script の新しい文法と機能について書かれています。 -注意: この内容は開発中の内容を含んでいます。予告なく破壊的変更が行われるおそれ -があります。 +THIS IS STILL UNDER DEVELOPMENT - ANYTHING CAN BREAK - ANYTHING CAN CHANGE 1. Vim9 script とは |vim9-script| 2. 古い Vim script からの変更点 |vim9-differences| -3. 新しい関数 |fast-functions| +3. 新しいスタイルの関数 |fast-functions| 4. 型 |vim9-types| -5. 名前空間と Import / Export |vim9script| +5. 名前空間、Import と Export |vim9script| 6. 将来的な変更: クラス |vim9-classes| 9. 言語設計の背景 |vim9-rationale| @@ -29,26 +27,25 @@ script の新しい文法と機能について書かれています。 1. Vim9 script とは *vim9-script* -注意: この内容は開発中の内容を含んでいます。予告なく破壊的変更が行われるおそれ -があります。 +THIS IS STILL UNDER DEVELOPMENT - ANYTHING CAN BREAK - ANYTHING CAN CHANGE -Vim script は、互換性の維持に気を配りながら成長してきました。そのため、古い -悪しき仕様を変更できないことが多いほか、 Vi との互換性に制約を受けて、より良い -解決策を採用できなくなっています。処理は遅く、実行するたびに各行のパースが行わ -れています。 +Vim script は、互換性の維持に気を配りながら成長してきました。そのため、古い悪 +しき仕様を変更できないことが多いほか、 Vi との互換性に制約を受けて、より良い解 +決策を採用できなくなっています。処理は遅く、実行するたびに各行のパースが行われ +ています。 -Vim9 script の主な目的は劇的な性能の向上です。これは、コマンドをより効率よ -く実行できる命令にコンパイルすることで実現しています。これにより、10倍から100 -倍の実行速度の向上が期待できます。 +Vim9 script の主な目的は劇的な性能の向上です。これは、コマンドをより効率よく実 +行できる命令にコンパイルすることで実現しています。これにより、10倍から100 倍の +実行速度の向上が期待できます。 -第2の目的は、Vim script 特有の文法を見直し、より一般的に使われる JavaScript -や TypeScript、 Java のようなプログラミング言語に近づけることです。 +第2の目的は、Vim script 特有の文法を見直し、より一般的に使われる JavaScript や +TypeScript、 Java のようなプログラミング言語に近づけることです。 パフォーマンスの向上は、下位互換性を犠牲にせずには達成できません。たとえば、関 数の引数を辞書 "a:" から利用できるようにするためには、かなりのオーバーヘッドが -必要になります。そのため、Vim9 script では、この辞書が利用できなくなりまし -た。その他の違いは、エラーの処理方法など、より微細なものです。 +必要になります。そのため、Vim9 script では、この辞書が利用できなくなりました。 +その他の違いは、エラーの処理方法など、より微細なものです。 Vim9 script は以下の場所で使用することができます。 - コマンド `:def` で定義された関数の中 @@ -59,16 +56,15 @@ Vim9 スクリプトファイルの中でコマンド `:function` で関数を は古い Vim script の記法が有効になります。 しかし、これは混乱を招く可能性があるため、推奨できません。 -Vim9 script と 古い Vim script は同時に利用できます。古いスクリプトを書 -き換えなくとも、以前と同様に実行することが可能です。高速化が必要なコードには、 -`:def` で定義する関数を使ったほうが良いかもしれません。 +Vim9 script と 古い Vim script は同時に利用できます。古いスクリプトを書き換え +なくとも、以前と同様に実行することが可能です。高速化が必要なコードには、`:def` +で定義する関数を使ったほうが良いかもしれません。 ============================================================================== 2. 古い Vim script からの変更点 *vim9-differences* -注意: この内容は開発中の内容を含んでいます。予告なく破壊的変更が行われるおそれ -があります。 +THIS IS STILL UNDER DEVELOPMENT - ANYTHING CAN BREAK - ANYTHING CAN CHANGE 概要 ~ @@ -85,8 +81,8 @@ Vim9 script と `:def` で定義する関数を使用する際に最もよく遭 var count = 0 count += 3 - `:final` と `:const` を使用して、定数を宣言できます。 > - final matches = [] # add matches - const names = ['Betty', 'Peter'] # cannot be changed + final matches = [] # matches を追加 + const names = ['Betty', 'Peter'] # 変更できない - `:final` は `:finally` の略語として使用することはできません。 - 変数と関数のスコープは、明示しない限りスクリプトローカルです。 - 関数を引数の型、戻り値の型とともに宣言します。 > @@ -102,14 +98,14 @@ Vim9 script と `:def` で定義する関数を使用する際に最もよく遭 古い Vim script のコメントは、ダブルクォーテーション (") で始めます。Vim9 scriptのコメントはハッシュ (#) で始めます。 > - # declarations - var count = 0 # number of occurrences + # 宣言 + var count = 0 # 出現回数 これは、ダブルクォーテーションは文字列の開始を表す文字でもあるからです。多くの 場所、特に改行を含む式の途中では、文字列とコメントの両方が現れるため、どちらを 意味しているのかわかりにくくなってしまいます。この混乱を避けるために、Vim9 -script では、ハッシュ (#) のみをコメントとして認識します。このコメント形式はシ -ェルスクリプトやPythonのコードと同じです。 +script では、ハッシュ (#) のみをコメントとして認識します。このコメント形式は +シェルスクリプトやPythonのコードと同じです。 Vi においてハッシュ (#) は行番号付きでテキストを表示します。Vim9 script では、 代わりに `:number` を使用します。 > @@ -134,8 +130,8 @@ Vim9 関数 ~ - コンパイルされた関数から呼び出されたり、関数リファレンスとして使用されたとき `:def` には `:function` の "range"、"abort"、"dict" や "closure" といったオプ -ションがありません。`:def` で定義する関数は常にエラー時は処理を中断 (abort) し、 -範囲を受け取らず、辞書関数にすることはできません。 +ションがありません。`:def` で定義する関数は常にエラー時は処理を中断 (abort) +し、範囲を受け取らず、辞書関数にすることはできません。 引数の型と戻り値の型を指定する必要があります。型には "any" を指定することがで き、型のチェックは古い関数と同様に実行時に行われます。 @@ -154,13 +150,13 @@ Vim9 関数 ~ 明示しない限りスクリプトローカルになる変数と関数のスコープ ~ *vim9-scopes* Vim9 script でスクリプト直下に `:function` や `:def` を使って関数を定義すると、 -関数はプリフィックス "s:" をつけた際のように、スクリプトローカルで定義されます。 -"s:" を明示することもできます。グローバルスコープの関数や変数を定義するにはプ -リフィックス "g:" をつける必要があります。autoload scriptで定義する場合は、 -"name#" をつけます。 > - def ThisFunction() # script-local - def s:ThisFunction() # script-local - def g:ThatFunction() # global +関数はプリフィックス "s:" をつけた際のように、スクリプトローカルで定義されま +す。"s:" を明示することもできます。グローバルスコープの関数や変数を定義するに +はプリフィックス "g:" をつける必要があります。autoload scriptで定義する場合 +は、"name#" をつけます。 > + def ThisFunction() # スクリプトローカル + def s:ThisFunction() # スクリプトローカル + def g:ThatFunction() # グローバル def scriptname#function() # autoload `:def` で定義した関数の中で `:function` や `:def` でネストした関数を定義するこ @@ -177,8 +173,8 @@ Vim9 script でスクリプト直下に `:function` や `:def` を使って関 しかし、明瞭にするためにもグローバル関数を参照する際はプリフィックス "g:" を付 けることを推奨します。 -いずれの場合でも、関数は使用されるよりも前に定義されていなくてはなりません。 -使用されるタイミングは、コマンド `:defcompile` によってコンパイルされるとき、ま +いずれの場合でも、関数は使用されるよりも前に定義されていなくてはなりません。使 +用されるタイミングは、コマンド `:defcompile` によってコンパイルされるとき、ま たは関数を呼び出す関数がコンパイルされているとき(戻り値の型を確認するため)で す。 @@ -214,7 +210,7 @@ script でのスクリプトローカル関数は、スクリプトが読み込 else var inner = 0 endif - echo inner # Error! + echo inner # エラー! 参照したい場合には、ブロックよりも前で宣言しなくてはなりません。 > var inner: number @@ -230,14 +226,14 @@ script でのスクリプトローカル関数は、スクリプトが読み込 var temp = 'temp' ... } - echo temp # Error! + echo temp # エラー! 変数を型つきで、かつ初期値なしで宣言した場合、その値はゼロ、False、または空で 初期化されます。 Vim9 script では `:let` は使用できません。すでに存在する変数に題してはコマンド -を使用せずに代入します。グローバル変数、ウィンドウ変数、タブ変数、バッファ変数、 -そして Vim 変数についてもどうようです。 +を使用せずに代入します。グローバル変数、ウィンドウ変数、タブ変数、バッファ変 +数、そして Vim 変数についても同様です。 変数は `:unlet` によって削除することもできます。 変数と関数は、すでに定義された、またはインポートされた変数と関数をシャドーイン @@ -251,8 +247,8 @@ Vim9 script では `:let` は使用できません。すでに存在する変数 g:global = 'value' var Funcref = g:ThatFunction -現在、`&opt = value` は "opt" オプションに値を設定する目的で使用されているため、 -`:substitute` コマンドをリピートする目的 ":&" を使用することはできません。 +現在、`&opt = value` は "opt" オプションに値を設定する目的で使用されているた +め、`:substitute` コマンドをリピートする目的 ":&" を使用することはできません。 定数 ~ @@ -262,17 +258,17 @@ Vim9 script では `:let` は使用できません。すでに存在する変数 たとえばリスト定数の内容を変更することができないとしている場合もあります。 Vim9ではこのどちらも定義することができます。 -変数とその値、両方を定数とするには、`:const` を使用します。何らかの複合的な値が -変更できないようにする際に使用します。例: > +変数とその値、両方を定数とするには、`:const` を使用します。何らかの複合的な値 +が変更できないようにする際に使用します。例: > const myList = [1, 2] - myList = [3, 4] # Error! - myList[0] = 9 # Error! - muList->add(3) # Error! + myList = [3, 4] # エラー! + myList[0] = 9 # エラー! + muList->add(3) # エラー! < *:final* 変数の変更のみを禁止するには、`:final` を使用します。この場合は、中の値自体を 変えることはできます。Java でよく知られるものです。例: > final myList = [1, 2] - myList = [3, 4] # Error! + myList = [3, 4] # エラー! myList[0] = 9 # OK muList->add(3) # OK @@ -282,16 +278,17 @@ Vim9ではこのどちらも定義することができます。 定数宣言は値そのものにのみ適用され、参照先の変数には影響しません。 > final females = ["Mary"] const NAMES = [["John", "Peter"], females] - NAMES[0] = ["Jack"] # Error! - NAMES[0][0] = "Jack" # Error! - NAMES[1] = ["Emma"] # Error! - Names[1][0] = "Emma" # OK, now females[0] == "Emma" + NAMES[0] = ["Jack"] # エラー! + NAMES[0][0] = "Jack" # エラー! + NAMES[1] = ["Emma"] # エラー! + Names[1][0] = "Emma" # OK, females[0] == "Emma" < *E1092* 変数を複数一度に宣言し、同時にアンパックする記法は現在サポートされていません。 > - var [v1, v2] = GetValues() # Error! -これは、リストの要素から型を推定せねばならず、現在はそれが容易ではないからです。 + var [v1, v2] = GetValues() # エラー! +これは、リストの要素から型を推定せねばならず、現在はそれが容易ではないからで +す。 :call と :eval は不要に ~ @@ -311,13 +308,13 @@ Vim9ではこのどちらも定義することができます。 'foobar'->Process() ('foobar')->Process() -一部の関数と Ex コマンドが紛らわしい場合、コロン (:) を前置することでそれが Ex コマ -ンドであることを明示することができます。たとえば、`:substitute` コマンドと +一部の関数と Ex コマンドが紛らわしい場合、コロン (:) を前置することでそれが Ex +コマンドであることを明示することができます。たとえば、`:substitute` コマンドと `substitute()` が該当します。`substitute(` で始まる場合は関数呼び出しですが、 コロンを前置することでコマンドを代わりに使用することができます。 > :substitute(pattern (replacement ( -注意: 変数は使用する前に宣言する必要がありますが、関数は宣言するより前に使用で +Note 変数は使用する前に宣言する必要がありますが、関数は宣言するより前に使用で きる点に注意してください。これは関数の循環参照を可能にするためです。関数を名前 で探さなければならないので、少し効率が悪いです。また、関数名のタイプミスは、関 数が呼び出されるときまで見つかりません。 @@ -356,20 +353,20 @@ function() は不要に ~ arg2 ) -角カッコ []、波カッコ {}、または丸カッコの中‘以外で’二項演算子御使用する場合、 -その前後で改行することができます。例: > +角カッコ []、波カッコ {}、または丸カッコの中‘以外で’二項演算子御使用する場 +合、その前後で改行することができます。例: > var text = lead .. middle .. end var total = start + - end - + end - correction var result = positive ? PosFunc(arg) : NegFunc(arg) -"->" を使用したメソッド呼び出し、そしてドット (.) を使用したメンバー参照の場合、 -その前に改行を置くことができます。 > +"->" を使用したメソッド呼び出し、そしてドット (.) を使用したメンバー参照の場 +合、その前に改行を置くことができます。 > var result = GetBuilder() ->BuilderSetWidth(333) ->BuilderSetHeight(777) @@ -378,8 +375,8 @@ function() は不要に ~ .member < *E1050* -行頭の演算子と識別できるようにするために、範囲指定の前にはコロンを置きます。 -"start" と "print" をつなげる例: > +行頭の演算子と識別できるようにするために、範囲指定の前にはコロンを置きま +す。"start" と "print" をつなげる例: > var result = start + print これは以下の記述と同じです。 > @@ -389,7 +386,7 @@ function() は不要に ~ var result = start :+ print -|+cmd| の引数にはコロンは不要な点に注意してください。 > +Note |+cmd| の引数にはコロンは不要です。 > edit +6 fname 関数の定義部においても、引数の間で改行をおくことができます。 > @@ -398,7 +395,7 @@ function() は不要に ~ separator = '-' ): string -注意: +Notes: - "enddef" は継続行の先頭に置くことはできません。それは関数の終端を意味します。 - 代入式の左辺を複数の行に分割できません。特にリストのアンパック |:let-unpack| を使用する場合は注意が必要です。以下は問題のない例です。 > @@ -436,7 +433,8 @@ function() は不要に ~ let dict = {'key': value} 後に、辞書にシンプルなキーを使用することが非常に一般的であることが明らかになっ -たため、キーをクォーテーションなしで指定できる表記が後方互換的に導入されました。 +たため、キーをクォーテーションなしで指定できる表記が後方互換的に導入されまし +た。 > let dict = #{key: value} @@ -466,22 +464,22 @@ function() は不要に ~ Vim9 script ではスペースの適切な使用を推奨しています。以下のような記述はできま せん。 > - var name=234 # Error! - var name= 234 # Error! - var name =234 # Error! + var name=234 # エラー! + var name= 234 # エラー! + var name =234 # エラー! "=" の前後にはスペースを置く必要があります。 > var name = 234 # OK コメント先頭のハッシュ (#) の前にもスペースが必要です。 > - var name = 234# Error! + var name = 234# エラー! var name = 234 # OK 多くの演算子の前後にはスペースが必要です。 スペースをおいてはいけない場合: - 関数の名前と "(" の間: > - call Func (arg) # Error! + call Func (arg) # エラー! call Func - \ (arg) # Error! + \ (arg) # エラー! call Func(arg) # OK call Func( \ arg) # OK @@ -503,8 +501,8 @@ script と扱いが異なります。 "text" falsy Error! "??" 演算子か "!" を使用している場合はエラーとなることはなく、すべての値は真ま -たは偽として評価されます。真偽の評価方法は JavaScripot とほぼ同じですが、空のリ -ストと辞書は偽として評価されます。 +たは偽として評価されます。真偽の評価方法は JavaScripot とほぼ同じですが、空の +リストと辞書は偽として評価されます。 型 真と評価される値 ~ bool v:true or 1 @@ -521,7 +519,8 @@ script と扱いが異なります。 class when not NULL object when not NULL (TODO: when isTrue() returns v:true) -真偽値演算子 "||" と "&&" は、値が真偽値、ゼロまたは1であることを期待します。 > +真偽値演算子 "||" と "&&" は、値が真偽値、ゼロまたは1であることを期待します。 +> 1 || false == true 0 || 1 == true 0 || false == false @@ -531,53 +530,55 @@ script と扱いが異なります。 'yes' && 0 Error! [] || 99 Error! -"!" を使って論理否定をすると、どのような方に対しても結果は真偽値になります。 -"!!" と二重論理否定をすることで、あらゆる型を真偽値に変換することができます。 > - !'yes' == false +"!" を使って論理否定をすると、どのような方に対しても結果は真偽値になりま +す。"!!" と二重論理否定をすることで、あらゆる型を真偽値に変換することができま +す。 > + !'yes' == false !![] == false - !![1, 2, 3] == true + !![1, 2, 3] == true 文字列の結合に `..` を使用すると、すべての単純型の被演算子は常に文字列に変換さ れます。 > 'hello ' .. 123 == 'hello 123' 'hello ' .. v:true == 'hello v:true' -単純型とは、文字列 (string)、数値 (float)、special {訳注: このspecialが何を指し -ているのか不明} と真偽値 (bool) です。他の型では |string()| が使用できます。 +単純型とは、文字列 (string)、数値 (float)、special {訳注: このspecialが何を指 +しているのか不明} と真偽値 (bool) です。他の型では |string()| が使用できます。 *false* *true* Vim9 script では "true" を v:true として、"false" を v:false として使うことが できます。 -文字列に対してインデックス [idx] や [idx, idx] を使用すると、バイト単位ではなく -文字単位のインデックスとして扱われます。例: > +文字列に対してインデックス [idx] や [idx, idx] を使用すると、バイト単位ではな +く文字単位のインデックスとして扱われます。例: > echo 'bár'[1] -古い Vim script ではこれは文字 0xc3 (不正な文字) となりますが、Vim9 script では -文字列 'á' が得られます。 +古い Vim script ではこれは文字 0xc3 (不正な文字) となりますが、Vim9 script で +は文字列 'á' が得られます。 気をつけるべきこと ~ *vim9-gotchas* -Vim9 は、一般的なプログラミング言語に近づくように設計されていますが、同時にレガ -シーな Vim コマンドをサポートしようとしています。そのため、いくつかの妥協をしな -ければなりませんでした。ここでは、意外と知られていないことをまとめてみました。 +Vim9 は、一般的なプログラミング言語に近づくように設計されていますが、同時にレ +ガシーな Vim コマンドをサポートしようとしています。そのため、いくつかの妥協を +しなければなりませんでした。ここでは、意外と知られていないことをまとめてみまし +た。 Exコマンドの範囲指定にはコロンを前置する必要があります。 > - -> # legacy Vim: shifts the previous line to the right - ->func() # Vim9: method call in continuation line - :-> # Vim9: shifts the previous line to the right + -> # レガシーな Vim: 前の行を右にシフト + ->func() # Vim9: 継続行におけるメソッド呼び出し + :-> # Vim9: 前の行を右にシフト - %s/a/b # legacy Vim: substitute on all lines + %s/a/b # レガシーな Vim: すべての行を置換 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: バックスラッシュなしの行継続 + :%s/a/b # Vim9: すべての行を置換 + 'text'->func() # Vim9: メソッド呼び出し + :'t # レガシーな Vim: マーク t へのジャンプ いくつかのExコマンドは Vim9 script の代入式と紛らわしくなります。 > - g:name = value # assignment - g:pattern:cmd # invalid command - ERROR - :g:pattern:cmd # :global command + g:name = value # 代入 + g:pattern:cmd # 不正なコマンド - エラー + :g:pattern:cmd # :グローバルコマンド `:def` で定義した関数はすべてコンパイルされます。古い関数によってベイルアウト することができ、以下の行はコンパイルされません。 > @@ -592,7 +593,7 @@ Vim9 関数はすべてコンパイルされます。 > if !has('feature') return endif - use-feature # May give compilation error + use-feature # コンパイルエラーが発生する可能性がある enddef 応急的に、2つの関数に分けることができます。 > func Maybe() @@ -612,8 +613,8 @@ Vim9 関数はすべてコンパイルされます。 > use-feature endif enddef -認識されていないコマンドを "|" でつなぐと、その後のコマンドは認識されないこと -に注意してください。次のような記述は `endif` がないというエラーになります。 > +Note 認識されていないコマンドを "|" でつなぐと、その後のコマンドは認識されませ +ん。次のような記述は `endif` がないというエラーになります。 > def Maybe() if has('feature') | use-feature | endif enddef @@ -943,7 +944,7 @@ 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 call searchfor#Stuff() < This goes in .../plugin/anyname.vim. "anyname.vim" can be freely chosen. From f099d63f10cd0c1e35cedaea9fb152c127a2f515 Mon Sep 17 00:00:00 2001 From: Kyoichiro Yamada Date: Fri, 18 Dec 2020 10:00:14 +0900 Subject: [PATCH 20/43] Apply suggestions from code review Co-authored-by: h_east --- doc/vim9.jax | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/doc/vim9.jax b/doc/vim9.jax index d5a6831d7..3c0c2ba4b 100644 --- a/doc/vim9.jax +++ b/doc/vim9.jax @@ -31,21 +31,21 @@ THIS IS STILL UNDER DEVELOPMENT - ANYTHING CAN BREAK - ANYTHING CAN CHANGE Vim script は、互換性の維持に気を配りながら成長してきました。そのため、古い悪 -しき仕様を変更できないことが多いほか、 Vi との互換性に制約を受けて、より良い解 +しき仕様を変更できないことが多いほか、Vi との互換性に制約を受けて、より良い解 決策を採用できなくなっています。処理は遅く、実行するたびに各行のパースが行われ ています。 Vim9 script の主な目的は劇的な性能の向上です。これは、コマンドをより効率よく実 -行できる命令にコンパイルすることで実現しています。これにより、10倍から100 倍の +行できる命令にコンパイルすることで実現しています。これにより、10倍から100倍の 実行速度の向上が期待できます。 第2の目的は、Vim script 特有の文法を見直し、より一般的に使われる JavaScript や -TypeScript、 Java のようなプログラミング言語に近づけることです。 +TypeScript、Java のようなプログラミング言語に近づけることです。 -パフォーマンスの向上は、下位互換性を犠牲にせずには達成できません。たとえば、関 -数の引数を辞書 "a:" から利用できるようにするためには、かなりのオーバーヘッドが -必要になります。そのため、Vim9 script では、この辞書が利用できなくなりました。 -その他の違いは、エラーの処理方法など、より微細なものです。 +パフォーマンスの向上は、100% の下位互換性を犠牲にせずには達成できません。たと +えば、関数の引数を辞書 "a:" から利用できるようにするためには、かなりのオーバー +ヘッドが必要になります。そのため、Vim9 script では、この辞書が利用できなくなり +ました。その他の違いは、エラーの処理方法など、より微細なものです。 Vim9 script は以下の場所で使用することができます。 - コマンド `:def` で定義された関数の中 @@ -53,23 +53,23 @@ Vim9 script は以下の場所で使用することができます。 - 上記のコンテキストで定義された自動コマンド Vim9 スクリプトファイルの中でコマンド `:function` で関数を定義すると、その中で -は古い Vim script の記法が有効になります。 +は旧来の Vim script の記法が有効になります。 しかし、これは混乱を招く可能性があるため、推奨できません。 -Vim9 script と 古い Vim script は同時に利用できます。古いスクリプトを書き換え +Vim9 script と旧来の Vim script は同時に利用できます。古いスクリプトを書き換え なくとも、以前と同様に実行することが可能です。高速化が必要なコードには、`:def` で定義する関数を使ったほうが良いかもしれません。 ============================================================================== -2. 古い Vim script からの変更点 *vim9-differences* +2. 旧来の Vim script からの変更点 *vim9-differences* THIS IS STILL UNDER DEVELOPMENT - ANYTHING CAN BREAK - ANYTHING CAN CHANGE 概要 ~ Vim9 script と `:def` で定義する関数を使用する際に最もよく遭遇する変更点を簡単 -にまとめると以下のとおりです。 +にまとめると以下のとおりです: - コメントはダブルクォーテーション (") ではなく、ハッシュ (#) で始めます。 > echo "hello" # コメント - 行継続文字 (\) はほとんどの場合、必要ありません。 > @@ -226,7 +226,7 @@ script でのスクリプトローカル関数は、スクリプトが読み込 var temp = 'temp' ... } - echo temp # エラー! + echo temp # エラー! 変数を型つきで、かつ初期値なしで宣言した場合、その値はゼロ、False、または空で 初期化されます。 From ac53da5c7c438601becf825ccfb8156aca846a19 Mon Sep 17 00:00:00 2001 From: Kyoichiro Yamada Date: Mon, 21 Dec 2020 23:07:03 +0900 Subject: [PATCH 21/43] fix points from code review --- doc/vim9.jax | 48 ++++++++++++++++++++++++------------------------ 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/doc/vim9.jax b/doc/vim9.jax index 3c0c2ba4b..0583123f9 100644 --- a/doc/vim9.jax +++ b/doc/vim9.jax @@ -15,7 +15,7 @@ THIS IS STILL UNDER DEVELOPMENT - ANYTHING CAN BREAK - ANYTHING CAN CHANGE 1. Vim9 script とは |vim9-script| -2. 古い Vim script からの変更点 |vim9-differences| +2. 旧来の Vim script からの変更点 |vim9-differences| 3. 新しいスタイルの関数 |fast-functions| 4. 型 |vim9-types| 5. 名前空間、Import と Export |vim9script| @@ -70,49 +70,49 @@ 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 -ハッシュ (#) から始まるコメント ~ +# から始まるコメント ~ -古い Vim script のコメントは、ダブルクォーテーション (") で始めます。Vim9 -scriptのコメントはハッシュ (#) で始めます。 > +旧来の Vim script のコメントは、ダブルクォーテーション (") で始めます。Vim9 +scriptのコメントは # で始めます。 > # 宣言 var count = 0 # 出現回数 これは、ダブルクォーテーションは文字列の開始を表す文字でもあるからです。多くの 場所、特に改行を含む式の途中では、文字列とコメントの両方が現れるため、どちらを 意味しているのかわかりにくくなってしまいます。この混乱を避けるために、Vim9 -script では、ハッシュ (#) のみをコメントとして認識します。このコメント形式は -シェルスクリプトやPythonのコードと同じです。 +script では、# のみをコメントとして認識します。このコメント形式はシェルスクリ +プトやPythonのコードと同じです。 -Vi においてハッシュ (#) は行番号付きでテキストを表示します。Vim9 script では、 -代わりに `:number` を使用します。 > +Vi において # は行番号付きでテキストを表示します。Vim9 script では、代わりに +`:number` を使用します。 > 101 number -可読性を向上するために、コマンドとハッシュ (#)、コメント文の間にはスペースをお -いてください。 +可読性を向上するために、コマンドと #、コメント文の間にはスペースをおいてくださ +い。 Vim9 関数 ~ @@ -322,7 +322,7 @@ Note 変数は使用する前に宣言する必要がありますが、関数は function() は不要に ~ -ユーザー定義の関数は、 `function()` を使わずとも関数リファレンスとして使用する +ユーザー定義の関数は、`function()` を使わずとも関数リファレンスとして使用する ことができます。引数の型と戻り値の型がチェックされます。関数はすでに定義されて いる必要があります。 > @@ -382,7 +382,7 @@ function() は不要に ~ これは以下の記述と同じです。 > var result = start + print -次のように書くと、 "start" を代入して、1行表示します。 > +次のように書くと、"start" を代入して、1行表示します。 > var result = start :+ print @@ -429,7 +429,7 @@ Notes: 辞書リテラル ~ -従来、 Vim は波括弧 {} で辞書リテラルの表記をサポートしてきました。 > +従来、Vim は波括弧 {} で辞書リテラルの表記をサポートしてきました。 > let dict = {'key': value} 後に、辞書にシンプルなキーを使用することが非常に一般的であることが明らかになっ @@ -469,7 +469,7 @@ Vim9 script ではスペースの適切な使用を推奨しています。以 var name =234 # エラー! "=" の前後にはスペースを置く必要があります。 > var name = 234 # OK -コメント先頭のハッシュ (#) の前にもスペースが必要です。 > +コメント先頭の # の前にもスペースが必要です。 > var name = 234# エラー! var name = 234 # OK @@ -490,7 +490,7 @@ Vim9 script ではスペースの適切な使用を推奨しています。以 条件と式 ~ -条件と式は、他の言語とおよそ同じように扱われます。いくつかの値は古い Vim +条件と式は、他の言語とおよそ同じように扱われます。いくつかの値は旧来の Vim script と扱いが異なります。 value legacy Vim script Vim9 script ~ 0 falsy falsy @@ -552,8 +552,8 @@ Vim9 script では "true" を v:true として、"false" を v:false として 文字列に対してインデックス [idx] や [idx, idx] を使用すると、バイト単位ではな く文字単位のインデックスとして扱われます。例: > echo 'bár'[1] -古い Vim script ではこれは文字 0xc3 (不正な文字) となりますが、Vim9 script で -は文字列 'á' が得られます。 +旧来の Vim script ではこれは文字 0xc3 (不正な文字) となりますが、Vim9 script +では文字列 'á' が得られます。 気をつけるべきこと ~ From d70bc3da6b1b83caabce2bc5b2ce397a7469b44a Mon Sep 17 00:00:00 2001 From: Kyoichiro Yamada Date: Sun, 17 Jan 2021 08:42:42 +0900 Subject: [PATCH 22/43] fix points from review https://github.com/vim-jp/vimdoc-ja-working/pull/864#discussion_r548315402 --- doc/vim9.jax | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/doc/vim9.jax b/doc/vim9.jax index 0583123f9..ff649da8a 100644 --- a/doc/vim9.jax +++ b/doc/vim9.jax @@ -71,27 +71,27 @@ 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 # から始まるコメント ~ From 655870b4265395edfbf6484c1b815fe588d9c8f5 Mon Sep 17 00:00:00 2001 From: Kyoichiro Yamada Date: Sun, 17 Jan 2021 08:52:51 +0900 Subject: [PATCH 23/43] fix points from review https://github.com/vim-jp/vimdoc-ja-working/pull/864#discussion_r548322781 --- doc/vim9.jax | 94 +++++++++++++++++++++++++--------------------------- 1 file changed, 46 insertions(+), 48 deletions(-) diff --git a/doc/vim9.jax b/doc/vim9.jax index ff649da8a..a4b0333d3 100644 --- a/doc/vim9.jax +++ b/doc/vim9.jax @@ -47,7 +47,7 @@ TypeScript、Java のようなプログラミング言語に近づけること ヘッドが必要になります。そのため、Vim9 script では、この辞書が利用できなくなり ました。その他の違いは、エラーの処理方法など、より微細なものです。 -Vim9 script は以下の場所で使用することができます。 +Vim9 script は以下の場所で使用することができます: - コマンド `:def` で定義された関数の中 - コマンド `vim9script` で始まるスクリプトファイルの中 - 上記のコンテキストで定義された自動コマンド @@ -70,27 +70,27 @@ THIS IS STILL UNDER DEVELOPMENT - ANYTHING CAN BREAK - ANYTHING CAN CHANGE Vim9 script と `:def` で定義する関数を使用する際に最もよく遭遇する変更点を簡単 にまとめると以下のとおりです: -- コメントはダブルクォーテーション (") ではなく、# で始めます。 > +- コメントはダブルクォーテーション (") ではなく、# で始めます: > echo "hello" # コメント -- 行継続文字 (\) はほとんどの場合、必要ありません。 > +- 行継続文字 (\) はほとんどの場合、必要ありません: > echo "hello " .. yourName .. ", how are you?" - 多くの場所にスペースが必要になります。 -- 値の代入には `:let` を使用せず、変数の宣言には `:var` を使用します。 > +- 値の代入には `:let` を使用せず、変数の宣言には `:var` を使用します: > var count = 0 count += 3 -- `:final` と `:const` を使用して、定数を宣言できます。 > +- `:final` と `:const` を使用して、定数を宣言できます: > final matches = [] # matches を追加 const names = ['Betty', 'Peter'] # 変更できない - `:final` は `:finally` の略語として使用することはできません。 - 変数と関数のスコープは、明示しない限りスクリプトローカルです。 -- 関数を引数の型、戻り値の型とともに宣言します。 > +- 関数を引数の型、戻り値の型とともに宣言します: > def CallMe(count: number, message: string): bool -- 関数は `:call` なしで呼び出します。 > +- 関数は `:call` なしで呼び出します: > writefile(['done'], 'file.txt') - `:xit`、`:t`、`:append`、`:change`、`:insert`と波括弧変数は使用できません。 -- コマンドの前に範囲指定を置くときは、コロン (:) を前置しなくてはなりません。 > +- コマンドの前に範囲指定を置くときは、コロン (:) を前置しなくてはなりません: > :%s/this/that @@ -123,7 +123,7 @@ Vim9 関数 ~ 多くのエラーは関数が実行される前に、コンパイルされる段階で検出されます。読みや すく理解しやすいコードを強制するために、構文は厳密に定められています。 -コンパイルは以下のタイミングで実行されます。 +コンパイルは以下のタイミングで実行されます: - 関数が最初に呼び出されるとき - 関数の定義されたスクリプトの中で、コマンド `:defcompile` に出会ったとき - 関数に対してコマンド `:disassemble` が実行されたとき @@ -141,7 +141,7 @@ Vim9 関数 ~ 引数辞書 "a:" と 引数リスト "a:000" はありません。 可変長引数を定義する場合は TypeScript のように、最後の引数として名前とlist型で -定義します。たとえば、数値の可変長引数の例は以下のとおりです。 > +定義します。たとえば、数値の可変長引数の例は以下のとおりです: > def MyFunc(...itemlist: list) for item in itemlist ... @@ -194,7 +194,7 @@ script でのスクリプトローカル関数は、スクリプトが読み込 `:const` で定義する必要があります。このセクションでは、両者を "変数" と呼ぶこ とにします。 -変数はスクリプトローカルや、関数、コードブロックのスコープで定義できます。 > +変数はスクリプトローカルや、関数、コードブロックのスコープで定義できます: > vim9script var script_var = 123 def SomeFunc() @@ -204,7 +204,7 @@ script でのスクリプトローカル関数は、スクリプトが読み込 ... 変数は、定義されたコードブロックか、ネストされた配下のブロックで参照することが -できます。コードブロックが終わったあとの処理から参照することはできません。 > +できます。コードブロックが終わったあとの処理から参照することはできません: > if cond var inner = 5 else @@ -212,7 +212,7 @@ script でのスクリプトローカル関数は、スクリプトが読み込 endif echo inner # エラー! -参照したい場合には、ブロックよりも前で宣言しなくてはなりません。 > +参照したい場合には、ブロックよりも前で宣言しなくてはなりません: > var inner: number if cond inner = 5 @@ -221,7 +221,7 @@ script でのスクリプトローカル関数は、スクリプトが読み込 endif echo inner -意図的に続く処理から変数を隠したいとき、ブロックを使うことができます。 > +意図的に続く処理から変数を隠したいとき、ブロックを使うことができます: > { var temp = 'temp' ... @@ -284,8 +284,7 @@ Vim9ではこのどちらも定義することができます。 Names[1][0] = "Emma" # OK, females[0] == "Emma" < *E1092* -変数を複数一度に宣言し、同時にアンパックする記法は現在サポートされていません。 -> +変数を複数一度に宣言し、同時にアンパックする記法は現在サポートされていません: > var [v1, v2] = GetValues() # エラー! これは、リストの要素から型を推定せねばならず、現在はそれが容易ではないからで す。 @@ -293,7 +292,7 @@ Vim9ではこのどちらも定義することができます。 :call と :eval は不要に ~ -関数は `:call` なしで呼ぶことができます。 > +関数は `:call` なしで呼ぶことができます: > writefile(lines, 'file') `:call` は引き続き使用できますが。やめたほうが良いでしょう。 @@ -311,7 +310,7 @@ Vim9ではこのどちらも定義することができます。 一部の関数と Ex コマンドが紛らわしい場合、コロン (:) を前置することでそれが Ex コマンドであることを明示することができます。たとえば、`:substitute` コマンドと `substitute()` が該当します。`substitute(` で始まる場合は関数呼び出しですが、 -コロンを前置することでコマンドを代わりに使用することができます。 > +コロンを前置することでコマンドを代わりに使用することができます: > :substitute(pattern (replacement ( Note 変数は使用する前に宣言する必要がありますが、関数は宣言するより前に使用で @@ -366,7 +365,7 @@ function() は不要に ~ : NegFunc(arg) "->" を使用したメソッド呼び出し、そしてドット (.) を使用したメンバー参照の場 -合、その前に改行を置くことができます。 > +合、その前に改行を置くことができます: > var result = GetBuilder() ->BuilderSetWidth(333) ->BuilderSetHeight(777) @@ -379,17 +378,17 @@ function() は不要に ~ す。"start" と "print" をつなげる例: > var result = start + print -これは以下の記述と同じです。 > +これは以下の記述と同じです: > var result = start + print -次のように書くと、"start" を代入して、1行表示します。 > +次のように書くと、"start" を代入して、1行表示します: > var result = start :+ print -Note |+cmd| の引数にはコロンは不要です。 > +Note |+cmd| の引数にはコロンは不要です: > edit +6 fname -関数の定義部においても、引数の間で改行をおくことができます。 > +関数の定義部においても、引数の間で改行をおくことができます: > def MyFunc( text: string, separator = '-' @@ -398,26 +397,26 @@ Note |+cmd| の引数にはコロンは不要です。 > Notes: - "enddef" は継続行の先頭に置くことはできません。それは関数の終端を意味します。 - 代入式の左辺を複数の行に分割できません。特にリストのアンパック |:let-unpack| - を使用する場合は注意が必要です。以下は問題のない例です。 > + を使用する場合は注意が必要です。以下は問題のない例です: > [var1, var2] = Func() -< 以下のように記述することはできません。 > +< 以下のように記述することはできません: > [var1, var2] = Func() - `:echo` や `:execute` のようなコマンドの引数は複数の行に分割できません。以下 - は問題のない例です。 > + は問題のない例です: > echo [1, 2] [3, 4] -< 以下のように記述することはできません。 > +< 以下のように記述することはできません: > echo [1, 2] [3, 4] - ラムダ関数の引数、"{" と "->" の間は複数の行に分割できません。以下は問題のな - い例です。 > + い例です: > filter(list, {k, v -> v > 0}) -< 以下のように記述することはできません。 > +< 以下のように記述することはできません: > filter(list, {k, v -> v > 0}) @@ -429,22 +428,21 @@ Notes: 辞書リテラル ~ -従来、Vim は波括弧 {} で辞書リテラルの表記をサポートしてきました。 > +従来、Vim は波括弧 {} で辞書リテラルの表記をサポートしてきました: > let dict = {'key': value} 後に、辞書にシンプルなキーを使用することが非常に一般的であることが明らかになっ たため、キーをクォーテーションなしで指定できる表記が後方互換的に導入されまし -た。 -> +た: > let dict = #{key: value} しかし、この #{} という表記は他の言語に比べて異色なものです。キーには式よりも リテラルを使うほうが一般的で、JavaScript が使っている構文を考えると、辞書リテ -ラルに {} の表記を使うほうがずっと便利です。 > +ラルに {} の表記を使うほうがずっと便利です: > let dict = {key: value} キーに式を使用する必要がある場合は、JavaScript と同様に角括弧を使用することが -できます。 > +できます: > let dict = {["key" .. nr]: value} @@ -463,13 +461,13 @@ Notes: スペース ~ Vim9 script ではスペースの適切な使用を推奨しています。以下のような記述はできま -せん。 > +せん: > var name=234 # エラー! var name= 234 # エラー! var name =234 # エラー! -"=" の前後にはスペースを置く必要があります。 > +"=" の前後にはスペースを置く必要があります: > var name = 234 # OK -コメント先頭の # の前にもスペースが必要です。 > +コメント先頭の # の前にもスペースが必要です: > var name = 234# エラー! var name = 234 # OK @@ -491,7 +489,7 @@ Vim9 script ではスペースの適切な使用を推奨しています。以 条件と式 ~ 条件と式は、他の言語とおよそ同じように扱われます。いくつかの値は旧来の Vim -script と扱いが異なります。 +script と扱いが異なります: value legacy Vim script Vim9 script ~ 0 falsy falsy 1 truthy truthy @@ -502,7 +500,7 @@ script と扱いが異なります。 "??" 演算子か "!" を使用している場合はエラーとなることはなく、すべての値は真ま たは偽として評価されます。真偽の評価方法は JavaScripot とほぼ同じですが、空の -リストと辞書は偽として評価されます。 +リストと辞書は偽として評価されます: 型 真と評価される値 ~ bool v:true or 1 @@ -519,7 +517,7 @@ script と扱いが異なります。 class when not NULL object when not NULL (TODO: when isTrue() returns v:true) -真偽値演算子 "||" と "&&" は、値が真偽値、ゼロまたは1であることを期待します。 +真偽値演算子 "||" と "&&" は、値が真偽値、ゼロまたは1であることを期待します: > 1 || false == true 0 || 1 == true @@ -532,13 +530,13 @@ script と扱いが異なります。 "!" を使って論理否定をすると、どのような方に対しても結果は真偽値になりま す。"!!" と二重論理否定をすることで、あらゆる型を真偽値に変換することができま -す。 > +す: > !'yes' == false !![] == false !![1, 2, 3] == true 文字列の結合に `..` を使用すると、すべての単純型の被演算子は常に文字列に変換さ -れます。 > +れます: > 'hello ' .. 123 == 'hello 123' 'hello ' .. v:true == 'hello v:true' @@ -575,27 +573,27 @@ Exコマンドの範囲指定にはコロンを前置する必要があります 'text'->func() # Vim9: メソッド呼び出し :'t # レガシーな Vim: マーク t へのジャンプ -いくつかのExコマンドは Vim9 script の代入式と紛らわしくなります。 > +いくつかのExコマンドは Vim9 script の代入式と紛らわしくなります: > g:name = value # 代入 g:pattern:cmd # 不正なコマンド - エラー :g:pattern:cmd # :グローバルコマンド `:def` で定義した関数はすべてコンパイルされます。古い関数によってベイルアウト -することができ、以下の行はコンパイルされません。 > +することができ、以下の行はコンパイルされません: > func Maybe() if !has('feature') return endif use-feature endfunc -Vim9 関数はすべてコンパイルされます。 > +Vim9 関数はすべてコンパイルされます: > def Maybe() if !has('feature') return endif use-feature # コンパイルエラーが発生する可能性がある enddef -応急的に、2つの関数に分けることができます。 > +応急的に、2つの関数に分けることができます: > func Maybe() if has('feature') call MaybyInner() @@ -607,14 +605,14 @@ Vim9 関数はすべてコンパイルされます。 > enddef endif また、偽として評価される定数式の条件をもった `if` の配下にサポート外のコードを -置くことができます。 > +置くことができます: > def Maybe() if has('feature') use-feature endif enddef Note 認識されていないコマンドを "|" でつなぐと、その後のコマンドは認識されませ -ん。次のような記述は `endif` がないというエラーになります。 > +ん。次のような記述は `endif` がないというエラーになります: > def Maybe() if has('feature') | use-feature | endif enddef From f5337d2ecd5ace3fffd0ea46af1b3d75a55e3a33 Mon Sep 17 00:00:00 2001 From: Kyoichiro Yamada Date: Sun, 17 Jan 2021 08:54:07 +0900 Subject: [PATCH 24/43] fix points from review https://github.com/vim-jp/vimdoc-ja-working/pull/864#discussion_r548324396 --- doc/vim9.jax | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/doc/vim9.jax b/doc/vim9.jax index a4b0333d3..f8e5f276e 100644 --- a/doc/vim9.jax +++ b/doc/vim9.jax @@ -210,7 +210,7 @@ script でのスクリプトローカル関数は、スクリプトが読み込 else var inner = 0 endif - echo inner # エラー! + echo inner # エラー! 参照したい場合には、ブロックよりも前で宣言しなくてはなりません: > var inner: number @@ -261,14 +261,14 @@ Vim9ではこのどちらも定義することができます。 変数とその値、両方を定数とするには、`:const` を使用します。何らかの複合的な値 が変更できないようにする際に使用します。例: > const myList = [1, 2] - myList = [3, 4] # エラー! - myList[0] = 9 # エラー! - muList->add(3) # エラー! + myList = [3, 4] # エラー! + myList[0] = 9 # エラー! + muList->add(3) # エラー! < *:final* 変数の変更のみを禁止するには、`:final` を使用します。この場合は、中の値自体を 変えることはできます。Java でよく知られるものです。例: > final myList = [1, 2] - myList = [3, 4] # エラー! + myList = [3, 4] # エラー! myList[0] = 9 # OK muList->add(3) # OK @@ -278,14 +278,14 @@ Vim9ではこのどちらも定義することができます。 定数宣言は値そのものにのみ適用され、参照先の変数には影響しません。 > final females = ["Mary"] const NAMES = [["John", "Peter"], females] - NAMES[0] = ["Jack"] # エラー! - NAMES[0][0] = "Jack" # エラー! - NAMES[1] = ["Emma"] # エラー! + NAMES[0] = ["Jack"] # エラー! + NAMES[0][0] = "Jack" # エラー! + NAMES[1] = ["Emma"] # エラー! Names[1][0] = "Emma" # OK, females[0] == "Emma" < *E1092* 変数を複数一度に宣言し、同時にアンパックする記法は現在サポートされていません: > - var [v1, v2] = GetValues() # エラー! + var [v1, v2] = GetValues() # エラー! これは、リストの要素から型を推定せねばならず、現在はそれが容易ではないからで す。 @@ -462,22 +462,22 @@ Notes: Vim9 script ではスペースの適切な使用を推奨しています。以下のような記述はできま せん: > - var name=234 # エラー! - var name= 234 # エラー! - var name =234 # エラー! + var name=234 # エラー! + var name= 234 # エラー! + var name =234 # エラー! "=" の前後にはスペースを置く必要があります: > var name = 234 # OK コメント先頭の # の前にもスペースが必要です: > - var name = 234# エラー! + var name = 234# エラー! var name = 234 # OK 多くの演算子の前後にはスペースが必要です。 スペースをおいてはいけない場合: - 関数の名前と "(" の間: > - call Func (arg) # エラー! + call Func (arg) # エラー! call Func - \ (arg) # エラー! + \ (arg) # エラー! call Func(arg) # OK call Func( \ arg) # OK From a05aa7ff7247655fa195f25016ddc1a2b049d494 Mon Sep 17 00:00:00 2001 From: Kyoichiro Yamada Date: Sun, 17 Jan 2021 08:58:10 +0900 Subject: [PATCH 25/43] fix points from code review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit https://github.com/vim-jp/vimdoc-ja-working/pull/864#discussion_r548325226 ついでに「レガシーな」という訳語を「旧来の」に置換 --- doc/vim9.jax | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/doc/vim9.jax b/doc/vim9.jax index f8e5f276e..91b3d0350 100644 --- a/doc/vim9.jax +++ b/doc/vim9.jax @@ -134,7 +134,7 @@ Vim9 関数 ~ し、範囲を受け取らず、辞書関数にすることはできません。 引数の型と戻り値の型を指定する必要があります。型には "any" を指定することがで -き、型のチェックは古い関数と同様に実行時に行われます。 +き、型のチェックは旧来の関数と同様に実行時に行われます。 引数を参照する際は、他のプログラミング言語と同様、"a:" をつけずに名前だけで指定 することができます。 @@ -556,22 +556,21 @@ Vim9 script では "true" を v:true として、"false" を v:false として 気をつけるべきこと ~ *vim9-gotchas* -Vim9 は、一般的なプログラミング言語に近づくように設計されていますが、同時にレ -ガシーな Vim コマンドをサポートしようとしています。そのため、いくつかの妥協を -しなければなりませんでした。ここでは、意外と知られていないことをまとめてみまし -た。 +Vim9 は、一般的なプログラミング言語に近づくように設計されていますが、同時に旧 +来の Vim コマンドをサポートしようとしています。そのため、いくつかの妥協をしな +ければなりませんでした。ここでは、意外と知られていないことをまとめてみました。 Exコマンドの範囲指定にはコロンを前置する必要があります。 > - -> # レガシーな Vim: 前の行を右にシフト + -> # 旧来の 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 へのジャンプ + :'t # 旧来の Vim: マーク t へのジャンプ いくつかのExコマンドは Vim9 script の代入式と紛らわしくなります: > g:name = value # 代入 From b687fa5ccf56077de34c1466b3a49f3e045e8b4f Mon Sep 17 00:00:00 2001 From: Kyoichiro Yamada Date: Sun, 17 Jan 2021 09:05:23 +0900 Subject: [PATCH 26/43] fix a point from review https://github.com/vim-jp/vimdoc-ja-working/pull/864#discussion_r548333372 --- doc/vim9.jax | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/vim9.jax b/doc/vim9.jax index 91b3d0350..23158ae93 100644 --- a/doc/vim9.jax +++ b/doc/vim9.jax @@ -577,8 +577,8 @@ Exコマンドの範囲指定にはコロンを前置する必要があります g:pattern:cmd # 不正なコマンド - エラー :g:pattern:cmd # :グローバルコマンド -`:def` で定義した関数はすべてコンパイルされます。古い関数によってベイルアウト -することができ、以下の行はコンパイルされません: > +`:def` で定義した関数はすべてコンパイルされます。旧来の関数は途中で脱出するこ +とができ、それ以降の行はパースされません: > func Maybe() if !has('feature') return From 1a7fe23426bd9f09b620c4793a7a8d0c914a5008 Mon Sep 17 00:00:00 2001 From: Kyoichiro Yamada Date: Sun, 17 Jan 2021 09:07:00 +0900 Subject: [PATCH 27/43] fix a point from review https://github.com/vim-jp/vimdoc-ja-working/pull/864#discussion_r553300675 --- doc/vim9.jax | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/doc/vim9.jax b/doc/vim9.jax index 23158ae93..efb5d2b56 100644 --- a/doc/vim9.jax +++ b/doc/vim9.jax @@ -528,9 +528,8 @@ script と扱いが異なります: 'yes' && 0 Error! [] || 99 Error! -"!" を使って論理否定をすると、どのような方に対しても結果は真偽値になりま -す。"!!" と二重論理否定をすることで、あらゆる型を真偽値に変換することができま -す: > +"!" を使って論理否定をすると、どのような型に対しても結果は真偽値になります。 +"!!" と二重論理否定をすることで、あらゆる型を真偽値に変換することができます: > !'yes' == false !![] == false !![1, 2, 3] == true From 4d044e7e25fce2015d5dab274e3bb490d9a4d8d5 Mon Sep 17 00:00:00 2001 From: Kyoichiro Yamada Date: Sun, 17 Jan 2021 17:27:56 +0900 Subject: [PATCH 28/43] fix points from code review https://github.com/vim-jp/vimdoc-ja-working/pull/864#discussion_r559087224 --- doc/vim9.jax | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/vim9.jax b/doc/vim9.jax index efb5d2b56..b6dbf8062 100644 --- a/doc/vim9.jax +++ b/doc/vim9.jax @@ -188,7 +188,7 @@ script でのスクリプトローカル関数は、スクリプトが読み込 れたきり、削除や置き換えはできません。 -:var、:final や :const で定義する変数 ~ +:var、:final や :const で宣言する変数 ~ *vim9-declaration* *:var* ローカル変数は `:var` で定義する必要があります。ローカル定数は `:final` または `:const` で定義する必要があります。このセクションでは、両者を "変数" と呼ぶこ From db3832c6d0e81a6c8e2267b1e0ec9d6d3cd2305a Mon Sep 17 00:00:00 2001 From: Kyoichiro Yamada Date: Sun, 17 Jan 2021 17:33:15 +0900 Subject: [PATCH 29/43] fix points from code review https://github.com/vim-jp/vimdoc-ja-working/pull/864#discussion_r559086796 --- doc/vim9.jax | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/vim9.jax b/doc/vim9.jax index b6dbf8062..bf6c2349f 100644 --- a/doc/vim9.jax +++ b/doc/vim9.jax @@ -70,7 +70,7 @@ THIS IS STILL UNDER DEVELOPMENT - ANYTHING CAN BREAK - ANYTHING CAN CHANGE Vim9 script と `:def` で定義する関数を使用する際に最もよく遭遇する変更点を簡単 にまとめると以下のとおりです: -- コメントはダブルクォーテーション (") ではなく、# で始めます: > +- コメントは " ではなく、# で始めます: > echo "hello" # コメント - 行継続文字 (\) はほとんどの場合、必要ありません: > echo "hello " @@ -96,8 +96,8 @@ Vim9 script と `:def` で定義する関数を使用する際に最もよく遭 # から始まるコメント ~ -旧来の Vim script のコメントは、ダブルクォーテーション (") で始めます。Vim9 -scriptのコメントは # で始めます。 > +旧来の Vim script のコメントは、ダブルクォーテーションで始めます。Vim9 script +のコメントは # で始めます。 > # 宣言 var count = 0 # 出現回数 From f00e753fee0d4740c40b4a56e2f1b226e754f871 Mon Sep 17 00:00:00 2001 From: Kyoichiro Yamada Date: Sun, 17 Jan 2021 17:34:20 +0900 Subject: [PATCH 30/43] fix a point from code review https://github.com/vim-jp/vimdoc-ja-working/pull/864#discussion_r559087327 --- doc/vim9.jax | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/vim9.jax b/doc/vim9.jax index bf6c2349f..e641739a8 100644 --- a/doc/vim9.jax +++ b/doc/vim9.jax @@ -233,7 +233,7 @@ script でのスクリプトローカル関数は、スクリプトが読み込 Vim9 script では `:let` は使用できません。すでに存在する変数に題してはコマンド を使用せずに代入します。グローバル変数、ウィンドウ変数、タブ変数、バッファ変 -数、そして Vim 変数についても同様です。 +数、そして Vim の定義済変数についても同様です。 変数は `:unlet` によって削除することもできます。 変数と関数は、すでに定義された、またはインポートされた変数と関数をシャドーイン From 5b63356a82d38fa9a9380abc84dee43728aa4ae2 Mon Sep 17 00:00:00 2001 From: Kyoichiro Yamada Date: Sun, 17 Jan 2021 17:35:48 +0900 Subject: [PATCH 31/43] fix a point for code review https://github.com/vim-jp/vimdoc-ja-working/pull/864#discussion_r559087634 --- doc/vim9.jax | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/vim9.jax b/doc/vim9.jax index e641739a8..8946e085f 100644 --- a/doc/vim9.jax +++ b/doc/vim9.jax @@ -375,7 +375,7 @@ function() は不要に ~ < *E1050* 行頭の演算子と識別できるようにするために、範囲指定の前にはコロンを置きま -す。"start" と "print" をつなげる例: > +す。"start" と print をつなげる例: > var result = start + print これは以下の記述と同じです: > From dfc22932d0d67e15f4a78e22f3393808c15ef950 Mon Sep 17 00:00:00 2001 From: Kyoichiro Yamada Date: Sun, 17 Jan 2021 17:50:01 +0900 Subject: [PATCH 32/43] more siquential for: https://github.com/vim-jp/vimdoc-ja-working/pull/864#discussion_r559088109 --- doc/vim9.jax | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/vim9.jax b/doc/vim9.jax index 8946e085f..1956f0342 100644 --- a/doc/vim9.jax +++ b/doc/vim9.jax @@ -499,8 +499,8 @@ script と扱いが異なります: "text" falsy Error! "??" 演算子か "!" を使用している場合はエラーとなることはなく、すべての値は真ま -たは偽として評価されます。真偽の評価方法は JavaScripot とほぼ同じですが、空の -リストと辞書は偽として評価されます: +たは偽として評価されます。これは JavaScripot とほぼ同じですが、空のリストと辞 +書は偽として評価されます: 型 真と評価される値 ~ bool v:true or 1 From 83e092bac678c7c8949136ec19c0b4948b7f23fb Mon Sep 17 00:00:00 2001 From: Kyoichiro Yamada Date: Tue, 19 Jan 2021 21:20:54 +0900 Subject: [PATCH 33/43] fix a point for review https://github.com/vim-jp/vimdoc-ja-working/pull/864#discussion_r559086110 --- doc/vim9.jax | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/vim9.jax b/doc/vim9.jax index 1956f0342..c21ee64ae 100644 --- a/doc/vim9.jax +++ b/doc/vim9.jax @@ -15,7 +15,7 @@ THIS IS STILL UNDER DEVELOPMENT - ANYTHING CAN BREAK - ANYTHING CAN CHANGE 1. Vim9 script とは |vim9-script| -2. 旧来の Vim script からの変更点 |vim9-differences| +2. 変更点 |vim9-differences| 3. 新しいスタイルの関数 |fast-functions| 4. 型 |vim9-types| 5. 名前空間、Import と Export |vim9script| From 6fc962a429d6baa8cee5adb570922619898362e3 Mon Sep 17 00:00:00 2001 From: Kyoichiro Yamada Date: Tue, 19 Jan 2021 21:22:55 +0900 Subject: [PATCH 34/43] fix a point from review https://github.com/vim-jp/vimdoc-ja-working/pull/864#discussion_r559086312 --- doc/vim9.jax | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/vim9.jax b/doc/vim9.jax index c21ee64ae..11e9a48f7 100644 --- a/doc/vim9.jax +++ b/doc/vim9.jax @@ -39,7 +39,7 @@ Vim9 script の主な目的は劇的な性能の向上です。これは、コ 行できる命令にコンパイルすることで実現しています。これにより、10倍から100倍の 実行速度の向上が期待できます。 -第2の目的は、Vim script 特有の文法を見直し、より一般的に使われる JavaScript や +第2の目的は、Vim script 特有の文法を回避し、より一般的に使われる JavaScript や TypeScript、Java のようなプログラミング言語に近づけることです。 パフォーマンスの向上は、100% の下位互換性を犠牲にせずには達成できません。たと From 90fcafb7707b902ee6e0b7b65aa10f393786ef5f Mon Sep 17 00:00:00 2001 From: Kyoichiro Yamada Date: Tue, 19 Jan 2021 21:34:33 +0900 Subject: [PATCH 35/43] fix a point from review https://github.com/vim-jp/vimdoc-ja-working/pull/864#discussion_r559086594 --- doc/vim9.jax | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/vim9.jax b/doc/vim9.jax index 11e9a48f7..90da7a9bf 100644 --- a/doc/vim9.jax +++ b/doc/vim9.jax @@ -68,8 +68,8 @@ THIS IS STILL UNDER DEVELOPMENT - ANYTHING CAN BREAK - ANYTHING CAN CHANGE 概要 ~ -Vim9 script と `:def` で定義する関数を使用する際に最もよく遭遇する変更点を簡単 -にまとめると以下のとおりです: +Vim9 script と `:def` で定義する関数を使用する際に最もよく遭遇する変更点の概要 +をまとめると以下のとおりです: - コメントは " ではなく、# で始めます: > echo "hello" # コメント - 行継続文字 (\) はほとんどの場合、必要ありません: > From 8b7ba3f19eb049baf328dfe5eb4a502c53bf2e6f Mon Sep 17 00:00:00 2001 From: Kyoichiro Yamada Date: Tue, 19 Jan 2021 21:40:24 +0900 Subject: [PATCH 36/43] fix a point from review https://github.com/vim-jp/vimdoc-ja-working/pull/864#discussion_r559088109 --- doc/vim9.jax | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/vim9.jax b/doc/vim9.jax index 90da7a9bf..a7cd16a31 100644 --- a/doc/vim9.jax +++ b/doc/vim9.jax @@ -498,9 +498,9 @@ script と扱いが異なります: "99" truthy Error! "text" falsy Error! -"??" 演算子か "!" を使用している場合はエラーとなることはなく、すべての値は真ま -たは偽として評価されます。これは JavaScripot とほぼ同じですが、空のリストと辞 -書は偽として評価されます: +"??" 演算子か "!" を使用している場合はエラーとなることはなく、すべての値は +falsy か truthy として評価されます。これは JavaScripot とほぼ同じですが、空の +リストと辞書は falsy として評価されます: 型 真と評価される値 ~ bool v:true or 1 From 119c4e79c91a425b349407270c3e038e963a3e15 Mon Sep 17 00:00:00 2001 From: Kyoichiro Yamada Date: Tue, 19 Jan 2021 21:41:25 +0900 Subject: [PATCH 37/43] fix a point from review https://github.com/vim-jp/vimdoc-ja-working/pull/864#discussion_r559086927 --- doc/vim9.jax | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/vim9.jax b/doc/vim9.jax index a7cd16a31..055670f65 100644 --- a/doc/vim9.jax +++ b/doc/vim9.jax @@ -89,7 +89,7 @@ Vim9 script と `:def` で定義する関数を使用する際に最もよく遭 def CallMe(count: number, message: string): bool - 関数は `:call` なしで呼び出します: > writefile(['done'], 'file.txt') -- `:xit`、`:t`、`:append`、`:change`、`:insert`と波括弧変数は使用できません。 +- `:xit`、`:t`、`:append`、`:change`、`:insert` と波括弧変数は使用できません。 - コマンドの前に範囲指定を置くときは、コロン (:) を前置しなくてはなりません: > :%s/this/that From a576b448e3a06c0282d04d699df00eb9cab0415f Mon Sep 17 00:00:00 2001 From: Kyoichiro Yamada Date: Tue, 19 Jan 2021 21:43:39 +0900 Subject: [PATCH 38/43] translate "Special" word ref: https://github.com/vim-jp/vimdoc-ja-working/pull/864#discussion_r559424288 --- doc/vim9.jax | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/vim9.jax b/doc/vim9.jax index 055670f65..248149a71 100644 --- a/doc/vim9.jax +++ b/doc/vim9.jax @@ -539,8 +539,8 @@ falsy か truthy として評価されます。これは JavaScripot とほぼ 'hello ' .. 123 == 'hello 123' 'hello ' .. v:true == 'hello v:true' -単純型とは、文字列 (string)、数値 (float)、special {訳注: このspecialが何を指 -しているのか不明} と真偽値 (bool) です。他の型では |string()| が使用できます。 +単純型とは、文字列 (string)、数値 (float)、特殊値 (special) と真偽値 (bool) で +す。他の型では |string()| が使用できます。 *false* *true* Vim9 script では "true" を v:true として、"false" を v:false として使うことが From 9334ab4f4128bc50f8ee2ead423b0c630922a96b Mon Sep 17 00:00:00 2001 From: Kyoichiro Yamada Date: Tue, 19 Jan 2021 21:50:04 +0900 Subject: [PATCH 39/43] fix a point from review https://github.com/vim-jp/vimdoc-ja-working/pull/864#discussion_r559086516 --- doc/vim9.jax | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/doc/vim9.jax b/doc/vim9.jax index 248149a71..41c80384d 100644 --- a/doc/vim9.jax +++ b/doc/vim9.jax @@ -42,10 +42,10 @@ Vim9 script の主な目的は劇的な性能の向上です。これは、コ 第2の目的は、Vim script 特有の文法を回避し、より一般的に使われる JavaScript や TypeScript、Java のようなプログラミング言語に近づけることです。 -パフォーマンスの向上は、100% の下位互換性を犠牲にせずには達成できません。たと -えば、関数の引数を辞書 "a:" から利用できるようにするためには、かなりのオーバー -ヘッドが必要になります。そのため、Vim9 script では、この辞書が利用できなくなり -ました。その他の違いは、エラーの処理方法など、より微細なものです。 +パフォーマンスの向上は、100% の下位互換性を捨てることによってのみ達成しうるも +のです。たとえば、関数の引数を辞書 "a:" から利用できるようにするためには、かな +りのオーバーヘッドが必要になります。そのため、Vim9 script では、この辞書が利用 +できなくなりました。その他の違いは、エラーの処理方法など、より微細なものです。 Vim9 script は以下の場所で使用することができます: - コマンド `:def` で定義された関数の中 From dabe7111ccf9b3cc686e90930253e05ae8cd7e41 Mon Sep 17 00:00:00 2001 From: Kyoichiro Yamada Date: Wed, 20 Jan 2021 11:21:05 +0900 Subject: [PATCH 40/43] Apply suggestions from code review Co-authored-by: Tsuyoshi CHO --- doc/vim9.jax | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/doc/vim9.jax b/doc/vim9.jax index 41c80384d..a007c8067 100644 --- a/doc/vim9.jax +++ b/doc/vim9.jax @@ -493,13 +493,13 @@ script と扱いが異なります: value legacy Vim script Vim9 script ~ 0 falsy falsy 1 truthy truthy - 99 truthy Error! - "0" falsy Error! - "99" truthy Error! - "text" falsy Error! + 99 truthy エラー! + "0" falsy エラー! + "99" truthy エラー! + "text" falsy エラー! "??" 演算子か "!" を使用している場合はエラーとなることはなく、すべての値は -falsy か truthy として評価されます。これは JavaScripot とほぼ同じですが、空の +falsy か truthy として評価されます。これは JavaScript とほぼ同じですが、空の リストと辞書は falsy として評価されます: 型 真と評価される値 ~ @@ -517,7 +517,7 @@ falsy か truthy として評価されます。これは JavaScripot とほぼ class when not NULL object when not NULL (TODO: when isTrue() returns v:true) -真偽値演算子 "||" と "&&" は、値が真偽値、ゼロまたは1であることを期待します: +真偽値演算子 "||" と "&&" は、値が真偽値、0または1であることを期待します: > 1 || false == true 0 || 1 == true From 8cf4e07157526d0da277fcb2fa85e7babcf1324b Mon Sep 17 00:00:00 2001 From: Kyoichiro Yamada Date: Thu, 21 Jan 2021 02:13:05 +0900 Subject: [PATCH 41/43] fix a point from review https://github.com/vim-jp/vimdoc-ja-working/pull/864#discussion_r560591889 --- doc/vim9.jax | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/vim9.jax b/doc/vim9.jax index a007c8067..b9b526f56 100644 --- a/doc/vim9.jax +++ b/doc/vim9.jax @@ -524,9 +524,9 @@ falsy か truthy として評価されます。これは JavaScript とほぼ同 0 || false == false 1 && true == true 0 && 1 == false - 8 || 0 Error! - 'yes' && 0 Error! - [] || 99 Error! + 8 || 0 エラー! + 'yes' && 0 エラー! + [] || 99 エラー! "!" を使って論理否定をすると、どのような型に対しても結果は真偽値になります。 "!!" と二重論理否定をすることで、あらゆる型を真偽値に変換することができます: > From 349ee2e5bb30d89756b108063a8fe8f11d122c62 Mon Sep 17 00:00:00 2001 From: Kyoichiro Yamada Date: Thu, 21 Jan 2021 02:33:34 +0900 Subject: [PATCH 42/43] wip: fix a point of review https://github.com/vim-jp/vimdoc-ja-working/pull/864#discussion_r560592056 --- doc/vim9.jax | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/doc/vim9.jax b/doc/vim9.jax index b9b526f56..a39911323 100644 --- a/doc/vim9.jax +++ b/doc/vim9.jax @@ -503,19 +503,19 @@ falsy か truthy として評価されます。これは JavaScript とほぼ同 リストと辞書は falsy として評価されます: 型 真と評価される値 ~ - bool v:true or 1 - number non-zero - float non-zero - string non-empty - blob non-empty - list non-empty (different from JavaScript) - dictionary non-empty (different from JavaScript) + bool v:true または 1 + number 非0 + float 非0 + string 空文字列以外 + blob 空ブロブ以外 + list 空リスト以外 (JavaScript とは異なります) + dictionary 空辞書以外 (JavaScript とは異なります) func when there is a function name special v:true - job when not NULL - channel when not NULL - class when not NULL - object when not NULL (TODO: when isTrue() returns v:true) + job 非 NULL + channel 非 NULL + class 非 NULL + object 非 NULL (TODO: isTrue() が v:true を返すとき) 真偽値演算子 "||" と "&&" は、値が真偽値、0または1であることを期待します: > From 1486c11c4acd37362f2dae366b9793a7527fd666 Mon Sep 17 00:00:00 2001 From: Kyoichiro Yamada Date: Sat, 23 Jan 2021 10:31:48 +0900 Subject: [PATCH 43/43] Apply suggestions from code review Co-authored-by: h_east --- doc/vim9.jax | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/doc/vim9.jax b/doc/vim9.jax index a39911323..3cbb35093 100644 --- a/doc/vim9.jax +++ b/doc/vim9.jax @@ -147,17 +147,17 @@ Vim9 関数 ~ ... -明示しない限りスクリプトローカルになる変数と関数のスコープ ~ +関数と変数はデフォルトでスクリプトローカル ~ *vim9-scopes* Vim9 script でスクリプト直下に `:function` や `:def` を使って関数を定義すると、 関数はプリフィックス "s:" をつけた際のように、スクリプトローカルで定義されま す。"s:" を明示することもできます。グローバルスコープの関数や変数を定義するに -はプリフィックス "g:" をつける必要があります。autoload scriptで定義する場合 -は、"name#" をつけます。 > +はプリフィックス "g:" をつける必要があります。オートロードスクリプトで定義する +場合は、"name#" をつけます。 > def ThisFunction() # スクリプトローカル def s:ThisFunction() # スクリプトローカル def g:ThatFunction() # グローバル - def scriptname#function() # autoload + def scriptname#function() # オートロード `:def` で定義した関数の中で `:function` や `:def` でネストした関数を定義するこ とができ、定義されたブロックローカルのスコープになります。 @@ -228,7 +228,7 @@ script でのスクリプトローカル関数は、スクリプトが読み込 } echo temp # エラー! -変数を型つきで、かつ初期値なしで宣言した場合、その値はゼロ、False、または空で +変数を型付きで、かつ初期値なしで宣言した場合、その値はゼロ、False、または空で 初期化されます。 Vim9 script では `:let` は使用できません。すでに存在する変数に題してはコマンド @@ -294,10 +294,10 @@ Vim9ではこのどちらも定義することができます。 関数は `:call` なしで呼ぶことができます: > writefile(lines, 'file') -`:call` は引き続き使用できますが。やめたほうが良いでしょう。 +`:call` は引き続き使用できますが、やめたほうが良いでしょう。 メソッド呼び出しには `eval` は必要ありません。Exコマンドと同名の識別子ではない -かぎり、直接に識別子から呼び出すことができます。例: > +限り、直接に識別子から呼び出すことができます。例: > myList->add(123) g:myList->add(123) [1, 2, 3]->Process() @@ -490,7 +490,7 @@ Vim9 script ではスペースの適切な使用を推奨しています。以 条件と式は、他の言語とおよそ同じように扱われます。いくつかの値は旧来の Vim script と扱いが異なります: - value legacy Vim script Vim9 script ~ + 値 旧来の Vim script Vim9 script ~ 0 falsy falsy 1 truthy truthy 99 truthy エラー!