Freigeben über


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!

Comments

  • Anonymous
    April 12, 2008
    PingBack from http://microsoftnews.askpcdoc.com/?p=1709

  • Anonymous
    April 12, 2008
    Will you please post your .emacs file? Thanks, Anthony

  • Anonymous
    April 13, 2008
    Have you checked out flymake-mode? It ships with emacs 22; it periodically invokes a compiler on your current buffer, highlights errors etc. Seems like a natural fit for a statically typed, one-file-equals-one-class language like C#. -Aemon

  • Anonymous
    April 13, 2008
    The comment has been removed

  • Anonymous
    April 13, 2008
    Is it possible to release what you've done as a handy-dandy install / plugin?

  • Anonymous
    April 13, 2008
    The problem is that while emacs and vim will always be flexible, they require a lot of knowledge, time etc... to gather stuff. And while you may know and enjoy writing elisp code, I simply refuse to learn something specifically for one program. I could live with python or ruby these days, or with a human-readable nice and easy special language, but learning lisp just so that i maximize using emacs sounds like sure overkill, especially cuz i would know i wouldnt really use lisp outside from that (sorry lispers)

  • Anonymous
    April 13, 2008
    The work you did would be valuable to people that wish to have a similar development environment. By using your experience to create an automatic installer, you'd have many greatful people (including me). If that wouldn't be feasible for you, just making a blog entry with all the steps outlined would be the next best thing.

  • Anonymous
    April 13, 2008
    Another request for you to post all the relevant source: .emacs and all the modified elisp files. It would be great to get a C# mode set up without having to reinvent everything you did. Also, I've started looking at modifying Tuareg mode into a full F# mode, and it would be great to take a look at some of the things you did and try to do something equivalent.

  • Anonymous
    April 13, 2008
    I can see this being useful for Mono developers, but I would never recommend emacs as a "standard" in any company trying to make money. It requires too much training and it's impressive customizability means no developer can work at another dev's desk. It also isn't worth giving up Team integration, refactoring tools (although some version of those do exist for C++ in emacs, I don't know if there are good c# versions), etc. But I'm biased. The first emacs setup I used launched with the text "If you need help, press [some key combination]." That key combination launched Eliza....

  • Anonymous
    April 13, 2008
    About folding.el and hideshow.el, I have just been using C-u <num> C-x $ to fold on indentation level.  Is hideshow.el significantly better?

  • Anonymous
    April 13, 2008
    The comment has been removed

  • Anonymous
    April 13, 2008
    Oooooh, I added the flymake stuff, which now works.  It's nifty.  I like it.   Flymake is at least 5 years old, but it still seems to be a bit rough. There's no doc in the el file.   It doesn't respect the "compile-command" variable of compile.el, instead hard-coding make.  There are a bunch of other missed opportunities for customization in flymake, too.  There's no doc for how to specify a different check-syntax build.  There's no doc for how to do a better cleanup - so I have temporary output files hanging around.  Why isn't flymake-allowed-file-name-masks an alist?  Basically flymake is bad manners all around.  But it's mostly working now, and it seems very handy.   I show what I did to get flymake to work with C#, in this post.  

  • Anonymous
    April 13, 2008
    Have you tried setting up etags for intellisense? I did that some time ago and it worked great.

  • Anonymous
    April 14, 2008
    The comment has been removed

  • Anonymous
    April 14, 2008
    The comment has been removed

  • Anonymous
    April 15, 2008
    @Jacob - I don't know if hideshow is better or worse than that magic incantation of keystrokes you provided.   I didn't read the spellbook on collapsing text, so I'm not sure I've picked the optimal mechanism there.  But what I have is built-in to emacs (from v22.2 at least) and it works for me .

  • Anonymous
    April 19, 2008
    Hey you do know that their is an Emacs mode inside of VS 2005 and higher; just go to Tools ->Options-> Enviroment->Keyboard and select Emacs.

  • Anonymous
    April 22, 2008
    RE: Flymake Agreed! flymake needs to be a much more general tool -- there's a lot more you can do with external programs than just highlight errors. Imagine if you could plugin profilers, syntax checkers etc...

  • Anonymous
    May 17, 2008
    I have been looking for lightweight alternatives to do C# development for a while, so far nothing really click with me. I'm not sure if I could use emacs (I haven't used before) but I will give it a try. Thanks for this post, very interesting stuff.

  • Anonymous
    May 30, 2008
    That's quite cool but what about the debug style features in C# - like rewriting some of the code while debugging and then seeing the changes immediately. Or dragging around the step though cursor back in "instruction time". These are some of the things I find quite useful. As is hovering the mouse over variables to see their value. I like the idea of emacs - I'd love to program my own commands and I quite like lisp - even emacs-lisp :D But I couldn't give up the comfort and ease of use of Visual Studio. Especially programming C# which is where is really excels.

  • Anonymous
    June 11, 2008
    The comment has been removed

  • Anonymous
    September 03, 2008
    The comment has been removed

  • Anonymous
    September 29, 2008
    We used emacs in college for writing C++.  It was great to use as an IDE.  Really do miss it even if I did not use it for very long.  It's great that someone has actually gone the route in having emacs support(partial) for C#.

  • Anonymous
    November 07, 2008
    The comment has been removed

  • Anonymous
    November 14, 2008
    Aemon: C# is statically typed, but not "one-file-equals-one-class".  You can have any number of toplevel classes in a file, and name the file anything you want. And I'm not sure what that has to do with flymake-mode: I love flymake even (especially?) for completely untyped languages.  A dumb syntax error is still a syntax error.  I'll have to figure out how to hook up C# to it now...

  • Anonymous
    January 30, 2009
    I'm surprised you aren't using Semantic. It does pretty much exactly what you want. cf. http://cedet.sourceforge.net/intellisense.shtml

  • Anonymous
    February 09, 2009
    I looked into semantic - http://blogs.msdn.com/dotnetinterop/archive/2008/04/21/c-code-completion-in-emacs-a-look-at-cedet-semantic-and-csde.aspx ...I found it wanting....but then was able to augment it with CSDE-Shell and get code completion.   

  • Anonymous
    July 09, 2009
    I find your information to be suspect since you claim to be an emacs user and yet fail to malign and condemn Visual Studio. On a more serious note, I find it reassuring that there exist people who see value in both options!  I keep trying to get into emacs, wondering if the frothing-at-the-mouth emacs-fanatics may have some secret, but I guess for the type of work I do it may not be worth the effort.  And while VS may not be the world's best text editor, I do lovelovelove its code completion and code navigation.

  • Anonymous
    July 23, 2009
    Ha - well there's a time and a place for frothing at the mouth, and it is not while typing in a text editor.  Emacs is useful to me but I wouldn't recommend to anyone that they go out and learn it themselves. Unless you have a supportive community of expert emacs users, and maybe a background in lisp, it will be hard to justify the effort.

  • Anonymous
    May 13, 2010
    Thanks for the great post-- I'll have to give that a try. In the meantime I've been impressed with the emacs keybindings in VS. You're right, it's not quite like using emacs, but it's unbelievably better than Matlab's poor attempts at mapping emacs keybindings.

  • Anonymous
    January 05, 2011
    The comment has been removed

  • Anonymous
    January 31, 2011
    You can hook "goto definition" and most things through emacs. Macros can access an API that does everything the IDE does. The primary API is huge: msdn.microsoft.com/.../envdte(v=VS.80).aspx. You can write a program that runs macros in the background, and call that program with lisp, effectively giving you direct control over Visual Studio's internals w/ emacs hotkeys.

  • Anonymous
    July 15, 2012
    I think VS is now significantly better than EMacs ( especially 2010-2012) by the time you installed all that stuff you would have learned a lot of the VS keys - VS is mostly KEY driven at its best and the control / replace and integrated typesafe refactoring's are gold on big projects... You can do everything emacs can but a lot more.. People need to change  and VS is not hard to learn ( well the mouse stuff is easy the keystroke stuff talks a big longer eg auto formats , snippets , selective replace etc) I still use emacs on Unix sometimes. Ben

  • Anonymous
    November 19, 2013
    all you need for awesome emacs c# development is omnisharp-emacs and omnisharp server.  It gives you intellisense/code complete, navigation, find all references, goto definition and more. It's quite easy to setup and is actively updated.  github.com/.../omnisharp-emacs and github.com/.../OmniSharpServer

  • Anonymous
    May 21, 2015
    The comment has been removed