codetools: started ability to load code completion snippets from an xml files, thanks to Don Ziesig, patch #15922

git-svn-id: trunk@42177 -
This commit is contained in:
mattias 2013-07-22 22:08:53 +00:00
parent 30837a8e7d
commit e02c8ef2c8
18 changed files with 982 additions and 189 deletions

2
.gitattributes vendored
View File

@ -675,6 +675,8 @@ components/codetools/changedeclarationtool.pas svneol=native#text/plain
components/codetools/codeatom.pas svneol=native#text/pascal components/codetools/codeatom.pas svneol=native#text/pascal
components/codetools/codebeautifier.pas svneol=native#text/plain components/codetools/codebeautifier.pas svneol=native#text/plain
components/codetools/codecache.pas svneol=native#text/pascal components/codetools/codecache.pas svneol=native#text/pascal
components/codetools/codecompletiontemplater.pas svneol=native#text/plain
components/codetools/codecompletiontemplates.xml svneol=native#text/plain
components/codetools/codecompletiontool.pas svneol=native#text/pascal components/codetools/codecompletiontool.pas svneol=native#text/pascal
components/codetools/codegraph.pas svneol=native#text/plain components/codetools/codegraph.pas svneol=native#text/plain
components/codetools/codeindex.pas svneol=native#text/plain components/codetools/codeindex.pas svneol=native#text/plain

View File

