I'm going to be in San Francisco next week for GDC. I'll be wandering around SF on Sunday 27th Feb, going to the summits on Monday and Tuesday, then on the Mono booth in the GDC Expo Wednesday through Friday.
If you're at GDC, please drop by our booth! And whether you're at GDC or just in the area, drop me an email or tweet me if you'd like to hang out (schedule permitting) and discuss anything related to Mono in games, Mono in general, MonoTouch, MonoDroid, and MonoDevelop.
When you type the "override" keyword in a C# class, MonoDevelop will show a completion list of all abstract or virtual members on base classes that have not been overridden, and interface members that have not been implemented. You don't even need to type the modifier (e.g. "public"), you can simply type "override" directly in the class body.
When you commit a selection from the list, it generates the implementation with the correct signature, with a single statement &emdash; a call to the base implementation if appropriate, or a NotImplementedException. This implementation is selected so you can immediately start replacing it with a real implementation.
Code snippets (or code templates) are an incredibly useful feature. They allow inserting and editing template blocks of code, which is useful for quickly replicating common patterns, or learning new patterns. This post explains how to use snippets, and a future post will explain how to create snippets.
There are three ways to use snippets: the Insert Template command, Tab expansion, and the Toolbox.
The Insert Template... command can be activated from the Edit->Insert Template... menu, or the Control-T keybinding on Windows and Linux. It shows a list of all templates valid for the current file type, and you can match them using the same substring matching as the completion list. Select one and hit Enter to activate it.
If there is a selection, then this command will turn into the Surround With... command. This only shows templates that have the "Surround With" flag. They will take the current selection and incorporate it into the template. For example, the "for" template will put the selection into the loop body.
If the snippet has a shortcut, type the shortcut and then hit Tab. The shortcut will be in the completion list, so if you pick the item from the completion list you must hit tab twice, once to commit the selection, and once to expand it. The second tab is necessary because snippets may have the same name as keywords or symbols, and if they activated as soon as they were committed, you would not be able to type the keyword or symbols. Indeed, there are built-in snippets for many C# keywords.
When the text editor is focussed, the Toolbox Pad shows all of the snippets valid for the current document. Drag one to the text editor to insert it at a specific position, or double-click it to insert it at the caret position.
When a snippet is inserted, it may simply insert plain text and move the caret to a location somewhere within it. However, advanced snippets will have linked regions to enable you to customize the usage of the snippet. For example, the C# "for" snippet contains two editable regions, with other regions linked to them.
When the template is activated, the region with the declaration of the loop variable "i" is selected. You may type a new name, and both other uses of that name will be updated. Then, hit Tab to move to the next editable region. You can now change the value of the upper limit of the loop. Tab and Shift-Tab can be used to cycles between the editable regions, and when you are done, hit Enter or Escape to exit region editing mode and move the caret to the loop body.
While experimenting with code, it can be very useful to comment a block of code temporarily.
To comment a block of code, use select Toggle Line Comment(s) from the context menu, or use the Control-Alt-C keybinding on Windows and Linux. If the current line is commented, it will be uncommented, or if it is not commented, it will be commented. If multiple lines are selected, then if any are not commented, they will all be commented. If all are commented, they will all be uncommented.
For C# files, this feature uses line comments, and if lines that are already commented are commented as part of a larger block, it adds another "level" of line comments onto those lines. This is useful, because it means that a region of code can be commented then uncommented, and actual comments within it will be preserved.
If you prefer to use multiline comments or
#if false directives, you can use "surround with" templates, which will be covered tomorrow.
It's easy to increase or decrease indentation of a block of code in MonoDevelop. Hit the Tab key while there is a selection, and the selected lines' indentation will be increased. Similarly, hit Shift-Tab and the indentation will be decreased.
There is also a command to do this. The indent command can be found in the Edit->Format->Indent Selection menu, with the keybinding Control-Alt-End on Windows and Linux, and Cmd-] on Mac. The unindent command is Edit->Format->Unindent Selection, with the keybinding Control-Alt-Home on Windows and Linux, and Cmd-[ on Mac.
MonoDevelop can also set the indentation to the "correct" value (as determined by the smart indenter) when tab is pressed, like emacs does. This can be enabled with Preferences->Behavior->Interpret tab as reindent command. For some reason, this command isn't keybindable.
To move lines around in the next editor, use the Alt-Up command to move the current line or current selected lines up, and use the Alt-Down command to move the lines down. If the language addin supports it, the lines will be re-indented to match the context when they move in and out of scopes.
This is incredibly useful for changing the order of statements.
Most users are familiar with word navigation, for moving the caret to the next or previous word: Control-Left/Control-Right on Windows and Linux, and Opt-Left/Opt-Right on Mac. A previous post discussed the different modes for word breaking.
A less well-known features is "subword" navigation, which is very similar, except that it breaks in more places, such camelCase boundaries within words and underscores within identifiers. This is really useful for modifying parts of identifiers precisely. The keybinding is Alt-Left/Alt-Right on Windows and Linux, and Control-Left/Control-Right on Mac. As with word navigation, they can be combined with the Shift modifier to modify the current selection range.
If you know the name of a type or file and want to go straight to it without having to dig through the solution pad and file contents, the Navigate To... command is your friend. This command can be activated with Ctrl-, on Windows or Linux, and Ctrl-.on Mac, or from the Search->Navigate To.. menu. It opens a window that shows a list of all the files, types and members in the solution, and you can filter and search these items using the same substring matching that the completion list uses. When you find the one you want, hit enter and you will be taken straight to it.
MonoDevelop also has Go To File and Go to Type commands, which behave the same way but are restricted to only showing files or types respectively. These predate the Navigate To command, and although its functionality is a superset of both of the older commands combined, they have been kept around because they're noticeably faster for extremely large projects.
There are various places where the MonoDevelop text editor needs to understand where words begin and end, for example, when you use control-left/right to move the caret (alt-left/right on Mac). We refer to this as "word breaking". Unfortunately, word breaking behaviour differs between OSes, and word breaking is often intended for text, not code. In addition, people become used to particular kinds of word breaking. For these reasons, we allow users to change MonoDevelop's word breaking mode in Preferences->Text Editor->Behavior.
In addition, the vi input mode has its own word breaking mode that mimics the behaviour of vim.
When using code completion to explore a new API, it's often useful to know where in the type hierarchy members are defined. For example, when looking for things you can do with a button, the members on the button are more interesting than the members on its superclasses. MonoDevelop makes it easier to do this with a featured called categorized mode. The completion list can be toggled into categorized mode using Ctrl-Space, and will stay in this mode until it is toggled off. While in this mode, items may be be grouped by the completion engine into categories, depending on context. For example, when listing members of types, they will be grouped by the class on which they're defined. Other groupings may be added in future.
When navigating the list with arrow keys, you can jump directly between groups using Shift-Up and Shift-Down. If the list is not in completion mode, these combinations will toggle it on.
Completion mode is not the default behaviour because it makes the ordering and filtering of the list less straightforward.