Creating live templates in BDS 2006

Posted by on in Blogs

Live templates are a nice new feature in BDS 2006, but they are badly documented (as Borland acknowledge). I expect someone will write a blog or a BDN article on the subject soon, but I thought a quick guide to creating your own templates might be helpful for now.

 

Each template resides in an XML file. You can create the XML file using either File|New|Other Files and then selecting the Code Template icon, or View | Templates and then clicking New. Either way, you get an XML file to edit.

 

The first line you need to change is this one:

         

<template name="" invoke="manual">

 

You need to fill in the template’s name – the text that will cause the template to be invoked -

and choose its invocation method. That can be manual, auto, or none: auto invocation means that the template will be invoked if the spacebar is pressed after typing the template’s name, manual invocation means you can press Tab or Ctrl-J to invoke the template, and none means you need to use Ctrl-J, Ctrl-Space or the Execute button from the Templates pane to invoke it.

 

You can also enter a description of your template, which will appear in the Templates pane, and yourself as author of your new template if you wish. But the other essential part of the XML file is this bit:

 

<code language=""><![CDATA[]]>

 

 

Notice the language tag first. You can specify that your template is for a particular language, including HTML and XML as well as (e.g.) Delphi. Then the Templates pane will show your template when you’re editing a file of the relevant type. (So if you make a template for Delphi, and you can’t see it while you’re editing the template .xml file, now you know why!)

 

On to the <![CDATA[]]> tag. Don’t believe the helpfile when it tells you to put your template code ‘between the <![CDATA[]]> tag and the </code> tag’ – that’s wrong. Your template needs to go between the innermost square brackets of the <![CDATA[]]> tag. For example:

 

<!CDATA[OutputDebugString(PChar(''));]]>

 

 

But just putting text there is rather limited. There are some special values you can use in this tag, but you need to go back to the code tag first and add information about the delimiter you’ll use to separate them from text. For example:

 

<code language="Delphi" delimiter="|">

 

 

Now we can use ‘end’ to tell Delphi where to put the cursor after the template has been invoked:

 

<!CDATA[OutputDebugString(PChar('|end|'));]]>

 

 

You can also use ‘*’ to specify indents. Note that white space and carriage returns in the <![CDATA[]]> tag will be observed in your template, though, so if you’re getting indents you don’t expect check to see you’ve removed any spaces.

 

You can use ‘selected’ to include any selected text in your template. So, to place selected text in an {$IFDEF}block:

 

<!CDATA[{$IFDEF TESTING}

|selected|{$ENDIF}

|end|]]>

 

When you do something like this, though, you probably also want to set the template to ‘surround’:

 

    <template name="IfTesting" surround="true" invoke="manual">

 

 

If you do that, you can invoke your template using the Surround context menu in the code editor. Just select the code you want in the block, right-click, go to Surround and click on your template in the list. Very handy for creating regions!

 

Last, but not least, we come to ‘points’. Points are the places the cursor will stop in as you Tab through a template, and you can specify default text and hints for them, and even get scripts to run when the user enters and leaves a point. I won’t deal with the scripts here – Daniel Wischnewski has already blogged about writing your own script engine: http://delphi-notes.blogspot.com/2005/12/creating-script-template-engine-for.html - but I’ll just show you the basics of creating them.

 

 

<![CDATA[raise |ExceptionClass|.CreateFmt(Format('|Message|', [|Args|]));

|end|]]>

 

Here the points are ExceptionClass, Message, and Args. When you invoke this template you can tab through to each point in turn, accepting the default text, or editing it. For this to work, though, you need to specify some information about each point in the template’s XML:

 

 

  <point name="ExceptionClass">

    <text>Exception</text>

    <hint>exception class</hint>

  </point>

  <point name="Message">

   <text>Oops %d</text>

  </point>

  <point name="Args">

   <hint>arguments for Format</hint>

  </point>

 

 

As you see, you can specify the default text, and the hint that the user will see (if they have hints turned on) – but you don’t have to specify either.

 

You can use one point several times, if you want the text the user writes to be repeated. (Note that only the first instance will be tabbed through.) For example, if you usually call Windows message handlers by the name of the Windows message minus the underscore, you could use a template like this, to save typing the name twice:

 

    <point name="MessageID">

         <text>

</text>

    </point>

    <code language="Delphi" delimiter="|"><![CDATA[procedure Wm|MessageID|(var Msg: TMessage); message WM_|MessageID|;|end|]]>

 

 

Creating these points in XML seems like a bit of a chore at first. But since you can write templates for XML, you can make it a bit easier with a template for points:

 

    <template name="point" invoke="manual">

         <description>

            create a point in code templates

         </description>

         <point name="PointName">

             <text>

                 PointName

             </text>

         </point>

         <code language="XML" delimiter="|"><![CDATA[<point name="PointName">

|*|<text>

|*||*||PointName|

|*|</text>

|*|<hint>

|*|</hint>

</point>|end|]]>

         </code>

    </template>

</codetemplate>

 

 

There's more to live templates, as you can see from the supplied examples and the codetemplates.xsd file in your {Dephi}ObjReposcode_templates directory, but I hope I've written enough here to get you started.

 

A note on directories: when you go to save your new template, the default directory it will be saved in is {Home}Local SettingsApplication DataBorlandBDS4.0code_templates. But if, like me, you hate stuff being saved to your C drive unnecessarily, don’t worry: you can save your own templates with the suppled ones in the {Delphi}ObjReposcode_templates directory, and Delphi will see them.

 



Comments

  • Guest
    Iman Monday, 5 December 2005

    Thanks for the tutorial. I did see a couple of extraneous ' scattered about. :)

  • Guest
    Deborah Pate Monday, 5 December 2005

    Oops :)

  • Guest
    Sebastian Wednesday, 14 December 2005

    Have you actually seen point scripts working? I've tried with my own templates and also tried the borland supplied, but it seems point scripts are not executed.

  • Guest
    Stanko Milo Tuesday, 26 September 2006

    I would just like to say that I am glad I've found your blog, Deborah, hope to see more good articles!

  • Guest
    Alejandro Wednesday, 18 March 2009

    thanks, you help me a lot. Can't stop to understand all of this but part of it makes the job :)

  • Please login first in order for you to submit comments
  • Page :
  • 1

Check out more tips and tricks in this development video: