[MonoDevelop] Who ate my code templates ?

Mike Krüger mkrueger at novell.com
Mon Mar 23 01:42:58 EDT 2009


Hi


Code templates are now completely different than they were before. 

I hope that our users will find them useful, I assume that only 20% of
the people are using the templates therefore it's time to introduce this
feature more deeply.

What are code templates?

Code templates saving valuable developer time by providing pre defined
code fragments that are used often in source code. That reaches from
small templates like generating an if construct to templates that can
generate whole classes (like an attribute).

How to activate templates ?

Code templates are generally activated by typing a shortcut like "for"
and hitting tab after the shortcut. An "Insert Template..." menu item
exists in the edit menu that only shows the templates. 

Templates can be used as normal "expansion" templates or as code
surrounding templates. Code surrounding templates require that some code
is selected and the "Surround With..." command activated the selected
code is now embedded inside the template. This is useful for example to
surround code with a try ... catch block.

Whats cool on the template system ?

Placeholders

The "new" cool feature is that templates can now define multiple
placeholders. 

For Example:

type 'for' - hit tab:

for (int $1 = 0; $1 < $2; $1++) {
$end$
}

The for template gets unwrapped and '$1' is selected if you type there
(the default value is 'i') all other instances of '$1' change to the
value typed at the first instance. Now hit tab again the caret jumps to
the next place holder '$2'. You can finish the template with the enter
key that places the caret at '$end$' - or just type anywhere in the code
outside of placeholders if you're satisfied with your template. 

Context sensitive templates

Note that templates can be context sensitive, therefore not all
templates are available anywhere.

For Example:

x = someOtherVar;

if you select the whole statement and hit "Surround With..." you get a
long list of statements to surround this with (if, for, try/catch etc.).
If you select only "someOtherVar" you get templates that are available
for expressions - that are currently only 2: (...) and ((cast_to)...).
(I find the type cast template very helpful - I hate to write type
casts.

Automatically defined fields

Automatically defined fields are fields that are not defined by the user
instead the template fills the contents of the field using a pre-defined
method. For example the constructor template "ctor" expands to:

$TypeName$ ()
{
$end$
}

And the $TypeName$ is inserted automatically. The auto fields are used
too for fully qualified type names. Fully qualified type names can be
shortened with a function depending on the usings that are available at
the template insertion point. (remember the old 'scwl' template that
always expanded to 'System.Console.WriteLine' ? The new 'cw' (OMG it's
50% shorter !!!) template only expands to 'System.Console.WriteLine' if
there is no 'using System' in that file)

Proposed field values

The proposed field values are a mix from auto defined fields and
editable fields. In these fields the user can type what he want but some
values are presented to the user that he can choose from.

Let's take an advanced template for demonstrating this.

Take the source code:
-----------
using System;
using System.Collections.Generic;

class MyClass
{
        public static int Main (string[] args)
        {
                List<int> list = new List<int> ();
                $
                return 0;
        }
}
-----------

Now type 'itar' (for ITearate ARray).

Following code is generated:
---------------
for (int i = 0; i < list.Count; i++) {
        int varname = list[i];
        
}
---------------
You can change the first 'i', the field 'list' and 'varname'. If you get
to the editing field for 'list' a pop up appears and you can select
between 'list' and 'args'. If you set 'args' here the code changes to:

---------------------------------------
for (int i = 0; i < args.Length; i++) {
        string varname = args[i];
                        
}
---------------------------------------

And change it back to list:

---------------------------------------
for (int i = 0; i < list.Count; i++) {
        int varname = list[i];                  

}
---------------------------------------

Note that Length/Count and the element types are auto defined fields
that change on the value for 'args/list'.

How to extend templates ?

Templates can be extended using the template editor available through
the settings dialog or adding them manually. Open the template editor
and closing it generates a template folder in the 

~/.config/MonoDevelop/templates/code

Directory. All user defined templates are stored here. The template
format is very straightforward. For example the mn template looks like:

-------------------------------------------------
<CodeTemplates version="3.0">
  <CodeTemplate version="2.0">
    <Header>
      <_Group>C#</_Group>
      <Version>1.0</Version>
      <MimeType>text/x-csharp</MimeType>
      <Shortcut>mn</Shortcut>
      <_Description>Sets minimum value to a variable</_Description>
      <TemplateType>Expansion</TemplateType>
    </Header>
    <Variables>
      <Variable name="var">
        <Default>var</Default>
        <_ToolTip>Variable name</_ToolTip>
      </Variable>
      <Variable name="SystemMin" isEditable="false">
        <Default>System.Min</Default>
        <Function>GetSimpleTypeName("System.Min")</Function>
      </Variable>
    </Variables>
    <Code><![CDATA[$var$ = $SystemMin$ ($var$, $end$);]]></Code>
  </CodeTemplate>
</CodeTemplates>
-----------------------------------------------

I hope that we'll get some more user defined templates that are
helpful :)

What needs to be done ?

The template system is very new therefore I except that there are bugs
here and there. 
The functions that are available through the extension object need to be
extended. I think we should let drive this by the requests of the
template writers.
More contexts for the templates. Currently there are only expressions
and 'normal' contexts. 
Sub 'mime types': Currently the set of templates are the same for the
whole file based on the mime types. But some files have a different
'language' depending on the position. For example inside 'doc' comments
could be a context for XML files. I think these sub contexts could be
very useful for embedded ASP.NET code.
The 'Surround With' list needs an input field to filter the templates.
Maybe the template/surround with pop ups need a category tree too.

Regards
Mike



More information about the Monodevelop-list mailing list