I am using Live Templates a lot in Delphi but have tried to come up with a solution to add GUIDS to templates. Does anyone know how to do this?
Below the template I have now with GUID as a word I need to replace manually.
<?xml version="1.0" encoding="utf-8" ?>
<codetemplate xmlns="http://schemas.borland.com/Delphi/2005/codetemplates"
version="1.0.0">
<template name="iacc" surround="false" invoke="manual">
<point name="name">
<text>
IntfAccessors
</text>
<hint>
Accessors name
</hint>
</point>
<description>
accessor declaration
</description>
<author>
PMH
</author>
<code language="Delphi" context="methoddecl" delimiter="|"> <![CDATA[I|name|Accessors = interface(IInterface)
GUID <-- here I want a GUID
end;
I|name| = interface(I|name|Accessors)
GUID <-- here I want a GUID
end;
]]>
</code>
</template>
</codetemplate>
You can extend the IDE by writing a custom scripting engine to do this. (Here's an article written by Nick Hodges with a similar example which inserts current date.)
I assume that the two different interfaces from your example template need two different IIDs so I wrote the scripting engine to load the point names from the "script" (it's just a list of name=value pairs where the name is the point name and the value must be NewGuid otherwise it's ignored) so you can create templates with multiple points, each receiving a separate new IID.
Example template intf.xml:
<?xml version="1.0" encoding="utf-8" ?>
<codetemplate xmlns="http://schemas.borland.com/Delphi/2005/codetemplates" version="1.0.0">
<template name="iacc" surround="false" invoke="manual">
<point name="name">
<text>
Accessor
</text>
<hint>
Accessors name
</hint>
</point>
<point name="guid1"/>
<point name="guid2"/>
<description>
accessor declaration
</description>
<author>
PMH
</author>
<script language="NewGuidScript" onvalidate="true">
guid1=NewGuid
guid2=NewGuid
</script>
<code language="Delphi" context="any" delimiter="|"> <![CDATA[I|name|Accessors = interface(IInterface)
|*||guid1|
end;
I|name| = interface(I|name|Accessors)
|*||guid2|
end;]]>
</code>
</template>
</codetemplate>
NewGuidScriptEngine.pas:
unit NewGuidScriptEngine;
interface
uses
Classes, SysUtils,
ToolsApi, CodeTemplateApi, DesignEditors;
type
TNewGuidScriptEngine = class(TNotifierObject, IOTACodeTemplateScriptEngine)
public
procedure Execute(const ATemplate: IOTACodeTemplate; const APoint: IOTACodeTemplatePoint; const ASyncPoints: IOTASyncEditPoints; const AScript: IOTACodeTemplateScript; var Cancel: Boolean);
function GetIDString: WideString;
function GetLanguage: WideString;
end;
procedure Register;
implementation
uses
ActiveX,
ComObj;
procedure Register;
begin
(BorlandIDEServices as IOTACodeTemplateServices).RegisterScriptEngine(TNewGuidScriptEngine.Create);
end;
procedure TNewGuidScriptEngine.Execute(const ATemplate: IOTACodeTemplate; const APoint: IOTACodeTemplatePoint;
const ASyncPoints: IOTASyncEditPoints; const AScript: IOTACodeTemplateScript; var Cancel: Boolean);
var
I: Integer;
Guid: TGUID;
P: IOTACodeTemplatePoint;
Points: TStringList;
begin
Cancel := False;
if not Assigned(ATemplate) then
Exit;
Points := TStringList.Create;
try
Points.Text := AScript.Script;
for I := 0 to Points.Count - 1 do
Points.Strings[I] := Trim(Points[I]);
for I := 0 to Points.Count - 1 do
if Points.ValueFromIndex[I] = 'NewGuid' then
begin
P := ATemplate.FindPoint(Points.Names[I]);
if Assigned(P) then
begin
OleCheck(CoCreateGuid(Guid));
P.Editable := False;
P.Value := '[''' + GUIDToString(Guid) + ''']';
end;
end;
finally
Points.Free;
end;
end;
function TNewGuidScriptEngine.GetIDString: WideString;
begin
Result := 'OndrejKelle.NewGuidScriptEngine';
end;
function TNewGuidScriptEngine.GetLanguage: WideString;
begin
Result := 'NewGuidScript';
end;
end.
Put the above unit into a designtime-only package, add a reference to designide.dcp to its requires
clause and install the package in the IDE.
Another useful, similar template might look like this:
<?xml version="1.0" encoding="utf-8" ?>
<codetemplate xmlns="http://schemas.borland.com/Delphi/2005/codetemplates" version="1.0.0">
<template name="iacc" surround="false" invoke="manual">
<point name="name">
<text>
</text>
<hint>
Accessors name
</hint>
</point>
<point name="guid1"/>
<point name="guid2"/>
<description>
accessor declaration
</description>
<author>
PMH
</author>
<script language="NewGuidScript" onvalidate="true">
guid1=NewGuid
guid2=NewGuid
</script>
<code language="Delphi" context="any" delimiter="|"> <![CDATA[const
SIID_I|name|Accessors = |guid1|;
IID_I|name|Accessors: TGUID = SIID_I|name|Accessors;
SIID_I|name| = |guid2|;
IID_I|name|: TGUID = SIID_I|name|;
type
I|name|Accessors = interface
[SIID_I|name|Accessors]
end;
I|name| = interface(I|name|Accessors)
[SIID_I|name|]
end;]]>
</code>
</template>
</codetemplate>
This would declare string as well as TGUID
constants and also reuse them in the interface declarations. In this case, the inserted GUID values should not be enclosed in square brackets. You have several options to adjust the scripting engine to do this:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With