My name is Michael Hutchinson and I'm a software engineer working for Xamarin on the MonoDevelop IDE and Mono for mobile platforms. Here you can find my journal, projects and photos.

Journal

MonoDevelop on Vista64

Last night I got MonoDevelop working (to some extent) on Windows Vista x64 using the Linux binaries, tweeting my progress along the way.

UPDATE: In another 5am hacking run this evening, I've managed to build MonoDevelop fully in Visual Studio 2008, and debug at all the way to the Welcome Page, using 32-bit debugging on Vista 64. However, I'm going to have to tidy the project file fixes a lot before I commit them.

My starting point was Jonathan Pobst's zip file for MonoDevelop on Windows as a starting point for the dependencies, except GTK# which I installed using the Novell GTK# 2.12.8 installer for .NET.

I then downloaded the openSUSE 11.0 MonoDevelop trunk binaries from my openSUSE Build Service repository, since openSUSE 11.0 has GTK# 2.12, which matches the version available on Windows. I then used 7-Zip to extract the binaries from the RPM, added the dependencies. Also, since some of MonoDevelop links against Mono.Posix 1.0, whereas 2.0 was in the MD directory, I downloaded the mono-core RPM, extracted the Mono.Posix 1.0 dll, and put it in the GAC.

No luck. MonoDevelop failed to run. GTK# doesn't have a 64-bit version, so it failed to locate its glue libraries. Fortunately, Corflags.exe can be used to flag that a PE image needs to be run in 32-bit mode, so after installing the .NET SDK to get hold of this, I marked MonoDevelop.exe as a 32-bit binary and ran it. It worked!

Screenshot of MonoDevelop 1.9.2 on Windows Vista 64

I ran into many bugs, some of which Jonathan had already filed. Some are due to our assumptions about the host OS, but there are also a few subtle bugs and runtime behaviours that MD depends on, and finding these helps us to improve Mono itself.

On the whole, it was pretty successful. On my 32-bit machine I can create HTML files in MD on .NET with fully working code completion, and the code completion window even goes transparent. I'm looking forward to the day that we can offer MonoDevelop as a stable IDE and platform on Windows and MacOSX.

Completing ASP.NET Collection Properties

I've recently been tweaking the ASP.NET completion, adding support for resolving valid children for a control. These can be properties, a property, or controls. More difficult was resolving the valid children for properties, but this is now done:

Screenshot of an ASP.NET file in MonoDevelop showing autocompletion on the children of a collection property.

Unfortunately, there aren't actually any designer or parser attributes for limiting the children of a property, so in order to resolve the children, I assume it's a collection, and look for an Add method with a single parameter derived from Control. If this exists, I use its parameter to filter the types in the control completion list. It's an ugly hack, but it works perfectly for tables and wizards. In the worst case, MonoDevelop falls back to showing all controls.

With this done, the ASP.NET completion is essentially feature-complete.

HTML Completion

The main thing I've been working on for the upcoming MonoDevelop 2.0 release is ASP.NET code completion, and I'm pretty happy with its current state. Recently I've been "downporting" this code into base classes to make it easier to write XML completion and HTML completion editor extensions. A while back I wrote a hybrid XML/ASP.NET/HTML parser, which I've been using in MonoDevelop for triggering ASP.NET code completion. The aims of this parser were to be extensible and to have good error recovery. This makes sharing code between XML-like completion extensions very easy — the completion triggering code and the path bar code are entirely shared between the editors.

After moving the HTML code down to a common base class, I decided to expose this functionality for actual HTML files, rather than just ASP.NET, and wrote an HTML text editor extension to handle this.

As well as parsing a path, for code completion, the parser can also parse a complete document into a tree. This is useful for code folding, error underlining, and the document outline. The ASP.NET extension does not yet use it in this mode, instead using the older and better-tested Mono ASP.NET parser, so the first time this saw use was in XAML completion (about which I still need to blog). I recently (and trivially) "crossported" this code over to the HTML text editor.

The final piece of the puzzle was to write an HTML tag state for the parser to enable it to recognise and implicitly close tags when appropriate. Putting this all together, we get to the most important thing: the screenshot.

Screenshot of an HTML file in MonoDevelop showing the warning underlines on implicitly closed elements.

The blue underlines are warnings, when a tag has been implicitly closed. Note that the document outline is still correctly formed. The red underline is of course an error, and the parser has recovered from that too.

Brahma on Mono

I'm very excited to see that Ananth, the author of the Brahma LINQ-to-GPU provider, now has it running on Mono using OpenGL.

If anyone's not heard of GPGPU, it's the technique of taking a graphic processor unit and using it to run general-purpose computation. Discrete GPUs are incredibly powerful, so if code is ported effectively, it sees a massive speedup. However, the graphics-centric APIs and ridiculously parallelised architecture make this non-trivial. This is where Brahma comes in. It takes your C# 3 LINQ expression trees and automagically runs them on your GPU.

