scala-ide/scala-ide — pull request #708 by sschaef (2014-05-28 15:59:01+00:00)
Title: T1002103 - new file wizard

Finally I managed to finish a PR, even though it took me much longer than I originally thought. Sadly, this PR is not in a state where it can be merged. The reason for this is that the wizard is not yet integrated into Eclipse, more information on this later.

First, a short summary of the design:

- The new wizard is written from scratch, it does not extend the existing `INewWizard` interface of the Eclipse API. The reason why I did it in this way is that the existing interface just provides some behavior for the existing wizards - it didn't allow me to change the GUI of the wizards. But changing the GUI is one of the main points of the new wizard. Therefore I created a new interface, which needs to be extended by clients.
- I added the extension point "fileCreator" to the IDE, which needs to provide a reference to an implementation of the interface `FileCreator`. `FileCreator` is the interface that provides all the behavior that is needed to validate and create a new file. The new file wizard simply forwards all the information that is inserted to the GUI to the methods of this interface.
- The implementation `ScalaFileCreator` provides all the behavior for Scala files. Though, for package objects it was necessary to update it slightly.
- The GUI is slightly different from the proposal. It turned out while implementing the GUI that the components are too large, thus they had to be tuned a little bit. Also, file endings are not shown because it turned out that there is no real need for them.
- The new wizard is meant to be used with both a mouse and a keyboard. When the wizard is opened the cursor is moved to the text field. A different template can be chosen by pressing the up and down button while the text field is selected. By pressing the selection can be moved to the project selection button. After choosing a different project the cursor is automatically moved back to the text field.
- The standard combo box of SWT can't show icons. I found a class on the Internet that can do it, it just pollutes our codebase with ~2k Java code.
- Originally I thought that it makes sense to support both a package notation and a normal path notation (the former creates a compilation unit, the latter just a normal file), but I don't think it is that important anymore, especially because the template based approach does not work with a normal file. At the moment, creating normal files works, but throws an exception once the template needs to be generated.
- The new wizard can be called by searching for "wizard handler" in the quick access component.

I'm quite proud on my creation, the code feels way cleaner in comparison to what I have to read daily in the Eclipse API. Seeing so many mistakes in API design really helps to avoid them in the own API. The API for `FileCreator` follows an 100% immutable approach, which seems to work greatly. A small downside of this approach is that every time a method of the `FileCreator` interface is called the file name needs to be parsed again. However, this is not a problem because it isn't a costly operation that needs to be invoked a lot. Now when the main work is done the whole design seems to follow the concept of a state machine. The next time I implement such an API I will go the way with an immutable state pattern to find out if the code could be improved further.

-----

Now, to the sad part, which really pisses me of: It turned out that there is _no_ way to integrate this wizard into Eclipse. Really, there is none. What would be needed is a way to integrate the wizard into at least three places: The "quick access" component, the menu that can be found under "File → New" and the dialog that can be opened under "File → New → Others". It is unbelievable, but the implementation of all these three components is pure madness. The first problem point is that there are three different implementations to call the wizards. The second problem is that there is no way to add own entries to these implementations, which leads me to the state that I don't know if I should laugh or cry. The entries that are shown are hardcoded in Java code (and the implementations are hardcoded in components that call them). This means that there is no way to either replace the components or to add more behavior by not using Reflection or AspectJ.

The quick access component can at least find existing commands, which means that the only existing way to call the new wizard at the moment is to search for "wizard handler". But there is no way to show an icon, for example, at the side of the command or to categorize the commands as it is done with the existing wizards. I think I have no choice and have to use AspectJ to inject my own wizard entries into the quick access component. You really have to take a look at the implementation if you like horror, the relevant class is `org.eclipse.ui.internal.quickaccess.SearchField`.

-----

I didn't yet finish to write all of the AspectJ code, this is something I have to do in the rest of the week. To come back to the new code, there are three features the old wizards could do but the new one can't (not counting that it is not possible to add superclasses etc. anymore, that was a design decision):

- Source folders can no longer be created (just normal folders). If this is what should be done, one have to use the "new source folder" command.
- No warnings are shown (about discouraged type names etc.), but this behavior can easily be added.
- Auto completion of package names is no longer supported, but can be implemented (I don't have the time to do it right now).

At the end, a list of things that still need to be done/looked at:

- [ ] The Eclipse based template engine, used by the wizard, currently shows a linked mode. One has to press to jump to the cursor position. It is possible to not use the linked mode, though and I think it should be changed in this direction.
- [ ] After the editor is opened, sometimes it happens to me that the dialog is not correctly disposed/the editor not correctly refreshed (one has to insert something to the editor to force a refresh). You will probably see the same behavior, but I hope that removing linked mode will also move this problem away.
- [ ] Removing the linked mode hopefully also solves the issues with files that are created outside of a source folder.
- [ ] There is an exception thrown when a file is immediately deleted after it is created (changing its content and doing a save still results in an exception).
- [ ] Existing plugins like the worksheet or the play-ide need to move their wizards, once the old wizard is deleted (I would like to do this together with this PR, once it is finished).
- [ ] Integration of the the new wizard into Eclipse
- [ ] Removal of the old wizards