Endgame

It seems that the build targets feature I previously wrote about is somewhat more work than I expected, mainly in terms of integration with the Eclipse GUI. With my university classes starting soon, and some work that I’ve been pushing ahead of me throughout GSoC, I am unable to finish this in time.

Therefore, I’ve parked the build target feature in a branch and decided to officially put a stop to this project for the time being. I have updated the EclipseFP web site to reflect the work I did. I also rolled a release that you can pull in using the Eclipse update mechanism. The details are provided on the web site.

I cannot say that I’m fully happy with the results that I achieved. I had hoped to get more mileage out of the integration with Scion, but adding all these features through the Eclipse API turned out to be hairier than I expected. However, I do feel I have made useful contributions on which future work can build.

I would like to thank my mentor, Thomas Schilling a.k.a. nominolo, for his guidance and his work on Scion. I would also like to thank Leif Frenzel, without whom EclipseFP wouldn’t have existed in the first place. And finally, thanks to the folks at Google who made GSoC a reality.

For now, I am forced to other business that I’ve been neglecting for far too long. Does that mean that EclipseFP is going to disappear from the radar again? I think not. There is sufficient interest in Haskell IDEs to keep this project going, and somebody will come along and keep improving upon it. Such is the nature of open source. And that somebody… might actually be me.

Update: it isn’t me after all. Less than a week after I wrote this, JP Moresmau chimed in on the mailing list, reporting some bugs, offering to fix them, then continue from there. He’s now taken over development. If you want to try EclipseFP, I recommend his latest version from here!

More robust Scion client code

New post, new theme! With this wider theme, the screenshots will no longer fall off the edge.

Although I did not plan to “build one to throw away”, this largely became reality nonetheless. By now I’ve done so many refactorings on the Scion client code that hardly a single line of the original remains. But I’m finally happy with the result.

The Scion client previously used its own command queue, which ensured that commands were sent to the server one after another. After some investigation, I replaced that by Eclipse’s job scheduling mechanism. With proper scheduling rules, we can keep the scheduler from running two commands simultaneously, so it is as powerful as the home-brew command queue. If one command depends on the result of another, we can make the second job fall asleep and have the first wake the second up when it’s done. And it has several advantages over the old system:

  • We can now set priorities on commands, so that interactive commands (such as computing the text of a tool tip) take precedence over longer-running commands (such as builds).
  • Commands will automatically be shown in the progress report windows.
  • The sender of a command can either run it asynchronously, or wait for the command to complete before continuing.
  • Of course, it’s simply less code to maintain and have bugs in!

Secondly, I introduced a Scion “manager” class that ensures that there is always one Scion server running per project. If the server crashes, it is restarted automatically and brought back to the same state as its previous incarnation.

Thirdly, all significant errors are now logged to the Error Log window in Eclipse. There should no longer be a need to turn on error tracing to troubleshoot problems in the Scion client/server system.

Finally, if the server fails to start in the first place, this is probably because its executable program could not be found. Most likely this is because the plugin is used for the first time. Therefore, we pop up a helpful dialog:

server-startup-error

Little things like this go a long way, making it easier to get up to speed with EclipseFP. In the same vein, I will start working on a “new project from existing source” feature that is well known from Java development in Eclipse. (EclipseFP is already able to import Cabal packages from a .tar.gz, but strangely not from a directory on disk!)

Compiling and error reporting

During the last few days, I have been reinstating error reporting. Previously, EclipseFP would call GHC, collect its output in a Java string, and send that string off to Cohatoe (the now defunct bridge from Java to Haskell). A Haskell module would parse the GHC output using Parsec, return the result back to Java, where EclipseFP would do fancy things with the parsed output.

If this all sounds very roundabout, you’re right. We are already interfacing with Haskell in the form of the Scion server, so why not let it do the compiling and send us (EclipseFP) the result in a formatted way? Thoughts in this direction are under way, but currently hampered by a few factors:

  • Scion talks with the GHC API, which is single-threaded. This means that during background compiles, every Scion-based function in the IDE would stop working. It should be possible to fix this by letting Scion itself do background compilation, while still servicing requests that do not need to communicate with the GHC API directly, but this requires much work inside the Scion server.
  • Ideally, when a Cabal file is present, Scion should let Cabal do the building. Unfortunately, Cabal does not play well as a library, because errors will terminate the program. This has been fixed in the upcoming Cabal 1.8, to be released along with GHC 6.12.1 in September.
  • When a Cabal file is not present, Scion should do something along the lines of “ghc –make”. However, the make functionality is currently still interwoven with the compiler itself. A consequence is that compilation results are only available after all modules have been compiled. A callback for progress reports is in the works for GHC 6.12.1.

