Delphi Programming
Register
Advertisement

Delphi 2006 introduced a feature called "Live Templates" that allows one to write macro type templates that expand from a keyword and are parameterized, i.e. you can tab through the parameters and supply them one by one. This is a great productivity aid. The best part is that you can provide your own and it is relatively simple to do so.

To use these "live templates," all you need to do is copy the XML snippet provided and save it in

"C:\Program Files\Borland\BDS\4.0\Objrepos\code_templates\delphi"

with an xml extension.

An alternate place to put them is

"c:\Documents and Settings\<your username>\Local Settings\Application Data\Borland\BDS\4.0\code_templates".

Note that you need to restart BDS if you just copy the file. Alternatively you can use the IDE to create a new template, delete all the automatically filled in stuff, copy and paste the template from below and use the IDE to save it. In that case the template will be immediately available.

A suggested file name is provided above the snippet but you can use whatever you like.

Live Templates for Developers Coming from VB

(Incidentally, Nick Hodges should be credited for sparking the idea for this page from his blog entry here.)

MsgBox

Just typing "msgbox" following by a space (or tab) will invoke this live template and generate the Delphi equivalent (with the ability to tab between the parameters you need to supply):

 MessageDlg('Hello', mtInformation, [mbOK], 0);

This script was adapted from Bob Swart's blog posting.


TEMPLATE FILE NAME: vb_live_template_msgbox.xml

<?xml version="1.0" encoding="utf-8" ?>
<codetemplate xmlns="http://schemas.borland.com/Delphi/2005/codetemplates" version="1.0.0">
 <template name="msgbox" invoke="auto">
   <description>MessageDlg live template</description>
   <author>Bob Swart</author>
   <point name="Message">
      <text>Hello</text>
      <hint>Message</hint>
   </point>
   <point name="MessageType">
      <text>mtInformation</text>
      <hint>Message Type</hint>
   </point>
   <point name="MessageButtons">
      <text>mbOK</text>
      <hint>Message Buttons</hint>
   </point>
   <code language="Delphi" delimiter="|">
      <![CDATA[MessageDlg('|Message|', |MessageType|, [|MessageButtons|], 0);|end|]]>
   </code>
   </template>
</codetemplate>

Database Live Templates

EOF

Here is a live template that automatically creates the following block of code (and allows you to change the dataset name) quickly. You simply type "eof" and hit <space> and the code block appears, positions you to change the name of "dataset", changes the name both places it's referenced, then places the cursor at the top of the new begin block.

 while not dataset.eof do
 begin
 dataset.Next;
 end; 

TEMPLATE FILE NAME: not_eof.xml

<?xml version="1.0" encoding="utf-8" ?>
<codetemplate	xmlns="http://schemas.borland.com/Delphi/2005/codetemplates"
				version="1.0.0">
<template name="eof" invoke="auto">
<point name="dataset">
  <script language="Delphi">
  InvokeCodeCompletion;
  </script>
  <text>
    dataset
  </text>
  <hint>
    dataset to loop through
  </hint>
</point>
<description>
  Template to loop through a dataset while not eof
</description>
<author>
  Jeremy D. Mullin
</author>
<code language="Delphi" context="methodbody" delimiter="|"><![CDATA[while not |dataset|.eof do
begin
|*||end|
|*||dataset|.Next;
end;
]]>
</code>
</template>
</codetemplate>

Live Templates for Developers used to CodeRush

FreeAndNil

Typing F translates into FreeAndNil(Variable). With the help of the LiveTemplate ScriptEngine from Adam Markowitz (see CodeCentral ID 29310) the text of the first point defaults to the Clipboard content. This template also works without this ScriptEngine installed.

TEMPLATE FILE NAME: cr_live_template_freeandnil.xml

<?xml version="1.0" encoding="utf-8" ?>
<codetemplate xmlns="http://schemas.borland.com/Delphi/2005/codetemplates" version="1.0.0">
  <template name="f" invoke="auto">
    <point name="variable">
      <text>variable</text>
      <hint>variable to be freed</hint>
    </point>
    <description>
      FreeAndNil
    </description>
    <author>
      Sebastian Modersohn
    </author>
    <script language="DelphiExample" onenter="false" onvalidate="true">
      |variable| := GetClipboardContents();
    </script>
    <code language="Delphi" context="methodbody" delimiter="|"><![CDATA[FreeAndNil(|variable|);]]>
    </code>
  </template>
