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 Tips: Code Focus

Code focus is a useful feature that helps to show the structure of your code. It's activated by hovering over one of the fold markers in the text editor margin for a few seconds. The activated fold region and its parent regions are highlighted using graduated colour differences on the text editor background.

Code focus highlighting regions in the text editor

Code focus can also be toggled on and off from the keyboard using the Control-Shift-K shortcut on Windows and Linux, or Cmd-Shift-K on Mac. When activated in this way it's persistent until toggled off, and it follows the caret, highlighting whichever region it's in.

MonoDevelop Tips: Preferences, Policies and Project Options

There are several different kinds of settings in MonoDevelop — Preferences, Policies and Project Options — and the distinction between them is not immediately clear. This post aims to provide an explanation of them and what they're used for.

Preferences

Preferences control MonoDevelop's behaviour and appearance, but do not directly affect projects' code or output. This means that they are user-specific, and are stored in the user profile. Examples of preferences are the text editor's colour scheme, whether the text editor shows line numbers, the font used for output pads, whether MonoDevelop jumps to errors after a build, and so on.

The Preferences dialog can be accessed from the MonoDevelop->Preferences menu item on Mac, the Tools->Options menu item on Windows, and the Edit->Preferences menu item on Linux. This is consistent with other applications on these platforms.

Project and Solution Options

Project Options are specific to projects, and affect how they're built and run. This includes things like compiler options, the name of the output file, the arguments used when running the project, and so on. These options are stored in the project file, so other users will be able to build and run the project correctly. Where possible, they are mapped to the options used by Visual Studio and the MSBuild/xbuild command-line build tools.

The Project Options dialog can be accessed from the Project->{Project Name} Options menu item, or from the Options context menu item on the project in the solution pad, or by double-clicking on the project in the solution pad.

Some options are part of a project configuration. Projects can have multiple configurations, so by switching between them you can build different outputs. Configurations will be covered in a future post.

Solution Options are similar to Project Options, but for solutions. The Solution Options dialog can be accessed from the Project-> Solution Options menu item, or from the Options context menu item on the solution in the solution pad, or by double-clicking on the solution in the solution pad.

Policies

Policies are settings that affect how projects and code are formatted and organized, such as code formatting settings, naming conventions, and so on. In many other IDEs these settings are user-specific preferences, which means that different users working on the same project do things inconsistently, or have to change their preferences depending on which project they're working. Policies ensure that these settings are consistent for different users working on a project, and make it easy to manage sets of policies across projects.

Because most policies are invariant across all projects within a solution, projects can be set to inherit the policy of their their parent solution or solution folder, and this is the default setting. This means that in most cases, policies only need to be edited on the solution, and these changes will be picked up by the projects. Policies settings panels are shown in the Project Options and Solution Options dialogs. They can be recognized by the "Policy" combo box at the top of the panel, which allows you to pick a policy to use, or set the item to inherit the policy from its parent. Alternatively, you can customize the settings, and the combo will show "Custom".

When a solution is first created, or a solution without policies is saved, it will take its initial policies from the user's default policies. From that point on, they are only stored in the solution and are not affected by changes in the user's default policies, else solutions could not be shared between users and maintain consistent policies.

While Preferences and Project Options are familiar to users of many other IDEs, policies are something unique to MonoDevelop, and hence they sometimes cause confusion. Another post will explore the policies system in more detail.

MonoDevelop Tips: Opening Multiple Solutions

Normally, MonoDevelop only allows a single instance of itself to be open, since many of its data files (preferences, code completion databases and so on) are not designed to be accessed by multiple instances at once. However, it is possible to open multiple solutions at once. In the Welcome Page, hold down the Control key while clicking in an item in the Recent Projects list. There is a hint about this feature in the status bar while you hover over these items: "Hold Control key to open in current workspace". Do this, and the solution will be opened without closing the old one.

Multiple solutions open at the same time

You can also open multiple solutions using the "Open" dialog. If you select a project or solution in the Open dialog, and a project or solution is already open, the dialog will show a "Close the existing workspace" checkbox, which is checked by default. Simply uncheck this, and open the solution.

The option to close the existing workspace when opening a solution

The reason these options are named the way they are is that MonoDevelop always has an implicit workspace. Because it's implicit, it's not displayed in the solution pad, as it would just waste space. When you open a solution, MonoDevelop normally closes the existing workspace, and creates a new one for the newly opened solution. These options allow you to override that behaviour, and instead add the newly opened solution to the existing workspace.

MonoDevelop Tips: Grouping Related Solutions with Workspaces

Workspaces can be used to organize related solutions, and provide a convenient way to open several solutions at once. Unlike projects in a solution, which can have references and build interdependencies on other project within the solution, solutions in a workspace are independent, and can be opened and built independently of the workspace and the other solutions in it.

To create a workspace, use the command File->New->Workspace, enter the desired name of the workspace, and select the location. The workspace will be saved as a mdw (MonoDevelop Workspace) file. To add existing items to workspace, right-click on it in the solution pad, and use Add->Existing Item. This allows you to add workspaces as well as solutions, since workspaces can be nested. There are also commands to Add->New Solution and Add->New Workspace, which create a new solution or workspace and add it to the workspace directly.

A workspace with a child workspace and child solutions

MonoDevelop Tips: Task Comments

