Wednesday, August 13, 2008

Attention to Detail

On and off for the last few months, I've been working on a plugin for IntelliJ (my favorite IDE and text editor) to support development in the Arc programming language, which is Paul Graham's (relatively) new dialect of Lisp. Writing code in Arc is sort of fun, because although it's young and immature, it's very small and clean. However, it's also fun to develop plugins for IntelliJ, because their plugin API - including their API for developing custom language plugins - is just fabulous. Consequently, I've spent very little time writing Arc code, and quite a lot of time working on my Arc plugin. To a hammer maker, everthing looks like a hammer, I guess.

Anyway, everything was fine until the switch from IntelliJ version 7.0 to version 8.0, in which they've introduced a fair amount of changes to the language plugin API, in order to better support languages other than Java. This is a great thing for IntelliJ, as it is now poised to become the premier IDE for Ruby, and Python, and a host of other languages in addition to Java. It's not such a great thing for me, however, in that I've had to make a variety of changes to the Arc plugin in order to get it creaking into action.

After a few late nights, I finally got most of the Arc plugin working in version 8, with one maddening exception: syntax highlighting. Now, syntax highlighting is one of the easiest things to make happen when writing an IntelliJ language plugin. You practically get it for free, because once you've written the lexer (which is your very first step, and which they also make very easy via JFlex), all you need to do is create a class which extends SyntaxHighlighterBase, specify the default colors and fonts you want for various tokens, and snap - you got yourself some syntax highlighting.

In version 8, (presumably) to better follow some sort of internal dependency injection blah blah blah, the JetBrains folks have changed the way you get a lot of these components created - instead of defining getters in your "MyLanguage extends Language" class, you add "extension" entries to your "plugin.xml" plugin configuration file. This is fine, except that the JetBrains folks haven't gotten around to updating the plugin documentation yet. At all.

But you're still not doomed, because they have been updating their own language plugins for version 8, and for their Javascript plugin, they've included all the source code! So all I should need to do is simply copy the right entry from the Javascript plugin.xml file, and I'm good to go, right?

<syntaxHighlighter language="Arc" implementation="com.bitbakery.plugin.arc.ArcSyntaxHighlighterProvider"/>


Looks right. Fire up the plugin, and I get... no syntax highlighting. So, I beg for help on the "Open API and Plugin Development" user forum over at intellij.net, and Maxim Shafirov (IntelliJ team lead!) is nice enough to respond that the correct XML attribute is "key" and not "language". So I try that, and still no luck. So I try to create the extension programmatically within the constructor of my ArcLangauge class. Still no luck. Finally, after a few hours of frustration, spread across two evenings, I decide to really look at the plugin.xml for the Javascript plugin:

<syntaxHighlighter key="JavaScript" factoryClass="com.intellij.lang.javascript.highlighting.JSSyntaxHighlighterProvider"/>


Oops. Turns out Maxim was very nicely telling me to quit blaming the plugin API changes, and pay attention to detail, because I wasn't.


When I was a freshman in college taking my first physics class, I would often find myself coming up with homework answers that didn't match those in the back of the textbook. I would bring these issues up to my professor during her office hours, and she would very patiently work through the problem with me and show me what I was doing wrong. And not once did I ever actually discover a wrong answer in the back of that textbook, although I thought I did, many, many times.

Occam's Razor is a principle which asserts that - all other things being equal - the simplest explanation is usually the correct explanation. And when you're programming computers, the simplest explanation is that it's not the other guy, it's you. So pay attention, because there are a lot more little things - and a lot more stupidity - than you might think.

It's a valuable lesson. I just wish I didn't have to keep re-learning it.

No comments: