Monodevelop Python Revisited

Development on my python addin for monodevelop has gone so quickly that I've gotten pretty excited about working on it. It has come from realization to working code in just a few short days. So I thought I'd put together a little overview of what I have added this week and where I'd like to go.

As an aside, I've noticed frequently that people do not understand that monodevelop can be used for more than writing .NET. Like many other IDE shells, it is a framework that facilitates development tools. It happens to be written and deployed on Mono. I think because of this, we may want to alter naming of addins in a way that make it less confusing. Michael Hutchinson suggested PyDevelop/RubyDevelop. Of course, RubyDevelop doesn't exist yet. IronRuby's AST should make that doable in a relatively short time period if someone is interested.

Its worthwhile to note that I only have support for python2.5. However, the core is built already to support more versions of the python runtime. I just need to do it.

Compiling of Code

Often times I forget that python code is compiled because it works so well. You can pre-compile your code to save a marginal amount of time during startup. It also lets you be sure that your code is syntactically correct. Debug mode will generate .pyc's by default and Release mode will generate .pyo's.

Parsing of Python

The parsing of python happens in a python subprocess. I originally did the interaction with the host process over stdin/stdout. I moved away from this as it became a source of contention as there is inherently no concurrency. Both python and .NET happen to come with HTTP utilities and I get concurrency for free! Therefore, the python process sets up an embedded HTTP server and the .NET code POST's to it. The result of the parsing comes back as an XML representation of the python AST along with some extra sauce. For example, I also analyze the code with pyflakes if it is available, allowing for warnings to be displayed inline with errors. You can see this in the image below. Currently, these are highlighted in red as well with errors, but I believe this will be changed in monodevelop before too long. Any of yellow, green, or blue would be a good choice in my opinion.

Python Source Regions

Now that we have an AST representation of the python source code we can start to do fancy things with it. We know how big blocks of code are, where they are located, and what modules they interact with. Using this knowledge, we build DomRegions to be used by the editor. This gives us code folding as you can see below.

You will notice throughout the rest of this overview, how this AST is fundamental to providing language support.

From the AST, I currently have information about:

Code Completion

With both regional and contextual information available, we can take the current editor cursor position to know where we currently are within the AST. This allows us to provide code completion for locals, attributes, functions, modules and whatnot. Note that I just have basic functionality here, and I intend to really beef this up in the short term. The proof that it works is there, so thats a decent start.

Smart Indentation

Its important for your text editor to not slow you down from your current thought process. One of the easiest ways to keep your flow moving is to always have your cursor in the right position. The editor will flow with your movements for blocks. This is really quite simple in python, as blocks are prefixed with a line ending in a colon “class Hi:”. My implementation of this may not be the correct way to go, but “it works”. Also note, until per project code formatting arrives in monodevelop, you should set your tab vs. spaces mode to 4 spaces.

Class Browser

Monodevelop includes an extensible class browser pad. The implementation really is a piece of art. I've been fortunate enough to write code for it a few times in the past. Anyhow, we use the AST objects directly within this tree to render a hierarchy of the modules within your project. I'd like to include imported modules outside your project as well.

Document Outline

In similar spirit to the class browser, the document outline pad provides a module hierarchy for the currently open source file. The implementation here is currently hack'ish do to the interfaces being very .NET specific. It sounds like this may change before monodevelop 2.0 is released.

Editor ComboBox JumpTo

Many developers have come to love the combobox at the top of the editor to jump to regions within their source file. I personally like to keep my individual sources as succinct as possible, but I understand why its useful. Therefore, I support that as well. Again, this is sort of hack'ish do the the current interfaces.

Where would I like to go?

I have lots of ideas and diminishing time to implement them. So if anyone feels like helping, its time to speak up.

The debugger interfaces appear to be stabilizing, so this sounds like a feature worth implementing. The bundled python debugger should help us a lot here. We can again work as a subprocess to perform the necessary hooks for step/locals/watches and whatnot. While we are at it, how about remote debugging over ssh.

I'm also excited to start on a profiler. The interfaces for the profiling API are thankfully generic enough to support this relatively easy. We again simply need a subprocess that writes out the profile snapshot to a file. Using the output from the profiler, I will build a view that includes (Module/Function, N Calls, Avg per call, Total time, and Total % of time). I haven't used profilers too much, so if you have suggestions on what you want to see, please don't hesitate to chime in.

An interactive python shell is a must. Will most likely defer to Vte and python/ipython for this.

UML generation is really quite easy when you have the AST already available. I would love to see someone make a gtk canvas that can read graphviz dot files. Making it look sexier than graphviz is a must. I remember using omnigraffle years ago and it looked incredible.

Templates. We need a bunch, simple as that. I'm thinking gtk examples, unit tests, twisted plugins, qt demos, clutter, GNOME, and more.

Code coverage is also useful and simple enough to record during runtime. We can use the output of this to render over the icons on the class pad. Essentially light up code paths that are never executed.

Setuptools integration could be worthy as lots of good projects in python are available from the python cheese shop. (“easy_install processing”).

Refactoring seems doable as the python language makes that fairly easy. I haven't looked at the refactoring API's within monodevelop yet, so its hard to say. At the minimum, I'd think renaming of methods, classes, and modules should be doable.

This is the end of me wasting your time, continue with your hacking and thanks for reading this far.

Update

git://git.dronelabs.com/git/users/chris/monodevelop-pybinding.git

If you have monodevelop from trunk, you can install from the Addin Manager using http://audidude.com/python-addin/

Update

This has been merged into monodevelop trunk. It is in extras/PyBinding/.

-- Christian Hergert 2008-10-03

Back to Index