Emacs is better than Visual Studio as a C# Development Tool?!!

I recently spent some time fiddling with my setup of emacs on Windows. I use emacs for lots of stuff; just now I optimized my setup for development of C# apps.

I knew of the JDEE, which has been around for a long time. JDEE is the Java Development Environment for Emacs; it used to go by the moniker of JDE. It has code completion (aka "intellisense"), compiling tools (ant I think), syntax highlighting, an "immediate window" (BeanShell) for evaluating Java expressions right now, that kind of thing. There was a copycat project launched in 2001 called CSDE (C# Dev Env for Emacs). It sounded like a great idea, but it is now stale as 3-day old doughnuts, not having been updated since early 2005. With just one contributor, it never reached critical mass. And no update since before the launch of .NET 2.0 means no support for generics, I suppose, no support for msbuild, nothing for the yield keyword, and other goodies like that. Certainly nothing for LINQ syntax or anonymous methods. I didn't even have the courage to take it for a test drive.

So lacking an integrated set of add-ons, what would be the best Emacs setup, for C# development? Here's what I put together.

  • First, emacs v22.2. This was released last week. I upgraded from v21.3. It was painless.
  • csharp-mode.el from Dylan Moonfire of Moonfire games. Latest is v0.7.0, Sept 2007.
    The main thing in this "mode" is C# syntax highlighting (using emacs' "font locking" capability) and auto-indenting.
  • A template library – I used yasnippet.el. This allows me to type "fore<TAB> and get a template of a foreach loop. Or I could type try<TAB> and get the boilerplate for a try…catch…finally. Yasnippet ships with templates for C, C++, Java, Ruby, Python, HTML, CSS, and even Fortran (??). But no csharp. I created a set: new class, foreach, arg parsing in a console app, xml serialization, if-then-else, while, using, and singleton among others.
  • hideshow.el, which is included in emacs v22.2. Hideshow can collapse or expand regions of text bounded by three-curly-braces . I almost never do that in my C# codeJ , so I had to write an extension to hideshow.el to allow it to recognize the region/endregion syntax supported in C#. There were some suggestions on the csharp page on the emacs wiki, that I only needed to set a regular expression up. But, 2 things: the regexp didn't work, and when I modified it to work, hideshow.el still did not behave as I wanted it to. So I had to write the extension. (I'll post that separately)
  • defaultcontent.el – fills empty (new) files with some default content. Every time I create a new .cs file from within emacs, I can fill it with a header, some copyright info, and even some boilerplate code, like using statements and a class skeleton. This is not part of emacs, it is a separate add-on. Setting up the new-file template was pretty easy.
  • skeleton.el – this does auto-insert of matching characters, so for example when I type an open-curly I get a close-curly automatically. This is included in emacs, all I needed to do was set it up.
  • htmlize.el – which is a bit of magic that generates html for the syntax-highlighted c# code. I wrote about this a few days ago.  This is the moral equivalent of CopySourceAsHtml, from Steven Coller.
  • Customization of the existing, built-in emacs stuff – like
    • timestamp. Timestamp is I can insert a field into the source file that emacs automagically updates every time I save the file. The default is that emacs looks only in the first 8 lines for the timestamp. But for C# code, that was not sufficient, so I needed to bump it out a bit. I can even stuff the timestamp into a const string within the class. Nice.
    • Properly configuring the next-error function in emacs to be able to see the error messages generated by csc.exe.
    • To properly use csharp-mode, I needed to define a C# Style, which defines my indentation preferences and so on. This is about 20 lines of elisp.
    • I wrote some elisp functions to do common refactoring tasks, like convert a field to a property with a getter and setter, stuff like that.
  • Setting up a default msbuild file. For quick little projects I'd like to build a single .cs file into an exe. But I don't want to change the msbuild file every time I create a new .cs file.  So it's gotta be general.
  • Stitching together all the pieces in my .emacs file. I need to load htmlize, hideshow, yasnippet, defaultcontent, and csharp-mode. Also need to set a bunch of key bindings and a style for csharp-mode and set up some hooks for hideshow.

There were some places where I came up short. Intellisense is something I really wanted, and I know it has been done within Emacs for Java. The CSDE though, was just too stale. I found a smaller package, dedicated more narrowly to just .NET intellisense, called csense. Bummer though; this thing did not work for me at all. It was a non-starter. I invested quite a bit of time but no joy. Couldn't find any doc. It seems like it was one of those things that someone built, and it worked for him, and that was it. I think it had something like 13 downloads.

I also checked out a package called folding.el. But it seemed heavier than hideshow.el, and unnecessarily so. Also, not sure if folding.el is still being maintained. I can't even find the URL now, where I downloaded it from, though I know I downloaded it. The emacs wiki says that the author appears to have vaporized. Anyway, I punted on folding.el.

I don't have integrated debugging, but I can separately start up the clrdbg.exe which is included in the .NET SDK.

I didn't bother with setting up unit testing. I can run nunit, from outside of emacs. So it's really independent.

The upshot is, I have a pretty good development environment for C# now, in Emacs. And, it's free. (no license charge) It uses emacs and a bunch of free add-ons, and the .NET SDK, which is a no-cost addition to Windows.

How does Emacs compare to Visual Studio?

Comparing Emacs to Visual Studio… hmmm…. Let me start by asking you a question: what is your time worth? I like what I have set up here, but I have to say, I don't think what I have done is accessible to, or feasible for, most people. I have used emacs for 20 years, the keybindings are in my nerve cells, it would be like major surgery for me to stop using it. But for most people, I imagine emacs itself would be hard to approach. Beyond that is the C# support, which is all add-on. The sheer number of pieces I had to seek out and install, configure, understand – that alone is daunting for most people I would guess. Couple that with the fact that I had to wade through and even write elisp code, which is yes, something I can do, though not very well. (I took a couple lisp courses in college 22 yrs ago) The other black magic is regular expressions, which are tricky and for some people, a complete puzzle. I had to use a ton of regexp's in the setup, for everything from hideshow (to find region/endregion) and the compile error messages. I have regexp knowledge from way back, too. All of this took lots of time to do, as well as some esoteric skills.

So for me, the emacs setup will continue to be useful. But for most devs, I'd guess it would be a tough sell.

In contrast, Visual Studio is just an install. Most things I want are set up already – I don't have to write a regular expression, for example, to find the compiler error message. I don't have to write an msbuild file to compile. The refactoring tasks are already built-in – you don't have to write code to describe what refactoring you want. Debugging is built in. Intellisense. Unit testing. Snippets. Collapsing regions of code. All of it is just soooo much more accessible for mere mortals, or for anyone, really who values their time realistically. And that doesn't even mention the graphical designers, the database designers (eg linq support), or the team-development capabilities of Visual Studio.

The Bottom Line

My effort at setting up emacs was a labor of love – it is not the kind of thing I would recommend to anyone who wants to actually make money at writing code. I did it because I wanted to see if it could be done. If time is money, I spent myself into the poorhouse setting up emacs for C# work. I spent a bunch of time evaluating options, exploring dead-ends. (I was just thinking – g*d help me if I lose my laptop, because my setup is totally unique and not reproducible.)

The bottom line is that it is possible to set up emacs as a dev environment for C#. What I got for myself – I will actually use it extensively, for quick jobs and small projects, as well as larger single-person efforts. For me, it will be better than VS, for those kinds of projects. But in the end, Visual Studio is still sooo much better in terms of overall cost/benefit.

On the other hand, all of the emacs stuff I did works on any platform. I benefited from emacs packages that were developed for and by devs using mono on non-Windows platforms. So I can see that for some people, emacs could make sense. The way I got into emacs, by the way, was in school. There was a critical mass of people using emacs as an editor, and so I was able to pick it up easily. Then I worked at a company where emacs was standard issue, and that is when emacs became part of my DNA. I had no choice in the matter. The emacs setup was all prearranged, set up and shaken down for me. I can see that continuing as a common scenario for new developers picking up emacs – when they join a team of experts who have done all the setup for them, and who can transfer the lore to them. The body of experts can make emacs accessible to the new guy. But without that, IDE's like Visual Studio just seem sooo much more broadly applicable.

Hey, last thing - If I've missed any gems for working with c# within emacs, please let me know! Especially intellisense!