C# Code Completion in emacs – CSDE now has a CsdeShell


I’ve been fiddling some more with C# code completion in emacs. I wrote a csde-shell.el that is the CSDE equivalent to JDE‘s beanshell.el . It runs as an inferior shell in emacs. The csde code-completion logic calls out to this shell to inquire about types by name. The shell then returns type information as lisp s-expressions, which can then be parsed and manipulated by csde-complete.el . Actually, the shell is nothing more than Powershell, with a particular assembly of mine loaded into it. The assembly exposes a couple static methods that return information about .NET types.


For example, if invoke this method within PowerShell:

[Ionic.Csde.Utilities]::GetTypeInfo(“System.IO.DriveInfo”,”mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089″);

Then I get back something like this:


(list “System.IO.DriveInfo” ‘type
(list
(list “Name” ‘property “System.String” (cons ‘typemodifiers (list “readonly” “public” )))
(list “DriveType” ‘property “System.IO.DriveType” (cons ‘typemodifiers (list “readonly” “public” )))
(list “DriveFormat” ‘property “System.String” (cons ‘typemodifiers (list “readonly” “public” )))
(list “IsReady” ‘property “System.Boolean” (cons ‘typemodifiers (list “readonly” “public” )))
(list “AvailableFreeSpace” ‘property “System.Int64” (cons ‘typemodifiers (list “readonly” “public” )))
(list “TotalFreeSpace” ‘property “System.Int64” (cons ‘typemodifiers (list “readonly” “public” )))
(list “TotalSize” ‘property “System.Int64” (cons ‘typemodifiers (list “readonly” “public” )))
(list “RootDirectory” ‘property “System.IO.DirectoryInfo” (cons ‘typemodifiers (list “readonly” “public” )))
(list “VolumeLabel” ‘property “System.String” (cons ‘typemodifiers (list “public” ))))
(list
(list “Equals” ‘function “System.Boolean” (list “System.Object” )
(cons ‘typemodifiers (list “public” )))
(list “GetDrives” ‘function “System.IO.DriveInfo[]” nil (cons ‘typemodifiers (list “public” “static” )))
(list “GetHashCode” ‘function “System.Int32” nil (cons ‘typemodifiers (list “public” )))
(list “GetType” ‘function “System.Type” nil (cons ‘typemodifiers (list “public” )))
(list “ToString” ‘function “System.String” nil (cons ‘typemodifiers (list “public” )))))

This is basically the same way JDEE works. It wasn’t too difficult to set up the shell, because I already had a shell (Powershell). The trickiest part was formatting and parsing the s-expressions, on both the C# side and the elisp side.


With this, if you install into your emacs CSDE (remember CSDE is abandonware, stuck at version 0.1 since 2002), and then try a csde-complete-at-point, you will get context-sensitive code completion. Yow! The first time I saw it, I had to rub my eyes!   Yes, I said C# code completion in emacs. And this is not dabbrev. 


Ok, settle down.  This is really just a proof-of-concept at this point. There are tons of limitations, just oodles of them. The code completion is not very robust. It does not do Constructors, or public fields. It is not savvy to public/private/internal etc modifiers. It does not do parameter lists on methods – so once you select a method you have to key in all the parameters with no assistance. (Really in its current state it is nothing more than a smart property and method browser.)  The C# parser in Semantic apparently does not know about the var keyword (anonymous types) introduced in C# 3.0. So if you use var, then you don’t get code completion. It only works, for now, on the classes in the .NET Framework base class library. It would have to be generalized to support other class libraries. Also, to be usable, all the pieces would have to be packaged together – CSDE, the CEDET and Semantic pieces, the Powershell piece. [ Update: I’ve attached to this post the elisp for csde  and the C# code for the CsdeShell.  But that is partial, not enough to get you started. more later on other posts. ]  


Like I said, tons of limitations. But it is a start. Yinz guys should ring me up if you have an interest in developing this further. Or, better, vote if you want me to make this a codeplex project, sort of CSDE-limited redux. (Remember the goal here was just code completion, much more limited that the broader goals of CSDE.)


 

csde-ionic-2008.08.20.zip

Comments (7)

  1. Derek says:

    This is nifty, looking forward to playing with it. 90% of my variable declarations use "var", so it’s not something that will be of tremendous practical use to me, but it looks like fun nonetheless.

    I’ve been waiting for the BCL source code to be released as a package (which is taking forever), at which point I would just run ctags on it and use that as my "completion". Source code is truth!

    In any case, I find dabbrev far more useful in general than so-called "smart" completion. It’s amazing how often intellisense "isn’t". As just one example, I tend to write code that calls methods before they exist. When I subsequently define the methods, dabbrev comes to my rescue, picking up the method name from the call. In order for "intelligent" completion to be useful, I have to code that in reverse. That’s very constraining, and frankly quite silly.

    I typically have several hundred buffers open (thanks desktop.el), so it’s quite rare that I ever have to tyM-/ anytM-/ fulM-/. UnintM-/ complM-/ is a truM-/ beaM-/ thiM-/.

  2. StuckInDotNet says:

    Stumbled upon your work here (c# completion, flymake on c# ,etc.) Looks very interesting. Can you share your code (including the regex to grok csc compilation errors)? I wonder how much work would it be to get CSDE updated (to use powershell/IronPython to do completion, to parse msbuild file use msbuild to do flymake/build etc). If there is a big enough crowd, maybe this can go somewhere.

    VS 2005’s emacs emulation is pretty decent (tab to indent works, at least), but it can’t beat the editing efficiency in Emacs with all the bells and whistles — people are always amazed at how fast I can switch buffers, let along all the dabbrev/completion stuff.

  3. I just recently stumbled upon your website… I have to say I am excited. I use emacs over VS everyday, and I am also frustrated by the lack of intellisense. I hear all kinds of bs about ‘real programmers not using intellisense’. I honestly don’t care. I love emacs, but I also NEED productivity. Intellisense makes things faster, and that is a fact.

    I am willing to help you build intellisense for emacs. We can reuse code or even begin from scratch. I have to warn you though, I am not fluid in listp just yet. But I am willing to spend time on it.

    Drop me a line if you are interested.

    aespinoza@structum.com.mx

  4. Shae Erisson says:

    I use emacs for SharePoint dev, I’m excited about this!

  5. The beanshell is something that, I think, was specially engineered to support the JDE, and particularly

  6. raf says:

    Hi,

    I’ve just release a tool that can do C# completion in emacs, and a little more.

    It’s an early release, so you should expect a lot of bugs.

    you can give it a try here : http://code.google.com/p/idebridge/

    your emacs articles was a source of inspiration for me, so thanks !