I can't wait to see it running on Linux!

ASP.NET Completion and MonoDevelop Debugger Packages

All the basic ASP.NET code completion features I wanted to get into MonoDevelop are now essentially complete and working with the new code completion database subsystem that Mike Kruger has written to replace our old one. It handles controls, directives and HTML, all of their attributes, and some attribute values, including some colourful and time-saving examples. I've been migrating code "downwards" into HTML and XML completion editor extension, and I'll write another day about how this works and how it'll make good XAML and XML completion easier in the future.

I couldn't wait to get these features out to users (so you can start giving me bug reports!), and I think that the C# code completion has stabilised sufficiently after Mike's changes, so I started updating my MonoDevelop trunk builds again. You'll also be able to try out the text editor and C# completion improvements, your MSBuild project files will be more compatible with VS, and you can play with my vi modes.

The biggest news is that the Mono debugger is officially supported with the recent Mono 2.0 release, so I added MonoDevelop debugger packages for MDB and also for GDB, so you can try the fruits of Lluis' fantastic debugger work. As a bonus, I also created monodevelop-python packages for Christian Hergert's Python addin, and monodevelop-vala packages for the Vala binding that Levi Bard contributed.

I'm taking a short break this weekend to see the fall leaves, and after that I'll be attacking the bug queue and taking a look either at per-project text editor settings, or maybe bringing the Moonlight support in MD back up to speed.

Vi modes in MonoDevelop

I've recently added simple vi modes emulation to MonoDevelop. It's been a relatively quick and easy hack, though I'm pretty sure I'm now running a deficit of free time. I'm not actually a vi user, but I've been hearing from several of our users that they miss vi navigation and commands. While most editors (for example emacs) can be simulated to some extend through a keybinding theme, it's impossible to replicate even the simplest behaviours of vi this way.

After seeing ViEmu, a successful vi emulation addin for Visual Studio, I realised that a vi mode in MonoDevelop would probably see a lot of use, and, as a challenge, decided to bootstrap it. I'm hoping that real vi/vim users will contribute tweaks and patches to bring it closer to a faithful vi experience.

Some of you might be wondering why I started from scratch, since over a year ago, Ankit embedded vim in MonoDevelop. There are several reasons why I don't think this is the best approach. Embedding vim means you have perfect vim support, but you have to manually integrate all of the MonoDevelop features one by one. Integrating code completion is only the first step. Consider integrating language item tooltips, refactoring/navigation commands, error underlining, code folding, language item combos, semantic highlighting, text templates draggable from the toolbox, debugger breakpoint and stepping markers, debugger value inspection tooltips. Even when you finish this, you have to deal with potential future features like per-project editor settings, contexual multi-field templates, and who knows what else. People using vim integration would always be second-class MonoDevelop users.

I don't want to bring MonoDevelop features to vim, I want to bring vi/vim features to MonoDevelop.

Spelunking deep into Mono.TextEditor code, I implemented vi modes and commands at the very core of the text editor. The action-based architecture made this pretty easy to do at the core, though I'm running into a few problems at the higher levels of MonoDevelop, particularly the C# smart indenter, which relies on hooking <Enter> keystrokes. Fortunately it's still very usable.

The code is in MD SVN, and can be enabled through a checkbox in the Preferences -> Text Editor -> Behaviour panel. Features implemented so far are:

Motions
h j k l w b % 0 ^ _ $ G { }
Delete commands
d d{motion} dd D x X
Change commands
c c{motion} cc C r R
Insert commands
a A i I o O
Ex commands
 :q :w :qw :q! :{linenumber}

In addition, keyboard directional keys act where appropriate, normal MonoDevelop keyboard shortcuts remain functional, and visual mode is implemented but so far can only be used with normal MonoDevelop keyboard shortcuts.

I have a pretty good idea of what I'd like to see and how I'd like to see them implemented, in particular with regard to refactoring so that macros and repeat commands can be implemented. This will not be easy, but there are many other low-hanging fruit: B W e E ( ) word and sentence navigation, simple search/replace, repeated motions (e.g. d10w), cut/copy/paste. I'd also like to add some ex commands for IDE features, e.g. build project, jump to definition, rename variable, go to base class, implement interface. These are pretty easy too, though naming the commands will take some thought. It might be worth borrowing some ideas from jVi/NetBeans.

Unfortunately I'm not likely to have any time to spend on vi modes in the near future, but I welcome contributions, and will be glad to provide guidance to anyone who'd like to contribute.

Hack Week: OGRE.NET Packaging

