To: vim_dev@googlegroups.com Subject: Patch 9.0.1001 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 9.0.1001 Problem: Classes are not documented or implemented yet. Solution: Make the first steps at documenting Vim9 objects, classes and interfaces. Make initial choices for the syntax. Add a skeleton implementation. Add "public" and "this" in the command table. Files: Filelist, runtime/doc/vim9.txt, runtime/doc/vim9class.txt, runtime/doc/Makefile, src/ex_cmds.h, src/ex_cmdidxs.h, src/vim9class.c, src/proto/vim9class.pro, src/proto.h, src/ex_docmd.c, src/errors.h, src/Makefile, src/Make_ami.mak, src/Make_mvc.mak, src/Make_vms.mms, src/Make_cyg_ming.mak, src/testdir/test_cmdmods.vim *** ../vim-9.0.1000/Filelist 2022-12-02 13:20:16.464758265 +0000 --- Filelist 2022-12-04 14:38:16.840614369 +0000 *************** *** 163,168 **** --- 163,169 ---- src/version.h \ src/vim.h \ src/vim9.h \ + src/vim9class.c \ src/vim9cmds.c \ src/vim9compile.c \ src/vim9execute.c \ *************** *** 327,332 **** --- 328,334 ---- src/proto/usercmd.pro \ src/proto/userfunc.pro \ src/proto/version.pro \ + src/proto/vim9class.pro \ src/proto/vim9cmds.pro \ src/proto/vim9compile.pro \ src/proto/vim9execute.pro \ *** ../vim-9.0.1000/runtime/doc/vim9.txt 2022-10-11 21:51:09.962103580 +0100 --- runtime/doc/vim9.txt 2022-12-03 21:49:26.591652433 +0000 *************** *** 16,22 **** 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| --- 16,22 ---- 3. New style functions |fast-functions| 4. Types |vim9-types| 5. Namespace, Import and Export |vim9script| ! 6. Classes and interfaces |vim9-classes| 9. Rationale |vim9-rationale| *************** *** 1940,2003 **** ============================================================================== ! 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`, the whole class must be in one file ! - Class names are always CamelCase (to avoid a name clash with builtin types) ! - A single constructor called "constructor" ! - Single inheritance with `class ThisClass extends BaseClass` ! - `abstract class` (class with incomplete implementation) ! - `interface` / `endinterface` (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 with a slightly different syntax. ! ! 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) ! - Mixins ! - For testing: Mock mechanism ! ! 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. ! ! Some commands have already been reserved: ! *:class* ! *:endclass* ! *:abstract* ! *:enum* ! *:endenum* ! *:interface* ! *:endinterface* ! *:static* ! *:type* ! ! Some examples: > ! ! abstract class Person ! static const prefix = 'xxx' ! var name: string ! ! def constructor(name: string) ! this.name = name ! enddef ! ! def display(): void ! echo name ! enddef - abstract def find(string): Person - endclass ============================================================================== --- 1940,1956 ---- ============================================================================== ! 6. Classes and interfaces *vim9-classes* ! In legacy script a Dictionary could be used as a kind-of object, by adding ! members that are functions. However, this is quite inefficient and requires ! the writer to do the work of making sure all the objects have the right ! members. See |Dictionary-function|. ! ! In |Vim9| script you can have classes, objects and interfaces like in most ! popular object-oriented programming languages. Since this is a lot of ! functionality it is located in a separate help file: |vim9class.txt|. ============================================================================== *************** *** 2284,2301 **** 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. - - It would be good to support real classes, and this is planned for a later - version. The support is a "minimal common functionality" of class support in - most languages. It will work much like Java, which is the most popular - programming language. - - vim:tw=78:ts=8:noet:ft=help:norl: --- 2237,2241 ---- *** ../vim-9.0.1000/runtime/doc/vim9class.txt 2022-12-04 20:08:19.507852383 +0000 --- runtime/doc/vim9class.txt 2022-12-04 20:02:27.131855358 +0000 *************** *** 0 **** --- 1,697 ---- + *vim9class.txt* For Vim version 9.0. Last change: 2022 Dec 04 + + + VIM REFERENCE MANUAL by Bram Moolenaar + + + NOTE - This is under development, anything can still change! - NOTE + + + Vim9 classes, objects, interfaces, types and enums. + + 1. Overview |Vim9-class-overview| + 2. A simple class |Vim9-simple-class| + 3. Using an abstract class |Vim9-abstract-class| + 4. Using an interface |Vim9-using-interface| + 5. More class details |Vim9-class| + 6. Type definition |Vim9-type| + 7. Enum |Vim9-enum| + + 9. Rationale + 10. To be done later + + ============================================================================== + + 1. Overview *Vim9-class-overview* + + The fancy term is "object-oriented programming". You can find lots of study + material about this subject. Here we document what |Vim9| script provides, + assuming you know the basics already. Added are helpful hints about how + to use this functionality effectively. + + The basic item is an object: + - An object stores state. It contains one or more variables that can each + have a value. + - An object usually provides functions that manipulate its state. These + functions are invoked "on the object", which is what sets it apart from the + traditional separation of data and code that manipulates the data. + - An object has a well defined interface, with typed member variables and + member functions. + - Objects are created by a class and all objects have the same interface. + This never changes, it is not dynamic. + + An object can only be created by a class. A class provides: + - A new() method, the constructor, which returns an object for the class. + This method is invoked on the class name: MyClass.new(). + - State shared by all objects of the class: class variables and constants. + - A hierarchy of classes, with super-classes and sub-classes, inheritance. + + An interface is used to specify properties of an object: + - An object can declare several interfaces that it implements. + - Different objects implementing the same interface can be used the same way. + + The class hierarchy allows for single inheritance. Otherwise interfaces are + to be used where needed. + + + Class modeling ~ + + You can model classes any way you like. Keep in mind what you are building, + don't try to model the real world. This can be confusing, especially because + teachers use real-world objects to explain class relations and you might think + your model should therefore reflect the real world. It doesn't! The model + should match your purpose. + + You will soon find that composition is often better than inheritance. Don't + waste time trying to find the optimal class model. Or waste time discussing + whether a square is a rectangle or that a rectangle is a square. It doesn't + matter. + + + ============================================================================== + + 2. A simple class *Vim9-simple-class* + + Let's start with a simple example: a class that stores a text position: > + + class TextPosition + this.lnum: number + this.col: number + + def new(lnum: number, col: number) + this.lnum = lnum + this.col = col + enddef + + def SetLnum(lnum: number) + this.lnum = lnum + enddef + + def SetCol(col: number) + this.col = col + enddef + + def SetPosition(lnum: number, col: number) + this.lnum = lnum + this.col = col + enddef + endclass + + You can create an object from this class with the new() method: > + + var pos = TextPosition.new(1, 1) + + The object members "lnum" and "col" can be accessed directly: > + + echo $'The text position is ({pos.lnum}, {pos.col})' + + If you have been using other object-oriented languages you will notice that + in Vim the object members are consistently referred to with the "this." + prefix. This is different from languages like Java and TypeScript. This + naming convention makes the object members easy to spot. Also, when a + variable does not have the "this." prefix you know it is not an object member. + + + Member write access ~ + + Now try to change an object member directly: > + + pos.lnum = 9 + + This will give you an error! That is because by default object members can be + read but not set. That's why the class provides a method for it: > + + pos.SetLnum(9) + + Allowing to read but not set an object member is the most common and safest + way. Most often there is no problem using a value, while setting a value may + have side effects that need to be taken care of. In this case, the SetLnum() + method could check if the line number is valid and either give an error or use + the closest valid value. + + If you don't care about side effects and want to allow the object member to be + changed at any time, you can make it public: > + + public this.lnum: number + public this.col number + + Now you don't need the SetLnum(), SetCol() and SetPosition() methods, setting + "pos.lnum" directly above will no longer give an error. + + + Private members ~ + + On the other hand, if you do not want the object members to be read directly, + you can make them private. This is done by prefixing an underscore to the + name: > + + this._lnum: number + this._col number + + Now you need to provide methods to get the value of the private members. + These are commonly call getters. We recommend using a name that starts with + "Get": > + + def GetLnum(): number + return this._lnum + enddef + + def GetCol() number + return this._col + enddef + + This example isn't very useful, the members might as well have been public. + It does become useful if you check the value. For example, restrict the line + number to the total number of lines: > + + def GetLnum(): number + if this._lnum > this._lineCount + return this._lineCount + endif + return this._lnum + enddef + + + Simplifying the new() method ~ + + Many constructors take values for the object members. Thus you very often see + this pattern: > + + this.lnum: number + this.col: number + + def new(lnum: number, col: number) + this.lnum = lnum + this.col = col + enddef + + Not only is this text you need to write, it also has the type of each member + twice. Since this is so common a shorter way to write new() is provided: > + + def new(this.lnum, this.col) + enddef + + The semantics are easy to understand: Providing the object member name, + including "this.", as the argument to new() means the value provided in the + new() call is assigned to that object member. This mechanism is coming from + the Dart language. + + The sequence of constructing a new object is: + 1. Memory is allocated and cleared. All values are zero/false/empty. + 2. For each declared member that has an initializer, the expression is + evaluated and assigned to the member. This happens in the sequence the + members are declared in the class. + 3. Arguments in the new() method in the "this.name" form are assigned. + 4. The body of the new() method is executed. + + TODO: for a sub-class the constructor of the parent class will be invoked + somewhere. + + + ============================================================================== + + 3. Using an abstract class *Vim9-abstract-class* + + An abstract class forms the base for at least one sub-class. In the class + model one often finds that a few classes have the same properties that can be + shared, but a class with those properties does not have enough state to create + an object from. A sub-class must extend the abstract class and add the + missing state and/or methods before it can be used to create objects for. + + An abstract class does not have a new() method. + + For example, a Shape class could store a color and thickness. You cannot + create a Shape object, it is missing the information about what kind of shape + it is. The Shape class functions as the base for a Square and a Triangle + class, for which objects can be created. Example: > + + abstract class Shape + this.color = Color.Black + this.thickness = 10 + endclass + + class Square extends Shape + this.size: number + + def new(this.size) + enddef + endclass + + class Triangle extends Shape + this.base: number + this.height: number + + def new(this.base, this.height) + enddef + endclass + < + *class-member* *:static* + Class members are declared with "static". They are used by the name without a + prefix: > + + class OtherThing + this.size: number + static totalSize: number + + def new(this.size) + totalSize += this.size + enddef + endclass + < + *class-method* + Class methods are also declared with "static". They have no access to object + members, they cannot use the "this" keyword. > + + class OtherThing + this.size: number + static totalSize: number + + " Clear the total size and return the value it had before. + static def ClearTotalSize(): number + var prev = totalSize + totalSize = 0 + return prev + enddef + endclass + + + ============================================================================== + + 4. Using an interface *Vim9-using-interface* + + The example above with Shape, Square and Triangle can be made more useful if + we add a method to compute the surface of the object. For that we create the + interface called HasSurface, which specifies one method Surface() that returns + a number. This example extends the one above: > + + abstract class Shape + this.color = Color.Black + this.thickness = 10 + endclass + + interface HasSurface + def Surface(): number + endinterface + + class Square extends Shape implements HasSurface + this.size: number + + def new(this.size) + enddef + + def Surface(): number + return this.size * this.size + enddef + endclass + + class Triangle extends Shape implements HasSurface + this.base: number + this.height: number + + def new(this.base, this.height) + enddef + + def Surface(): number + return this.base * this.height / 2 + enddef + endclass + + The interface name can be used as a type: > + + var shapes: list = [ + Square.new(12), + Triangle.new(8, 15), + ] + for shape in shapes + echo $'the surface is {shape.Surface()}' + endfor + + + ============================================================================== + + 5. More class details *Vim9-class* + + Defining a class ~ + *:class* *:endclass* *:abstract* + A class is defined between `:class` and `:endclass`. The whole class is + defined in one script file. It is not possible to add to a class later. + + It is possible to define more than one class in a script file. Although it + usually is better to export only one main class. It can be useful to define + types, enums and helper classes though. + + The `:abstract` keyword may be prefixed and `:export` may be used. That gives + these variants: > + + class ClassName + endclass + + export class ClassName + endclass + + abstract class ClassName + endclass + + export abstract class ClassName + endclass + < + *E1314* + The class name should be CamelCased. It must start with an uppercase letter. + That avoids clashing with builtin types. + + After the class name these optional items can be used. Each can appear only + once. They can appear in any order, although this order is recommended: > + extends ClassName + implements InterfaceName, OtherInterface + specifies SomeInterface + < *extends* + A class can extend one other class. + *implements* + A class can implement one or more interfaces. + *specifies* + A class can declare it's interface, the object members and methods, with a + named interface. This avoids the need for separately specifying the + interface, which is often done an many languages, especially Java. + + + Defining an interface ~ + *:interface* *:endinterface* + An interface is defined between `:interface` and `:endinterface`. It may be + prefixed with `:export`: > + + interface InterfaceName + endinterface + + export interface InterfaceName + endinterface + + An interface can declare object members, just like in a class but without any + initializer. + + An interface can declare methods with `:def`, including the arguments and + return type, but without the body and without `:enddef`. Example: > + + interface HasSurface + this.size: number + def Surface(): number + endinterface + + The "Has" prefix can be used to make it easier to guess this is an interface + name, with a hint about what it provides. + + + Default constructor ~ + + In case you define a class without a new() method, one will be automatically + defined. This default constructor will have arguments for all the object + members, in the order they were specified. Thus if your class looks like: > + + class AutoNew + this.name: string + this.age: number + this.gender: Gender + endclass + + Then The default constructor will be: > + + def new(this.name, this.age, this.gender) + enddef + + All object members will be used, also private access ones. + + + Multiple constructors ~ + + Normally a class has just one new() constructor. In case you find that the + constructor is often called with the same arguments you may want to simplify + your code by putting those arguments into a second constructor method. For + example, if you tend to use the color black a lot: > + + def new(this.garment, this.color, this.size) + enddef + ... + var pants = new(Garment.pants, Color.black, "XL") + var shirt = new(Garment.shirt, Color.black, "XL") + var shoes = new(Garment.shoes, Color.black, "45") + + Instead of repeating the color every time you can add a constructor that + includes it: > + + def newBlack(this.garment, this.size) + this.color = Color.black + enddef + ... + var pants = newBlack(Garment.pants, "XL") + var shirt = newBlack(Garment.shirt, "XL") + var shoes = newBlack(Garment.shoes, "9.5") + + Note that the method name must start with "new". If there is no method called + "new()" then the default constructor is added, even though there are other + constructor methods. + + + ============================================================================== + + 6. Type definition *Vim9-type* *:type* + + A type definition is giving a name to a type specification. For Example: > + + :type ListOfStrings list + + TODO: more explanation + + + ============================================================================== + + 7. Enum *Vim9-enum* *:enum* *:endenum* + + An enum is a type that can have one of a list of values. Example: > + + :enum Color + White + Red + Green + Blue + Black + :endenum + + TODO: more explanation + + + ============================================================================== + + 9. Rationale + + Most of the choices for |Vim9| classes come from popular and recently + developed languages, such as Java, TypeScript and Dart. The syntax has been + made to fit with the way Vim script works, such as using `endclass` instead of + using curly braces around the whole class. + + Some common constructs of object-oriented languages were chosen very long ago + when this kind of programming was still new, and later found to be + sub-optimal. By this time those constructs were widely used and changing them + was not an option. In Vim we do have the freedom to make different choices, + since classes are completely new. We can make the syntax simpler and more + consistent than what "old" languages use. Without diverting too much, it + should still mostly look like what you know from existing languages. + + Some recently developed languages add all kinds of fancy features that we + don't need for Vim. But some have nice ideas that we do want to use. + Thus we end up with a base of what is common in popular languages, dropping + what looks like a bad idea, and adding some nice features that are easy to + understand. + + The main rules we use to make decisions: + - Keep it simple. + - No surprises, mostly do what other languages are doing. + - Avoid mistakes from the past. + - Avoid the need for the script writer to consult the help to understand how + things work, most things should be obvious. + - Keep it consistent. + - Aim at an average size plugin, not at a huge project. + + + Using new() for the constructor ~ + + Many languages use the class name for the constructor method. A disadvantage + is that quite often this is a long name. And when changing the class name all + constructor methods need to be renamed. Not a big deal, but still a + disadvantage. + + Other languages, such as TypeScript, use a specific name, such as + "constructor()". That seems better. However, using "new" or "new()" to + create a new object has no obvious relation with "constructor()". + + For |Vim9| script using the same method name for all constructors seemed like + the right choice, and by calling it new() the relation between the caller and + the method being called is obvious. + + + No overloading of the constructor ~ + + In Vim script, both legacy and |Vim9| script, there is no overloading of + functions. That means it is not possible to use the same function name with + different types of arguments. Therefore there also is only one new() + constructor. + + With |Vim9| script it would be possible to support overloading, since + arguments are typed. However, this gets complicated very quickly. Looking at + a new() call one has to inspect the types of the arguments to know which of + several new() methods is actually being called. And that can require + inspecting quite a bit of code. For example, if one of the arguments is the + return value of a method, you need to find that method to see what type it is + returning. + + Instead, every constructor has to have a different name, starting with "new". + That way multiple constructors with different arguments are possible, while it + is very easy to see which constructor is being used. And the type of + arguments can be properly checked. + + + No overloading of methods ~ + + Same reasoning as for the constructor: It is often not obvious what type + arguments have, which would make it difficult to figure out what method is + actually being called. Better just give the methods a different name, then + type checking will make sure it works as you intended. This rules out + polymorphism, which we don't really need anyway. + + + Using "this.member" everywhere ~ + + The object members in various programming languages can often be accessed in + different ways, depending on the location. Sometimes "this." has to be + prepended to avoid ambiguity. They are usually declared without "this.". + That is quite inconsistent and sometimes confusing. + + A very common issue is that in the constructor the arguments use the same name + as the object member. Then for these members "this." needs to be prefixed in + the body, while for other members this is not needed and often omitted. This + leads to a mix of members with and without "this.", which is inconsistent. + + For |Vim9| classes the "this." prefix is always used. Also for declaring the + members. Simple and consistent. When looking at the code inside a class it's + also directly clear which variable references are object members and which + aren't. + + + Single inheritance and interfaces ~ + + Some languages support multiple inheritance. Although that can be useful in + some cases, it makes the rules of how a class works quite complicated. + Instead, using interfaces to declare what is supported is much simpler. The + very popular Java language does it this way, and it should be good enough for + Vim. The "keep it simple" rule applies here. + + Explicitly declaring that a class supports an interface makes it easy to see + what a class is intended for. It also makes it possible to do proper type + checking. When an interface is changed any class that declares to implement + it will be checked if that change was also changed. The mechanism to assume a + class implements an interface just because the methods happen to match is + brittle and leads to obscure problems, let's not do that. + + + Using class members ~ + + Using "static member" to declare a class member is very common, nothing new + here. In |Vim9| script these can be accessed directly by their name. Very + much like how a script-local variable can be used in a function. Since object + members are always accessed with "this." prepended, it's also quickly clear + what kind of member it is. + + TypeScript prepends the class name before the class member, also inside the + class. This has two problems: The class name can be rather long, taking up + quite a bit of space, and when the class is renamed all these places need to + be changed too. + + + Using "ClassName.new()" to construct an object ~ + + Many languages use the "new" operator to create an object, which is actually + kind of strange, since the constructor is defined as a method with arguments, + not a command. TypeScript also has the "new" keyword, but the method is + called "constructor()", it is hard to see the relation between the two. + + In |Vim9| script the constructor method is called new(), and it is invoked as + new(), simple and straightforward. Other languages use "new ClassName()", + while there is no ClassName() method, it's a method by another name in the + class called ClassName. Quite confusing. + + + Default read access to object members ~ + + Some users will remark that the access rules for object members are + asymmetric. Well, that is intentional. Changing a value is a very different + action than reading a value. The read operation has no side effects, it can + be done any number of times without affecting the object. Changing the value + can have many side effects, and even have a ripple effect, affecting other + objects. + + When adding object members one usually doesn't think much about this, just get + the type right. And normally the values are set in the new() method. + Therefore defaulting to read access only "just works" in most cases. And when + directly writing you get an error, which makes you wonder if you actually want + to allow that. This helps writing code with fewer mistakes. + + + Making object membes private with an underscore ~ + + When an object member is private, it can only be read and changed inside the + class (and in sub-classes), then it cannot be used outside of the class. + Prepending an underscore is a simple way to make that visible. Various + programming languages have this as a recommendation. + + In case you change your mind and want to make the object member accessible + outside of the class, you will have to remove the underscore everywhere. + Since the name only appears in the class (and sub-classes) they will be easy + to find and change. + + The other way around is much harder: you can easily prepend an underscore to + the object member inside the class to make it private, but any usage elsewhere + you will have to track down and change. You may have to make it a "set" + method call. This reflects the real world problem that taking away access + requires work to be done for all places where that access exists. + + An alternative would have been using the "private" keyword, just like "public" + changes the access in the other direction. Well, that's just to reduce the + number of keywords. + + + No protected object members ~ + + Some languages provide several ways to control access to object members. The + most known is "protected", and the meaning varies from language to language. + Others are "shared", "private" and even "friend". + + These rules make life more difficult. That can be justified in projects where + many people work on the same, complex code where it is easy to make mistakes. + Especially when refactoring or other changes to the class model. + + The Vim scripts are expected to be used in a plugin, with just one person or a + small team working on it. Complex rules then only make it more complicated, + the extra safety provide by the rules isn't really needed. Let's just keep it + simple and not specify access details. + + + ============================================================================== + + 10. To be done later + + Can a newSomething() constructor invoke another constructor? If yes, what are + the restrictions? + + Thoughts: + - Generics for a class: `class ` + - Generics for a function: `def GetLast(key: Tkey)` + - Mixins: not sure if that is useful, leave out for simplicity. + + Some things that look like good additions: + - For testing: Mock mechanism + + An important class to 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. + + + vim:tw=78:ts=8:noet:ft=help:norl: *** ../vim-9.0.1000/runtime/doc/Makefile 2022-05-13 12:03:04.000000000 +0100 --- runtime/doc/Makefile 2022-12-03 22:18:13.326975383 +0000 *************** *** 113,118 **** --- 115,121 ---- todo.txt \ uganda.txt \ undo.txt \ + userfunc.txt \ usr_01.txt \ usr_02.txt \ usr_03.txt \ *************** *** 158,163 **** --- 161,167 ---- version9.txt \ vi_diff.txt \ vim9.txt \ + vim9class.txt \ visual.txt \ windows.txt \ workshop.txt *************** *** 261,266 **** --- 267,273 ---- todo.html \ uganda.html \ undo.html \ + userfunc.html \ usr_01.html \ usr_02.html \ usr_03.html \ *************** *** 307,312 **** --- 314,320 ---- vi_diff.html \ vimindex.html \ vim9.html \ + vim9class.html \ visual.html \ windows.html \ workshop.html *** ../vim-9.0.1000/src/ex_cmds.h 2022-10-07 17:26:19.023293895 +0100 --- src/ex_cmds.h 2022-12-04 17:11:19.528621148 +0000 *************** *** 126,132 **** EXCMD(CMD_aboveleft, "aboveleft", ex_wrongmodifier, EX_NEEDARG|EX_EXTRA|EX_NOTRLCOM, ADDR_NONE), ! EXCMD(CMD_abstract, "abstract", ex_ni, EX_EXTRA|EX_TRLBAR|EX_CMDWIN|EX_LOCK_OK, ADDR_NONE), EXCMD(CMD_all, "all", ex_all, --- 126,132 ---- EXCMD(CMD_aboveleft, "aboveleft", ex_wrongmodifier, EX_NEEDARG|EX_EXTRA|EX_NOTRLCOM, ADDR_NONE), ! EXCMD(CMD_abstract, "abstract", ex_class, EX_EXTRA|EX_TRLBAR|EX_CMDWIN|EX_LOCK_OK, ADDR_NONE), EXCMD(CMD_all, "all", ex_all, *************** *** 354,360 **** EXCMD(CMD_clast, "clast", ex_cc, EX_RANGE|EX_COUNT|EX_TRLBAR|EX_BANG, ADDR_UNSIGNED), ! EXCMD(CMD_class, "class", ex_ni, EX_EXTRA|EX_TRLBAR|EX_CMDWIN|EX_LOCK_OK|EX_EXPORT, ADDR_NONE), EXCMD(CMD_close, "close", ex_close, --- 354,360 ---- EXCMD(CMD_clast, "clast", ex_cc, EX_RANGE|EX_COUNT|EX_TRLBAR|EX_BANG, ADDR_UNSIGNED), ! EXCMD(CMD_class, "class", ex_class, EX_EXTRA|EX_TRLBAR|EX_CMDWIN|EX_LOCK_OK|EX_EXPORT, ADDR_NONE), EXCMD(CMD_close, "close", ex_close, *************** *** 567,582 **** EXCMD(CMD_endif, "endif", ex_endif, EX_TRLBAR|EX_SBOXOK|EX_CMDWIN|EX_LOCK_OK|EX_WHOLE, ADDR_NONE), ! EXCMD(CMD_endinterface, "endinterface", ex_ni, EX_EXTRA|EX_TRLBAR|EX_CMDWIN|EX_LOCK_OK, ADDR_NONE), ! EXCMD(CMD_endclass, "endclass", ex_ni, EX_EXTRA|EX_TRLBAR|EX_CMDWIN|EX_LOCK_OK, ADDR_NONE), EXCMD(CMD_enddef, "enddef", ex_endfunction, EX_TRLBAR|EX_CMDWIN|EX_LOCK_OK|EX_WHOLE, ADDR_NONE), ! EXCMD(CMD_endenum, "endenum", ex_ni, EX_EXTRA|EX_TRLBAR|EX_CMDWIN|EX_LOCK_OK, ADDR_NONE), EXCMD(CMD_endfunction, "endfunction", ex_endfunction, --- 567,582 ---- EXCMD(CMD_endif, "endif", ex_endif, EX_TRLBAR|EX_SBOXOK|EX_CMDWIN|EX_LOCK_OK|EX_WHOLE, ADDR_NONE), ! EXCMD(CMD_endinterface, "endinterface", ex_wrongmodifier, EX_EXTRA|EX_TRLBAR|EX_CMDWIN|EX_LOCK_OK, ADDR_NONE), ! EXCMD(CMD_endclass, "endclass", ex_wrongmodifier, EX_EXTRA|EX_TRLBAR|EX_CMDWIN|EX_LOCK_OK, ADDR_NONE), EXCMD(CMD_enddef, "enddef", ex_endfunction, EX_TRLBAR|EX_CMDWIN|EX_LOCK_OK|EX_WHOLE, ADDR_NONE), ! EXCMD(CMD_endenum, "endenum", ex_wrongmodifier, EX_EXTRA|EX_TRLBAR|EX_CMDWIN|EX_LOCK_OK, ADDR_NONE), EXCMD(CMD_endfunction, "endfunction", ex_endfunction, *************** *** 594,600 **** EXCMD(CMD_enew, "enew", ex_edit, EX_BANG|EX_TRLBAR, ADDR_NONE), ! EXCMD(CMD_enum, "enum", ex_ni, EX_EXTRA|EX_TRLBAR|EX_CMDWIN|EX_LOCK_OK|EX_EXPORT, ADDR_NONE), EXCMD(CMD_eval, "eval", ex_eval, --- 594,600 ---- EXCMD(CMD_enew, "enew", ex_edit, EX_BANG|EX_TRLBAR, ADDR_NONE), ! EXCMD(CMD_enum, "enum", ex_enum, EX_EXTRA|EX_TRLBAR|EX_CMDWIN|EX_LOCK_OK|EX_EXPORT, ADDR_NONE), EXCMD(CMD_eval, "eval", ex_eval, *************** *** 756,762 **** EXCMD(CMD_intro, "intro", ex_intro, EX_TRLBAR|EX_CMDWIN|EX_LOCK_OK, ADDR_NONE), ! EXCMD(CMD_interface, "interface", ex_ni, EX_EXTRA|EX_TRLBAR|EX_CMDWIN|EX_LOCK_OK, ADDR_NONE), EXCMD(CMD_isearch, "isearch", ex_findpat, --- 756,762 ---- EXCMD(CMD_intro, "intro", ex_intro, EX_TRLBAR|EX_CMDWIN|EX_LOCK_OK, ADDR_NONE), ! EXCMD(CMD_interface, "interface", ex_interface, EX_EXTRA|EX_TRLBAR|EX_CMDWIN|EX_LOCK_OK, ADDR_NONE), EXCMD(CMD_isearch, "isearch", ex_findpat, *************** *** 1215,1220 **** --- 1215,1223 ---- EXCMD(CMD_put, "put", ex_put, EX_RANGE|EX_WHOLEFOLD|EX_BANG|EX_REGSTR|EX_TRLBAR|EX_ZEROR|EX_CMDWIN|EX_LOCK_OK|EX_MODIFY, ADDR_LINES), + EXCMD(CMD_public, "public", ex_wrongmodifier, + EX_EXTRA|EX_TRLBAR|EX_CMDWIN|EX_LOCK_OK, + ADDR_NONE), EXCMD(CMD_pwd, "pwd", ex_pwd, EX_TRLBAR|EX_CMDWIN|EX_LOCK_OK, ADDR_NONE), *************** *** 1488,1494 **** EXCMD(CMD_startreplace, "startreplace", ex_startinsert, EX_BANG|EX_TRLBAR|EX_CMDWIN|EX_LOCK_OK, ADDR_NONE), ! EXCMD(CMD_static, "static", ex_ni, EX_EXTRA|EX_TRLBAR|EX_CMDWIN|EX_LOCK_OK, ADDR_NONE), EXCMD(CMD_stopinsert, "stopinsert", ex_stopinsert, --- 1491,1497 ---- EXCMD(CMD_startreplace, "startreplace", ex_startinsert, EX_BANG|EX_TRLBAR|EX_CMDWIN|EX_LOCK_OK, ADDR_NONE), ! EXCMD(CMD_static, "static", ex_wrongmodifier, EX_EXTRA|EX_TRLBAR|EX_CMDWIN|EX_LOCK_OK, ADDR_NONE), EXCMD(CMD_stopinsert, "stopinsert", ex_stopinsert, *************** *** 1614,1619 **** --- 1617,1625 ---- EXCMD(CMD_throw, "throw", ex_throw, EX_EXTRA|EX_NEEDARG|EX_SBOXOK|EX_CMDWIN|EX_LOCK_OK|EX_WHOLE, ADDR_NONE), + EXCMD(CMD_this, "this", ex_wrongmodifier, + EX_EXTRA|EX_NEEDARG|EX_SBOXOK|EX_CMDWIN|EX_LOCK_OK|EX_WHOLE, + ADDR_NONE), EXCMD(CMD_tjump, "tjump", ex_tag, EX_BANG|EX_TRLBAR|EX_WORD1, ADDR_NONE), *************** *** 1665,1671 **** EXCMD(CMD_tunmap, "tunmap", ex_unmap, EX_EXTRA|EX_TRLBAR|EX_NOTRLCOM|EX_CTRLV|EX_CMDWIN|EX_LOCK_OK, ADDR_NONE), ! EXCMD(CMD_type, "type", ex_ni, EX_EXTRA|EX_TRLBAR|EX_CMDWIN|EX_LOCK_OK|EX_EXPORT, ADDR_NONE), EXCMD(CMD_undo, "undo", ex_undo, --- 1671,1677 ---- EXCMD(CMD_tunmap, "tunmap", ex_unmap, EX_EXTRA|EX_TRLBAR|EX_NOTRLCOM|EX_CTRLV|EX_CMDWIN|EX_LOCK_OK, ADDR_NONE), ! EXCMD(CMD_type, "type", ex_type, EX_EXTRA|EX_TRLBAR|EX_CMDWIN|EX_LOCK_OK|EX_EXPORT, ADDR_NONE), EXCMD(CMD_undo, "undo", ex_undo, *** ../vim-9.0.1000/src/ex_cmdidxs.h 2022-09-03 21:35:50.184158219 +0100 --- src/ex_cmdidxs.h 2022-12-04 15:39:24.835737128 +0000 *************** *** 21,36 **** /* n */ 308, /* o */ 328, /* p */ 340, ! /* q */ 379, ! /* r */ 382, ! /* s */ 402, ! /* t */ 472, ! /* u */ 518, ! /* v */ 529, ! /* w */ 550, ! /* x */ 564, ! /* y */ 574, ! /* z */ 575 }; /* --- 21,36 ---- /* n */ 308, /* o */ 328, /* p */ 340, ! /* q */ 380, ! /* r */ 383, ! /* s */ 403, ! /* t */ 473, ! /* u */ 520, ! /* v */ 531, ! /* w */ 552, ! /* x */ 566, ! /* y */ 576, ! /* z */ 577 }; /* *************** *** 56,66 **** /* m */ { 1, 0, 0, 0, 7, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16 }, /* n */ { 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 8, 10, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0 }, /* o */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 5, 0, 0, 0, 0, 0, 0, 9, 0, 11, 0, 0, 0 }, ! /* p */ { 1, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 9, 0, 0, 16, 17, 26, 0, 27, 0, 28, 0 }, /* q */ { 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* r */ { 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 19, 0, 0, 0, 0 }, /* s */ { 2, 6, 15, 0, 19, 23, 0, 25, 26, 0, 0, 29, 31, 35, 39, 41, 0, 50, 0, 51, 0, 64, 65, 0, 66, 0 }, ! /* t */ { 2, 0, 19, 0, 24, 26, 0, 27, 0, 28, 0, 29, 33, 36, 38, 39, 0, 40, 42, 0, 43, 0, 0, 0, 45, 0 }, /* u */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* v */ { 1, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 12, 15, 0, 0, 0, 0, 18, 0, 19, 0, 0, 0, 0, 0 }, /* w */ { 2, 0, 0, 0, 0, 0, 0, 3, 4, 0, 0, 0, 0, 8, 0, 9, 10, 0, 0, 0, 12, 13, 0, 0, 0, 0 }, --- 56,66 ---- /* m */ { 1, 0, 0, 0, 7, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16 }, /* n */ { 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 8, 10, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0 }, /* o */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 5, 0, 0, 0, 0, 0, 0, 9, 0, 11, 0, 0, 0 }, ! /* p */ { 1, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 9, 0, 0, 16, 17, 26, 0, 28, 0, 29, 0 }, /* q */ { 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* r */ { 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 19, 0, 0, 0, 0 }, /* s */ { 2, 6, 15, 0, 19, 23, 0, 25, 26, 0, 0, 29, 31, 35, 39, 41, 0, 50, 0, 51, 0, 64, 65, 0, 66, 0 }, ! /* t */ { 2, 0, 19, 0, 24, 26, 0, 27, 0, 29, 0, 30, 34, 37, 39, 40, 0, 41, 43, 0, 44, 0, 0, 0, 46, 0 }, /* u */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* v */ { 1, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 12, 15, 0, 0, 0, 0, 18, 0, 19, 0, 0, 0, 0, 0 }, /* w */ { 2, 0, 0, 0, 0, 0, 0, 3, 4, 0, 0, 0, 0, 8, 0, 9, 10, 0, 0, 0, 12, 13, 0, 0, 0, 0 }, *************** *** 69,72 **** /* z */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }; ! static const int command_count = 592; --- 69,72 ---- /* z */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }; ! static const int command_count = 594; *** ../vim-9.0.1000/src/vim9class.c 2022-12-04 20:08:19.523852382 +0000 --- src/vim9class.c 2022-12-04 17:10:26.100686606 +0000 *************** *** 0 **** --- 1,110 ---- + /* vi:set ts=8 sts=4 sw=4 noet: + * + * VIM - Vi IMproved by Bram Moolenaar + * + * Do ":help uganda" in Vim to read copying and usage conditions. + * Do ":help credits" in Vim to see a list of people who contributed. + * See README.txt for an overview of the Vim source code. + */ + + /* + * vim9class.c: Vim9 script class support + */ + + #define USING_FLOAT_STUFF + #include "vim.h" + + #if defined(FEAT_EVAL) || defined(PROTO) + + // When not generating protos this is included in proto.h + #ifdef PROTO + # include "vim9.h" + #endif + + /* + * Handle ":class" and ":abstract class" up to ":endclass". + */ + void + ex_class(exarg_T *eap) + { + int is_abstract = eap->cmdidx == CMD_abstract; + + char_u *arg = eap->arg; + if (is_abstract) + { + if (STRNCMP(arg, "class", 5) != 0 || !VIM_ISWHITE(arg[5])) + { + semsg(_(e_invalid_argument_str), arg); + return; + } + arg = skipwhite(arg + 5); + } + + if (!ASCII_ISUPPER(*arg)) + { + semsg(_(e_class_name_must_start_with_uppercase_letter_str), arg); + return; + } + + // TODO: + // generics: + // extends SomeClass + // implements SomeInterface + // specifies SomeInterface + + + // TODO: handle until "endclass" is found: + // object and class members (public, read access, private): + // public this.varname + // public static varname + // this.varname + // static varname + // this._varname + // static _varname + // + // constructors: + // def new() + // enddef + // def newOther() + // enddef + // + // methods (object, class, generics): + // def someMethod() + // enddef + // static def someMethod() + // enddef + // def someMethod() + // enddef + // static def someMethod() + // enddef + } + + /* + * Handle ":interface" up to ":endinterface". + */ + void + ex_interface(exarg_T *eap UNUSED) + { + // TODO + } + + /* + * Handle ":enum" up to ":endenum". + */ + void + ex_enum(exarg_T *eap UNUSED) + { + // TODO + } + + /* + * Handle ":type". + */ + void + ex_type(exarg_T *eap UNUSED) + { + // TODO + } + + + #endif // FEAT_EVAL *** ../vim-9.0.1000/src/proto/vim9class.pro 2022-12-04 20:08:19.527852383 +0000 --- src/proto/vim9class.pro 2022-12-04 17:00:37.753590459 +0000 *************** *** 0 **** --- 1,6 ---- + /* vim9class.c */ + void ex_class(exarg_T *eap); + void ex_interface(exarg_T *eap); + void ex_enum(exarg_T *eap); + void ex_type(exarg_T *eap); + /* vim: set ft=c : */ *** ../vim-9.0.1000/src/proto.h 2022-11-30 20:20:52.751228273 +0000 --- src/proto.h 2022-12-04 14:33:39.324958458 +0000 *************** *** 215,220 **** --- 215,221 ---- # ifdef FEAT_EVAL // include vim9.h here, the types defined there are used by function arguments. # include "vim9.h" + # include "vim9class.pro" # include "vim9cmds.pro" # include "vim9compile.pro" # include "vim9execute.pro" *** ../vim-9.0.1000/src/ex_docmd.c 2022-11-28 18:51:38.955571567 +0000 --- src/ex_docmd.c 2022-12-04 16:58:01.129631271 +0000 *************** *** 267,272 **** --- 267,273 ---- # define ex_breaklist ex_ni # define ex_call ex_ni # define ex_catch ex_ni + # define ex_class ex_ni # define ex_compiler ex_ni # define ex_continue ex_ni # define ex_debug ex_ni *************** *** 282,291 **** # define ex_endif ex_ni # define ex_endtry ex_ni # define ex_endwhile ex_ni # define ex_eval ex_ni # define ex_execute ex_ni - # define ex_incdec ex_ni # define ex_finally ex_ni # define ex_finish ex_ni # define ex_function ex_ni # define ex_if ex_ni --- 283,294 ---- # define ex_endif ex_ni # define ex_endtry ex_ni # define ex_endwhile ex_ni + # define ex_enum ex_ni # define ex_eval ex_ni # define ex_execute ex_ni # define ex_finally ex_ni + # define ex_incdec ex_ni + # define ex_interface ex_ni # define ex_finish ex_ni # define ex_function ex_ni # define ex_if ex_ni *************** *** 300,305 **** --- 303,309 ---- # define ex_scriptnames ex_ni # define ex_throw ex_ni # define ex_try ex_ni + # define ex_type ex_ni # define ex_unlet ex_ni # define ex_while ex_ni # define ex_import ex_ni *************** *** 6693,6704 **** } /* ! * Command modifier used in a wrong way. */ static void ex_wrongmodifier(exarg_T *eap) { ! eap->errmsg = _(e_invalid_command); } /* --- 6697,6709 ---- } /* ! * Command modifier used in a wrong way. Also for other commands that can't ! * appear at the toplevel. */ static void ex_wrongmodifier(exarg_T *eap) { ! eap->errmsg = ex_errmsg(e_invalid_command_str, eap->cmd); } /* *** ../vim-9.0.1000/src/errors.h 2022-11-25 16:31:46.964606667 +0000 --- src/errors.h 2022-12-04 14:57:23.938237758 +0000 *************** *** 3345,3347 **** --- 3345,3351 ---- INIT(= N_("E1312: Not allowed to change the window layout in this autocmd")); EXTERN char e_not_allowed_to_add_or_remove_entries_str[] INIT(= N_("E1313: Not allowed to add or remove entries (%s)")); + #ifdef FEAT_EVAL + EXTERN char e_class_name_must_start_with_uppercase_letter_str[] + INIT(= N_("E1314: Class name must start with an uppercase letter: %s")); + #endif *** ../vim-9.0.1000/src/Makefile 2022-11-30 18:11:52.694904295 +0000 --- src/Makefile 2022-12-04 14:36:48.416718399 +0000 *************** *** 1584,1589 **** --- 1585,1591 ---- usercmd.c \ userfunc.c \ version.c \ + vim9class.c \ vim9cmds.c \ vim9compile.c \ vim9execute.c \ *************** *** 1741,1746 **** --- 1743,1749 ---- objects/usercmd.o \ objects/userfunc.o \ objects/version.o \ + objects/vim9class.o \ objects/vim9cmds.o \ objects/vim9compile.o \ objects/vim9execute.o \ *************** *** 1931,1936 **** --- 1934,1940 ---- usercmd.pro \ userfunc.pro \ version.pro \ + vim9class.pro \ vim9cmds.pro \ vim9compile.pro \ vim9execute.pro \ *************** *** 3489,3494 **** --- 3493,3501 ---- objects/userfunc.o: userfunc.c $(CCC) -o $@ userfunc.c + objects/vim9class.o: vim9class.c + $(CCC) -o $@ vim9class.c + objects/vim9cmds.o: vim9cmds.c $(CCC) -o $@ vim9cmds.c *************** *** 4168,4173 **** --- 4175,4185 ---- proto/gui_beval.pro structs.h regexp.h gui.h libvterm/include/vterm.h \ libvterm/include/vterm_keycodes.h alloc.h ex_cmds.h spell.h proto.h \ globals.h errors.h version.h + objects/vim9class.o: vim9class.c vim.h protodef.h auto/config.h feature.h os_unix.h \ + auto/osdef.h ascii.h keymap.h termdefs.h macros.h option.h beval.h \ + proto/gui_beval.pro structs.h regexp.h gui.h libvterm/include/vterm.h \ + libvterm/include/vterm_keycodes.h alloc.h ex_cmds.h spell.h proto.h \ + globals.h errors.h vim9.h objects/vim9cmds.o: vim9cmds.c vim.h protodef.h auto/config.h feature.h os_unix.h \ auto/osdef.h ascii.h keymap.h termdefs.h macros.h option.h beval.h \ proto/gui_beval.pro structs.h regexp.h gui.h libvterm/include/vterm.h \ *** ../vim-9.0.1000/src/Make_ami.mak 2022-11-30 18:11:52.694904295 +0000 --- src/Make_ami.mak 2022-12-04 14:37:12.024690186 +0000 *************** *** 174,179 **** --- 174,180 ---- userfunc.c \ version.c \ viminfo.c \ + vim9class.c \ vim9cmds.c \ vim9compile.c \ vim9execute.c \ *** ../vim-9.0.1000/src/Make_mvc.mak 2022-11-30 18:11:52.694904295 +0000 --- src/Make_mvc.mak 2022-12-04 14:37:52.456642607 +0000 *************** *** 735,740 **** --- 735,741 ---- $(OUTDIR)\undo.obj \ $(OUTDIR)\usercmd.obj \ $(OUTDIR)\userfunc.obj \ + $(OUTDIR)\vim9class.obj \ $(OUTDIR)\vim9cmds.obj \ $(OUTDIR)\vim9compile.obj \ $(OUTDIR)\vim9execute.obj \ *************** *** 1708,1713 **** --- 1709,1716 ---- $(OUTDIR)/version.obj: $(OUTDIR) version.c $(INCL) version.h + $(OUTDIR)/vim9class.obj: $(OUTDIR) vim9class.c $(INCL) vim9.h + $(OUTDIR)/vim9cmds.obj: $(OUTDIR) vim9cmds.c $(INCL) vim9.h $(OUTDIR)/vim9compile.obj: $(OUTDIR) vim9compile.c $(INCL) vim9.h *************** *** 1915,1920 **** --- 1918,1924 ---- proto/undo.pro \ proto/usercmd.pro \ proto/userfunc.pro \ + proto/vim9class.pro \ proto/vim9cmds.pro \ proto/vim9compile.pro \ proto/vim9execute.pro \ *** ../vim-9.0.1000/src/Make_vms.mms 2022-11-30 18:11:52.694904295 +0000 --- src/Make_vms.mms 2022-12-04 14:38:47.272579548 +0000 *************** *** 409,414 **** --- 409,415 ---- usercmd.c \ userfunc.c \ version.c \ + vim9class.c \ vim9cmds.c \ vim9compile.c \ vim9execute.c \ *************** *** 534,539 **** --- 535,541 ---- usercmd.obj \ userfunc.obj \ version.obj \ + vim9class.obj \ vim9cmds.obj \ vim9compile.obj \ vim9execute.obj \ *************** *** 1122,1127 **** --- 1124,1133 ---- ascii.h keymap.h termdefs.h macros.h structs.h regexp.h \ gui.h beval.h [.proto]gui_beval.pro option.h ex_cmds.h proto.h \ errors.h globals.h version.h + vim9class.obj : vim9class.c vim.h [.auto]config.h feature.h os_unix.h \ + ascii.h keymap.h termdefs.h macros.h structs.h regexp.h \ + gui.h beval.h [.proto]gui_beval.pro option.h ex_cmds.h proto.h \ + errors.h globals.h version.h vim9cmds.obj : vim9cmds.c vim.h [.auto]config.h feature.h os_unix.h \ ascii.h keymap.h termdefs.h macros.h structs.h regexp.h \ gui.h beval.h [.proto]gui_beval.pro option.h ex_cmds.h proto.h \ *** ../vim-9.0.1000/src/Make_cyg_ming.mak 2022-11-30 18:11:52.694904295 +0000 --- src/Make_cyg_ming.mak 2022-12-04 14:39:13.456549960 +0000 *************** *** 851,856 **** --- 851,857 ---- $(OUTDIR)/usercmd.o \ $(OUTDIR)/userfunc.o \ $(OUTDIR)/version.o \ + $(OUTDIR)/vim9class.o \ $(OUTDIR)/vim9cmds.o \ $(OUTDIR)/vim9compile.o \ $(OUTDIR)/vim9execute.o \ *************** *** 1251,1256 **** --- 1252,1259 ---- $(OUTDIR)/version.o: version.c $(INCL) version.h + $(OUTDIR)/vim9class.o: vim9class.c $(INCL) vim9.h + $(OUTDIR)/vim9cmds.o: vim9cmds.c $(INCL) vim9.h $(OUTDIR)/vim9compile.o: vim9compile.c $(INCL) vim9.h *** ../vim-9.0.1000/src/testdir/test_cmdmods.vim 2022-11-02 13:30:37.542314565 +0000 --- src/testdir/test_cmdmods.vim 2022-12-04 17:26:30.679877888 +0000 *************** *** 15,20 **** --- 15,30 ---- lines = getline(top, bot) var mods = lines->map((_, v) => substitute(v, '.*"\(\k*\)".*', '\1', '')) + # Add the other commands that use ex_wrongmodifier. + mods->extend([ + 'endclass', + 'endenum', + 'endinterface', + 'public', + 'static', + 'this', + ]) + # Check the lists are equal. Convert them to a dict to get a clearer error # message. var cmds_dict = {} *** ../vim-9.0.1000/src/version.c 2022-12-03 18:35:04.248951287 +0000 --- src/version.c 2022-12-03 21:51:16.795575975 +0000 *************** *** 697,698 **** --- 697,700 ---- { /* Add new patch number below this line */ + /**/ + 1001, /**/ -- hundred-and-one symptoms of being an internet addict: 227. You sleep next to your monitor. Or on top of it. /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// \\\ \\\ sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///