A common practice when writing code is to annotate incomplete or questionable areas with comments prefixed with warnings like TODO, HACK, FIXME, and so on. MonoDevelop draws attention to these by recognizing them and highlighting them:

A task comment highlighted in the source editor

The Task List pad, accessed from View->Pads->Task List, has section that lists all of these items and allows you to jump directly to them. This is useful if you're looking for things to fix.

Task comments in the Task List pad

There are several built-in tokens for recognizing task comments, but you can define your own in Preferences->Task List. When you add a task comment token, comments with that token will be highlighted and listed the same way as the built-in ones.

Task

You can also set different importance levels for different task tokens, and can set the colours used in the task list for the different levels.

MonoDevelop Tips: Custom XML Schemas

MonoDevelop's XML autocompletion is driven by XML schemas, although there is a fallback that will use existing nodes in the file to provide a very basic form of completion. MonoDevelop keeps a list of known schemas, and when trying to provide completion for a given namespace, it looks in that list to find one that matches the namespace. There are built-in schemas for several namespaces, but it's possible to add your own in Preferences->Other->XML Schemas. Registered schemas must have a unique namespace, since that's how they're identified.

The custom XML schemas panel

In the option panel there is also a list of file associations. If you add a file extension to this list, it will be treated as XML, so it will get syntax highlighting, code folding, code completion. and so on. You can also specify the default schema for the file, using one of the registered schemas. This will be used as the schema for the root element, even if it's not explicitly specified in the file.

MonoDevelop Tips: Author Information

There are many convenient things MonoDevelop can do, but for some it needs to know a bit about you, such as your name, your email address, and who owns the copyright on your work. This is used for adding standard file headers, committing to a VCS repository, creating AssemblyInfo.cs files, and so on. You can provide this information in the Author Information panel in Preferences.

The author information panel

If there is a solution for which you wish to use different information, you can override the author information for that solution in the Solution Options. This is stored in the solution's user preferences (the *.userprefs file) so it won't be shared with other users.

MonoDevelop Tips: Inline Errors

In MonoDevelop 2.4, we introduced inline error markers, similar to Xcode. When you build, errors and warnings are shown inline in the code as message bubbles, though of course they also remain available as a list in the Error List pad.

An inline error message bubble

We do our best to make sure the message bubbles don't become too intrusive, but remain usable. They are normally shown on the end of the line that they affect, but if they are too long, they will wrap onto a new line. If they are really long, they ellipsize, but the full error remains available on a tooltip. If there are multiple errors or warnings on one line, they collapse down to a single line with an indicator indicating how many there are. Clicking on this indicator or moving the caret into the line causes the bubble to expand over the lines below and show all the messages, and clicking on the indicator again or moving the caret out of the line causes the bubble to collapse.

A collapsible inline error message bubble

Editing a line with a message bubble causes the bubble to dim slightly, to indicate that it's probably no longer valid.

By default, message bubbles are shown for both warnings and errors, and MonoDevelop takes you to the first error immediately after the build. These behaviours are configurable in Preferences->Build, where you can configure what happens after the build: whether to jump to errors and warnings, or just errors, or not at all; whether to show the error pad automatically; and whether to show message bubbles for errors, for errors and warnings, or not at all.

The inline error options

There are several commands for working with message bubbles, accessible from the View->Message Bubbles menu. The Hide/Show Message Bubble command hides or shows all the message bubbles, and the Toggle Message Bubble command hides or shows just the message bubbles on the current line. The latter command is also accessible via the context menu in the text editor margin. When bubbles are hidden, the error marker in the margin will remain there until the next build.

MonoDevelop Tips: Duplicate a Line

When there is no selection in the MonoDevelop text editor, the copy and cut commands act on the current line. This makes it easy to move a line (Control-X, move to line below target location, Control-V) or duplicate a line (Control-C, Control-V).

MonoDevelop Tips: Build Actions

Files in a MonoDevelop (or Visual Studio) project have a build action which controls what happens to the file during a build. Here are some of the common build actions for C# projects:

Compile
The file will be passed to the C# compiler as a source file.
EmbeddedResource
The file will be passed to the C# compiler as a resource to be embedded in the assembly. For historical reasons, it's displayed as "Embed as resource".
None
The file is not part of the build in any way, it's simply included in the project for easy access from the IDE.
Content
For ASP.NET projects, these files will included as part of the site when it's deployed. For MonoTouch and MonoMac projects, they'll be included in the app bundle.
Page
In Silverlight/Moonlight projects, this is used for xaml files to be included in the app. In MonoTouch and MonoMac, it's used for xib files.

You can also define arbitrary build actions, and if your project uses the MSBuild build engine, you can write custom tasks to process files with particular build actions.

There are various ways to set files' build actions. When files are first added to the project from templates, they will have an appropriate build action set by the template. When files are added from the Add Files dialog, they will have the default build action for that file type, unless you explicitly override it using the combobox in the dialog.

Overriding the default build action when adding files

For files that are already in the project, you can change the build action by selecting the file in the solution pad, then using the dropdown in the property pad.

Changing the build action using the property pad

Common build actions can be set using the solution pad's context menu, which has the advantage that it supports multi-selection, so you can change many files at once.

Changing the build action using the solution pad context menu

Pages

Subscribe to Journal