</codetemplate>

i: Integer Declaration

Typing i: results in i: Integer. Useful for declaring i: Integer variable.

TEMPLATE FILE NAME: cr_live_template_integerdecl.xml

<?xml version="1.0" encoding="utf-8" ?>
<codetemplate xmlns="http://schemas.borland.com/Delphi/2005/codetemplates" version="1.0.0">
  <template name="i:" invoke="auto">
    <description>
      AutoComplete i: Integer declaration
    </description>
    <author>
      Sebastian Modersohn
    </author>
    <code language="Delphi" context="methodbody" delimiter="|"><![CDATA[i: Integer;]]>
    </code>
  </template>
</codetemplate>

Alternatively, if you want to use it anywhere but have your variable declared in the correct spot:

<?xml version="1.0" encoding="utf-8" ?>
<codetemplate xmlns="http://schemas.borland.com/Delphi/2005/codetemplates" version="1.0.0">
  <template name="i:" invoke="auto">
    <description>
      AutoComplete i: Integer declaration
    </description>
    <author>
      Sebastian Modersohn / Thomas Mueller
    </author>
    <point name="ident" editable="false">
      <text>i</text>
    </point>
    <point name="type" editable="false">
      <text>Integer</text>
    </point>
    <script language="Delphi" onenter="false" onleave="true">
      DeclareVariable(|ident|, |type|);
      RemoveTemplate;
    </script>
    <code language="Delphi" context="methodbody" delimiter="|">
      <![CDATA[|ident||type|]]>
    </code>
  </template>
</codetemplate>

s: String Declaration

Typing s: results in s: String. Useful for declaring s: String variable.

TEMPLATE FILE NAME: cr_live_template_stringdecl.xml

<?xml version="1.0" encoding="utf-8" ?>
<codetemplate xmlns="http://schemas.borland.com/Delphi/2005/codetemplates" version="1.0.0">
  <template name="s:" invoke="auto">
    <description>
      AutoComplete s: String declaration
    </description>
    <author>
      Sebastian Modersohn
    </author>
    <code language="Delphi" context="methodbody" delimiter="|"><![CDATA[s: String;]]>
    </code>
  </template>
</codetemplate>

convert typo ";=" to ":="

This will convert a common typo where you type ";=" but really meant ":=" to what you meant.

TEMPLATE FILE NAME: semicolon-equals-typo.xml

<?xml version="1.0" encoding="utf-8" ?>
<codetemplate xmlns="http://schemas.borland.com/Delphi/2005/codetemplates" version="1.0.0">
  <template name=";=" invoke="auto">
    <description>
      convert typo ;= to :=
    </description>
    <author>
      twm
    </author>
    <code language="Delphi" delimiter="|">
      <![CDATA[:= |end|]]>
    </code>
  </template>
</codetemplate>

Property that refers to a field

Those two templates create a property declaration that refers to a field. Press Ctrl-Shift-C afterwards to have the IDE add the fields.

Readonly property

This will create a readonly property that refers to an object's field.

TEMPLATE FILE NAME: propfreadonly.xml

<?xml version="1.0" encoding="utf-8" ?>
<codetemplate	xmlns="http://schemas.borland.com/Delphi/2005/codetemplates"
				version="1.0.0">
	<template name="propfreadonly" invoke="none">
		<description>
			read only property for field, press Ctrl-Shift-C afterwards to add the fields
		</description>
		<author>
			twm
		</author>
		<point name="ident">
			<text>Name</text>
			<hint>the name for the property</hint>
		</point>
		<point name="type">
			<text>Integer</text>
			<hint>the type for the property</hint>
		</point>
		<code language="Delphi" delimiter="|">
		<![CDATA[property |ident|: |type| read F|ident|;
|end|]]>
		</code>
	</template>
</codetemplate>

Read/write property

This will create a read/write property that refers to an object's field.

TEMPLATE FILE NAME: propfreadwrite.xml