@ -0,0 +1,432 @@
{
***************************************************************************
* *
* This source is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This code is distributed in the hope that it will be useful, but *
* WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
* General Public License for more details. *
* *
* A copy of the GNU General Public License is available on the World *
* Wide Web at <http://www.gnu.org/copyleft/gpl.html>. You can also *
* obtain it by writing to the Free Software Foundation, *
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
* *
***************************************************************************
Author: Donald Ziesig
Abstract
TTemplateExpander provides xml templates to replace the hard-coded
pascal snippets used by TCodeCompletionCodeTool.
The xml file fragment for the Setter method:
<templates>
*
*
*
<template name="SetterMethod">
procedure <ClassName>.<AccessParam/>(<PropVarName/>: <PropType/>);<br/>
begin
<indent/>if <VarName/>=<PropVarName/> then Exit;<br/>
<indent/><VarName/>:=<PropVarName/>;<br/>
end;<br/>
</template>
*
*
*
</templates>
produces pascal:
procedure TMyClass.SetMyVar(AValue: MyType);
begin
if AValue=MyVar then Exit;
MyVar:=AValue;
end;
===============================================================================
The following xml tags are implemented:
<if var="SomeBool"> ... </if> generates pascal code if string value of
the argument named "SomeBool" is "true".
<ifnot var="SomeBool" ... </ifnot> generates pascal code if string value of
the argument named "SomeBool" is not "true"
<else> ... </else> must immediately follow </if> or </ifnot>.
generates pascal code if the negation of
the previous tag is true.
<count var="SomeVar"> ... </count> generates pascal code for zero or more
values of the string argument "SomeVar".
The values are encoded as a single string
of the form "Arg0?Arg1?...ArgN?" (Yeah, I
know. See the comments below about a hack.)
<indent/> is replaced by the appropriate Indent string.
<br/> is replaced by the appropriate LineEnd string.
<SomeVar/> is replaced by the string element of ArgVal
which corresponds to the string element of
ArgName.
}
unit CodeCompletionTemplater;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, laz2_DOM, laz2_XMLRead, LazFileUtils, LazUTF8Classes,
CodeCache, FileProcs;
type
{ TTemplateExpander }
TTemplateExpander = class
private
FCode: TCodeBuffer;
fCodeChangeStep: Integer;
procedure LoadCode;
procedure SetCode(AValue: TCodeBuffer);
protected
XMLDoc : TXMLDocument;
Root : TDOMNode;
function ArgCount(Args: String): Integer;
function ArgN(Args: String; Index : Integer) : String;
function ExpandTemplate(Template: TDOMNode;
LineEnd, Indent : String;
ArgName: array of String;
ArgVal: array of const;
CountIndex: Integer = -1): String;
function FindTemplate(TemplateName: String): TDOMNode;
public
constructor Create;
destructor Destroy; override;
function Expand(TemplateName : String;
LineEnd, Indent : String;
ArgName : array of String;
ArgVal : array of const): String;
function TemplateExists(TemplateName: String): Boolean;
property Doc: TXMLDocument read XMLDoc;
property Code: TCodeBuffer read FCode write SetCode;
procedure ReloadCode;
end;
var
Expander : TTemplateExpander; // will be set by CodeToolBoss
implementation
{ TTemplateExpander }
//
// ArgCount and ArgN are part of a hack to overcome the fact that
// "array of const" can not contain another array.
//
// instead of a convenient ['a',...,['x1,'x2'],...,'z'] we must use something
// like ['a',...,'x1?x2?',...'z'] (which is what I chose just for simplicity)
//
function TTemplateExpander.ArgCount(Args: String): Integer;
var
I : Integer;
begin
Result := 0;
for I := 1 to Length(Args) do
if Args[I] = '?' then
Inc(Result);
end;
function TTemplateExpander.ArgN(Args: String; Index: Integer): String;
var
I : Integer;
P : Integer;
S : String;
begin
S := Args;
for I := 0 to pred(Index) do
begin
P := Pos('?',S);
S := Copy(S,P+1,65535);
end;
P := Pos('?',S);
Result := Copy(S,1,P-1);
end;
constructor TTemplateExpander.Create;
begin
fCodeChangeStep:=CTInvalidChangeStamp;
end;
destructor TTemplateExpander.Destroy;
begin
FCode:=nil;
FreeAndNil(XMLDoc);
end;
function TTemplateExpander.Expand(TemplateName: String; LineEnd,
Indent: String; ArgName: array of String; ArgVal: array of const): String;
var
Template : TDOMNode;
begin
Template := FindTemplate(TemplateName);
if Template = nil then
raise Exception.Create('Template "' + TemplateName + '" not found in TemplateExpander.');
Result := ExpandTemplate(Template, #13#10, ' ', ArgName, ArgVal);
end;
function TTemplateExpander.ExpandTemplate(Template: TDOMNode; LineEnd,
Indent: String; ArgName: array of String; ArgVal: array of const;
CountIndex : Integer): String;
// Sequential search of ArgName array to return corresponding element
// of the ArgVal array (appropriately processed if it simulates being
// an array itself.
function GetArgValue(Name : String; Index : Integer = -1): String;
var
I : Integer;
S : String;
begin
for I := 0 to pred(Length(ArgName)) do
if ArgName[I] = Name then
begin
S := AnsiString(ArgVal[I].VAnsiString);
if (Index < 0) or (Pos('?',S) = 0) then
Result := S
else
Result := ArgN(S, Index);
exit;
end;
raise Exception.Create('ExpandTemplate could not find Argument named "' + Name + '"');
end;
function GetBoolArgValue(Name : String; Index : Integer = -1): Boolean;
var
I : Integer;
begin
for I := 0 to pred(Length(ArgName)) do
if ArgName[I] = Name then
begin
Result := ArgVal[I].VBoolean;
exit;
end;
raise Exception.Create('ExpandTemplate could not find Argument named "' + Name + '"');
end;
function GetNodeValue(Node : TDOMNode; Required : Boolean = True): String;
var
Len : Integer;
begin
Result := '';
Len := Node.Attributes.Length;
if Required then
if Len = 0 then
raise Exception.Create('Missing attribute tag for node "' + Node.NodeName + '"');
if Len > 0 then
Result := Node.Attributes.Item[0].NodeValue;
end;
var
Node : TDOMNode;
N : String;
S : String;
Name : String;
R : String; // for debugger
PrevNode : TDOMNode;
CommentFlag : Boolean;
CountArgs : String;
NArgs : Integer;
I : Integer;
begin
R := '';
PrevNode := nil;
Node := Template.FirstChild;
while Node <> nil do
begin
N := Node.NodeName;
S := Node.NodeValue;
CommentFlag := False;
// plain text in the xml file is copied directly to the output (almost).
if N = '#text' then
begin
if Pos(#10, S) = 1 then // Hack to work around XML parser that leaves
S := Copy(S,2,65535); // A new-line when text appears in first
R := R + S; // column of the XML file.
end
// indent the text using the string argument Indent
else if N = 'indent' then
begin
Name := GetNodeValue(Node, False);
if Name = '' then
R := R + Indent
else
R := R + GetArgValue(Name);
end
// add the line break using the string argument LineEnd
else if N = 'br' then
R := R + LineEnd
// process the xml 'if' tag
else if (N = 'if') then
begin
Name := GetNodeValue(Node); //Node.Attributes.Item[0].NodeValue;
if GetBoolArgValue(Name) then
R := R + ExpandTemplate(Node, LineEnd,Indent,ArgName,ArgVal);
end
// process the xml 'ifnot' tag
else if (N = 'ifnot') then
begin
Name := GetNodeValue(Node); //Node.Attributes.Item[0].NodeValue;
if not GetBoolArgValue(Name) then
R := R + ExpandTemplate(Node, LineEnd,Indent,ArgName,ArgVal);
end
// process the xml 'else' tag. This is sneaky. The else tag must (almost)
// immediately follow the closing of either the 'if' or 'ifnot' tags. (The
// exception allows comments to intervene)
//
// The original implementation used separate 'else' and 'elsenot' tags, but
// the xml file got so confusing at times that it was better to add some
// nasty looking code here to make the xml neater.
else if N = 'else' then
begin
if PrevNode = nil then
raise Exception.Create('Expander: "else" without "if" or "ifnot"');
if PrevNode.NodeName = 'if' then
begin
Name := GetNodeValue(PrevNode); //PrevNode.Attributes.Item[0].NodeValue;
if GetBoolArgValue(Name) then
R := R + ExpandTemplate(Node, LineEnd,Indent,ArgName,ArgVal);
end
else if PrevNode.NodeName = 'ifnot' then
begin
Name := GetNodeValue(PrevNode); //PrevNode.Attributes.Item[0].NodeValue;
if not GetBoolArgValue(Name) then
R := R + ExpandTemplate(Node, LineEnd,Indent,ArgName,ArgVal);
end
else
raise Exception.Create('Expander: mis-placed "else" following ' + PrevNode.NodeName);
end
// process the xml 'count' tag. This implements multiple lines to be generated
// from array or list data in the pascal code. This was originally needed to
// implement the 'AssignMethod' template.
else if N = 'count' then
begin
Name := GetNodeValue(Node); //Node.Attributes.Item[0].NodeValue;
CountArgs := GetArgValue(Name);
NArgs := ArgCount(CountArgs);
for I := 0 to pred(Nargs) do
R := R + ExpandTemplate(Node, LineEnd,Indent,ArgName,ArgVal, I);
end
// process all other xml tags (less comment) as requests for the pascal variable
// specified by the tag name: e.g., <ClassName/> will look for an argument name
// of ClassName in the ArgNames array and get the corresponding value from the
// ArgVals array;
else if N <> '#comment' then
R := R + GetArgValue(N, CountIndex)
{$IFDEF DebugTemplate }
else
begin
R := R + '{ ' + Node.NodeValue + ' }';
CommentFlag := True;
end;
{$ELSE DebugTemplate}
else
CommentFlag := True;
{$ENDIF DebugTemplate}
// ignore the comment nodes in subsequent processing.
if not CommentFlag then PrevNode := Node;
Node := Node.NextSibling;
end;
Result := R;
end;
function TTemplateExpander.FindTemplate(TemplateName : String): TDOMNode;
var
N : String;
begin
if not Assigned(Root) then
begin
Result := nil;
exit;
end;
if Root.NodeName <> 'templates' then
raise Exception.Create('Root node of codetools TemplateExpander = "' + Root.NodeName + '", "templates" expected.');
// Sequential search of list of templates.
Result := Root.FirstChild;
while Result <> nil do
begin
N := Result.NodeName;
if N <> '#comment' then // ignores first level comments
begin
if N <> 'template' then
raise Exception.Create('template node of codetools TemplateExpander = "' + N + '", "template" expected.');
if Result.Attributes.Item[0].NodeValue = TemplateName then
break;
end;
Result := Result.NextSibling;
end;
end;
procedure TTemplateExpander.LoadCode;
var
ms: TMemoryStream;
begin
if Code=nil then begin
fCodeChangeStep:=CTInvalidChangeStamp;
exit;
end;
fCodeChangeStep:=Code.ChangeStep;
Root:=nil;
FreeAndNil(XMLDoc);
ms:=TMemoryStream.Create;
try
Code.SaveToStream(ms);
ms.Position:=0;
ReadXMLFile(XMLDoc, ms);
Root := XMLDoc.DocumentElement;
finally
ms.Free;
end;
end;
procedure TTemplateExpander.SetCode(AValue: TCodeBuffer);
begin
if FCode=AValue then Exit;
FCode:=AValue;
LoadCode;
end;
function TTemplateExpander.TemplateExists(TemplateName: String): Boolean;
begin
ReloadCode;
Result := FindTemplate(TemplateName) <> nil;
end;
procedure TTemplateExpander.ReloadCode;
begin
if Code=nil then exit;
if Code.ChangeStep=fCodeChangeStep then exit;
LoadCode;
end;
end.

View File

@ -0,0 +1,54 @@
<?xml version="1.0" encoding="UTF-8"?>
<templates>
<!--
The first of any duplicated templates is the one that will be used.
This allows backups to be saved in this file.
-->
<template name="SetterMethod">
procedure <ClassName/>.<AccessParam/>(<PropVarName/>: <PropType/>);<br/>
begin<br/>
<indent/>if <VarName/>=<PropVarName/> then Exit;<br/>
<indent/><VarName/>:=<PropVarName/>;<br/>
end;
</template>
<template name="AssignMethodDef">
procedure <ProcName/>(<ParamName/>: <ParamType/> );<if var="Override"> override;</if>
</template>
<template name="AssignMethod">
procedure <ClassName/>.<ProcName/>(<ParamName/>: <ParamType/>);<br/>
<ifnot var="SameType">
var<br/>
<indent/><SrcVar/>: <ClassName/>;<br/>
</ifnot>
begin<br/>
<if var="CallInherited0">
<indent/>inherited <ProcName/>(<ParamName/>);<br/>
</if>
<ifnot var="SameType">
<indent/>if <ParamName/> is <ClassName/> then<br/>
<indent/>begin<br/>
<indent/><indent/><SrcVar/> := <ClassName/>(<ParamName/>);<br/>
</ifnot>
<count var="NodeExt">
<indent/><indent/><NodeExt/> := <SrcVar/>.<NodeExt/>;<br/>
</count>
<ifnot var="SameType">
<if var="CallInherited1">
<indent/>end<br/>
<indent/>else<br/>
<indent/><indent/>inherited <ProcName/>(<ParamName/>);<br/>
</if>
<else>
<indent/>end;<br/>
</else>
</ifnot>
end;
</template>
<template name="PrettyColon">: </template>
</templates>

View File

@ -77,6 +77,7 @@ interface
{off $DEFINE VerboseCompleteMethod} {off $DEFINE VerboseCompleteMethod}
{off $DEFINE VerboseCompleteLocalVarAssign} {off $DEFINE VerboseCompleteLocalVarAssign}
{off $DEFINE VerboseCompleteEventAssign} {off $DEFINE VerboseCompleteEventAssign}
{$DEFINE UseXMLTemplates}
uses uses
{$IFDEF MEM_CHECK} {$IFDEF MEM_CHECK}
@ -85,7 +86,7 @@ uses
Classes, SysUtils, FileProcs, CodeToolsStrConsts, CodeTree, CodeAtom, Classes, SysUtils, FileProcs, CodeToolsStrConsts, CodeTree, CodeAtom,
CodeCache, CustomCodeTool, PascalParserTool, MethodJumpTool, CodeCache, CustomCodeTool, PascalParserTool, MethodJumpTool,
FindDeclarationTool, KeywordFuncLists, CodeToolsStructs, BasicCodeTools, FindDeclarationTool, KeywordFuncLists, CodeToolsStructs, BasicCodeTools,
LinkScanner, SourceChanger, CodeGraph, AVL_Tree; LinkScanner, SourceChanger, CodeGraph, AVL_Tree, codecompletiontemplater;
type type
TNewClassPart = (ncpPrivateProcs, ncpPrivateVars, TNewClassPart = (ncpPrivateProcs, ncpPrivateVars,
@ -137,6 +138,7 @@ type
fNewMainUsesSectionUnits: TAVLTree; // tree of AnsiString fNewMainUsesSectionUnits: TAVLTree; // tree of AnsiString
procedure AddNewPropertyAccessMethodsToClassProcs(ClassProcs: TAVLTree; procedure AddNewPropertyAccessMethodsToClassProcs(ClassProcs: TAVLTree;
const TheClassName: string); const TheClassName: string);
procedure SetSetPropertyVariablename(AValue: string);
function UpdateProcBodySignature(ProcBodyNodes: TAVLTree; function UpdateProcBodySignature(ProcBodyNodes: TAVLTree;
const BodyNodeExt: TCodeTreeNodeExtension; const BodyNodeExt: TCodeTreeNodeExtension;
ProcAttrCopyDefToBody: TProcHeadAttributes; var ProcsCopied: boolean; ProcAttrCopyDefToBody: TProcHeadAttributes; var ProcsCopied: boolean;
@ -363,7 +365,7 @@ type
public public
// Options // Options
property SetPropertyVariablename: string read FSetPropertyVariablename property SetPropertyVariablename: string read FSetPropertyVariablename
write FSetPropertyVariablename; write SetSetPropertyVariablename;
property CompleteProperties: boolean read FCompleteProperties property CompleteProperties: boolean read FCompleteProperties
write FCompleteProperties; write FCompleteProperties;
property AddInheritedCodeToOverrideMethod: boolean property AddInheritedCodeToOverrideMethod: boolean
@ -456,6 +458,12 @@ begin
FSourceChangeCache.MainScanner:=Scanner; FSourceChangeCache.MainScanner:=Scanner;
end; end;
procedure TCodeCompletionCodeTool.SetSetPropertyVariablename(aValue: string);
begin
if FSetPropertyVariablename=aValue then Exit;
FSetPropertyVariablename:=aValue;
end;
function TCodeCompletionCodeTool.OnTopLvlIdentifierFound( function TCodeCompletionCodeTool.OnTopLvlIdentifierFound(
Params: TFindDeclarationParams; const FoundContext: TFindContext Params: TFindDeclarationParams; const FoundContext: TFindContext
): TIdentifierFoundResult; ): TIdentifierFoundResult;
@ -1067,8 +1075,17 @@ begin
+'invalid target for a var'); +'invalid target for a var');
end; end;
InsertTxt:=VariableName+':'+VariableType+';'; {$IFDEF UseXMLTemplates}
if ( Expander <> nil ) and Expander.TemplateExists('PrettyColon') then
begin
InsertTxt:=VariableName+Expander.Expand('PrettyColon','','',[],[])+VariableType+';';
end
else
{$ENDIF}
begin
InsertTxt:=VariableName+':'+VariableType+';';
//DebugLn(['TCodeCompletionCodeTool.AddLocalVariable C InsertTxt="',InsertTxt,'" ParentNode=',ParentNode.DescAsString,' HeaderNode=',HeaderNode.DescAsString,' OtherSectionNode=',OtherSectionNode.DescAsString,' VarSectionNode=',VarSectionNode.DescAsString,' CursorNode=',CursorNode.DescAsString]); //DebugLn(['TCodeCompletionCodeTool.AddLocalVariable C InsertTxt="',InsertTxt,'" ParentNode=',ParentNode.DescAsString,' HeaderNode=',HeaderNode.DescAsString,' OtherSectionNode=',OtherSectionNode.DescAsString,' VarSectionNode=',VarSectionNode.DescAsString,' CursorNode=',CursorNode.DescAsString]);
end;
if (VarSectionNode<>nil) then begin if (VarSectionNode<>nil) then begin
// there is already a var section // there is already a var section
@ -2641,6 +2658,9 @@ var
Params: TFindDeclarationParams; Params: TFindDeclarationParams;
ParamName: String; ParamName: String;
// create param list without brackets // create param list without brackets
{$IFDEF UseXMLTemplates}
Colon : String;
{$ENDIF}
begin begin
Result:=''; Result:='';
CleanList:=''; CleanList:='';
@ -2684,8 +2704,20 @@ begin
Result:=Result+';'; Result:=Result+';';
CleanList:=CleanList+';'; CleanList:=CleanList+';';
end; end;
Result:=Result+ParamName+':'+ParamType; {$IFDEF UseXMLTemplates}
CleanList:=CleanList+ParamType; if assigned( Expander ) and Expander.TemplateExists('PrettyColon') then
begin
Colon := Expander.Expand('PrettyColon', '','', // Doesn't use linebreak or indentation
[], [] );
Result:=Result+ParamName+Colon+ParamType;
CleanList:=CleanList+Colon+ParamType;
end
else
{$ENDIF UseXMLTemplates}
begin
Result:=Result+ParamName+':'+ParamType;
CleanList:=CleanList+':'+ParamType;
end;
// next // next
MoveCursorToCleanPos(ExprEndPos); MoveCursorToCleanPos(ExprEndPos);
ReadNextAtom; ReadNextAtom;
@ -2806,7 +2838,20 @@ const
// prepend 'procedure' keyword // prepend 'procedure' keyword
if IsFunction then if IsFunction then
ProcCode:='function '+ProcCode+':'+FuncType+';' begin
{$IFDEF UseXMLTemplates}
if ( Expander <> nil ) and Expander.TemplateExists('PrettyColon') then
begin
ProcCode:= 'function '+ProcCode+
Expander.Expand('PrettyColon','','',[],[])
+FuncType+';';
end
else
{$ENDIF}
begin
ProcCode:='function '+ProcCode+':'+FuncType+';';
end;
end
else else
ProcCode:='procedure '+ProcCode+';'; ProcCode:='procedure '+ProcCode+';';
CleanProcHead:=CleanProcHead+';'; CleanProcHead:=CleanProcHead+';';
@ -2998,6 +3043,15 @@ begin
CodeCompleteSrcChgCache:=SourceChangeCache; CodeCompleteSrcChgCache:=SourceChangeCache;
// check if variable already exists // check if variable already exists
if not VarExistsInCodeCompleteClass(UpperCaseStr(VarName)) then begin if not VarExistsInCodeCompleteClass(UpperCaseStr(VarName)) then begin
{$IFDEF UseXMLTemplates}
if ( Expander <> nil ) and Expander.TemplateExists('PrettyColon') then
begin
AddClassInsertion(UpperCaseStr(VarName),
VarName+Expander.Expand('PrettyColon','','',[],[])+VarType+';',VarName,ncpPublishedVars);
end
else
{$ENDIF}
AddClassInsertion(UpperCaseStr(VarName), AddClassInsertion(UpperCaseStr(VarName),
VarName+':'+VarType+';',VarName,ncpPublishedVars); VarName+':'+VarType+';',VarName,ncpPublishedVars);
if not InsertAllNewClassParts then if not InsertAllNewClassParts then
@ -5803,6 +5857,9 @@ var
SrcVar: String; SrcVar: String;
i: Integer; i: Integer;
Beauty: TBeautifyCodeOptions; Beauty: TBeautifyCodeOptions;
{$IFDEF UseXMLTemplates}
NodeExtsStr: String;
{$ENDIF}
begin begin
Result:=false; Result:=false;
NewPos:=CleanCodeXYPosition; NewPos:=CleanCodeXYPosition;
@ -5812,67 +5869,114 @@ begin
Beauty:=SourceChanger.BeautifyCodeOptions; Beauty:=SourceChanger.BeautifyCodeOptions;
aClassName:=ExtractClassName(ClassNode,false); aClassName:=ExtractClassName(ClassNode,false);
CleanDef:=ProcName+'('+ParamType+');'; CleanDef:=ProcName+'('+ParamType+');';
Def:='procedure '+ProcName+'('+ParamName+':'+ParamType+');'; {$IFDEF UseXMLTemplates}
if OverrideMod then Def:=Def+'override;'; if assigned( Expander ) and Expander.TemplateExists('AssignMethodDef') then
begin
Def := Expander.Expand('AssignMethodDef', '','', // Doesn't use linebreak or indentation
['ProcName', 'ParamName', 'ParamType', 'Override' ],
[ ProcName, ParamName, ParamType, OverrideMod ] );
end else
{$ENDIF UseXMLTemplates}
begin
Def:='procedure '+ProcName+'('+ParamName+':'+ParamType+');';
if OverrideMod then Def:=Def+'override;';
end;
SrcVar:=ParamName; SrcVar:=ParamName;
// create the proc header // create the proc header
SameType:=CompareIdentifiers(PChar(aClassName),PChar(ParamType))=0; SameType:=CompareIdentifiers(PChar(aClassName),PChar(ParamType))=0;
e:=SourceChanger.BeautifyCodeOptions.LineEnd; e:=SourceChanger.BeautifyCodeOptions.LineEnd;
Indent:=0; Indent:=0;
IndentStep:=SourceChanger.BeautifyCodeOptions.Indent; IndentStep:=SourceChanger.BeautifyCodeOptions.Indent;
ProcBody:='procedure '+aClassName+'.'+ProcName+'('+ParamName+':'+ParamType+');'+e; {$IFDEF UseXMLTemplates}
if not SameType then begin if assigned(Expander) and Expander.TemplateExists('AssignMethod') then begin
// add local variable if not SameType then begin
SrcVar:=LocalVarName; // add local variable
if SrcVar='' then SrcVar:=LocalVarName;
SrcVar:='aSource'; if SrcVar='' then
if CompareIdentifiers(PChar(SrcVar),PChar(ParamName))=0 then begin
if CompareIdentifiers(PChar(SrcVar),'aSource')=0 then
SrcVar:='aSrc'
else
SrcVar:='aSource'; SrcVar:='aSource';
if CompareIdentifiers(PChar(SrcVar),PChar(ParamName))=0 then begin
if CompareIdentifiers(PChar(SrcVar),'aSource')=0 then
SrcVar:='aSrc'
else
SrcVar:='aSource';
end;
end;
// add assignments
NodeExtsStr := '';
if MemberNodeExts<>nil then begin
for i:=0 to MemberNodeExts.Count-1 do
begin
NodeExt:=TCodeTreeNodeExtension(MemberNodeExts[i]);
NodeExtsStr := NodeExtsStr + NodeExt.Txt + '?';
end;
end;
ProcBody := Expander.Expand( 'AssignMethod',e,GetIndentStr(Indent),
['ClassName', 'ProcName', 'ParamName', 'ParamType',
'SameType', 'SrcVar', 'Inherited0', 'Inherited1',
'NodeExt' ],
[ aClassName, ProcName, ParamName, ParamType,
SameType, SrcVar,
CallInherited and (not CallInheritedOnlyInElse),
CallInherited and CallInheritedOnlyInElse,
NodeExtsStr ] );
end
else
{$ENDIF UseXMLTemplates}
begin
ProcBody:='procedure '+aClassName+'.'+ProcName+'('+ParamName+':'+ParamType+');'+e;
if not SameType then begin
// add local variable
SrcVar:=LocalVarName;
if SrcVar='' then
SrcVar:='aSource';
if CompareIdentifiers(PChar(SrcVar),PChar(ParamName))=0 then begin
if CompareIdentifiers(PChar(SrcVar),'aSource')=0 then
SrcVar:='aSrc'
else
SrcVar:='aSource';
end;
ProcBody:=ProcBody+'var'+e
+Beauty.GetIndentStr(Indent+IndentStep)+SrcVar+':'+aClassName+';'+e;
end; end;
ProcBody:=ProcBody+'var'+e ProcBody:=ProcBody+'begin'+e;
+Beauty.GetIndentStr(Indent+IndentStep)+SrcVar+':'+aClassName+';'+e;
end;
ProcBody:=ProcBody+'begin'+e;
inc(Indent,IndentStep);
// call inherited
if CallInherited and (not CallInheritedOnlyInElse) then
ProcBody:=ProcBody
+Beauty.GetIndentStr(Indent)+'inherited '+ProcName+'('+ParamName+');'+e;
if not SameType then begin
// add a parameter check to the new procedure
ProcBody:=ProcBody
+Beauty.GetIndentStr(Indent)+'if '+ParamName+' is '+aClassName+' then'+e
+Beauty.GetIndentStr(Indent)+'begin'+e;
inc(Indent,IndentStep); inc(Indent,IndentStep);
ProcBody:=ProcBody+Beauty.GetIndentStr(Indent)+SrcVar+':='+aClassName+'('+ParamName+');'+e;
end;
// add assignments // call inherited
if MemberNodeExts<>nil then begin if CallInherited and (not CallInheritedOnlyInElse) then
for i:=0 to MemberNodeExts.Count-1 do begin ProcBody:=ProcBody
NodeExt:=TCodeTreeNodeExtension(MemberNodeExts[i]); +Beauty.GetIndentStr(Indent)+'inherited '+ProcName+'('+ParamName+');'+e;
// add assignment
ProcBody:=ProcBody+Beauty.GetIndentStr(Indent)+NodeExt.Txt+':='+SrcVar+'.'+NodeExt.Txt+';'+e;
end;
end;
if not SameType then begin if not SameType then begin
// close if block // add a parameter check to the new procedure
dec(Indent,IndentStep); ProcBody:=ProcBody
if CallInherited and CallInheritedOnlyInElse then begin +Beauty.GetIndentStr(Indent)+'if '+ParamName+' is '+aClassName+' then'+e
ProcBody:=ProcBody+Beauty.GetIndentStr(Indent)+'end else'+e +Beauty.GetIndentStr(Indent)+'begin'+e;
+Beauty.GetIndentStr(Indent+IndentStep)+'inherited '+ProcName+'('+ParamName+');'+e; inc(Indent,IndentStep);
end else begin ProcBody:=ProcBody+Beauty.GetIndentStr(Indent)+SrcVar+':='+aClassName+'('+ParamName+');'+e;
ProcBody:=ProcBody+Beauty.GetIndentStr(Indent)+'end;'+e
end; end;
// add assignments
if MemberNodeExts<>nil then begin
for i:=0 to MemberNodeExts.Count-1 do begin
NodeExt:=TCodeTreeNodeExtension(MemberNodeExts[i]);
// add assignment
ProcBody:=ProcBody+Beauty.GetIndentStr(Indent)+NodeExt.Txt+':='+SrcVar+'.'+NodeExt.Txt+';'+e;
end;
end;
if not SameType then begin
// close if block
dec(Indent,IndentStep);
if CallInherited and CallInheritedOnlyInElse then begin
ProcBody:=ProcBody+Beauty.GetIndentStr(Indent)+'end else'+e
+Beauty.GetIndentStr(Indent+IndentStep)+'inherited '+ProcName+'('+ParamName+');'+e;
end else begin
ProcBody:=ProcBody+Beauty.GetIndentStr(Indent)+'end;'+e
end;
end;
// close procedure body
ProcBody:=ProcBody+'end;';
end; end;
// close procedure body
ProcBody:=ProcBody+'end;';
if not InitClassCompletion(ClassNode,SourceChanger) then exit; if not InitClassCompletion(ClassNode,SourceChanger) then exit;
ProcBody:=SourceChanger.BeautifyCodeOptions.BeautifyStatement(ProcBody,0); ProcBody:=SourceChanger.BeautifyCodeOptions.BeautifyStatement(ProcBody,0);
@ -6851,19 +6955,33 @@ var
end; end;
} }
ProcBody:= {$IFDEF UseXMLTemplates}
'procedure ' if assigned(Expander) and Expander.TemplateExists('SetterMethod') then
+ExtractClassName(PropNode.Parent.Parent,false)+'.'+AccessParam begin
+'('+SetPropertyVariablename+':'+PropType+');' debugln(['CompleteWriteSpecifier ', 'USING template for SetterMethod']);
+BeautifyCodeOpts.LineEnd ProcBody := Expander.Expand( 'SetterMethod',
+'begin'+BeautifyCodeOpts.LineEnd BeautifyCodeOpts.LineEnd,
+BeautifyCodeOpts.GetIndentStr(BeautifyCodeOpts.Indent) GetIndentStr(BeautifyCodeOpts.Indent),
+'if '+VariableName+'='+SetPropertyVariablename+' then Exit;' ['ClassName', 'AccessParam','PropVarName', 'PropType','VarName'],
[ExtractClassName(PropNode.Parent.Parent,false), AccessParam, SetPropertyVariablename, PropType, VariableName] );
end
else
{$ENDIF}
begin
ProcBody:=
'procedure '
+ExtractClassName(PropNode.Parent.Parent,false)+'.'+AccessParam
+'('+SetPropertyVariablename+':'+PropType+');'
+BeautifyCodeOpts.LineEnd +BeautifyCodeOpts.LineEnd
+BeautifyCodeOpts.GetIndentStr(BeautifyCodeOpts.Indent) +'begin'+BeautifyCodeOpts.LineEnd
+VariableName+':='+SetPropertyVariablename+';' +BeautifyCodeOpts.GetIndentStr(BeautifyCodeOpts.Indent)
+BeautifyCodeOpts.LineEnd +'if '+VariableName+'='+SetPropertyVariablename+' then Exit;'
+'end;'; +BeautifyCodeOpts.LineEnd
+BeautifyCodeOpts.GetIndentStr(BeautifyCodeOpts.Indent)
+VariableName+':='+SetPropertyVariablename+';'
+BeautifyCodeOpts.LineEnd
+'end;';
end;
if IsClassProp then if IsClassProp then
ProcBody:='class '+ProcBody; ProcBody:='class '+ProcBody;
end; end;
@ -8921,6 +9039,5 @@ begin
FAddInheritedCodeToOverrideMethod:=true; FAddInheritedCodeToOverrideMethod:=true;
end; end;
end. end.

View File

@ -46,7 +46,7 @@ uses
EventCodeTool, CodeTree, CodeAtom, SourceChanger, DefineTemplates, CodeCache, EventCodeTool, CodeTree, CodeAtom, SourceChanger, DefineTemplates, CodeCache,
ExprEval, LinkScanner, KeywordFuncLists, FindOverloads, CodeBeautifier, ExprEval, LinkScanner, KeywordFuncLists, FindOverloads, CodeBeautifier,
FindDeclarationCache, DirectoryCacher, AVL_Tree, FindDeclarationCache, DirectoryCacher, AVL_Tree,
PPUCodeTools, LFMTrees, DirectivesTree, PPUCodeTools, LFMTrees, DirectivesTree, codecompletiontemplater,
PascalParserTool, CodeToolsConfig, CustomCodeTool, FindDeclarationTool, PascalParserTool, CodeToolsConfig, CustomCodeTool, FindDeclarationTool,
IdentCompletionTool, StdCodeTools, ResourceCodeTool, CodeToolsStructs, IdentCompletionTool, StdCodeTools, ResourceCodeTool, CodeToolsStructs,
CTUnitGraph, CodeTemplatesTool, ExtractProcTool; CTUnitGraph, CodeTemplatesTool, ExtractProcTool;
@ -88,6 +88,7 @@ type
FCatchExceptions: boolean; FCatchExceptions: boolean;
FChangeStep: integer; FChangeStep: integer;
FCheckFilesOnDisk: boolean; FCheckFilesOnDisk: boolean;
FCodeCompletionTemplateFileName: String;
FCodeNodeTreeChangeStep: integer; FCodeNodeTreeChangeStep: integer;
FCompleteProperties: boolean; FCompleteProperties: boolean;
FCurCodeTool: TCodeTool; // current codetool FCurCodeTool: TCodeTool; // current codetool
@ -141,8 +142,10 @@ type
procedure SetAbortable(const AValue: boolean); procedure SetAbortable(const AValue: boolean);
procedure SetAddInheritedCodeToOverrideMethod(const AValue: boolean); procedure SetAddInheritedCodeToOverrideMethod(const AValue: boolean);
procedure SetCheckFilesOnDisk(NewValue: boolean); procedure SetCheckFilesOnDisk(NewValue: boolean);
procedure SetCodeCompletionTemplateFileName(AValue: String);
procedure SetCompleteProperties(const AValue: boolean); procedure SetCompleteProperties(const AValue: boolean);
procedure SetIndentSize(NewValue: integer); procedure SetIndentSize(NewValue: integer);
procedure SetSetPropertyVariablename(AValue: string);
procedure SetTabWidth(const AValue: integer); procedure SetTabWidth(const AValue: integer);
procedure SetUseTabs(AValue: boolean); procedure SetUseTabs(AValue: boolean);
procedure SetVisibleEditorLines(NewValue: integer); procedure SetVisibleEditorLines(NewValue: integer);
@ -279,7 +282,7 @@ type
property IndentSize: integer read FIndentSize write SetIndentSize; property IndentSize: integer read FIndentSize write SetIndentSize;
property JumpCentered: boolean read FJumpCentered write SetJumpCentered; property JumpCentered: boolean read FJumpCentered write SetJumpCentered;
property SetPropertyVariablename: string property SetPropertyVariablename: string
read FSetPropertyVariablename write FSetPropertyVariablename; read FSetPropertyVariablename write SetSetPropertyVariablename;
property VisibleEditorLines: integer property VisibleEditorLines: integer
read FVisibleEditorLines write SetVisibleEditorLines; read FVisibleEditorLines write SetVisibleEditorLines;
property TabWidth: integer read FTabWidth write SetTabWidth; property TabWidth: integer read FTabWidth write SetTabWidth;
@ -290,6 +293,10 @@ type
read FAddInheritedCodeToOverrideMethod read FAddInheritedCodeToOverrideMethod
write SetAddInheritedCodeToOverrideMethod; write SetAddInheritedCodeToOverrideMethod;
// code completion templates
property CodeCompletionTemplateFileName : String read FCodeCompletionTemplateFileName
write SetCodeCompletionTemplateFileName;
// source changing // source changing
procedure BeginUpdate; procedure BeginUpdate;
function EndUpdate: boolean; function EndUpdate: boolean;
@ -5431,6 +5438,29 @@ begin
FCurCodeTool.CheckFilesOnDisk:=NewValue; FCurCodeTool.CheckFilesOnDisk:=NewValue;
end; end;
procedure TCodeToolManager.SetCodeCompletionTemplateFileName(AValue: String);
var
OldValue: String;
Code: TCodeBuffer;
begin
AValue:=CleanAndExpandFilename(AValue);
if FCodeCompletionTemplateFileName=AValue then Exit;
OldValue:=FCodeCompletionTemplateFileName;
FCodeCompletionTemplateFileName:=AValue;
if CompareFilenames(FCodeCompletionTemplateFileName,OldValue)=0 then exit;
if (FCodeCompletionTemplateFileName<>'') then
Code:=LoadFile(FCodeCompletionTemplateFileName,true,false)
else
Code:=nil;
if Code<>nil then begin
if Expander=nil then
Expander:=TTemplateExpander.Create;
Expander.Code:=Code;
end else begin
FreeAndNil(Expander);
end;
end;
procedure TCodeToolManager.SetCompleteProperties(const AValue: boolean); procedure TCodeToolManager.SetCompleteProperties(const AValue: boolean);
begin begin
if CompleteProperties=AValue then exit; if CompleteProperties=AValue then exit;
@ -5479,6 +5509,12 @@ begin
FCurCodeTool.JumpCentered:=NewValue; FCurCodeTool.JumpCentered:=NewValue;
end; end;
procedure TCodeToolManager.SetSetPropertyVariablename(aValue: string);
begin
if FSetPropertyVariablename=aValue then Exit;
FSetPropertyVariablename:=aValue;
end;
procedure TCodeToolManager.SetCursorBeyondEOL(NewValue: boolean); procedure TCodeToolManager.SetCursorBeyondEOL(NewValue: boolean);
begin begin
if NewValue=FCursorBeyondEOL then exit; if NewValue=FCursorBeyondEOL then exit;

View File

@ -1,4 +1,4 @@
<?xml version="1.0"?> <?xml version="1.0" encoding="UTF-8"?>
<CONFIG> <CONFIG>
<Package Version="4"> <Package Version="4">
<Name Value="CodeTools"/> <Name Value="CodeTools"/>
@ -29,7 +29,7 @@
<License Value="GPL-2 <License Value="GPL-2
"/> "/>
<Version Major="1" Release="1"/> <Version Major="1" Release="1"/>
<Files Count="60"> <Files Count="61">
<Item1> <Item1>
<Filename Value="Makefile"/> <Filename Value="Makefile"/>
<Type Value="Text"/> <Type Value="Text"/>
@ -269,8 +269,12 @@
</Item59> </Item59>
<Item60> <Item60>
<Filename Value="ctunitgroupgraph.pas"/> <Filename Value="ctunitgroupgraph.pas"/>
<UnitName Value="ctunitgroupgraph"/> <UnitName Value="CTUnitGroupGraph"/>
</Item60> </Item60>
<Item61>
<Filename Value="codecompletiontemplater.pas"/>
<UnitName Value="codecompletiontemplater"/>
</Item61>
</Files> </Files>
<LazDoc Paths="docs"/> <LazDoc Paths="docs"/>
<i18n> <i18n>

View File

@ -19,7 +19,7 @@ uses
SourceChanger, SourceLog, StdCodeTools, OtherIdentifierTree, SourceChanger, SourceLog, StdCodeTools, OtherIdentifierTree,
CodeToolsCfgScript, CTXMLFixFragment, CTUnitGraph, ChangeDeclarationTool, CodeToolsCfgScript, CTXMLFixFragment, CTUnitGraph, ChangeDeclarationTool,
CodeToolsFPCMsgs, UnitDictionary, ctloadlaz, CTUnitGroupGraph, CodeToolsFPCMsgs, UnitDictionary, ctloadlaz, CTUnitGroupGraph,
LazarusPackageIntf; CodeCompletionTemplater, LazarusPackageIntf;
implementation implementation

View File

@ -1,12 +1,10 @@
object CodeMacroPromptDlg: TCodeMacroPromptDlg object CodeMacroPromptDlg: TCodeMacroPromptDlg
Caption = 'CodeMacroPromptDlg'
ClientHeight = 300
ClientWidth = 400
PixelsPerInch = 112
HorzScrollBar.Page = 399
VertScrollBar.Page = 299
Left = 290 Left = 290
Height = 300 Height = 300
Top = 163 Top = 163
Width = 400 Width = 400
HorzScrollBar.Page = 399
VertScrollBar.Page = 299
Caption = 'CodeMacroPromptDlg'
LCLVersion = '1.1'
end end

View File

@ -32,7 +32,7 @@ interface
uses uses
Classes, SysUtils, LCLProc, Forms, Controls, Graphics, Dialogs, Classes, SysUtils, LCLProc, Forms, Controls, Graphics, Dialogs,
BasicCodeTools, BasicCodeTools, CodeToolManager,
SynEditAutoComplete, SynPluginTemplateEdit, SynPluginSyncronizedEditBase, SynEdit, SynEditAutoComplete, SynPluginTemplateEdit, SynPluginSyncronizedEditBase, SynEdit,
MacroIntf, LazIDEIntf, SrcEditorIntf; MacroIntf, LazIDEIntf, SrcEditorIntf;
@ -114,6 +114,10 @@ implementation
{$R *.lfm} {$R *.lfm}
const const
MaxLevel = 10; // prevent cycling MaxLevel = 10; // prevent cycling
@ -463,12 +467,12 @@ var
Pattern: String; Pattern: String;
LineText: String; LineText: String;
Parser: TLazTemplateParser; Parser: TLazTemplateParser;
CodeToolBossOriginalIndent : Integer; // So I don't break anything else (hopefully)
begin begin
Result:=false; Result:=false;
//debugln('ExecuteCodeTemplate ',dbgsName(SrcEdit),' ',dbgsName(SrcEdit.EditorControl)); //debugln('ExecuteCodeTemplate ',dbgsName(SrcEdit),' ',dbgsName(SrcEdit.EditorControl));
AEditor:=SrcEdit.EditorControl as TSynEdit; AEditor:=SrcEdit.EditorControl as TSynEdit;
Pattern:=TemplateValue; Pattern:=TemplateValue;
Parser := TLazTemplateParser.Create(Pattern); Parser := TLazTemplateParser.Create(Pattern);
AEditor.BeginUpdate; AEditor.BeginUpdate;
try try
@ -498,8 +502,17 @@ begin
Parser.EnableMacros := Attributes.IndexOfName(CodeTemplateEnableMacros)>=0; Parser.EnableMacros := Attributes.IndexOfName(CodeTemplateEnableMacros)>=0;
Parser.KeepSubIndent := Attributes.IndexOfName(CodeTemplateKeepSubIndent)>=0; Parser.KeepSubIndent := Attributes.IndexOfName(CodeTemplateKeepSubIndent)>=0;
Parser.Indent := BaseIndent; Parser.Indent := BaseIndent;
LazarusIDE.SaveSourceEditorChangesToCodeCache(nil); CodeToolBossOriginalIndent := CodeToolBoss.IndentSize;
if not Parser.SubstituteCodeMacros(SrcEdit) then exit; if Parser.KeepSubIndent then
CodeToolBoss.IndentSize := BaseIndent // Use additional indentation
else
CodeToolBoss.IndentSize := 0; // Use current indentation
try
LazarusIDE.SaveSourceEditorChangesToCodeCache(nil);
if not Parser.SubstituteCodeMacros(SrcEdit) then exit;
finally
CodeToolBoss.IndentSize := CodeToolBossOriginalIndent;
end;
s:=AEditor.Lines[p.y-1]; s:=AEditor.Lines[p.y-1];
if TokenStartX>length(s) then if TokenStartX>length(s) then

View File

@ -1,7 +1,7 @@
object CodeTemplateDialog: TCodeTemplateDialog object CodeTemplateDialog: TCodeTemplateDialog
Left = 332 Left = 332
Height = 542 Height = 542
Top = 224 Top = 174
Width = 497 Width = 497
ActiveControl = FilenameEdit ActiveControl = FilenameEdit
BorderIcons = [biSystemMenu] BorderIcons = [biSystemMenu]
@ -11,7 +11,7 @@ object CodeTemplateDialog: TCodeTemplateDialog
OnClose = FormClose OnClose = FormClose
OnCreate = FormCreate OnCreate = FormCreate
Position = poScreenCenter Position = poScreenCenter
LCLVersion = '0.9.31' LCLVersion = '1.1'
object FilenameGroupBox: TGroupBox object FilenameGroupBox: TGroupBox
Left = 6 Left = 6
Height = 51 Height = 51
@ -20,13 +20,13 @@ object CodeTemplateDialog: TCodeTemplateDialog
Align = alTop Align = alTop
BorderSpacing.Around = 6 BorderSpacing.Around = 6
Caption = 'FilenameGroupBox' Caption = 'FilenameGroupBox'
ClientHeight = 33 ClientHeight = 31
ClientWidth = 481 ClientWidth = 481
TabOrder = 0 TabOrder = 0
object FilenameEdit: TEdit object FilenameEdit: TEdit
AnchorSideRight.Control = FilenameButton AnchorSideRight.Control = FilenameButton
Left = 9 Left = 9
Height = 21 Height = 26
Top = 4 Top = 4
Width = 435 Width = 435
Anchors = [akTop, akLeft, akRight] Anchors = [akTop, akLeft, akRight]
@ -41,7 +41,7 @@ object CodeTemplateDialog: TCodeTemplateDialog
AnchorSideBottom.Side = asrBottom AnchorSideBottom.Side = asrBottom
Left = 449 Left = 449
Height = 23 Height = 23
Top = 2 Top = 7
Width = 26 Width = 26
Anchors = [akRight, akBottom] Anchors = [akRight, akBottom]
BorderSpacing.Right = 6 BorderSpacing.Right = 6
@ -58,7 +58,7 @@ object CodeTemplateDialog: TCodeTemplateDialog
Align = alTop Align = alTop
BorderSpacing.Around = 6 BorderSpacing.Around = 6
Caption = 'TemplatesGroupBox' Caption = 'TemplatesGroupBox'
ClientHeight = 149 ClientHeight = 147
ClientWidth = 481 ClientWidth = 481
TabOrder = 1 TabOrder = 1
object TemplateListBox: TListBox object TemplateListBox: TListBox
@ -68,7 +68,7 @@ object CodeTemplateDialog: TCodeTemplateDialog
AnchorSideBottom.Control = TemplatesGroupBox AnchorSideBottom.Control = TemplatesGroupBox
AnchorSideBottom.Side = asrBottom AnchorSideBottom.Side = asrBottom
Left = 6 Left = 6
Height = 137 Height = 135
Top = 6 Top = 6
Width = 315 Width = 315
Anchors = [akTop, akLeft, akRight, akBottom] Anchors = [akTop, akLeft, akRight, akBottom]
@ -78,7 +78,9 @@ object CodeTemplateDialog: TCodeTemplateDialog
BorderSpacing.Bottom = 6 BorderSpacing.Bottom = 6
ItemHeight = 0 ItemHeight = 0
OnSelectionChange = TemplateListBoxSelectionChange OnSelectionChange = TemplateListBoxSelectionChange
ScrollWidth = 311
TabOrder = 0 TabOrder = 0
TopIndex = -1
end end
object AddButton: TButton object AddButton: TButton
AnchorSideTop.Control = TemplateListBox AnchorSideTop.Control = TemplateListBox
@ -132,20 +134,20 @@ object CodeTemplateDialog: TCodeTemplateDialog
AnchorSideRight.Control = Owner AnchorSideRight.Control = Owner
AnchorSideBottom.Control = FilenameGroupBox AnchorSideBottom.Control = FilenameGroupBox
Left = 6 Left = 6
Height = 268 Height = 262
Top = 236 Top = 236
Width = 485 Width = 485
Align = alClient Align = alClient
BorderSpacing.Around = 6 BorderSpacing.Around = 6
Caption = 'EditTemplateGroupBox' Caption = 'EditTemplateGroupBox'
ClientHeight = 250 ClientHeight = 242
ClientWidth = 481 ClientWidth = 481
TabOrder = 2 TabOrder = 2
object UseMacrosCheckBox: TCheckBox object UseMacrosCheckBox: TCheckBox
Left = 6 Left = 6
Height = 17 Height = 22
Top = 6 Top = 6
Width = 117 Width = 171
BorderSpacing.Bottom = 7 BorderSpacing.Bottom = 7
Caption = 'UseMacrosCheckBox' Caption = 'UseMacrosCheckBox'
ParentShowHint = False ParentShowHint = False
@ -158,10 +160,10 @@ object CodeTemplateDialog: TCodeTemplateDialog
AnchorSideTop.Control = UseMacrosCheckBox AnchorSideTop.Control = UseMacrosCheckBox
AnchorSideTop.Side = asrCenter AnchorSideTop.Side = asrCenter
AnchorSideRight.Side = asrBottom AnchorSideRight.Side = asrBottom
Left = 149 Left = 203
Height = 23 Height = 28
Top = 3 Top = 3
Width = 116 Width = 144
AutoSize = True AutoSize = True
BorderSpacing.Left = 20 BorderSpacing.Left = 20
BorderSpacing.Around = 6 BorderSpacing.Around = 6
@ -177,8 +179,8 @@ object CodeTemplateDialog: TCodeTemplateDialog
AnchorSideBottom.Control = EditTemplateGroupBox AnchorSideBottom.Control = EditTemplateGroupBox
AnchorSideBottom.Side = asrBottom AnchorSideBottom.Side = asrBottom
Left = 6 Left = 6
Height = 146 Height = 137
Top = 98 Top = 99
Width = 469 Width = 469
BorderSpacing.Around = 6 BorderSpacing.Around = 6
Anchors = [akTop, akLeft, akRight, akBottom] Anchors = [akTop, akLeft, akRight, akBottom]
@ -604,6 +606,12 @@ object CodeTemplateDialog: TCodeTemplateDialog
'TemplateSynEdit' 'TemplateSynEdit'
) )
VisibleSpecialChars = [vscSpace, vscTabAtLast] VisibleSpecialChars = [vscSpace, vscTabAtLast]
SelectedColor.BackPriority = 50
SelectedColor.ForePriority = 50
SelectedColor.FramePriority = 50
SelectedColor.BoldPriority = 50
SelectedColor.ItalicPriority = 50
SelectedColor.UnderlinePriority = 50
BracketHighlightStyle = sbhsBoth BracketHighlightStyle = sbhsBoth
BracketMatchColor.Background = clNone BracketMatchColor.Background = clNone
BracketMatchColor.Foreground = clNone BracketMatchColor.Foreground = clNone
@ -639,6 +647,8 @@ object CodeTemplateDialog: TCodeTemplateDialog
object TSynGutterSeparator object TSynGutterSeparator
Width = 2 Width = 2
MouseActions = <> MouseActions = <>
MarkupInfo.Background = clWhite
MarkupInfo.Foreground = clGray
end end
object TSynGutterCodeFolding object TSynGutterCodeFolding
MouseActions = < MouseActions = <
@ -700,8 +710,8 @@ object CodeTemplateDialog: TCodeTemplateDialog
AnchorSideRight.Control = EditTemplateGroupBox AnchorSideRight.Control = EditTemplateGroupBox
AnchorSideRight.Side = asrBottom AnchorSideRight.Side = asrBottom
Left = 6 Left = 6
Height = 39 Height = 30
Top = 53 Top = 63
Width = 469 Width = 469
Anchors = [akTop, akLeft, akRight] Anchors = [akTop, akLeft, akRight]
AutoFill = True AutoFill = True
@ -725,9 +735,9 @@ object CodeTemplateDialog: TCodeTemplateDialog
AnchorSideTop.Control = UseMacrosCheckBox AnchorSideTop.Control = UseMacrosCheckBox
AnchorSideTop.Side = asrBottom AnchorSideTop.Side = asrBottom
Left = 6 Left = 6
Height = 17 Height = 22
Top = 30 Top = 35
Width = 139 Width = 202
BorderSpacing.Top = 6 BorderSpacing.Top = 6
Caption = 'KeepSubIndentCheckBox' Caption = 'KeepSubIndentCheckBox'
ParentShowHint = False ParentShowHint = False
@ -737,8 +747,8 @@ object CodeTemplateDialog: TCodeTemplateDialog
end end
object ButtonPanel: TButtonPanel object ButtonPanel: TButtonPanel
Left = 6 Left = 6
Height = 26 Height = 32
Top = 510 Top = 504
Width = 485 Width = 485
OKButton.Name = 'OKButton' OKButton.Name = 'OKButton'
OKButton.DefaultCaption = True OKButton.DefaultCaption = True

