Delphi Programming
(41 intermediate revisions by 21 users not shown)
Line 1: Line 1:
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.
+
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.
   
  +
==How to use live templates==
 
To use these "live templates," all you need to do is copy the XML snippet provided and save it in
 
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"
+
D2006: c:\Program Files\Borland\BDS\4.0\ObjRepos\Code_Templates\Delphi\
  +
D2009: c:\Program Files\CodeGear\RAD Studio\6.0\ObjRepos\Code_Templates\Delphi\
 
with an xml extension.
 
with an xml extension.
   
An alternate place to put them is
+
Alternate places to put them are
"c:\Documents and Settings\<your username>\Local Settings\Application Data\Borland\BDS\4.0\code_templates".
+
D2006: c:\Documents and Settings\<username>\Local Settings\Application Data\Borland\BDS\4.0\code_templates\
  +
D2009: c:\Users\<username>\Documents\RAD Studio\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.
 
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.
Line 14: Line 17:
 
== Live Templates for Developers Coming from VB ==
 
== Live Templates for Developers Coming from VB ==
   
(Incidentally, Nick Hodges should be credited for sparking the idea for this page from his blog entry [http://www.lemanix.com/nickblog/PermaLink,guid,20ca8206-06e9-4f6e-a476-0757aa0da6be.aspx here].)
 
   
 
=== MsgBox ===
 
=== MsgBox ===
Line 48: Line 50:
 
</code>
 
</code>
 
</template>
 
</template>
  +
</codetemplate>
  +
</pre>
  +
  +
== General Language Templates ==
  +
  +
  +
=== TODO ===
  +
  +
This template will create a TODO item in your source
  +
  +
TEMPLATE FILE NAME: '''todo.xml'''
  +
<pre>
  +
<?xml version="1.0" encoding="utf-8" ?>
  +
<codetemplate xmlns="http://schemas.borland.com/Delphi/2005/codetemplates"
  +
version="1.0.0">
  +
<template name="todo" invoke="auto">
  +
<description>A live template to create a TODO item</description>
  +
<author>Bill Mullen</author>
  +
<point name="Owner">
  +
<text>Owner</text>
  +
<hint>Enter the person responsible for this item</hint>
  +
</point>
  +
<point name="Category">
  +
<text>General</text>
  +
<hint>Enter the category for this item</hint>
  +
</point>
  +
<point name="ActionItem">
  +
<text>ActionItem</text>
  +
<hint>Enter the action to be taken</hint>
  +
</point>
  +
<code language="Delphi" delimiter="|">
  +
<![CDATA[{TODO -o|Owner| -c|Category| : |ActionItem|}]]>
  +
</code>
  +
</template>
  +
</codetemplate>
  +
</pre>
  +
  +
  +
== 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'''
  +
<pre>
  +
<?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>
 
</codetemplate>
 
</pre>
 
</pre>
Line 55: Line 138:
 
=== FreeAndNil ===
 
=== FreeAndNil ===
   
Typing F translates into FreeAndNil(Variable). CodeRush originally used the clipboard content for Variable, but it is not (yet) possible to refer to the Clipboard content from within Live Templates.
+
Typing F translates into FreeAndNil(Variable). With the help of the LiveTemplate ScriptEngine from Adam Markowitz (see [http://cc.embarcadero.com/Item/23910 CodeCentral ID 23910]) 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'''
 
TEMPLATE FILE NAME: '''cr_live_template_freeandnil.xml'''
Line 63: Line 146:
 
<template name="f" invoke="auto">
 
<template name="f" invoke="auto">
 
<point name="variable">
 
<point name="variable">
<script language="LWScript">Paste</script>
 
 
<text>variable</text>
 
<text>variable</text>
 
<hint>variable to be freed</hint>
 
<hint>variable to be freed</hint>
Line 73: Line 155:
 
Sebastian Modersohn
 
Sebastian Modersohn
 
</author>
 
</author>
  +
<script language="DelphiExample" onenter="false" onvalidate="true">
  +
|variable| := GetClipboardContents();
  +
</script>
 
<code language="Delphi" context="methodbody" delimiter="|"><![CDATA[FreeAndNil(|variable|);]]>
 
<code language="Delphi" context="methodbody" delimiter="|"><![CDATA[FreeAndNil(|variable|);]]>
 
</code>
 
</code>
Line 81: Line 166:
 
=== i: Integer Declaration ===
 
=== i: Integer Declaration ===
   
Typing i: results in i: Integer. Usefull for declaring i: Integer variable.
+
Typing i: results in i: Integer. Useful for declaring i: Integer variable.
   
 
TEMPLATE FILE NAME: '''cr_live_template_integerdecl.xml'''
 
TEMPLATE FILE NAME: '''cr_live_template_integerdecl.xml'''
Line 125: Line 210:
 
<![CDATA[|ident||type|]]>
 
<![CDATA[|ident||type|]]>
 
</code>
 
</code>
  +
</template>
 
  +
</codetemplate>
 
</pre>
 
</pre>
   
Line 149: Line 235:
 
</pre>
 
</pre>
   
=== convert typo ";=" to ":=" ===
+
== convert typo ";=" to ":=" ==
   
 
This will convert a common typo where you type ";=" but really meant ":=" to what you meant.
 
This will convert a common typo where you type ";=" but really meant ":=" to what you meant.
Line 165: Line 251:
 
twm
 
twm
 
</author>
 
</author>
<code language="Delphi">
+
<code language="Delphi" delimiter="|">
<![CDATA[:= ]]>
+
<![CDATA[:= |end|]]>
 
</code>
 
</code>
 
</template>
 
</template>
Line 172: Line 258:
 
</pre>
 
</pre>
   
=== readonly Property that refers to a field ===
+
== Property that refers to a field ==
   
This will create a readonly property that reafers to an object's 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 ===
TEMPLATE FILE NAME: '''propf.xml'''
 
  +
  +
This will create a readonly property that refers to an object's field.
  +
  +
TEMPLATE FILE NAME: '''propfreadonly.xml'''
   
 
<pre>
 
<pre>
Line 182: Line 272:
 
<codetemplate xmlns="http://schemas.borland.com/Delphi/2005/codetemplates"
 
<codetemplate xmlns="http://schemas.borland.com/Delphi/2005/codetemplates"
 
version="1.0.0">
 
version="1.0.0">
<template name="propf" invoke="none">
+
<template name="propfreadonly" invoke="none">
 
<description>
 
<description>
property for field
+
read only property for field
 
</description>
 
</description>
 
<author>
 
<author>
Line 197: Line 287:
 
<hint>the type for the property</hint>
 
<hint>the type for the property</hint>
 
</point>
 
</point>
  +
<script language="Delphi" onenter="false" onleave="true">
  +
InvokeClassCompletion;
  +
</script>
 
<code language="Delphi" delimiter="|">
 
<code language="Delphi" delimiter="|">
 
<![CDATA[property |ident|: |type| read F|ident|;
 
<![CDATA[property |ident|: |type| read F|ident|;
Line 205: Line 298:
 
</pre>
 
</pre>
   
  +
=== Read/write property ===
=== Live Templates for Pseudo Templates ===
 
   
  +
This will create a read / write property that refers to an object's field.
On [http://dztemplates.berlios.de dztemplates.berlios.de] you can find [http://www.dummzeuch.de/delphi/object_pascal_templates/english.html "pseudo templates"]. "Pseudo templates" are actually more like C++'s templates or C# and Java's generic types.
 
  +
  +
TEMPLATE FILE NAME: '''propfreadwrite.xml'''
  +
  +
<pre>
  +
<?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
  +
</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>
  +
<script language="Delphi" onenter="false" onleave="true">
  +
InvokeClassCompletion;
  +
</script>
  +
<code language="Delphi" delimiter="|">
  +
<![CDATA[property |ident|: |type| read F|ident| write F|ident|;
  +
|end|]]>
  +
</code>
  +
</template>
  +
</codetemplate>
  +
</pre>
  +
  +
=== Getter, Setter or Field ===
  +
This will create a read / write property that refers to either Get/Set methods or an object's field depending on what changes you make once invoked using '''propgs''' and either tab or space in the IDE.
  +
  +
TEMPLATE FILE NAME: '''PropertyGetSet.xml'''
  +
  +
<pre>
  +
<?xml version="1.0" encoding="utf-8" ?>
  +
<codetemplate xmlns="http://schemas.borland.com/Delphi/2005/codetemplates" version="1.0.0">
  +
<template name="propgs" invoke="auto">
  +
<description>Property with Getter and Setter.</description>
  +
<author>twm-tdh</author>
  +
<point name="Name">
  +
<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>
  +
<point name="Getter">
  +
<text>Get</text>
  +
<hint>the property Getter</hint>
  +
</point>
  +
<point name="Setter">
  +
<text>Set</text>
  +
<hint>the property Setter</hint>
  +
</point>
  +
<code language="Delphi" delimiter="|">
  +
<![CDATA[property |Name|: |Type| read |Getter||Name| write |Setter||Name|;|end|]]>
  +
</code>
  +
</template>
  +
</codetemplate>
  +
</pre>
  +
  +
== 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.
  +
'''Adding the script Tag with InvokeClassCompletion (see below) makes it unnecessary to press the Shift-Ctrl-C afterwards'''
  +
  +
TEMPLATE FILE NAME: '''FormExecute.xml'''
  +
  +
<pre>
  +
<?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>
  +
<script language="Delphi" onenter="false" onleave="true">
  +
InvokeClassCompletion;
  +
</script>
  +
<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>
  +
</pre>
  +
  +
Como assim?
  +
  +
== Live Templates for Pseudo Templates ==
  +
  +
On [https://osdn.net/projects/dzlib-tools/svn/view/dzlivetemplates/trunk/?root=dzlib-tools https://osdn.net/projects/dzlib-tools/] you can find [http://www.dummzeuch.de/delphi/object_pascal_templates/english.html "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.
 
In the 1.0.1 release some Live Templates are included that make using these pseudo templates easier.
  +
  +
== Improvements for existing templates ==
  +
  +
=== forin ===
  +
  +
The <tt>forin</tt> template always declares the iterator variable as TObject ([http://qc.borland.com/wc/qcmain.aspx?d=36085 QC 36085]). Here is a <tt>forint</tt> 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).
  +
  +
<pre>
  +
<?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>
  +
</pre>
   
 
== Troubleshooting Tips ==
 
== Troubleshooting Tips ==
   
* The language attribute is case-sensitive. "delphi" doesn't work, but "Delphi" does.
+
* The language attribute is case-sensitive. "delphi" doesn't work, but "Delphi" does.
  +
   
 
== More Information on Live Templates ==
 
== More Information on Live Templates ==
   
 
See [[Live Templates Technical Info]]
 
See [[Live Templates Technical Info]]
  +
  +
See [[Editing the template_template]]
  +
  +
Simon Stuart had [https://web.archive.org/web/20110301211212/http://www.lakraven.com/delphi-stuff/radplates/ a Live Template Editor project called RADPlates] but unfortunately it's no longer available.
  +
  +
[https://bitbucket.org/sglienke/spring4d/src/master/Code%20Templates/ a big collection of Live Templates]
  +
[[Category:References]]

Revision as of 14:45, 10 October 2019

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.

How to use live templates

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

D2006: c:\Program Files\Borland\BDS\4.0\ObjRepos\Code_Templates\Delphi\
D2009: c:\Program Files\CodeGear\RAD Studio\6.0\ObjRepos\Code_Templates\Delphi\

with an xml extension.

Alternate places to put them are

D2006: c:\Documents and Settings\<username>\Local Settings\Application Data\Borland\BDS\4.0\code_templates\
D2009: c:\Users\<username>\Documents\RAD Studio\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

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>

General Language Templates

TODO

This template will create a TODO item in your source

TEMPLATE FILE NAME: todo.xml

<?xml version="1.0" encoding="utf-8" ?>
<codetemplate	xmlns="http://schemas.borland.com/Delphi/2005/codetemplates"
				version="1.0.0">
	<template name="todo" invoke="auto">
		<description>A live template to create a TODO item</description>
		<author>Bill Mullen</author>
		<point name="Owner">
			<text>Owner</text>
			<hint>Enter the person responsible for this item</hint>
		</point>
		<point name="Category">
			<text>General</text>
			<hint>Enter the category for this item</hint>
		</point>
		<point name="ActionItem">
			<text>ActionItem</text>
			<hint>Enter the action to be taken</hint>
		</point>
		<code language="Delphi" delimiter="|">
			<![CDATA[{TODO -o|Owner| -c|Category| : |ActionItem|}]]>
		</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 23910) 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
		</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>
		<script language="Delphi" onenter="false" onleave="true">
			InvokeClassCompletion;
		</script>
		<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
		</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>
		<script language="Delphi" onenter="false" onleave="true">
			InvokeClassCompletion;
		</script>
		<code language="Delphi" delimiter="|">
		<![CDATA[property |ident|: |type| read F|ident| write F|ident|;
|end|]]>
		</code>
	</template>
</codetemplate>

Getter, Setter or Field

This will create a read / write property that refers to either Get/Set methods or an object's field depending on what changes you make once invoked using propgs and either tab or space in the IDE.

TEMPLATE FILE NAME: PropertyGetSet.xml

<?xml version="1.0" encoding="utf-8" ?>
<codetemplate    xmlns="http://schemas.borland.com/Delphi/2005/codetemplates" version="1.0.0">
    <template name="propgs" invoke="auto">
        <description>Property with Getter and Setter.</description>
        <author>twm-tdh</author>
        <point name="Name">
            <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>
        <point name="Getter">
            <text>Get</text>
            <hint>the property Getter</hint>
        </point>
        <point name="Setter">
            <text>Set</text>
            <hint>the property Setter</hint>
        </point>
        <code language="Delphi" delimiter="|">
        <![CDATA[property |Name|: |Type| read |Getter||Name| write |Setter||Name|;|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. Adding the script Tag with InvokeClassCompletion (see below) makes it unnecessary to press the Shift-Ctrl-C afterwards

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>
		<script language="Delphi" onenter="false" onleave="true">
			InvokeClassCompletion;
		</script>
		<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 https://osdn.net/projects/dzlib-tools/ 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

Simon Stuart had a Live Template Editor project called RADPlates but unfortunately it's no longer available.

a big collection of Live Templates