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 (35)

  1. Anthony says:

    Will you please post your .emacs file?

    Thanks,

    Anthony

  2. Aemon says:

    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

  3. Barry Kelly says:

    I use a variety of editors for general purpose code writing, but the only reasons I end up firing an IDE are (1) debugging, (2) intellisense and (3) code navigation (goto definition, goto declaration, with automatic disassembly of the public interface where necessary). Without 1, 2 and 3, I’d have no need for an IDE. However, by your own admission, these are exactly the things that emacs wouldn’t give me, so it all amounts to not being a reason to use emacs (note that doesn’t mean "a reason not to use emacs; I mean absence of a reason, not a reason to avoid).

    The main editor for general purpose stuff is joe, running in Cygwin. I have it configured for syntax highlighting for all the languages I use; combined with ctags it has very very rudimentary goto support. I can write macros for snippets, which I usually don’t end up using. About the only one I use is for braces: insert ‘{‘ here, return twice (with indent), insert ‘}’, go up one line, tab.

  4. Sammy Larbi says:

    Is it possible to release what you’ve done as a handy-dandy install / plugin?

  5. she says:

    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)

  6. Pesinos says:

    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.

  7. Andy Norris says:

    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.

  8. Seth Morris says:

    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….

  9. Jacob says:

    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?

  10. DotNetInterop says:

    OK, in response to the requests from Sammy and Pesinos, I will package up what I do, to try to make it installable and re-usable for just about anyone.  I don’t have a linux machine though, so can’t test it there. Gotta think about the best way to deliver it.  It’s maybe just a zip of the elisp files and the snippets and the templates.  

    I was hesitant to pack it up just yet, because I think intellisense is a big hole. Also I will have to look into the flymake minor mode.

  11. DotNetInterop says:

    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.  

  12. anon says:

    Have you tried setting up etags for intellisense? I did that some time ago and it worked great.

  13. MasterChief says:

    You are so lame man… you spent all that time just so you have MOST of the features you get for free on the C# express. lol you FAIL at seeing the big picture

  14. DotNetInterop says:

    MasterChief, thanks for commenting.  Thanks for pointing out how LAME I am.  Very helpful.  Let me ask you something though – Did you read the article?  I spent all that time to see how much time it would take me, and what I would get for my time.

  15. DotNetInterop says:

    @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 .

  16. Blair says:

    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.

  17. Aemon says:

    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…

  18. 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.

  19. Dan says:

    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 😀 But I couldn’t give up the comfort and ease of use of Visual Studio. Especially programming C# which is where is really excels.

  20. Allan says:

    I’ve tried the emacs mode in VS 2005.  It’s ok, it gives you the most common keybindings, but it is NOT like using emacs.

    There’s a set of VB macros floating around somewhere that will give you an emacs-ish experience in MS Word as well.

    I use emacs to edit C# code, but I use VS to build and otherwise work on "solutions".  I’ve never liked intellisense too much, and I debug by instrumenting and understanding my code, not by stepping line-by-line through with a debugger. So given my style, I have not yet found enough motivation to try to create a full .NET IDE in emacs.

  21. gareth says:

    I came up with almost the same solution, nice to see I haven’t missed much. I have VS though so I can use one simplification which is to use the .sln file to build: I have a function which looks upwards in the directory tree from the current buffer for a .proj or .sln file and compiles it through the devenv.com program in an emacs compilation buffer.

    For intellisense, tags work fine together with HHelper (which can be used as a command line searchable msdn). These days I only fire up the VS gui once or twice a day for stepthrough debugging.  

    I have to say I wouldn’t recommend someone learn emacs just to avoid VS if VS is available. You’ve got to appreciate it as an all-in-one solution, I do sql queries, file access, even launching programs from inside emacs, the power comes in customizing it to your exact desires, but you’ve got to have those desires.

  22. 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#.

  23. Timothy Murray says:

    Great post, thanks–your efforts are definitely NOT lame.

    As a contractor, I have to maintain cross platform proficiency and xemacs/cygwin on dos really helps me maintain that. Your site really helps as well.

    fwiw, (I am new to c# and .net) I can run the .Net 3.5 SDK shell in xemacs on cygwin. I am definitely going to implement your setup for c# dev with the Powershell.

    That port of the Beanshell to the Powershell is really interesting stuff; I will be implementing it at my current gig.

    fwiw, check out planner.el  –ms outlook for emacsen

    Cordially,

    t.

  24. Tyson says:

    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…

  25. adf says:

    I’m surprised you aren’t using Semantic. It does pretty much exactly what you want. cf. http://cedet.sourceforge.net/intellisense.shtml

  26. DotNetInterop says:

    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. 

     

  27. that's what she says:

    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.

  28. DotNetInterop says:

    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.

  29. syrex314 says:

    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.

  30. all just tools says:

    emacs guys try to tell VS guys how much more efficient emacs is. VS guys don't really care because it is so much easier and more intuitive. For me I don't have all the time in the world trying to figure out all the nerdy things. I just want to get my job done, and VS does this right. I run codes so that I see outputs which help me understand science questions. either VS or emacs is just freakin tool. I want to spend as little time as possible with the tool.

  31. Graham says:

    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.

  32. Ben says:

    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

  33. bdog says:

    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

  34. Aaron says:

    Saying Emacs is better than VS on a Microsoft site? You sir have some gigantic balls.