Thursday, September 25, 2008

Auto formatting code in MonoDevelop 1.0

I struggled with keeping my code formatted correctly, especially for C# formatting standards (I'm a long-time Java developer). Artistic Style is an opensource code-formatter.

Here's how I was able to get MonoDevelop to auto-format my C# code. For MonoDevelop 1.0, it requires patching the source due to a Mono bug.

This patch will work easily on the MonoDevelop 1.0 sources.

Getting and Patching MonoDevelop Source
This is really just a workaround -- the real issue appears to be a problem with the Mono compiler, not with MonoDevelop. However, by adding a simple cast to an anonymous delegate, the compiler works fine.

Get the MonoDevelop 1.0 Source Tar Ball
$ wget http://go-mono.com/sources/monodevelop/monodevelop-1.0.tar.bz2
$ tar xfvj monodevelop-1.0.tar.bz2
Compile and run MonoDevelop
For me on Ubuntu, I had to install some dependencies. Most all of them were lib*-dev packages. Just run "./configure" and fix the dependencies until configure reports no errors. Once dependencies were sorted out, here's how I built and run it before making changes:
$ cd monodevelop-1.0
$ ./configure
$ make
$ make run
Apply the Patch and Recompile
The following patch simply adds a cast to the anonymous delegate as a work-around to the mono bug.

You can easily manually apply the patch by editing line 79 of src/core/MonoDevelop.Core/MonoDevelop.Core/StringParserService.cs and just casting the anonymous delegate to a GenerateString type:
stringGenerators [providedTag.ToUpper ()] = (GenerateString)delegate (string tag) {
Here's a patch file if you want to apply it automatically:

--- src/core/MonoDevelop.Core/MonoDevelop.Core/StringParserService.cs 2008-03-10 20:21:08.000000000 -0600
+++ src/core/MonoDevelop.Core/MonoDevelop.Core/StringParserService.cs 2008-09-25 10:42:48.000000000 -0600
@@ -76,7 +76,7 @@
public static void RegisterStringTagProvider (IStringTagProvider tagProvider)
{
foreach (string providedTag in tagProvider.Tags) {
- stringGenerators [providedTag.ToUpper ()] = delegate (string tag) {
+ stringGenerators [providedTag.ToUpper ()] = (GenerateString)delegate (string tag) {
return tagProvider.Convert (tag);
};
}


Apply the patch with the following commands (assuming patchfile.txt contains the above text!)
$ cd monodevelop-1.0
$ patch -p0 < patchfile.txt
Rebuild and Run MonoDevelop
Once you have MonoDevelop building, we can run it and hook astyle up to it.
$ make run
Artistic Style -- Astyle
The astyle executable must be installed, of course. On Ubuntu, I just installed the "astyle" package via "sudo apt-get install astyle". From the Artistic Style web site you can get whatever distribution you want, or build it from source.

Once it is installed on your system, make sure it is in your command path.

Configure MonoDevelop External Tool
  1. In MonoDevelop, go to Edit->Preferences...
  2. Drill down to Tools->External Tools (a minor bug in MonoDevelop forces you to select another node before you select "External Tools")
  3. Click the "Add" button and fill in the following information:
    Title: _Format with AStyle
    Command: astyle
    Arguments: -b -n -N ${ItemPath}
    Working Directory: ${ItemDir}
    Click "Save Current File"
  4. Click OK

You may want to add additional cmd line options. Please let me know if there are any others that should be used for C#!

Now, when editing a file, you can use Tools->Format with AStyle (or Alt-T, F). You will be prompted to re-load the changed file at the top of the editor window.

1 comment:

Johan said...

External program execution failed.
Error while starting:
'astyle -b -n -N ${ItemPath}'. The process has exited