View File

@ -502,6 +502,7 @@ var
CaretXY: TPoint; CaretXY: TPoint;
p: integer; p: integer;
i: Integer; i: Integer;
Indent : String;
begin begin
List:=TStringList.Create; List:=TStringList.Create;
try try
@ -529,9 +530,10 @@ begin
exit; exit;
end; end;
Indent := StringOfChar(' ',CodeToolBoss.IndentSize);
Value:=''; Value:='';
for i:=0 to List.Count-1 do for i:=0 to List.Count-1 do
Value:=Value+List[i]+': ;'+LineEnding; Value:=Value+ Indent + List[i]+': ;'+LineEnding;
finally finally
List.Free; List.Free;
end; end;
@ -1230,7 +1232,7 @@ begin
TemplateSynEdit.Lines.BeginUpdate; TemplateSynEdit.Lines.BeginUpdate;
TemplateSynEdit.Lines.Clear; TemplateSynEdit.Lines.Clear;
//debugln('TCodeTemplateDialog.ShowCurCodeTemplate A a=',dbgs(a)); // debugln('TCodeTemplateDialog.ShowCurCodeTemplate A a=',dbgs(a));
if a >= 0 if a >= 0
then begin then begin
EditTemplateGroupBox.Caption:=dbgstr(SynAutoComplete.Completions[a]) EditTemplateGroupBox.Caption:=dbgstr(SynAutoComplete.Completions[a])