Last week was my second Hack Week at Novell. Massi and I had been intending to hack on a demo for embedding Mono in games, but realised that the overhead of bootstrapping a stable working environment would most likely frustrate our efforts to get something within the week.

Instead, I decided to package some game libraries for Mono on the openSUSE Build Service. I planned to package Axiom, OpenTK and OGRE.NET, and write some MonoDevelop templates for them, but got rather tied up in the details of packaging OGRE.NET and its unmanaged dependencies (I now know far more about packaging SONAMEd libraries than I wanted to!). As a result, I only completed the packaging for OGRE.NET, though I will get around to packaging the others sometime.

You can now install my OGRE.NET and OGRE packages for OpenSUSE 11, reference OgreDotNet and Math3D from MonoDevelop, and start writing code without having to worry about unmanaged libraries, etc.:

Screenshot of a MonoDevelop running an OGRE.NET demo.

Massi did an alternate Mono game embedding demo, and investigated how we could optimise SWIG (or some other binding generator such as DoxyBind) to generate better Mono bindings for C++ code.

Web Application Projects in MD and VWD

I'm very pleased that Visual Web Developer Express 2008 has now gained Web Application project support in Service Pack 1. This means that MonoDevelop users will be able to share ASP.NET projects with VWD developers.

For those of you who haven't heard the story behind this, Web Application projects are support for developing your ASP.NET site as a project. Although VS.NET and VS.NET 2003 did this, it was removed in VS 2005 in favour of "Web Sites", which consider a web site to be a directory. As I'm sure you can guess, the latter system is convenient for editing websites in-place — and they even had FTP support for this purpose — but in my opinion it's a poor system for well-structured development. Clearly other people thought so, because Web Applications were added back to Visual Studio 2005 as an optional addon, and included in VS 2008. Finally in VS2008 SP1, it's reached the free version. The reason for this is quite simple; it's a necessity for proper ASP.NET MVC development.

At the moment, MD trunk does a passable job of opening projects from VWD 2008 SP1, but building and deployment isn't so great, because when I originally implemented these, I had to work around some of the limitations in MD's build and deployment system. These workarounds aren't quite compatible with the MSBuild projects from VS. I'm currently trying to make this seamless by tweaking our MSBuild loader to more closely match the MSBuild build targets and file copy semantics, making the MD deployment system slightly more generic, and implementing the build and deployment targets "correctly" for ASP.NET projects.

Support for importing Web Sites may come later, but for now, it's good to see that we can now interoperate with Microsoft's free ASP.NET development tool.

Demoing Mono in Games

I'm trying to plan some examples of using Mono in game development, so that we have time to get together some solid demos and samples for next year's GDC.

I'm primarily interested in showing how Mono fits into the existing games development ecosystem; we don't really have an XNA-like story for developing fully managed games in Mono at this point. The focus of the demos will therefore be:

  • How easy it is to embed Mono into a game and use it for scripting and gameplay programming.
  • How the Mono and .NET development tools make development faster, easier and more robust.
  • How Mono's performance compares to popular scripting engines such as Lua and Python.
  • (Possibly) using Moonlight as a Mono-scriptable, artist-friendly UI engine.

Does anyone know of any complete games or cool demos for which source or C/C++ SDKs are available, so that Mono could be embedded as a scripting engine? (I'm already considering Source Engine and Quake 3).

Nice ideas for demos would be useful too, though obviously developing a serious game from scratch is out of the question...

Building an IDE Navigation History

MonoDevelop has a code navigation history. When you switch views, or jump around between definitions, it logs the history, and you can browse back and forth like a web browser. However, it has some major issues -- the history it generates is unintuitive and erratic. It seems like it should be a really useful feature, but in practice is frustrating to use, so I recently decided to give it an overhaul.

Unfortunately, navigation isn't an easy thing to get right in an IDE. It's easy to log too many points. For example, if navigation points are logged every time the user switches between all their open document tabs looking for something, it gets very cluttered.

The most important thing is how it fits into the users' code navigation, so I decided to blog in order to get some feedback on my current thoughts.

In my opinion the following actions should not trigger logging of navigation points:

  • Switching through files by control-tabbing or clicking on the tabs.
  • Jumping using the search pad or the error pad
  • Navigation between items using the document outline or the class browser
  • Moving the cursor around with the keys and/or mouse (but this should alter/update the existing nav point)

Whereas the following points should be logged:

  • The destination of a "Go to definition" command
  • The point that's left behind when executing a "Go to definition" command, if it's not too close to the current point
  • A jump to an event handler from a designer
  • Locations in which text is edited, though these points should be carefully pruned so that there are no more than one or two per file

In summary, only direct interaction with the document -- and in particular, large jumps -- should be logged.

How will this fit into your coding flow?

Pages

Subscribe to Journal