Wednesday, August 22, 2007

Zen, C++, IDE reloaded

So I think my initial thought when I started this blog was that within some months of getting started, emacs would have proved itself; I would have gathered helpful hints from around the internet, consolidated them, and turned my emacs work environment into a killer, "have fun developing" environment. Not only that but I would be able to sleep easy at night knowing that I had done it all in emacs. If I was more into being green and less into cars, it would be the same sort of moral superiority that some people derive from owning and operating hybrids... or not. I may just be making random stabs at the hybrid crowd for no good reason, vainly trying to mask my frustration with my own failure to achieve a sense of 'holier-than-thouness'.

Perfect... 1 paragraph and I've insulted a bunch of (oops almost used do-gooders there) people trying to make a difference and help the planet and invented a word... gratuitously.

So I think where I was going with was that there's a lot of functionality in emacs and a lot of people get a lot out of it. I was just hoping to provide a friendly place to pick up some tips on maximizing its use targeted to people with similar (IDE-driven) sensibilities to mine. But, it won't be that way. So, I'll just walk through where I've been from there to now.

First, emacs. Built it for Mac OS X. And started playing. For one thing, it totally kicks ass at one of my basic requirements for work which is to be able to seamlessly develop on a remote machine via ssh. The baseline version TRAMP that ships with emacs 22 allows you to easily load files from a remote machine via ssh just by opening a file with the following syntax: '/ssh:user@machine:/path/to/file.cpp'. What's really nice about TRAMP (given our shady connection to the data center) is that it saves the file in /tmp and all autosaves are performed locally. Only when you make emacs save does it actually go over the network. And if you crash, TRAMP provides a way to restore those backed up files. It also caches directory information enough to make tab complete pretty useable even over a slow connection. The packaged version of TRAMP's only weakness was in building, grepping, and debugging. To do these, you had to use remote versions of the commands that were a bit buggy. However, if you patch to the latest version of TRAMP, the standard commands will 'just work' via ssh. So that's that. TRAMP is totally impressive.

CVS integration is also very good in emacs. It's another feature that seems to just work and is generally pretty good. Diffs and history for files are fairly easy to get at via windowed menus and I don't feel the need to perform those things via the keyboard.

I was also happy with emacs' editing capabilities and general configurability. It's satisfying to envy a simple editing command available in a different editor and just implement it. That said, if the feature you happen to be drooling over is continuous syntax checking, function completion, or god forbid refactoring support, you're in for a ride.

The easiest thing to do for continuous syntax checking seems to be fly-make... a package that finds the Makefile for your current file and runs it with the target check-syntax. With gcc you can set this target up to be something along the lines of: g++ -fsyntax-only $(INCLUDES) $(CPP_FILES) and the module will run in the background highlighting errors. It's pretty useful and really easy to use, but it doesn't always work. Fairly often it would alert me that it was going to crap out... and then it would crap out. At some point, I even got it to take down all of emacs (which incidentally, it how I found out about TRAMP's awesome recovery features).

So that's not great, but then in terms of completion of functions, etc. There's just very little out there. The best thing is the probably CEDET which is collection of .el files to help make emacs into an IDE. Personally, I couldn't get it to even byte-compile the .el files on my mac and even running on the non-compiled version, it didn't do much for me. I've heard similar reviews from friends who have played with it. It may get there. It's an exciting idea. It's opensource, so if you're inclined you can work on it... but it's not there.

Crap... I just checked the length of this in preview and it's a monster. How do people write short blogs?

All of this led me to Eclipse C++. It, too, is opensource, so I figured I could work on problems that I found. And it already supports C++ and better yet I even found a remote plugin for it. But there were some problems. For one, yes it supports C++ but it seems to get tripped up on templates fairly easily and sometimes is just unhappy and won't offer completion hints. It quickly became my opinion that no hints were better than occasional hints. It's just too painful when it frequently doesn't work but you expect it to. I think that ends up being slower than planning to not get help from the IDE. Next, eclipse seems to have been designed with the keyboard forgotten. Everything is mouse centric from navigation to code inspection. Furthermore, I couldn't find any code generation features written (e.g., getters/setters or constructor). Next the code base is way too massive to think about doing anything quickly (as opposed to emacs). Finally, the remote stuff sucked after using TRAMP.

So what now? This is a two part answer, I guess. Answer 1: IntelliJ in textmode. And here's why. It has a lot of the great editing capabilities that I got with emacs including incremental search and macros (although the latter are not as convenient as they are in emacs). It has better file navigation -- I don't think I can live without the cmd-n interface... seriously. It doesn't have remote file editing/building (for C++ obviously) -- but I have handled both of those problems with shell scripts that make it all seamless. It has nicer CVS integration -- it's diffs are great. It has built in syntax highlighting for C++. And it's fast and looks nice.

Part 2 of the answer is that it also supports extension so I'm working on a C++ extension for it. This is a bit of large undertaking since it entails writing a full parser for C++, but at least I can do it in Java, in IntelliJ, be as ghetto about it as I want, and pretty much anything will be better than what I had before.