View File

@ -38,10 +38,12 @@ uses
Classes, SysUtils, LazConf, FileUtil, Laz2_XMLCfg, lazutf8classes, Classes, SysUtils, LazConf, FileUtil, Laz2_XMLCfg, lazutf8classes,
LResources, Forms, Controls, Buttons, LclProc, ExtCtrls, LResources, Forms, Controls, Buttons, LclProc, ExtCtrls,
Dialogs, CodeToolManager, DefineTemplates, SourceChanger, SynEdit, Dialogs, CodeToolManager, DefineTemplates, SourceChanger, SynEdit,
IDEOptionsIntf, IDEOptionDefs, LazarusIDEStrConsts, IDEProcs; IDEOptionsIntf, MacroIntf, IDEOptionDefs, LazarusIDEStrConsts, IDEProcs;
const const
DefaultIndentationFilename = 'laz_indentation.pas'; // in directory GetPrimaryConfigPath DefaultIndentationFilename = 'laz_indentation.pas'; // in directory GetPrimaryConfigPath
DefaultCodeCompletionFilename =
'$(LazarusDir)'+PathDelim+'components'+PathDelim+'codetools'+PathDelim+'codecompletiontemplates.xml';
type type
@ -106,7 +108,12 @@ type
fIndentationFilename: String; fIndentationFilename: String;
FIndentContextSensitive: boolean; FIndentContextSensitive: boolean;
// code completion templates
FCodeCompletionTemplateFileName : String;
procedure SetCodeCompletionTemplateFileName(aValue: String);
procedure SetFilename(const AValue: string); procedure SetFilename(const AValue: string);
procedure SetSetPropertyVariablename(aValue: string);
public public
class function GetGroupCaption:string; override; class function GetGroupCaption:string; override;
class function GetInstance: TAbstractIDEOptions; override; class function GetInstance: TAbstractIDEOptions; override;
@ -194,7 +201,7 @@ type
property PrivateVariablePrefix: string property PrivateVariablePrefix: string
read FPrivateVariablePrefix write FPrivateVariablePrefix; read FPrivateVariablePrefix write FPrivateVariablePrefix;
property SetPropertyVariablename: string property SetPropertyVariablename: string
read FSetPropertyVariablename write FSetPropertyVariablename; read FSetPropertyVariablename write SetSetPropertyVariablename;
property UsesInsertPolicy: TUsesInsertPolicy property UsesInsertPolicy: TUsesInsertPolicy
read FUsesInsertPolicy write FUsesInsertPolicy; read FUsesInsertPolicy write FUsesInsertPolicy;
@ -221,6 +228,10 @@ type
read fIndentationFileName write fIndentationFileName; read fIndentationFileName write fIndentationFileName;
property IndentContextSensitive: boolean read FIndentContextSensitive property IndentContextSensitive: boolean read FIndentContextSensitive
write FIndentContextSensitive; write FIndentContextSensitive;
// code completion templates
property CodeCompletionTemplateFileName : String read FCodeCompletionTemplateFileName
write SetCodeCompletionTemplateFileName;
end; end;
var var
@ -482,6 +493,11 @@ begin
FIndentContextSensitive := FIndentContextSensitive :=
XMLConfig.GetValue('CodeToolsOptions/Indentation/ContextSensitive',true); XMLConfig.GetValue('CodeToolsOptions/Indentation/ContextSensitive',true);
// code completion templates
FCodeCompletionTemplateFileName :=
XMLConfig.GetValue('CodeToolsOptions/CodeCompletionTemplate/FileName'
, DefaultCodeCompletionFilename);
XMLConfig.Free; XMLConfig.Free;
except except
on E: Exception do begin on E: Exception do begin
@ -619,6 +635,10 @@ begin
XMLConfig.SetDeleteValue('CodeToolsOptions/Indentation/ContextSensitive' XMLConfig.SetDeleteValue('CodeToolsOptions/Indentation/ContextSensitive'
, FIndentContextSensitive, true); , FIndentContextSensitive, true);
// code completion templates
XMLConfig.SetDeleteValue('CodeToolsOptions/CodeCompletionTemplate/FileName'
, FCodeCompletionTemplateFileName, DefaultCodeCompletionFilename);
XMLConfig.Flush; XMLConfig.Flush;
XMLConfig.Free; XMLConfig.Free;
except except
@ -628,6 +648,13 @@ begin
end; end;
end; end;
procedure TCodeToolsOptions.SetCodeCompletionTemplateFileName(aValue: String);
begin
aValue:=TrimFilename(aValue);
if FCodeCompletionTemplateFileName=aValue then Exit;
FCodeCompletionTemplateFileName:=aValue;
end;
procedure TCodeToolsOptions.SetFilename(const AValue: string); procedure TCodeToolsOptions.SetFilename(const AValue: string);
begin begin
FFilename:=AValue; FFilename:=AValue;
@ -641,11 +668,18 @@ begin
GetPrimaryConfigPath+'/'+DefaultCodeToolsOptsFile); GetPrimaryConfigPath+'/'+DefaultCodeToolsOptsFile);
CopySecondaryConfigFile(DefaultCodeToolsOptsFile); CopySecondaryConfigFile(DefaultCodeToolsOptsFile);
if (not FileExistsCached(ConfFileName)) then begin if (not FileExistsCached(ConfFileName)) then begin
debugln('Looking for code tools config file: "' + ConfFileName + '"');
debugln(UTF8ToConsole(lisCompilerNOTECodetoolsConfigFileNotFoundUsingDefaults)); debugln(UTF8ToConsole(lisCompilerNOTECodetoolsConfigFileNotFoundUsingDefaults));
end; end;
FFilename:=ConfFilename; FFilename:=ConfFilename;
end; end;
procedure TCodeToolsOptions.SetSetPropertyVariablename(aValue: string);
begin
if FSetPropertyVariablename=aValue then Exit;
FSetPropertyVariablename:=aValue;
end;
procedure TCodeToolsOptions.Assign(Source: TPersistent); procedure TCodeToolsOptions.Assign(Source: TPersistent);
var var
CodeToolsOpts: TCodeToolsOptions absolute Source; CodeToolsOpts: TCodeToolsOptions absolute Source;
@ -770,6 +804,9 @@ begin
fIndentationFilename:= fIndentationFilename:=
TrimFilename(GetPrimaryConfigPath+PathDelim+DefaultIndentationFilename); TrimFilename(GetPrimaryConfigPath+PathDelim+DefaultIndentationFilename);
FIndentContextSensitive:=true; FIndentContextSensitive:=true;
// code completion templates
fCodeCompletionTemplateFileName := DefaultCodeCompletionFilename;
end; end;
procedure TCodeToolsOptions.ClearGlobalDefineTemplates; procedure TCodeToolsOptions.ClearGlobalDefineTemplates;
@ -882,6 +919,7 @@ procedure TCodeToolsOptions.AssignTo(Dest: TPersistent);
var var
Boss: TCodeToolManager absolute Dest; Boss: TCodeToolManager absolute Dest;
Beauty: TBeautifyCodeOptions absolute Dest; Beauty: TBeautifyCodeOptions absolute Dest;
aFilename: String;
begin begin
if Dest is TCodeToolManager then if Dest is TCodeToolManager then
begin begin
@ -895,6 +933,13 @@ begin
// CreateCode - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // CreateCode - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
AssignTo(Boss.SourceChangeCache.BeautifyCodeOptions); AssignTo(Boss.SourceChangeCache.BeautifyCodeOptions);
Boss.SetPropertyVariablename:=SetPropertyVariablename; Boss.SetPropertyVariablename:=SetPropertyVariablename;
//
aFilename:=CodeCompletionTemplateFileName;
IDEMacros.SubstituteMacros(aFilename);
aFilename:=TrimFilename(aFilename);
if (aFilename<>'') and not FilenameIsAbsolute(aFilename) then
aFilename:=TrimFilename(AppendPathDelim(GetPrimaryConfigPath)+aFilename);
Boss.CodeCompletionTemplateFileName:=aFilename;
end end
else else
if Dest is TBeautifyCodeOptions then if Dest is TBeautifyCodeOptions then

View File

@ -1,10 +1,10 @@
object CodetoolsClassCompletionOptionsFrame: TCodetoolsClassCompletionOptionsFrame object CodetoolsClassCompletionOptionsFrame: TCodetoolsClassCompletionOptionsFrame
Left = 0 Left = 0
Height = 455 Height = 431
Top = 0 Top = 0
Width = 572 Width = 575
ClientHeight = 455 ClientHeight = 431
ClientWidth = 572 ClientWidth = 575
TabOrder = 0 TabOrder = 0
Visible = False Visible = False
DesignLeft = 336 DesignLeft = 336
@ -41,7 +41,7 @@ object CodetoolsClassCompletionOptionsFrame: TCodetoolsClassCompletionOptionsFra
Left = 256 Left = 256
Height = 100 Height = 100
Top = 0 Top = 0
Width = 316 Width = 319
Anchors = [akTop, akLeft, akRight] Anchors = [akTop, akLeft, akRight]
AutoFill = True AutoFill = True
AutoSize = True AutoSize = True
@ -63,9 +63,9 @@ object CodetoolsClassCompletionOptionsFrame: TCodetoolsClassCompletionOptionsFra
AnchorSideTop.Control = ClassPartInsertPolicyRadioGroup AnchorSideTop.Control = ClassPartInsertPolicyRadioGroup
AnchorSideTop.Side = asrBottom AnchorSideTop.Side = asrBottom
Left = 6 Left = 6
Height = 18 Height = 24
Top = 106 Top = 106
Width = 249 Width = 227
BorderSpacing.Around = 6 BorderSpacing.Around = 6
Caption = 'MixMethodsAndPropertiesCheckBox' Caption = 'MixMethodsAndPropertiesCheckBox'
TabOrder = 2 TabOrder = 2
@ -75,9 +75,9 @@ object CodetoolsClassCompletionOptionsFrame: TCodetoolsClassCompletionOptionsFra
AnchorSideTop.Control = UpdateAllMethodSignaturesCheckBox AnchorSideTop.Control = UpdateAllMethodSignaturesCheckBox
AnchorSideTop.Side = asrBottom AnchorSideTop.Side = asrBottom
Left = 6 Left = 6
Height = 18 Height = 24
Top = 154 Top = 166
Width = 228 Width = 204
BorderSpacing.Around = 6 BorderSpacing.Around = 6
Caption = 'ClassHeaderCommentsCheckBox' Caption = 'ClassHeaderCommentsCheckBox'
TabOrder = 3 TabOrder = 3
@ -90,23 +90,23 @@ object CodetoolsClassCompletionOptionsFrame: TCodetoolsClassCompletionOptionsFra
AnchorSideRight.Side = asrBottom AnchorSideRight.Side = asrBottom
AnchorSideBottom.Side = asrBottom AnchorSideBottom.Side = asrBottom
Left = 0 Left = 0
Height = 168 Height = 184
Top = 202 Top = 226
Width = 572 Width = 575
Anchors = [akTop, akLeft, akRight] Anchors = [akTop, akLeft, akRight]
AutoSize = True AutoSize = True
BorderSpacing.Top = 6 BorderSpacing.Top = 6
Caption = 'PropertyCompletionGroupBox' Caption = 'PropertyCompletionGroupBox'
ClientHeight = 146 ClientHeight = 167
ClientWidth = 564 ClientWidth = 571
TabOrder = 4 TabOrder = 4
object PropertyCompletionCheckBox: TCheckBox object PropertyCompletionCheckBox: TCheckBox
AnchorSideLeft.Control = PropertyCompletionGroupBox AnchorSideLeft.Control = PropertyCompletionGroupBox
AnchorSideTop.Control = PropertyCompletionGroupBox AnchorSideTop.Control = PropertyCompletionGroupBox
Left = 6 Left = 6
Height = 18 Height = 24
Top = 6 Top = 6
Width = 208 Width = 192
BorderSpacing.Around = 6 BorderSpacing.Around = 6
Caption = 'PropertyCompletionCheckBox' Caption = 'PropertyCompletionCheckBox'
TabOrder = 0 TabOrder = 0
@ -118,24 +118,24 @@ object CodetoolsClassCompletionOptionsFrame: TCodetoolsClassCompletionOptionsFra
AnchorSideRight.Control = PropertyCompletionGroupBox AnchorSideRight.Control = PropertyCompletionGroupBox
AnchorSideRight.Side = asrBottom AnchorSideRight.Side = asrBottom
Left = 6 Left = 6
Height = 110 Height = 125
Top = 30 Top = 36
Width = 552 Width = 559
Anchors = [akTop, akLeft, akRight] Anchors = [akTop, akLeft, akRight]
AutoSize = True AutoSize = True
BorderSpacing.Around = 6 BorderSpacing.Around = 6
BevelOuter = bvNone BevelOuter = bvNone
ChildSizing.Layout = cclTopToBottomThenLeftToRight ChildSizing.Layout = cclTopToBottomThenLeftToRight
ChildSizing.ControlsPerLine = 5 ChildSizing.ControlsPerLine = 5
ClientHeight = 110 ClientHeight = 125
ClientWidth = 552 ClientWidth = 559
TabOrder = 1 TabOrder = 1
object SetPropertyVariablenameLabel: TLabel object SetPropertyVariablenameLabel: TLabel
AnchorSideTop.Side = asrCenter AnchorSideTop.Side = asrCenter
Left = 11 Left = 11
Height = 16 Height = 15
Top = 3 Top = 5
Width = 191 Width = 171
BorderSpacing.Right = 6 BorderSpacing.Right = 6
BorderSpacing.CellAlignHorizontal = ccaRightBottom BorderSpacing.CellAlignHorizontal = ccaRightBottom
BorderSpacing.CellAlignVertical = ccaCenter BorderSpacing.CellAlignVertical = ccaCenter
@ -144,10 +144,10 @@ object CodetoolsClassCompletionOptionsFrame: TCodetoolsClassCompletionOptionsFra
end end
object PrivateVariablePrefixLabel: TLabel object PrivateVariablePrefixLabel: TLabel
AnchorSideTop.Side = asrCenter AnchorSideTop.Side = asrCenter
Left = 39 Left = 36
Height = 16 Height = 15
Top = 25 Top = 30
Width = 163 Width = 146
BorderSpacing.Right = 6 BorderSpacing.Right = 6
BorderSpacing.CellAlignHorizontal = ccaRightBottom BorderSpacing.CellAlignHorizontal = ccaRightBottom
BorderSpacing.CellAlignVertical = ccaCenter BorderSpacing.CellAlignVertical = ccaCenter
@ -157,9 +157,9 @@ object CodetoolsClassCompletionOptionsFrame: TCodetoolsClassCompletionOptionsFra
object PropertyStoredIdentPostfixLabel: TLabel object PropertyStoredIdentPostfixLabel: TLabel
AnchorSideTop.Side = asrCenter AnchorSideTop.Side = asrCenter
Left = 0 Left = 0
Height = 16 Height = 15
Top = 47 Top = 55
Width = 202 Width = 182
BorderSpacing.Right = 6 BorderSpacing.Right = 6
BorderSpacing.CellAlignHorizontal = ccaRightBottom BorderSpacing.CellAlignHorizontal = ccaRightBottom
BorderSpacing.CellAlignVertical = ccaCenter BorderSpacing.CellAlignVertical = ccaCenter
@ -168,10 +168,10 @@ object CodetoolsClassCompletionOptionsFrame: TCodetoolsClassCompletionOptionsFra
end end
object PropertyWriteIdentPrefixLabel: TLabel object PropertyWriteIdentPrefixLabel: TLabel
AnchorSideTop.Side = asrCenter AnchorSideTop.Side = asrCenter
Left = 15 Left = 11
Height = 16 Height = 15
Top = 69 Top = 80
Width = 187 Width = 171
BorderSpacing.Right = 6 BorderSpacing.Right = 6
BorderSpacing.CellAlignHorizontal = ccaRightBottom BorderSpacing.CellAlignHorizontal = ccaRightBottom
BorderSpacing.CellAlignVertical = ccaCenter BorderSpacing.CellAlignVertical = ccaCenter
@ -180,10 +180,10 @@ object CodetoolsClassCompletionOptionsFrame: TCodetoolsClassCompletionOptionsFra
end end
object PropertyReadIdentPrefixLabel: TLabel object PropertyReadIdentPrefixLabel: TLabel
AnchorSideTop.Side = asrCenter AnchorSideTop.Side = asrCenter
Left = 17 Left = 14
Height = 16 Height = 15
Top = 91 Top = 105
Width = 185 Width = 168
BorderSpacing.Right = 6 BorderSpacing.Right = 6
BorderSpacing.CellAlignHorizontal = ccaRightBottom BorderSpacing.CellAlignHorizontal = ccaRightBottom
BorderSpacing.CellAlignVertical = ccaCenter BorderSpacing.CellAlignVertical = ccaCenter
@ -193,8 +193,8 @@ object CodetoolsClassCompletionOptionsFrame: TCodetoolsClassCompletionOptionsFra
object SetPropertyVariablenameEdit: TEdit object SetPropertyVariablenameEdit: TEdit
AnchorSideTop.Side = asrBottom AnchorSideTop.Side = asrBottom
AnchorSideRight.Side = asrBottom AnchorSideRight.Side = asrBottom
Left = 208 Left = 188
Height = 22 Height = 25
Top = 0 Top = 0
Width = 80 Width = 80
TabOrder = 0 TabOrder = 0
@ -203,9 +203,9 @@ object CodetoolsClassCompletionOptionsFrame: TCodetoolsClassCompletionOptionsFra
object PrivateVariablePrefixEdit: TEdit object PrivateVariablePrefixEdit: TEdit
AnchorSideTop.Side = asrBottom AnchorSideTop.Side = asrBottom
AnchorSideRight.Side = asrBottom AnchorSideRight.Side = asrBottom
Left = 208 Left = 188
Height = 22 Height = 25
Top = 22 Top = 25
Width = 80 Width = 80
TabOrder = 1 TabOrder = 1
Text = 'PrivateVariablePrefixEdit' Text = 'PrivateVariablePrefixEdit'
@ -213,9 +213,9 @@ object CodetoolsClassCompletionOptionsFrame: TCodetoolsClassCompletionOptionsFra
object PropertyStoredIdentPostfixEdit: TEdit object PropertyStoredIdentPostfixEdit: TEdit
AnchorSideTop.Side = asrBottom AnchorSideTop.Side = asrBottom
AnchorSideRight.Side = asrBottom AnchorSideRight.Side = asrBottom
Left = 208 Left = 188
Height = 22 Height = 25
Top = 44 Top = 50
Width = 80 Width = 80
TabOrder = 2 TabOrder = 2
Text = 'PropertyStoredIdentPostfixEdit' Text = 'PropertyStoredIdentPostfixEdit'
@ -223,9 +223,9 @@ object CodetoolsClassCompletionOptionsFrame: TCodetoolsClassCompletionOptionsFra
object PropertyWriteIdentPrefixEdit: TEdit object PropertyWriteIdentPrefixEdit: TEdit
AnchorSideTop.Side = asrBottom AnchorSideTop.Side = asrBottom
AnchorSideRight.Side = asrBottom AnchorSideRight.Side = asrBottom
Left = 208 Left = 188
Height = 22 Height = 25
Top = 66 Top = 75
Width = 80 Width = 80
TabOrder = 3 TabOrder = 3
Text = 'PropertyWriteIdentPrefixEdit' Text = 'PropertyWriteIdentPrefixEdit'
@ -233,9 +233,9 @@ object CodetoolsClassCompletionOptionsFrame: TCodetoolsClassCompletionOptionsFra
object PropertyReadIdentPrefixEdit: TEdit object PropertyReadIdentPrefixEdit: TEdit
AnchorSideTop.Side = asrBottom AnchorSideTop.Side = asrBottom
AnchorSideRight.Side = asrBottom AnchorSideRight.Side = asrBottom
Left = 208 Left = 188
Height = 22 Height = 25
Top = 88 Top = 100
Width = 80 Width = 80
TabOrder = 4 TabOrder = 4
Text = 'PropertyReadIdentPrefixEdit' Text = 'PropertyReadIdentPrefixEdit'
@ -247,9 +247,9 @@ object CodetoolsClassCompletionOptionsFrame: TCodetoolsClassCompletionOptionsFra
AnchorSideTop.Control = ClassHeaderCommentsCheckBox AnchorSideTop.Control = ClassHeaderCommentsCheckBox
AnchorSideTop.Side = asrBottom AnchorSideTop.Side = asrBottom
Left = 6 Left = 6
Height = 18 Height = 24
Top = 178 Top = 196
Width = 283 Width = 251
BorderSpacing.Around = 6 BorderSpacing.Around = 6
Caption = 'ClassImplementationCommentsCheckBox' Caption = 'ClassImplementationCommentsCheckBox'
TabOrder = 5 TabOrder = 5
@ -259,9 +259,9 @@ object CodetoolsClassCompletionOptionsFrame: TCodetoolsClassCompletionOptionsFra
AnchorSideTop.Control = MixMethodsAndPropertiesCheckBox AnchorSideTop.Control = MixMethodsAndPropertiesCheckBox
AnchorSideTop.Side = asrBottom AnchorSideTop.Side = asrBottom
Left = 6 Left = 6
Height = 18 Height = 24
Top = 130 Top = 136
Width = 257 Width = 235
BorderSpacing.Around = 6 BorderSpacing.Around = 6
Caption = 'UpdateAllMethodSignaturesCheckBox' Caption = 'UpdateAllMethodSignaturesCheckBox'
TabOrder = 6 TabOrder = 6

