Sunday, June 29, 2008

Stupid Eclipse Tricks

Overall, Eclipse is great platform to program on, and making a plugin is an experience I would recommend to any coder because it will get you acquainted with a large, complex and fairly well-architectured system.

Of course, nothing is perfect, and Eclipse has faults just like the rest of us. Living in Java-land, it tends to suffer from what is termed ravioli code, where code is scattered throughout hundreds of tiny, tiny objects. Often, to do what you want to do, you need to define one class which then configured by another class which itself may be generated by some factory object. Often, I find the complex tasks are made very easy, but it can be maddening to track down the documentation for tiny little changes I want to make.

And occasionally, poor design does manage to slip in. Take the argument list tooltip (one of the 3 essential editor components). This handy guy gives you function signatures and a little descriptive documentation. In Cusp, The signature is formatted in bold to make it quicker for your eye to pick out. Displaying the tooltip to the user with the required information was trivial. Making part of it bold, that was the hard part.

Here's a quick overview of the architecture. To get your editor to behave the way you want it to, you subclass TextSourceViewerConfiguration, which then informs the editor how it should colorize syntax, how to indent, how to automplete, etc (most of these configurations involve returning another object that does the actual work). Lest you think this is an unnecessary abstraction, it turned out to be very handy when I wanted to make the input area of the REPL behave like the editor, even though they are different beasts.

In there, we tell the editor about Arglist Assistance as follows:


ca = new ContentAssistant();
ca.setContentAssistProcessor(new ArglistAssistProcessor(editor),
IDocument.DEFAULT_CONTENT_TYPE);

IPreferenceStore ps = LispPlugin.getDefault().getPreferenceStore();
ca.enableAutoActivation(ps.getBoolean(PreferenceConstants.AUTO_POPUP_COMPLETIONS));
ca.enableAutoInsert(ps.getBoolean(PreferenceConstants.AUTO_INSERT_COMPLETIONS));
ca.setAutoActivationDelay(ps.getInt(PreferenceConstants.AUTO_POPUP_COMPLETIONS_DELAY));
ca.setProposalPopupOrientation(ContentAssistant.CONTEXT_INFO_BELOW);
if( ps.getBoolean(PreferenceConstants.ARGLIST_BELOW)){
ca.setContextInformationPopupOrientation(ContentAssistant.CONTEXT_INFO_BELOW);
} else {
ca.setContextInformationPopupOrientation(ContentAssistant.CONTEXT_INFO_ABOVE);
}

...

public IContentAssistant getContentAssistant(ISourceViewer sourceViewer) {
ca.setInformationControlCreator(new LispTextHoverControlCreator());
return ca;
}


As you may or may not have noticed, ArglistAssistProcessor is the class that actually figures out what information to display. It parses the document to find out what function is being called (or if the cursor is even in a place where a tooltip makes sense), then talks to Swank to get the information, and then returns that in a format Eclipse understands. The process may sound a little complex when you first run into it, but it is well-covered in the tutorials, so it's fairly easy to get to this point.

But how do I format that text for easier reading? Here, the documentation failed me. And so I'm writing up the answer as a service to the rest of you who may want to do this.

Part of the interface for IContentAssistProcessor is getContextInformationValidator(), which returns an IContextInformationValidator, the object that determines when it is time get rid of the tooltip. It turns out that to format the tooltip, you need to make this object also implement IContextInformationValidator.

This is bad design for so many reasons. Nothing in the documentation indicates that this is the place to do the formatting, and it makes no logical sense for a validator to also (sometimes) act as a formatter. It is also rather contrary to the usual Java and Eclipse way to take an object designed for a completely separate task, and, if it happens to implement another interface, use it for that as well. I'm pretty sure this was slapped on with little thought.

But now it's documented. If you're wondering how to format your tooltips in your own editor, now you know.

Wednesday, June 25, 2008

Eclipse 3.4


The latest version of Eclipse is out. The new bits look very shiny, so I may have to go and download it, which I should probably do anyway for the sake of keeping Cusp up to date. Or, I may stick to the lazy route, and wait for Ubuntu to distribute the new version.

Tuesday, June 24, 2008

What do you look for in a development environment?


It turns out that my core needs for an editor are very basic. Back when I first started constructing Cusp, I had three primary things that were absolutely necessary for me to consider it a useful tool:
  1. Syntax Highlighting. Above all else, I need this. Without basic coloring, I find code far far harder to work with, and any time I'm sshed into my server and forced to edit Lisp code in Emacs, the first thing I do is M-x font-lock-mode. In fact, I can get along pretty happily with this functionality alone in an editor, which probably why most basic text editors since Notepad make sure to include it. (Interesting note: for a long time Dr. Scheme did not have this functionality, and it made me a little embarrassed when recommending it to people.)

  2. Autocomplete. Saves typing, and precious (human) memory space. With this, you usually only need a general idea of what function you're looking for. Glancing through the list of functions is almost always faster than poking through documentation. This makes the editor and order of magnitude friendlier to people who are new to the language, and makes learning your way around the language much easier. And even now that I know Lisp fairly well, it lets me code faster and with fewer typos.

  3. Argument list assistance. Another important learning tool. You should never have to do something a computer can do for you, and one thing computers are way better at is memorizing function signatures. This saves time and a break in your workflow by looking up the documentation for you and telling you just what your function wants. (As a bonus, it really should include a quick bit of function documentation if available.) This sort of thing is great when you're, say, trying to sort out the differences between elt and nth.

    As an aside, this feature is one of the reasons I decided to bundle SBCL rather than CLisp. CLisp promptly forgets the argument names to a function, and can only tell me that it wants (elt arg0 arg1) and (nth arg0 arg1). SBCL is far more helpful, informing me that it wants (elt SEQUENCE INDEX) and (nth N LIST).

    As an additional aside, and because I just can't resist beating on Emacs, this information really should be displayed in a tooltip where you're typing (whether it goes above or below is a matter of taste). Making the user's eyes jump to the bottom of the screen and then seek out the cursor again is inefficient.

And that's all. Give me those in an editor and I'll be pretty well satisfied. Happily, these are also tasks that Eclipse makes very easy. Of course, since I was making a Lisp editor, parenthesis matching, integration with the runtime, and a REPL were also required, but that doesn't apply to most languages, and those were also fairly easily done. From there, it was a short walk to functional equivalence with SLIME.

So keep that in mind, editor-makers. Those three things are all you really need. And if you use Eclipse, all the hard work has already been done for you.