In the light of all these obstacles (especially the first one, which cannot be solved by installing a HEAD build of GHC) I decided to keep the current way of calling GHC as an external process. However, this meant that the output parsing had to be rewritten in Java. Moreover, because compiling a large project might take a while,  gathering up all output and processing it all at once is not the best approach. My new parser works directly on the output stream from the GHC process, so all errors will appear live in the IDE as soon as GHC spits them out.

With that in place, I sprinkled on some UI code (oh, this makes it sound so easy…) and got things working again. Like error squigglies:

You can hover over the error to get the message. Note that an error marker is also shown in the left margin, and next to the scrollbar. This last one is very convenient if you want to jump to an error in a large source file. These are the kinds of features that Eclipse gives you for free, which is the reason why I chose to do Haskell in Eclipse in the first place. Unfortunately, an error marker on the icon of the editor’s tab is more difficult, so I left that out for now.

The Project Explorer now also shows error markers on files that do not compile:

Parents of files with errors also receive this marker. This makes it easy to locate problems in a large project.

Errors are, as usual, also reported in a special Problems view:

It would be better if only the first line were shown, and could be expanded to show the additional information, but for a first attempt this will do.

If parsing of GHC’s output might fail for some reason, an error will be reported in the Error Log (which contains Eclipse errors, not Haskell errors), and you can always see the raw output in the Console:

Very nice.

There is, however, one small problem currently. This is caused by a mismatch between GHC’s notion of building, and Eclipse’s. When building, EclipseFP will visit all files in the project, then invoke “ghc –make” on them. It suffices to call “ghc –make” only on the file containing the main function, and GHC will take care of the rest. But not only is this approach wasteful: it will also lead to error markers appearing and disappearing as the same file gets compiled (as a dependency) multiple times. My plan for solving this is to add a project option to specify the main module and the name of the main function, so that we can call GHC only on that module. Much more efficient.

Cosmetics

Since I was feeling creative today, I decided I would work on some cosmetic issues in EclipseFP that have been bothering me for a while. They make the whole thing look unprofessional and out of tune with the rest of the Eclipse environment. Luckily, Eclipse has a User Interface Guidelines document for me to follow.

I started with some icons. The Guidelines specify precisely how they should look. The icons used in the Package Explorer are now in the same style as their Java counterparts:

project-explorer

Note how the Haskell source files have a nice lambda icon, and the literate source file also has its own icon. The Haskell project itself has a subtle lambda overlay. (I see now that I missed the Libraries icon. Also, the text “[GHC]” should be dimmed. Made a note of these.)

Editors, too, get the new icons:

editor-icons

And finally, the one that I’m most proud of. I figured it would be nice to have the new official “lambda-and-bind” Haskell logo somewhere. And what better place for this than the icon of the Haskell Perspective? So I brushed up my pixel painting skills and drew a variant of the Haskell logo that blends in with the Eclipse environment:

perspective-icons

It’s always there, subtle, but visible, recognisable and fresh. I like it.

Posted in EclipseFP. Tags: . 3 Comments »

“Open Definition” and code improvements

Work on this project has been slow until a few days ago, but now I’m back in business. I’m getting the hang of this Eclipse API thing, which makes everything go much smoother. Today I present to you: a more robust Scion client, a rudimentary “Open Definition” feature, and a configurable path to the Scion server program.

The improved client code for the Scion server works with a command queue. It spawns one thread that is tightly coupled to the server process. This thread waits for a command to arrive in the queue, then sends it off to the server and waits for the response. If the server crashes for some reason, it will be restarted and the command will be retried on the new incarnation. The original sender of the command (for example, a GUI element) specifies a timeout: if the command is not executed successfully within this time, the client gives up and the original sender is left to deal with the problem in whatever way it sees fit.

Then, for the mandatory screenshots, I built a feature similar to the “Open Declaration (F3)” feature that you might know from Java development in Eclipse. You can select an identifier and hit F3 (or go through the context menu or main menu), and you will jump to the place where the identifier is defined:

A context menu item to open the definition of the selected identifier

After clicking Open Definition, we are taken to the definition of the selected function

This feature is very rudimentary: it only works if the definition is in the current file; you have to select the identifier; and the Ctrl+click that Java users may know does not work yet.

I also added a Preferences page to configure the location of the Scion executable. Autodetection is in the works, but is not there yet. Automatically installing Scion via Cabal upon request would also be a very nice feature to have.

This preference page may be a trivial feature, but very important: now that the path to my home directory is no longer hard-coded, other people might actually be able to try my code too! Feeling adventurous? See the next post!

Follow

Get every new post delivered to your Inbox.