View File

@ -25,7 +25,7 @@ unit codetools_classcompletion_options;
interface interface
uses uses
Classes, SysUtils, FileUtil, Forms, ExtCtrls, StdCtrls, Classes, SysUtils, FileUtil, Forms, ExtCtrls, StdCtrls, Buttons, Dialogs,
SourceChanger, CodeToolsOptions, LazarusIDEStrConsts, IDEOptionsIntf; SourceChanger, CodeToolsOptions, LazarusIDEStrConsts, IDEOptionsIntf;
type type
@ -53,7 +53,6 @@ type
SetPropertyVariablenameLabel: TLabel; SetPropertyVariablenameLabel: TLabel;
UpdateAllMethodSignaturesCheckBox: TCheckBox; UpdateAllMethodSignaturesCheckBox: TCheckBox;
private private
{ private declarations }
public public
function GetTitle: String; override; function GetTitle: String; override;
procedure Setup(ADialog: TAbstractOptionsEditorDialog); override; procedure Setup(ADialog: TAbstractOptionsEditorDialog); override;

View File

@ -39,7 +39,7 @@ object CodetoolsCodeCreationOptionsFrame: TCodetoolsCodeCreationOptionsFrame
Left = 6 Left = 6
Height = 24 Height = 24
Top = 112 Top = 112
Width = 261 Width = 217
BorderSpacing.Around = 6 BorderSpacing.Around = 6
Caption = 'ForwardProcsKeepOrderCheckBox' Caption = 'ForwardProcsKeepOrderCheckBox'
TabOrder = 1 TabOrder = 1
@ -78,7 +78,7 @@ object CodetoolsCodeCreationOptionsFrame: TCodetoolsCodeCreationOptionsFrame
Left = 6 Left = 6
Height = 24 Height = 24
Top = 254 Top = 254
Width = 279 Width = 231
BorderSpacing.Left = 6 BorderSpacing.Left = 6
BorderSpacing.Top = 6 BorderSpacing.Top = 6
Caption = 'UpdateMultiProcSignaturesCheckBox' Caption = 'UpdateMultiProcSignaturesCheckBox'
@ -91,9 +91,51 @@ object CodetoolsCodeCreationOptionsFrame: TCodetoolsCodeCreationOptionsFrame
Left = 6 Left = 6
Height = 24 Height = 24
Top = 278 Top = 278
Width = 315 Width = 261
BorderSpacing.Left = 6 BorderSpacing.Left = 6
Caption = 'UpdateOtherProcSignaturesCaseCheckBox' Caption = 'UpdateOtherProcSignaturesCaseCheckBox'
TabOrder = 4 TabOrder = 4
end end
object TemplateFileLabel: TLabel
AnchorSideLeft.Control = UpdateOtherProcSignaturesCaseCheckBox
AnchorSideTop.Control = TemplateFileEdit
AnchorSideTop.Side = asrCenter
Left = 6
Height = 15
Top = 307
Width = 100
Caption = 'TemplateFileLabel'
ParentColor = False
end
object TemplateFileEdit: TEdit
AnchorSideLeft.Control = TemplateFileLabel
AnchorSideLeft.Side = asrBottom
AnchorSideTop.Control = UpdateOtherProcSignaturesCaseCheckBox
AnchorSideTop.Side = asrBottom
AnchorSideRight.Control = TemplateFileBrowseButton
Left = 106
Height = 25
Top = 302
Width = 439
Anchors = [akTop, akLeft, akRight]
TabOrder = 5
Text = 'TemplateFileEdit'
end
object TemplateFileBrowseButton: TButton
AnchorSideTop.Control = TemplateFileEdit
AnchorSideRight.Control = Owner
AnchorSideRight.Side = asrBottom
AnchorSideBottom.Control = TemplateFileEdit
AnchorSideBottom.Side = asrBottom
Left = 545
Height = 25
Top = 302
Width = 21
Anchors = [akTop, akRight, akBottom]
AutoSize = True
BorderSpacing.Right = 6
Caption = '...'
OnClick = TemplateFileBrowseButtonClick
TabOrder = 6
end
end end