<?xml version="1.0" encoding="utf-8" ?>
<codetemplate	xmlns="http://schemas.borland.com/Delphi/2005/codetemplates"
				version="1.0.0">
	<template name="propfreadwrite" invoke="none">
		<description>
			read write property for field, press Ctrl-Shift-C afterwards to add the fields
		</description>
		<author>
			twm
		</author>
		<point name="ident">
			<text>Name</text>
			<hint>the name for the property</hint>
		</point>
		<point name="type">
			<text>Integer</text>
			<hint>the type for the property</hint>
		</point>
		<code language="Delphi" delimiter="|">
		<![CDATA[property |ident|: |type| read F|ident| write F|ident|;
|end|]]>
		</code>
	</template>
</codetemplate>

Execute class method for a form

Generates a class method for a form that creates the form, shows it modally and returns true, if OK was pressed. Press Shift-Ctrl-C afterwards to add the method's declaration.

TEMPLATE FILE NAME: FormExecute.xml

<?xml version="1.0" encoding="utf-8" ?>
<codetemplate	xmlns="http://schemas.borland.com/Delphi/2005/codetemplates"
				version="1.0.0">
	<template name="FormExecute" invoke="manual">
		<description>
			creates an Execute class method for a form, press Shift-Ctrl afterwards
			to add the method declaration.
		</description>
		<author>
			twm
		</author>
		<point name="FormClass">
			<text>TForm</text>
			<hint>name of the form class</hint>
		</point>
		<point name="Value">
			<text>_Value</text>
			<hint>value edited with this form</hint>
		</point>
		<point name="Type">
			<text>string</text>
			<hint>Type of value</hint>
		</point>
		<point name="control">
			<text>Edit1</text>
			<hint>control that edits the value</hint>
		</point>
		<point name="property">
			<text>Text</text>
			<hint>property of the control for editing</hint>
		</point>
		<code language="Delphi" delimiter="|"><![CDATA[
class function |FormClass|.Execute(_Owner: TComponent; var |Value|: |Type|): boolean;
var
  frm: |FormClass|;
begin
  frm := |FormClass|.Create(_Owner);
  try
	frm.|control|.|property| := |Value|;|end|
	Result := (frm.ShowModal = mrOK);
	if Result then begin
	  |Value| := frm.|control|.|property|;
	end;
  finally
	frm.Free;
  end;
end;
		]]>
		</code>
	</template>
</codetemplate>

Como assim?

Live Templates for Pseudo Templates

On dztemplates.berlios.de you can find "pseudo templates". "Pseudo templates" are actually more like C++'s templates or C# and Java's generic types.

In the 1.0.1 release some Live Templates are included that make using these pseudo templates easier.

Improvements for existing templates

forin

The forin template always declares the iterator variable as TObject (QC 36085). Here is a forint template which has an entry point for the type too. Unfortunately the type stays in the code and must be removed manually (there is only RemoveTemplate as a script command available, but that would clear everything).

<?xml version="1.0" encoding="utf-8" ?>
<codetemplate	xmlns="http://schemas.borland.com/Delphi/2005/codetemplates"
				version="1.0.0">
	<template name="forint" surround="true" invoke="manual">
		<script language="Delphi" onenter="false" onleave="false" onvalidate="true">
			ValidateForTemplate;
		</script>
		<point name="ident">
			<text>
			MyElem
			</text>
			<hint>
				collection element iterator variable
			</hint>
		</point>
		<point name="type">
			<text>
			MyElemType
			</text>
			<hint>
				type of iterator variable
			</hint>
		</point>
		<point name="collection">
			<text>
				MyList
			</text>
			<hint>
				collection to iterate
			</hint>
		</point>
		<description>
			for in loop
		</description>
		<author>
			Sebastian Modersohn
		</author>
		<script language="Delphi" onenter="false" onleave="true">
			DeclareVariable(|ident|, |type|);
		</script>
		<code language="Delphi" context="methodbody" delimiter="|"><![CDATA[for |ident|: |type| in |collection| do
begin
|selected||*||end|
end;
]]>
		</code>
	</template>
</codetemplate>

Troubleshooting Tips

  • The language attribute is case-sensitive. "delphi" doesn't work, but "Delphi" does.

More Information on Live Templates

See Live Templates Technical Info

see Editing the template_template

Advertisement