View File

@ -25,8 +25,9 @@ unit codetools_codecreation_options;
interface interface
uses uses
Classes, SysUtils, FileUtil, Forms, ExtCtrls, StdCtrls, Classes, SysUtils, FileUtil, Forms, ExtCtrls, StdCtrls, Dialogs,
SourceChanger, CodeToolsOptions, LazarusIDEStrConsts, IDEOptionsIntf; SourceChanger, CodeToolsOptions, LazarusIDEStrConsts, IDEOptionsIntf,
IDEDialogs;
type type
@ -35,9 +36,13 @@ type
TCodetoolsCodeCreationOptionsFrame = class(TAbstractIDEOptionsEditor) TCodetoolsCodeCreationOptionsFrame = class(TAbstractIDEOptionsEditor)
ForwardProcsInsertPolicyRadioGroup: TRadioGroup; ForwardProcsInsertPolicyRadioGroup: TRadioGroup;
ForwardProcsKeepOrderCheckBox: TCheckBox; ForwardProcsKeepOrderCheckBox: TCheckBox;
TemplateFileBrowseButton: TButton;
TemplateFileEdit: TEdit;
TemplateFileLabel: TLabel;
UpdateMultiProcSignaturesCheckBox: TCheckBox; UpdateMultiProcSignaturesCheckBox: TCheckBox;
UpdateOtherProcSignaturesCaseCheckBox: TCheckBox; UpdateOtherProcSignaturesCaseCheckBox: TCheckBox;
UsesInsertPolicyRadioGroup: TRadioGroup; UsesInsertPolicyRadioGroup: TRadioGroup;
procedure TemplateFileBrowseButtonClick(Sender: TObject);
private private
public public
function GetTitle: String; override; function GetTitle: String; override;
@ -53,6 +58,26 @@ implementation
{ TCodetoolsCodeCreationOptionsFrame } { TCodetoolsCodeCreationOptionsFrame }
procedure TCodetoolsCodeCreationOptionsFrame.TemplateFileBrowseButtonClick(
Sender: TObject);
var
OpenDialog: TOpenDialog;
begin
OpenDialog:=TOpenDialog.Create(nil);
try
InitIDEFileDialog(OpenDialog);
OpenDialog.Title:=lisChooseAFileWithCodeToolsTemplates;
OpenDialog.Options:=OpenDialog.Options+[ofFileMustExist];
OpenDialog.Filter:=lisCodetoolsTemplateFile+' (*.xml)|*.xml|'+dlgAllFiles+
'|'+GetAllFilesMask;
if OpenDialog.Execute then
TemplateFileEdit.Text:=OpenDialog.FileName;
finally
StoreIDEFileDialog(OpenDialog);
OpenDialog.Free;
end;
end;
function TCodetoolsCodeCreationOptionsFrame.GetTitle: String; function TCodetoolsCodeCreationOptionsFrame.GetTitle: String;
begin begin
Result := dlgCodeCreation; Result := dlgCodeCreation;
@ -73,10 +98,6 @@ begin
end; end;
ForwardProcsKeepOrderCheckBox.Caption:=dlgForwardProcsKeepOrder; ForwardProcsKeepOrderCheckBox.Caption:=dlgForwardProcsKeepOrder;
UpdateMultiProcSignaturesCheckBox.Caption:=
lisCTOUpdateMultipleProcedureSignatures;
UpdateOtherProcSignaturesCaseCheckBox.Caption:=
lisUpdateOtherProcedureSignaturesWhenOnlyLetterCaseHa;
with UsesInsertPolicyRadioGroup do begin with UsesInsertPolicyRadioGroup do begin
Caption:=lisNewUnitsAreAddedToUsesSections; Caption:=lisNewUnitsAreAddedToUsesSections;
@ -90,6 +111,13 @@ begin
EndUpdate; EndUpdate;
end; end;
end; end;
UpdateMultiProcSignaturesCheckBox.Caption:=
lisCTOUpdateMultipleProcedureSignatures;
UpdateOtherProcSignaturesCaseCheckBox.Caption:=
lisUpdateOtherProcedureSignaturesWhenOnlyLetterCaseHa;
TemplateFileLabel.Caption:=lisTemplateFile;
end; end;
procedure TCodetoolsCodeCreationOptionsFrame.ReadSettings( procedure TCodetoolsCodeCreationOptionsFrame.ReadSettings(
@ -106,8 +134,6 @@ begin
end; end;
ForwardProcsKeepOrderCheckBox.Checked := KeepForwardProcOrder; ForwardProcsKeepOrderCheckBox.Checked := KeepForwardProcOrder;
UpdateMultiProcSignaturesCheckBox.Checked:=UpdateMultiProcSignatures;
UpdateOtherProcSignaturesCaseCheckBox.Checked:=UpdateOtherProcSignaturesCase;
case UsesInsertPolicy of case UsesInsertPolicy of
uipFirst: UsesInsertPolicyRadioGroup.ItemIndex:=0; uipFirst: UsesInsertPolicyRadioGroup.ItemIndex:=0;
@ -118,6 +144,11 @@ begin
//uipAlphabetically: //uipAlphabetically:
UsesInsertPolicyRadioGroup.ItemIndex:=4; UsesInsertPolicyRadioGroup.ItemIndex:=4;
end; end;
UpdateMultiProcSignaturesCheckBox.Checked:=UpdateMultiProcSignatures;
UpdateOtherProcSignaturesCaseCheckBox.Checked:=UpdateOtherProcSignaturesCase;
TemplateFileEdit.Text:=CodeCompletionTemplateFileName;
end; end;
end; end;
@ -133,8 +164,6 @@ begin
end; end;
KeepForwardProcOrder := ForwardProcsKeepOrderCheckBox.Checked; KeepForwardProcOrder := ForwardProcsKeepOrderCheckBox.Checked;
UpdateMultiProcSignatures:=UpdateMultiProcSignaturesCheckBox.Checked;
UpdateOtherProcSignaturesCase:=UpdateOtherProcSignaturesCaseCheckBox.Checked;
case UsesInsertPolicyRadioGroup.ItemIndex of case UsesInsertPolicyRadioGroup.ItemIndex of
0: UsesInsertPolicy:=uipFirst; 0: UsesInsertPolicy:=uipFirst;
@ -143,6 +172,11 @@ begin
3: UsesInsertPolicy:=uipLast; 3: UsesInsertPolicy:=uipLast;
else UsesInsertPolicy:=uipAlphabetically; else UsesInsertPolicy:=uipAlphabetically;
end; end;
UpdateMultiProcSignatures:=UpdateMultiProcSignaturesCheckBox.Checked;
UpdateOtherProcSignaturesCase:=UpdateOtherProcSignaturesCaseCheckBox.Checked;
CodeCompletionTemplateFileName:=TemplateFileEdit.Text;
end; end;
end; end;

View File

@ -1346,6 +1346,7 @@ resourcestring
dlgDelTemplate = 'Delete template '; dlgDelTemplate = 'Delete template ';
dlgChsCodeTempl = 'Choose code template file (*.dci)'; dlgChsCodeTempl = 'Choose code template file (*.dci)';
dlgAllFiles = 'All files'; dlgAllFiles = 'All files';
lisCodetoolsTemplateFile = 'Codetools template file';
lisExecutable = 'Executable'; lisExecutable = 'Executable';
lisEditorFileTypes = 'Editor file types'; lisEditorFileTypes = 'Editor file types';
lisPkgMgrNew = 'new'; lisPkgMgrNew = 'new';
@ -1994,6 +1995,8 @@ resourcestring
dlgCOCfgCmpMessages = 'Messages'; dlgCOCfgCmpMessages = 'Messages';
lisChooseAnFPCMessageFile = 'Choose an FPC message file'; lisChooseAnFPCMessageFile = 'Choose an FPC message file';
lisFPCMessageFile = 'FPC message file'; lisFPCMessageFile = 'FPC message file';
lisChooseAFileWithCodeToolsTemplates = 'Choose a file with CodeTools '
+'templates';
dlgCOOther = 'Other'; dlgCOOther = 'Other';
dlgCOInherited = 'Inherited'; dlgCOInherited = 'Inherited';
dlgCOCompilerCommands = 'Compiler Commands'; dlgCOCompilerCommands = 'Compiler Commands';
@ -5796,6 +5799,7 @@ resourcestring
+'signatures'; +'signatures';
lisUpdateOtherProcedureSignaturesWhenOnlyLetterCaseHa = 'Update other ' lisUpdateOtherProcedureSignaturesWhenOnlyLetterCaseHa = 'Update other '
+'procedure signatures when only letter case has changed'; +'procedure signatures when only letter case has changed';
lisTemplateFile = 'Template file';
implementation implementation

View File

@ -1,4 +1,4 @@
inherited SourceNotebook: TSourceNotebook object SourceNotebook: TSourceNotebook
Left = 533 Left = 533
Height = 300 Height = 300
Top = 374 Top = 374
@ -8,10 +8,11 @@ inherited SourceNotebook: TSourceNotebook
ClientHeight = 300 ClientHeight = 300
ClientWidth = 400 ClientWidth = 400
OnMouseUp = FormMouseUp OnMouseUp = FormMouseUp
object StatusBar: TStatusBar[0] LCLVersion = '1.1'
object StatusBar: TStatusBar
Left = 0 Left = 0
Height = 23 Height = 21
Top = 277 Top = 279
Width = 400 Width = 400
Panels = < Panels = <
item item