1 { /***************************************************************************
2                  codetoolsoptions.pas  -  Lazarus IDE unit
3                  -----------------------------------------
4 
5  ***************************************************************************/
6 
7  ***************************************************************************
8  *                                                                         *
9  *   This source is free software; you can redistribute it and/or modify   *
10  *   it under the terms of the GNU General Public License as published by  *
11  *   the Free Software Foundation; either version 2 of the License, or     *
12  *   (at your option) any later version.                                   *
13  *                                                                         *
14  *   This code is distributed in the hope that it will be useful, but      *
15  *   WITHOUT ANY WARRANTY; without even the implied warranty of            *
16  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     *
17  *   General Public License for more details.                              *
18  *                                                                         *
19  *   A copy of the GNU General Public License is available on the World    *
20  *   Wide Web at <http://www.gnu.org/copyleft/gpl.html>. You can also      *
21  *   obtain it by writing to the Free Software Foundation,                 *
22  *   Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1335, USA.   *
23  *                                                                         *
24  ***************************************************************************
25 
26   Author: Mattias Gaertner
27 
28   Abstract:
29     - TCodeToolsOptions
30 }
31 unit CodeToolsOptions;
32 
33 {$mode objfpc}{$H+}
34 
35 interface
36 
37 uses
38   Classes, SysUtils,
39   // LazUtils
40   LazFileUtils, Laz2_XMLCfg, LazUTF8, LazUTF8Classes, LazFileCache, LazStringUtils,
41   // LCL
42   LCLProc, LCLType,
43   // CodeTools
44   CodeToolManager, DefineTemplates, SourceChanger,
45   // IdeIntf
46   IDEOptionsIntf, IDEOptEditorIntf, MacroIntf,
47   // IDE
48   LazConf, LazarusIDEStrConsts;
49 
50 const
51   DefaultIndentationFilename = 'laz_indentation.pas'; // in directory GetPrimaryConfigPath
52   DefaultCodeCompletionFilename =
53     '$(LazarusDir)'+PathDelim+'components'+PathDelim+'codetools'+PathDelim+'codecompletiontemplates.xml';
54 
55 type
56 
57   TIdentComplIncludeWords = (icwDontInclude, icwIncludeFromCurrentUnit,
58     icwIncludeFromAllUnits);
59 
60   { TCodeToolsOptions }
61 
62   TCodeToolsOptions = class(TAbstractIDEEnvironmentOptions)
63   private
64     FClassHeaderComments: boolean;
65     FClassImplementationComments: boolean;
66     FFilename: string;
67     FIdentComplAddDo: Boolean;
68     FIdentComplAddParameterBrackets: boolean;
69     FIdentComplReplaceIdentifier: boolean;
70     FIdentComplJumpToError: boolean;
71     FIdentComplShowHelp: boolean;
72 
73     // General
74     FAdjustTopLineDueToComment: boolean;
75     FAvoidUnnecessaryJumps: boolean;
76     FIdentComplSortForHistory: boolean;
77     FIdentComplSortForScope: boolean;
78     FJumpSingleLinePos: integer;
79     FJumpCodeBlockPos: integer;
80     FCursorBeyondEOL: boolean;
81     FSkipForwardDeclarations: boolean;
82     FJumpToMethodBody: boolean;
83 
84     // Define Templates
85     FGlobalDefineTemplates: TDefineTemplate;
86     FDefinesEditMainSplitterTop: integer;
87     FDefinesPreviewMainSplitterPos: integer;
88     FDefinesPreviewTemplSplitterPos: integer;
89 
90     // CodeCreation
91     FAddInheritedCodeToOverrideMethod: boolean;
92     FCompleteProperties: boolean;
93     FLineLength: integer;
94     FClassPartInsertPolicy: TClassPartInsertPolicy;
95     FMixMethodsAndProperties: boolean;
96     FForwardProcBodyInsertPolicy: TForwardProcBodyInsertPolicy;
97     FKeepForwardProcOrder: boolean;
98     FMethodInsertPolicy: TMethodInsertPolicy;
99     FMethodDefaultSection: TInsertClassSection;
100     FKeyWordPolicy : TWordPolicy;
101     FIdentifierPolicy: TWordPolicy;
102     FUpdateAllMethodSignatures: boolean;
103     FUpdateMultiProcSignatures: boolean;
104     FUpdateOtherProcSignaturesCase: boolean;
105     FGroupLocalVariables: boolean;
106     FOverrideStringTypesWithFirstParamType: Boolean;
107     FWordPolicyExceptions: TStringList;
108     FDoNotSplitLineInFront: TAtomTypes;
109     FDoNotSplitLineAfter: TAtomTypes;
110     FDoInsertSpaceInFront: TAtomTypes;
111     FDoInsertSpaceAfter: TAtomTypes;
112     FPropertyReadIdentPrefix: string;
113     FPropertyWriteIdentPrefix: string;
114     FPropertyStoredIdentPostfix: string;
115     FPrivateVariablePrefix: string;
116     FSetPropertyVariablename: string;
117     FSetPropertyVariableIsPrefix: Boolean;
118     FSetPropertyVariableUseConst: Boolean;
119     FUsesInsertPolicy: TUsesInsertPolicy;
120 
121     // identifier completion
122     FIdentComplAddSemicolon: Boolean;
123     FIdentComplAddAssignOperator: Boolean;
124     FIdentComplAutoStartAfterPoint: boolean;
125     FIdentComplAutoUseSingleIdent: boolean;
126     FIdentComplUseContainsFilter: Boolean;
127     FIdentComplIncludeWords: TIdentComplIncludeWords;
128     FIdentComplShowIcons: Boolean;
129 
130     // auto indentation
131     FIndentOnLineBreak: boolean;
132     FIndentOnPaste: boolean;
133     fIndentationFilename: String;
134     FIndentContextSensitive: boolean;
135 
136     // code completion templates
137     FCodeCompletionTemplateFileName : String;
138 
139     procedure SetCodeCompletionTemplateFileName(aValue: String);
140     procedure SetFilename(const AValue: string);
141     procedure SetSetPropertyVariablename(aValue: string);
142     procedure SetSetPropertyVariableIsPrefix(aValue: Boolean);
143     procedure SetSetPropertyVariableUseConst(aValue: Boolean);
144   public
GetGroupCaptionnull145     class function GetGroupCaption:string; override;
GetInstancenull146     class function GetInstance: TAbstractIDEOptions; override;
147     procedure DoAfterWrite(Restore: boolean); override;
148   public
149     constructor Create;
150     destructor Destroy; override;
151     procedure Clear;
152     procedure ClearGlobalDefineTemplates;
153     procedure Load;
154     procedure Save;
155     procedure AssignGlobalDefineTemplatesToTree(Tree: TDefineTree);
156     property Filename: string read FFilename write SetFilename;
157     procedure SetLazarusDefaultFilename;
158     procedure Assign(Source: TPersistent); override;
159     procedure AssignTo(Dest: TPersistent); override;
IsEqualnull160     function IsEqual(CodeToolsOpts: TCodeToolsOptions): boolean;
CreateCopynull161     function CreateCopy: TCodeToolsOptions;
162     procedure ReadGlobalDefinesTemplatesFromTree(Tree: TDefineTree);
163     procedure CreateDefaultIndentationFile;
164 
165     // General
166     property AdjustTopLineDueToComment: boolean
167       read FAdjustTopLineDueToComment write FAdjustTopLineDueToComment;
168     property AvoidUnnecessaryJumps: boolean read FAvoidUnnecessaryJumps write FAvoidUnnecessaryJumps;
169     property JumpSingleLinePos: integer read FJumpSingleLinePos write FJumpSingleLinePos;
170     property JumpCodeBlockPos: integer read FJumpCodeBlockPos write FJumpCodeBlockPos;
171     property CursorBeyondEOL: boolean
172       read FCursorBeyondEOL write FCursorBeyondEOL;
173     property SkipForwardDeclarations: boolean read FSkipForwardDeclarations write FSkipForwardDeclarations;
174     property JumpToMethodBody: boolean read FJumpToMethodBody write FJumpToMethodBody;
175     // Define Templates
176     property GlobalDefineTemplates: TDefineTemplate read FGlobalDefineTemplates;
177     property DefinesEditMainSplitterTop: integer read FDefinesEditMainSplitterTop
178                                               write FDefinesEditMainSplitterTop;
179     property DefinesPreviewMainSplitterPos: integer
180        read FDefinesPreviewMainSplitterPos write FDefinesPreviewMainSplitterPos;
181     property DefinesPreviewTemplSplitterPos: integer
182        read FDefinesPreviewTemplSplitterPos write FDefinesPreviewTemplSplitterPos;
183 
184     // CodeCreation
185     property CompleteProperties: boolean
186       read FCompleteProperties write FCompleteProperties;
187     property AddInheritedCodeToOverrideMethod: boolean
188       read FAddInheritedCodeToOverrideMethod write FAddInheritedCodeToOverrideMethod;
189     property LineLength: integer read FLineLength write FLineLength;
190     property ClassPartInsertPolicy: TClassPartInsertPolicy
191       read FClassPartInsertPolicy write FClassPartInsertPolicy;
192     property MixMethodsAndProperties: boolean
193       read FMixMethodsAndProperties write FMixMethodsAndProperties;
194     property UpdateAllMethodSignatures: boolean
195       read FUpdateAllMethodSignatures write FUpdateAllMethodSignatures;
196     property ForwardProcBodyInsertPolicy: TForwardProcBodyInsertPolicy
197       read FForwardProcBodyInsertPolicy write FForwardProcBodyInsertPolicy;
198     property KeepForwardProcOrder: boolean
199       read FKeepForwardProcOrder write FKeepForwardProcOrder;
200     property UpdateMultiProcSignatures: boolean
201       read FUpdateMultiProcSignatures write FUpdateMultiProcSignatures;
202     property UpdateOtherProcSignaturesCase: boolean
203       read FUpdateOtherProcSignaturesCase write FUpdateOtherProcSignaturesCase;
204     property GroupLocalVariables: boolean
205       read FGroupLocalVariables write FGroupLocalVariables;
206     property OverrideStringTypesWithFirstParamType: Boolean
207       read FOverrideStringTypesWithFirstParamType write FOverrideStringTypesWithFirstParamType;
208     property ClassHeaderComments: boolean
209       read FClassHeaderComments write FClassHeaderComments;
210     property ClassImplementationComments: boolean
211       read FClassImplementationComments write FClassImplementationComments;
212     property MethodInsertPolicy: TMethodInsertPolicy
213       read FMethodInsertPolicy write FMethodInsertPolicy;
214     property MethodDefaultSection: TInsertClassSection
215       read FMethodDefaultSection write FMethodDefaultSection;
216     property KeyWordPolicy : TWordPolicy
217       read FKeyWordPolicy write FKeyWordPolicy;
218     property IdentifierPolicy: TWordPolicy
219       read FIdentifierPolicy write FIdentifierPolicy;
220     property WordPolicyExceptions: TStringList
221       read FWordPolicyExceptions write FWordPolicyExceptions;
222     property DoNotSplitLineInFront: TAtomTypes
223       read FDoNotSplitLineInFront write FDoNotSplitLineInFront;
224     property DoNotSplitLineAfter: TAtomTypes
225       read FDoNotSplitLineAfter write FDoNotSplitLineAfter;
226     property DoInsertSpaceInFront: TAtomTypes
227       read FDoInsertSpaceInFront write FDoInsertSpaceInFront;
228     property DoInsertSpaceAfter: TAtomTypes
229       read FDoInsertSpaceAfter write FDoInsertSpaceAfter;
230     property PropertyReadIdentPrefix: string
231       read FPropertyReadIdentPrefix write FPropertyReadIdentPrefix;
232     property PropertyWriteIdentPrefix: string
233       read FPropertyWriteIdentPrefix write FPropertyWriteIdentPrefix;
234     property PropertyStoredIdentPostfix: string
235       read FPropertyStoredIdentPostfix write FPropertyStoredIdentPostfix;
236     property PrivateVariablePrefix: string
237       read FPrivateVariablePrefix write FPrivateVariablePrefix;
238     property SetPropertyVariablename: string
239       read FSetPropertyVariablename write SetSetPropertyVariablename;
240     property SetPropertyVariableIsPrefix: Boolean
241       read FSetPropertyVariableIsPrefix write SetSetPropertyVariableIsPrefix;
242     property SetPropertyVariableUseConst: Boolean
243       read FSetPropertyVariableUseConst write SetSetPropertyVariableUseConst;
244     property UsesInsertPolicy: TUsesInsertPolicy
245       read FUsesInsertPolicy write FUsesInsertPolicy;
246 
247     // identifier completion
248     property IdentComplAddSemicolon: Boolean read FIdentComplAddSemicolon
249                                              write FIdentComplAddSemicolon;
250     property IdentComplAddAssignOperator: Boolean read FIdentComplAddAssignOperator
251                                              write FIdentComplAddAssignOperator;
252     property IdentComplAddDo: Boolean read FIdentComplAddDo write FIdentComplAddDo;
253     property IdentComplAutoStartAfterPoint: boolean read FIdentComplAutoStartAfterPoint
254                                            write FIdentComplAutoStartAfterPoint;
255     property IdentComplAutoUseSingleIdent: boolean read FIdentComplAutoUseSingleIdent
256                                            write FIdentComplAutoUseSingleIdent;
257     property IdentComplUseContainsFilter: boolean read FIdentComplUseContainsFilter
258                                            write FIdentComplUseContainsFilter;
259     property IdentComplIncludeWords: TIdentComplIncludeWords read FIdentComplIncludeWords
260                                            write FIdentComplIncludeWords;
261     property IdentComplShowIcons: boolean read FIdentComplShowIcons
262                                            write FIdentComplShowIcons;
263     property IdentComplAddParameterBrackets: boolean
264       read FIdentComplAddParameterBrackets write FIdentComplAddParameterBrackets;
265     property IdentComplReplaceIdentifier: boolean
266       read FIdentComplReplaceIdentifier write FIdentComplReplaceIdentifier;
267     property IdentComplJumpToError: boolean
268       read FIdentComplJumpToError write FIdentComplJumpToError;
269     property IdentComplShowHelp: boolean read FIdentComplShowHelp
270                                          write FIdentComplShowHelp;
271     property IdentComplSortForHistory: boolean read FIdentComplSortForHistory
272                                              write FIdentComplSortForHistory;
273     property IdentComplSortForScope: boolean read FIdentComplSortForScope
274                                              write FIdentComplSortForScope;
275 
276     // indentation
277     property IndentOnLineBreak: boolean read FIndentOnLineBreak
278                                          write FIndentOnLineBreak;
279     property IndentOnPaste: boolean read FIndentOnPaste write FIndentOnPaste;
280     property IndentationFileName: String
281       read fIndentationFileName write fIndentationFileName;
282     property IndentContextSensitive: boolean read FIndentContextSensitive
283       write FIndentContextSensitive;
284 
285     // code completion templates
286     property CodeCompletionTemplateFileName : String read FCodeCompletionTemplateFileName
287                                                      write SetCodeCompletionTemplateFileName;
288   end;
289 
290 var
291   CodeToolsOpts: TCodeToolsOptions = nil;
292 
GetTranslatedAtomTypesnull293 function GetTranslatedAtomTypes(a: TAtomType): string;
TranslatedAtomToTypenull294 function TranslatedAtomToType(const s: string): TAtomType;
ReadIdentifiernull295 function ReadIdentifier(const s, DefaultIdent: string): string;
296 
297 const
298   IdentComplIncludeWordsNames: array[TIdentComplIncludeWords] of shortstring = (
299       'No', 'FromCurrentUnit', 'FromAllUnits'
300     );
IdentComplIncludeWordsNamesToEnumnull301 function IdentComplIncludeWordsNamesToEnum(const s: string): TIdentComplIncludeWords;
302 
303 implementation
304 
305 {$R lazarus_indentation.res}
306 
307 const
308   CodeToolsOptionsVersion = 2;
309   DefaultCodeToolsOptsFile = 'codetoolsoptions.xml';
310 
IdentComplIncludeWordsNamesToEnumnull311 function IdentComplIncludeWordsNamesToEnum(const s: string): TIdentComplIncludeWords;
312 begin
313   for Result:=Low(TIdentComplIncludeWords) to High(TIdentComplIncludeWords) do
314     if SysUtils.CompareText(IdentComplIncludeWordsNames[Result],s)=0 then exit;
315   Result:=icwDontInclude;
316 end;
317 
GetTranslatedAtomTypesnull318 function GetTranslatedAtomTypes(a: TAtomType): string;
319 begin
320   case a of
321   atNone: Result:=lisCodeToolsOptsNone;
322   atKeyword: Result:=lisCodeToolsOptsKeyword;
323   atIdentifier: Result:=lisCodeToolsOptsIdentifier;
324   atColon: Result:=lisCodeToolsOptsColon;
325   atSemicolon: Result:=lisCodeToolsOptsSemicolon;
326   atComma: Result:=lisCodeToolsOptsComma;
327   atPoint: Result:=lisCodeToolsOptsPoint;
328   atAt: Result:=lisCodeToolsOptsAt;
329   atNumber: Result:=lisCodeToolsOptsNumber;
330   atStringConstant: Result:=lisCodeToolsOptsStringConst;
331   atNewLine: Result:=lisCodeToolsOptsNewLine;
332   atSpace: Result:=lisCodeToolsOptsSpace;
333   atSymbol: Result:=lisCodeToolsOptsSymbol;
334   atBracket: Result:=lisCodeToolsOptsBracket;
335   atCaret: Result:=lisCodeToolsOptsCaret;
336   else
337     Result:='???';
338   end;
339 end;
340 
TranslatedAtomToTypenull341 function TranslatedAtomToType(const s: string): TAtomType;
342 begin
343   for Result:=Low(TAtomType) to High(TAtomType) do
344     if s=GetTranslatedAtomTypes(Result) then exit;
345   Result:=atNone;
346 end;
347 
ReadAtomTypesFromXMLnull348 function ReadAtomTypesFromXML(XMLConfig: TXMLConfig; const Path: string;
349   DefaultValues: TAtomTypes): TAtomTypes;
350 var a: TAtomType;
351 begin
352   Result:=[];
353   for a:=Low(TAtomType) to High(TAtomType) do begin
354     if (a<>atNone)
355     and (XMLConfig.GetValue(Path+AtomTypeNames[a]+'/Value',a in DefaultValues))
356     then
357       Include(Result,a);
358   end;
359 end;
360 
361 procedure WriteAtomTypesToXML(XMLConfig: TXMLConfig; const Path: string;
362   NewValues, DefaultValues: TAtomTypes);
363 var a: TAtomType;
364 begin
365   for a:=Low(TAtomType) to High(TAtomType) do begin
366     if (a<>atNone) then
367       XMLConfig.SetDeleteValue(Path+AtomTypeNames[a]+'/Value',
368                                a in NewValues,a in DefaultValues);
369   end;
370 end;
371 
372 
IsIdentifiernull373 function IsIdentifier(const s: string): boolean;
374 var i: integer;
375 begin
376   Result:=false;
377   if (s='') then exit;
378   for i:=1 to length(s) do begin
379     if not (s[i] in ['_','A'..'Z','a'..'z']) then exit;
380   end;
381   Result:=true;
382 end;
383 
ReadIdentifiernull384 function ReadIdentifier(const s, DefaultIdent: string): string;
385 begin
386   if IsIdentifier(s) then
387     Result:=s
388   else
389     Result:=DefaultIdent;
390 end;
391 
392 { TCodeToolsOptions }
393 
394 constructor TCodeToolsOptions.Create;
395 begin
396   inherited Create;
397   FFilename:='';
398   FWordPolicyExceptions := TStringList.Create;
399   Clear;
400 end;
401 
402 destructor TCodeToolsOptions.Destroy;
403 begin
404   ClearGlobalDefineTemplates;
405   FWordPolicyExceptions.Free;
406   inherited Destroy;
407 end;
408 
TCodeToolsOptions.GetGroupCaptionnull409 class function TCodeToolsOptions.GetGroupCaption: string;
410 begin
411   Result := dlgGroupCodetools;
412 end;
413 
TCodeToolsOptions.GetInstancenull414 class function TCodeToolsOptions.GetInstance: TAbstractIDEOptions;
415 begin
416   Result := CodeToolsOpts;
417 end;
418 
419 procedure TCodeToolsOptions.DoAfterWrite(Restore: boolean);
420 begin
421   inherited DoAfterWrite(Restore);
422   if not Restore then
423     Save;
424 end;
425 
426 procedure TCodeToolsOptions.Load;
427 var
428   XMLConfig: TXMLConfig;
429   FileVersion: integer;
430   AJumpCentered: Boolean;
431 
432   procedure LoadGlobalDefineTemplates;
433   begin
434     // delete old one
435     ClearGlobalDefineTemplates;
436     // create empty one
437     FGlobalDefineTemplates:=TDefineTemplate.Create;
438     FGlobalDefineTemplates.Name:='';
439     // load
440     FGlobalDefineTemplates.LoadFromXMLConfig(XMLConfig,'CodeToolsGlobalDefines/',
441       true,true);
442     // delete if still empty
443     if FGlobalDefineTemplates.Name='' then begin
444       ClearGlobalDefineTemplates;
445     end else begin
446       FGlobalDefineTemplates.SetDefineOwner(Self,true);
447     end;
448   end;
449 
450 begin
451   CreateDefaultIndentationFile;
452   try
453     XMLConfig:=TXMLConfig.Create(FFileName);
454     FileVersion:=XMLConfig.GetValue('CodeToolsOptions/Version/Value',0);
455     if (FileVersion<>0) and (FileVersion<CodeToolsOptionsVersion) then
456       debugln(lisCompilerNOTELoadingOldCodetoolsOptionsFile, FFileName);
457 
458     // General
459     FAdjustTopLineDueToComment:=XMLConfig.GetValue(
460       'CodeToolsOptions/AdjustTopLineDueToComment/Value',true);
461     if FileVersion<2 then
462     begin
463       AJumpCentered:=XMLConfig.GetValue('CodeToolsOptions/JumpCentered/Value',
464         true);
465       if AJumpCentered then
466         FJumpSingleLinePos := 50
467       else
468         FJumpSingleLinePos := 0;
469       FJumpCodeBlockPos := 0;
470     end else
471     begin
472       FJumpSingleLinePos:=XMLConfig.GetValue('CodeToolsOptions/JumpSingleLinePos/Value', 50);
473       FJumpCodeBlockPos:=XMLConfig.GetValue('CodeToolsOptions/JumpCodeBlockPos/Value', 0);
474     end;
475     FAvoidUnnecessaryJumps:=XMLConfig.GetValue('CodeToolsOptions/AvoidUnnecessaryJumps/Value', True);
476     FCursorBeyondEOL:=XMLConfig.GetValue(
477       'CodeToolsOptions/CursorBeyondEOL/Value',true);
478     FSkipForwardDeclarations:=XMLConfig.GetValue(
479       'CodeToolsOptions/SkipForwardDeclarations/Value',false);
480     FJumpToMethodBody:=XMLConfig.GetValue(
481       'CodeToolsOptions/JumpToMethodBody/Value',false);
482 
483     // Define templates
484     LoadGlobalDefineTemplates;
485     FDefinesEditMainSplitterTop:=XMLConfig.GetValue(
486       'CodeToolsOptions/DefinesEditMainSplitter/Top',100);
487     FDefinesPreviewMainSplitterPos:=XMLConfig.GetValue(
488       'CodeToolsOptions/DefinesPreviewMainSplitter/Position',280);
489     FDefinesPreviewTemplSplitterPos:=XMLConfig.GetValue(
490       'CodeToolsOptions/DefinesPreviewTemplSplitter/Position',100);
491 
492     // CodeCreation
493     FAddInheritedCodeToOverrideMethod:=XMLConfig.GetValue(
494       'CodeToolsOptions/AddInheritedCodeToOverrideMethod/Value',true);
495     FCompleteProperties:=XMLConfig.GetValue(
496       'CodeToolsOptions/CompleteProperties/Value',true);
497     FLineLength:=XMLConfig.GetValue(
498       'CodeToolsOptions/LineLengthXMLConfig/Value',80);
499     FClassPartInsertPolicy:=ClassPartPolicyNameToPolicy(XMLConfig.GetValue(
500       'CodeToolsOptions/ClassPartInsertPolicy/Value',
501       ClassPartInsertPolicyNames[cpipAlphabetically]));
502     FMixMethodsAndProperties:=XMLConfig.GetValue(
503       'CodeToolsOptions/MixMethodsAndProperties/Value',false);
504     FUpdateAllMethodSignatures:=XMLConfig.GetValue(
505       'CodeToolsOptions/UpdateAllMethodSignatures/Value',true);
506     FForwardProcBodyInsertPolicy:=ForwardProcBodyInsertPolicyNameToPolicy(
507       XMLConfig.GetValue('CodeToolsOptions/ForwardProcBodyInsertPolicy/Value',
508         ForwardProcBodyInsertPolicyNames[fpipInFrontOfMethods]));
509     FKeepForwardProcOrder:=XMLConfig.GetValue(
510       'CodeToolsOptions/KeepForwardProcOrder/Value',true);
511     FUpdateMultiProcSignatures:=XMLConfig.GetValue(
512       'CodeToolsOptions/UpdateMultiProcSignatures/Value',true);
513     FUpdateOtherProcSignaturesCase:=XMLConfig.GetValue(
514       'CodeToolsOptions/UpdateOtherProcSignaturesCase/Value',true);
515     FGroupLocalVariables:=XMLConfig.GetValue(
516       'CodeToolsOptions/GroupLocalVariables/Value',true);
517     FOverrideStringTypesWithFirstParamType:=XMLConfig.GetValue(
518       'CodeToolsOptions/OverrideStringTypesWithFirstParamType/Value',true);
519     FClassHeaderComments:=XMLConfig.GetValue(
520       'CodeToolsOptions/ClassHeaderComments/Value',true);
521     FClassImplementationComments:=XMLConfig.GetValue(
522       'CodeToolsOptions/ClassImplementationComments/Value',true);
523 
524     FMethodInsertPolicy:=MethodInsertPolicyNameToPolicy(XMLConfig.GetValue(
525       'CodeToolsOptions/MethodInsertPolicy/Value',
526       MethodInsertPolicyNames[mipClassOrder]));
527     FMethodDefaultSection:=InsertClassSectionNameToSection(XMLConfig.GetValue(
528       'CodeToolsOptions/MethodDefaultSection/Value',
529       InsertClassSectionNames[DefaultMethodDefaultSection]));
530     FKeyWordPolicy:=WordPolicyNameToPolicy(XMLConfig.GetValue(
531       'CodeToolsOptions/KeyWordPolicy/Value',
532       WordPolicyNames[wpLowerCase]));
533     FIdentifierPolicy:=WordPolicyNameToPolicy(XMLConfig.GetValue(
534       'CodeToolsOptions/IdentifierPolicy/Value',
535       WordPolicyNames[wpNone]));
536     WordPolicyExceptions.Text:=LineBreaksToSystemLineBreaks(XMLConfig.GetValue(
537       'CodeToolsOptions/WordPolicyExceptions/Value', ''));
538     FDoNotSplitLineInFront:=ReadAtomTypesFromXML(XMLConfig,
539       'CodeToolsOptions/DoNotSplitLineInFront/',DefaultDoNotSplitLineInFront);
540     FDoNotSplitLineAfter:=ReadAtomTypesFromXML(XMLConfig,
541       'CodeToolsOptions/DoNotSplitLineAfter/',DefaultDoNotSplitLineAfter);
542     FDoInsertSpaceInFront:=ReadAtomTypesFromXML(XMLConfig,
543       'CodeToolsOptions/DoInsertSpaceInFront/',DefaultDoInsertSpaceInFront);
544     FDoInsertSpaceAfter:=ReadAtomTypesFromXML(XMLConfig,
545       'CodeToolsOptions/DoInsertSpaceAfter/',DefaultDoInsertSpaceAfter);
546     FPropertyReadIdentPrefix:=ReadIdentifier(XMLConfig.GetValue(
547       'CodeToolsOptions/PropertyReadIdentPrefix/Value',''),'Get');
548     FPropertyWriteIdentPrefix:=ReadIdentifier(XMLConfig.GetValue(
549       'CodeToolsOptions/PropertyWriteIdentPrefix/Value',''),'Set');
550     FPropertyStoredIdentPostfix:=ReadIdentifier(XMLConfig.GetValue(
551       'CodeToolsOptions/PropertyStoredIdentPostfix/Value',''),'IsStored');
552     FPrivateVariablePrefix:=ReadIdentifier(XMLConfig.GetValue(
553       'CodeToolsOptions/PrivateVariablePrefix/Value',''),'F');
554     FSetPropertyVariablename:=ReadIdentifier(XMLConfig.GetValue(
555       'CodeToolsOptions/SetPropertyVariablename/Value',''),'AValue');
556     FSetPropertyVariableIsPrefix:=XMLConfig.GetValue(
557       'CodeToolsOptions/SetPropertyVariableIsPrefix/Value',false);
558     FSetPropertyVariableUseConst:=XMLConfig.GetValue(
559       'CodeToolsOptions/SetPropertyVariableUseConst/Value',false);
560     FUsesInsertPolicy:=UsesInsertPolicyNameToPolicy(XMLConfig.GetValue(
561       'CodeToolsOptions/UsesInsertPolicy/Value',
562       UsesInsertPolicyNames[DefaultUsesInsertPolicy]));
563 
564     // identifier completion
565     FIdentComplAddSemicolon:=XMLConfig.GetValue(
566       'CodeToolsOptions/IdentifierCompletion/AddSemicolon',true);
567     FIdentComplAddAssignOperator:=XMLConfig.GetValue(
568       'CodeToolsOptions/IdentifierCompletion/AddAssignOperator',true);
569     FIdentComplAddDo:=XMLConfig.GetValue(
570       'CodeToolsOptions/IdentifierCompletion/AddDo',true);
571     FIdentComplAutoStartAfterPoint:=XMLConfig.GetValue(
572       'CodeToolsOptions/IdentifierCompletion/AutoStartAfterPoint',true);
573     FIdentComplAutoUseSingleIdent:=XMLConfig.GetValue(
574       'CodeToolsOptions/IdentifierCompletion/AutoUseSingleIdent',true);
575     FIdentComplUseContainsFilter:=XMLConfig.GetValue(
576       'CodeToolsOptions/IdentifierCompletion/UseContainsFilter',true);
577     FIdentComplIncludeWords:=IdentComplIncludeWordsNamesToEnum(XMLConfig.GetValue(
578       'CodeToolsOptions/IdentifierCompletion/IncludeWords',
579       IdentComplIncludeWordsNames[icwIncludeFromAllUnits]));
580     FIdentComplShowIcons:=XMLConfig.GetValue(
581       'CodeToolsOptions/IdentifierCompletion/ShowIcons',false);
582     FIdentComplAddParameterBrackets:=XMLConfig.GetValue(
583       'CodeToolsOptions/IdentifierCompletion/AutoAddParameterBrackets',true);
584     FIdentComplReplaceIdentifier:=XMLConfig.GetValue(
585       'CodeToolsOptions/IdentifierCompletion/ReplaceIdentifier',true);
586     FIdentComplJumpToError:=XMLConfig.GetValue(
587       'CodeToolsOptions/IdentifierCompletion/JumpToError',true);
588     FIdentComplShowHelp:=XMLConfig.GetValue(
589       'CodeToolsOptions/IdentifierCompletion/ShowHelp',false);
590     FIdentComplSortForHistory:=XMLConfig.GetValue(
591       'CodeToolsOptions/IdentifierCompletion/SortForHistory',true);
592     FIdentComplSortForScope:=XMLConfig.GetValue(
593       'CodeToolsOptions/IdentifierCompletion/SortForScope',true);
594 
595     // indentation
596     FIndentOnLineBreak :=
597       XMLConfig.GetValue('CodeToolsOptions/Indentation/OnLineBreak/Enabled',true);
598     FIndentOnPaste :=
599       XMLConfig.GetValue('CodeToolsOptions/Indentation/OnPaste/Enabled',true);
600     fIndentationFilename :=
601       XMLConfig.GetValue('CodeToolsOptions/Indentation/FileName'
602       , TrimFilename(AppendPathDelim(GetPrimaryConfigPath)+DefaultIndentationFilename));
603     FIndentContextSensitive :=
604       XMLConfig.GetValue('CodeToolsOptions/Indentation/ContextSensitive',true);
605 
606     // code completion templates
607     FCodeCompletionTemplateFileName :=
608       XMLConfig.GetValue('CodeToolsOptions/CodeCompletionTemplate/FileName'
609       , DefaultCodeCompletionFilename);
610 
611     XMLConfig.Free;
612   except
613     on E: Exception do begin
614       DebugLn('[TCodeToolsOptions.Load]  error reading "',FFilename,'": ',E.Message);
615     end;
616   end;
617 end;
618 
619 procedure TCodeToolsOptions.Save;
620 var
621   XMLConfig: TXMLConfig;
622 
623   procedure SaveGlobalDefineTemplates;
624   begin
625     if FGlobalDefineTemplates<>nil then
626       FGlobalDefineTemplates.SaveToXMLConfig(XMLConfig,
627         'CodeToolsGlobalDefines/',true,false,true,false);
628   end;
629 
630 begin
631   try
632     InvalidateFileStateCache;
633     XMLConfig:=TXMLConfig.CreateClean(FFileName);
634     XMLConfig.SetValue('CodeToolsOptions/Version/Value',CodeToolsOptionsVersion);
635 
636     // General
637     XMLConfig.SetDeleteValue('CodeToolsOptions/AdjustTopLineDueToComment/Value',
638                              FAdjustTopLineDueToComment,true);
639     XMLConfig.SetDeleteValue('CodeToolsOptions/JumpSingleLinePos/Value',
640                              FJumpSingleLinePos,50);
641     XMLConfig.SetDeleteValue('CodeToolsOptions/JumpCodeBlockPos/Value',
642                              FJumpCodeBlockPos,0);
643     XMLConfig.SetDeleteValue('CodeToolsOptions/AvoidUnnecessaryJumps/Value',
644                              FAvoidUnnecessaryJumps,True);
645     XMLConfig.SetDeleteValue('CodeToolsOptions/CursorBeyondEOL/Value',
646                              FCursorBeyondEOL,true);
647     XMLConfig.SetDeleteValue('CodeToolsOptions/SkipForwardDeclarations/Value',
648                              FSkipForwardDeclarations,false);
649     XMLConfig.SetDeleteValue('CodeToolsOptions/JumpToMethodBody/Value',
650                              FJumpToMethodBody,false);
651     // Define templates
652     SaveGlobalDefineTemplates;
653     XMLConfig.SetDeleteValue('CodeToolsOptions/DefinesEditMainSplitter/Top',
654                              FDefinesEditMainSplitterTop,100);
655     XMLConfig.SetDeleteValue('CodeToolsOptions/DefinesPreviewMainSplitter/Position',
656                              FDefinesPreviewMainSplitterPos,280);
657     XMLConfig.SetDeleteValue('CodeToolsOptions/DefinesPreviewTemplSplitter/Position',
658                              FDefinesPreviewTemplSplitterPos,100);
659 
660     // CodeCreation
661     XMLConfig.SetDeleteValue(
662       'CodeToolsOptions/AddInheritedCodeToOverrideMethod/Value',
663       AddInheritedCodeToOverrideMethod,true);
664     XMLConfig.SetDeleteValue(
665       'CodeToolsOptions/CompleteProperties/Value',CompleteProperties,true);
666     XMLConfig.SetDeleteValue(
667       'CodeToolsOptions/LineLengthXMLConfig/Value',FLineLength,80);
668     XMLConfig.SetDeleteValue('CodeToolsOptions/ClassPartInsertPolicy/Value',
669       ClassPartInsertPolicyNames[FClassPartInsertPolicy],
670       ClassPartInsertPolicyNames[cpipAlphabetically]);
671     XMLConfig.SetDeleteValue(
672       'CodeToolsOptions/MixMethodsAndProperties/Value',FMixMethodsAndProperties,
673       false);
674     XMLConfig.SetDeleteValue(
675       'CodeToolsOptions/UpdateAllMethodSignatures/Value',FUpdateAllMethodSignatures,
676       true);
677     XMLConfig.SetDeleteValue('CodeToolsOptions/ForwardProcBodyInsertPolicy/Value',
678       ForwardProcBodyInsertPolicyNames[FForwardProcBodyInsertPolicy],
679       ForwardProcBodyInsertPolicyNames[fpipInFrontOfMethods]);
680     XMLConfig.SetDeleteValue(
681       'CodeToolsOptions/KeepForwardProcOrder/Value',FKeepForwardProcOrder,true);
682     XMLConfig.SetDeleteValue(
683       'CodeToolsOptions/ClassHeaderComments/Value',FClassHeaderComments,true);
684     XMLConfig.SetDeleteValue(
685       'CodeToolsOptions/UpdateMultiProcSignatures/Value',FUpdateMultiProcSignatures,
686       true);
687     XMLConfig.SetDeleteValue(
688       'CodeToolsOptions/UpdateOtherProcSignaturesCase/Value',FUpdateOtherProcSignaturesCase,
689       true);
690     XMLConfig.SetDeleteValue(
691       'CodeToolsOptions/GroupLocalVariables/Value',FGroupLocalVariables,
692       true);
693     XMLConfig.SetDeleteValue(
694       'CodeToolsOptions/OverrideStringTypesWithFirstParamType/Value',FOverrideStringTypesWithFirstParamType,
695       true);
696     XMLConfig.SetDeleteValue(
697       'CodeToolsOptions/ClassImplementationComments/Value',
698       FClassImplementationComments,true);
699     XMLConfig.SetDeleteValue('CodeToolsOptions/MethodInsertPolicy/Value',
700       MethodInsertPolicyNames[FMethodInsertPolicy],
701       MethodInsertPolicyNames[mipClassOrder]);
702     XMLConfig.SetDeleteValue('CodeToolsOptions/MethodDefaultSection/Value',
703       InsertClassSectionNames[FMethodDefaultSection],
704       InsertClassSectionNames[DefaultMethodDefaultSection]);
705     XMLConfig.SetDeleteValue('CodeToolsOptions/KeyWordPolicy/Value',
706       WordPolicyNames[FKeyWordPolicy],
707       WordPolicyNames[wpLowerCase]);
708     XMLConfig.SetDeleteValue('CodeToolsOptions/IdentifierPolicy/Value',
709       WordPolicyNames[FIdentifierPolicy],
710       WordPolicyNames[wpNone]);
711     XMLConfig.SetDeleteValue('CodeToolsOptions/WordPolicyExceptions/Value',
712       Trim(LineBreaksToSystemLineBreaks(WordPolicyExceptions.Text)),'');
713     WriteAtomTypesToXML(XMLConfig,'CodeToolsOptions/DoNotSplitLineInFront/',
714       FDoNotSplitLineInFront,DefaultDoNotSplitLineInFront);
715     WriteAtomTypesToXML(XMLConfig,'CodeToolsOptions/DoNotSplitLineAfter/',
716       FDoNotSplitLineAfter,DefaultDoNotSplitLineAfter);
717     WriteAtomTypesToXML(XMLConfig,'CodeToolsOptions/DoInsertSpaceInFront/',
718       FDoInsertSpaceInFront,DefaultDoInsertSpaceInFront);
719     WriteAtomTypesToXML(XMLConfig,'CodeToolsOptions/DoInsertSpaceAfter/',
720       FDoInsertSpaceAfter,DefaultDoInsertSpaceAfter);
721     XMLConfig.SetDeleteValue('CodeToolsOptions/PropertyReadIdentPrefix/Value',
722       FPropertyReadIdentPrefix,'Get');
723     XMLConfig.SetDeleteValue('CodeToolsOptions/PropertyWriteIdentPrefix/Value',
724       FPropertyWriteIdentPrefix,'Set');
725     XMLConfig.SetDeleteValue('CodeToolsOptions/PropertyStoredIdentPostfix/Value',
726       FPropertyStoredIdentPostfix,'IsStored');
727     XMLConfig.SetDeleteValue('CodeToolsOptions/PrivateVariablePrefix/Value',
728       FPrivateVariablePrefix,'F');
729     XMLConfig.SetDeleteValue('CodeToolsOptions/SetPropertyVariablename/Value',
730       FSetPropertyVariablename,'AValue');
731     XMLConfig.SetDeleteValue('CodeToolsOptions/SetPropertyVariableIsPrefix/Value',
732       FSetPropertyVariableIsPrefix,false);
733     XMLConfig.SetDeleteValue('CodeToolsOptions/SetPropertyVariableUseConst/Value',
734       FSetPropertyVariableUseConst,false);
735     XMLConfig.SetDeleteValue('CodeToolsOptions/UsesInsertPolicy/Value',
736       UsesInsertPolicyNames[FUsesInsertPolicy],
737       UsesInsertPolicyNames[DefaultUsesInsertPolicy]);
738 
739     // identifier completion
740     XMLConfig.SetDeleteValue('CodeToolsOptions/IdentifierCompletion/AddSemicolon',
741       FIdentComplAddSemicolon,true);
742     XMLConfig.SetDeleteValue('CodeToolsOptions/IdentifierCompletion/AddAssignOperator',
743       FIdentComplAddAssignOperator,true);
744     XMLConfig.SetDeleteValue('CodeToolsOptions/IdentifierCompletion/AddDo',
745       FIdentComplAddDo,true);
746     XMLConfig.SetDeleteValue('CodeToolsOptions/IdentifierCompletion/AutoStartAfterPoint',
747       FIdentComplAutoStartAfterPoint,true);
748     XMLConfig.SetDeleteValue('CodeToolsOptions/IdentifierCompletion/AutoUseSingleIdent',
749       FIdentComplAutoUseSingleIdent,true);
750     XMLConfig.SetDeleteValue('CodeToolsOptions/IdentifierCompletion/UseContainsFilter',
751       FIdentComplUseContainsFilter,true);
752     XMLConfig.SetDeleteValue('CodeToolsOptions/IdentifierCompletion/IncludeWords',
753       IdentComplIncludeWordsNames[FIdentComplIncludeWords],
754       IdentComplIncludeWordsNames[icwIncludeFromAllUnits]);
755     XMLConfig.SetDeleteValue('CodeToolsOptions/IdentifierCompletion/ShowIcons',
756       FIdentComplShowIcons,false);
757     XMLConfig.SetDeleteValue('CodeToolsOptions/IdentifierCompletion/AutoAddParameterBrackets',
758       FIdentComplAddParameterBrackets,true);
759     XMLConfig.SetDeleteValue('CodeToolsOptions/IdentifierCompletion/ReplaceIdentifier',
760       FIdentComplReplaceIdentifier,true);
761     XMLConfig.SetDeleteValue('CodeToolsOptions/IdentifierCompletion/JumpToError',
762       FIdentComplJumpToError,true);
763     XMLConfig.SetDeleteValue('CodeToolsOptions/IdentifierCompletion/ShowHelp',
764       FIdentComplShowHelp,false);
765     XMLConfig.SetDeleteValue('CodeToolsOptions/IdentifierCompletion/SortForHistory',
766       FIdentComplSortForHistory,true);
767     XMLConfig.SetDeleteValue('CodeToolsOptions/IdentifierCompletion/SortForScope',
768       FIdentComplSortForScope,true);
769 
770     // indentation
771     XMLConfig.SetDeleteValue('CodeToolsOptions/Indentation/OnLineBreak/Enabled'
772       , FIndentOnLineBreak, true);
773     XMLConfig.SetDeleteValue('CodeToolsOptions/Indentation/OnPaste/Enabled'
774       , FIndentOnPaste, true);
775     XMLConfig.SetDeleteValue('CodeToolsOptions/Indentation/FileName'
776       , fIndentationFilename, '');
777     XMLConfig.SetDeleteValue('CodeToolsOptions/Indentation/ContextSensitive'
778       , FIndentContextSensitive, true);
779 
780     // code completion templates
781     XMLConfig.SetDeleteValue('CodeToolsOptions/CodeCompletionTemplate/FileName'
782       , FCodeCompletionTemplateFileName, DefaultCodeCompletionFilename);
783 
784     XMLConfig.Flush;
785     XMLConfig.Free;
786   except
787     on E: Exception do begin
788       DebugLn('[TCodeToolsOptions.Save]  error writing "',FFilename,'": ',E.Message);
789     end;
790   end;
791 end;
792 
793 procedure TCodeToolsOptions.SetCodeCompletionTemplateFileName(aValue: String);
794 begin
795   aValue:=TrimFilename(aValue);
796   if FCodeCompletionTemplateFileName=aValue then Exit;
797   FCodeCompletionTemplateFileName:=aValue;
798 end;
799 
800 procedure TCodeToolsOptions.SetFilename(const AValue: string);
801 begin
802   FFilename:=AValue;
803 end;
804 
805 procedure TCodeToolsOptions.SetLazarusDefaultFilename;
806 var
807   ConfFileName: string;
808 begin
809   ConfFileName:=AppendPathDelim(GetPrimaryConfigPath)+DefaultCodeToolsOptsFile;
810   CopySecondaryConfigFile(DefaultCodeToolsOptsFile);
811   if (not FileExistsCached(ConfFileName)) then begin
812     debugln('Looking for code tools config file:  "' + ConfFileName + '"');
813     debugln(lisCompilerNOTECodetoolsConfigFileNotFoundUsingDefaults);
814   end;
815   FFilename:=ConfFilename;
816 end;
817 
818 procedure TCodeToolsOptions.SetSetPropertyVariableIsPrefix(aValue: Boolean);
819 begin
820   if FSetPropertyVariableIsPrefix=aValue then Exit;
821   FSetPropertyVariableIsPrefix:=aValue;
822 end;
823 
824 procedure TCodeToolsOptions.SetSetPropertyVariablename(aValue: string);
825 begin
826   if FSetPropertyVariablename=aValue then Exit;
827   FSetPropertyVariablename:=aValue;
828 end;
829 
830 procedure TCodeToolsOptions.SetSetPropertyVariableUseConst(aValue: Boolean);
831 begin
832   if FSetPropertyVariableUseConst=aValue then Exit;
833   FSetPropertyVariableUseConst:=aValue;
834 end;
835 
836 procedure TCodeToolsOptions.Assign(Source: TPersistent);
837 var
838   CodeToolsOpts: TCodeToolsOptions absolute Source;
839 begin
840   if not ((Source = nil) or (Source is TCodeToolsOptions)) then
841   begin
842     inherited Assign(Source);
843     Exit;
844   end;
845 
846   if CodeToolsOpts <> nil then
847   begin
848     // General
849     FAdjustTopLineDueToComment:=CodeToolsOpts.FAdjustTopLineDueToComment;
850     FJumpSingleLinePos:=CodeToolsOpts.FJumpSingleLinePos;
851     FJumpCodeBlockPos:=CodeToolsOpts.FJumpCodeBlockPos;
852     FAvoidUnnecessaryJumps:=CodeToolsOpts.FAvoidUnnecessaryJumps;
853     FCursorBeyondEOL:=CodeToolsOpts.FCursorBeyondEOL;
854     FAddInheritedCodeToOverrideMethod:=CodeToolsOpts.AddInheritedCodeToOverrideMethod;
855     FCompleteProperties:=CodeToolsOpts.CompleteProperties;
856     FSkipForwardDeclarations:=CodeToolsOpts.FSkipForwardDeclarations;
857     FJumpToMethodBody:=CodeToolsOpts.FJumpToMethodBody;
858 
859     // define templates
860     ClearGlobalDefineTemplates;
861     FGlobalDefineTemplates:=
862       CodeToolsOpts.FGlobalDefineTemplates.CreateCopy(false,true,true);
863     if FGlobalDefineTemplates<>nil then
864       FGlobalDefineTemplates.SetDefineOwner(Self,true);
865     FDefinesEditMainSplitterTop:=CodeToolsOpts.DefinesEditMainSplitterTop;
866     FDefinesPreviewMainSplitterPos:=CodeToolsOpts.DefinesPreviewMainSplitterPos;
867     FDefinesPreviewTemplSplitterPos:=CodeToolsOpts.DefinesPreviewTemplSplitterPos;
868 
869     // CodeCreation
870     FLineLength:=CodeToolsOpts.FLineLength;
871     FClassPartInsertPolicy:=CodeToolsOpts.FClassPartInsertPolicy;
872     FMixMethodsAndProperties:=CodeToolsOpts.MixMethodsAndProperties;
873     FUpdateAllMethodSignatures:=CodeToolsOpts.UpdateAllMethodSignatures;
874     FForwardProcBodyInsertPolicy:=CodeToolsOpts.ForwardProcBodyInsertPolicy;
875     FKeepForwardProcOrder:=CodeToolsOpts.KeepForwardProcOrder;
876     FUpdateMultiProcSignatures:=CodeToolsOpts.UpdateMultiProcSignatures;
877     FUpdateOtherProcSignaturesCase:=CodeToolsOpts.UpdateOtherProcSignaturesCase;
878     FGroupLocalVariables:=CodeToolsOpts.GroupLocalVariables;
879     FOverrideStringTypesWithFirstParamType:=CodeToolsOpts.OverrideStringTypesWithFirstParamType;
880     FClassHeaderComments:=CodeToolsOpts.ClassHeaderComments;
881     FClassImplementationComments:=CodeToolsOpts.ClassImplementationComments;
882     FMethodInsertPolicy:=CodeToolsOpts.FMethodInsertPolicy;
883     FMethodDefaultSection:=CodeToolsOpts.FMethodDefaultSection;
884     FKeyWordPolicy:=CodeToolsOpts.FKeyWordPolicy;
885     FIdentifierPolicy:=CodeToolsOpts.FIdentifierPolicy;
886     FDoNotSplitLineInFront:=CodeToolsOpts.FDoNotSplitLineInFront;
887     FDoNotSplitLineAfter:=CodeToolsOpts.FDoNotSplitLineAfter;
888     FDoInsertSpaceInFront:=CodeToolsOpts.FDoInsertSpaceInFront;
889     FDoInsertSpaceAfter:=CodeToolsOpts.FDoInsertSpaceAfter;
890     FPropertyReadIdentPrefix:=CodeToolsOpts.FPropertyReadIdentPrefix;
891     FPropertyWriteIdentPrefix:=CodeToolsOpts.FPropertyWriteIdentPrefix;
892     FPropertyStoredIdentPostfix:=CodeToolsOpts.FPropertyStoredIdentPostfix;
893     FPrivateVariablePrefix:=CodeToolsOpts.FPrivateVariablePrefix;
894     FSetPropertyVariablename:=CodeToolsOpts.FSetPropertyVariablename;
895     FSetPropertyVariableIsPrefix:=CodeToolsOpts.FSetPropertyVariableIsPrefix;
896     FSetPropertyVariableUseConst:=CodeToolsOpts.FSetPropertyVariableUseConst;
897     FUsesInsertPolicy:=CodeToolsOpts.FUsesInsertPolicy;
898 
899     // identifier completion
900     FIdentComplAddSemicolon:=CodeToolsOpts.FIdentComplAddSemicolon;
901     FIdentComplAddAssignOperator:=CodeToolsOpts.FIdentComplAddAssignOperator;
902     FIdentComplAddDo:=CodeToolsOpts.FIdentComplAddDo;
903     FIdentComplAutoStartAfterPoint:=CodeToolsOpts.FIdentComplAutoStartAfterPoint;
904     FIdentComplAutoUseSingleIdent:=CodeToolsOpts.FIdentComplAutoUseSingleIdent;
905     FIdentComplUseContainsFilter:=CodeToolsOpts.FIdentComplUseContainsFilter;
906     FIdentComplShowIcons:=CodeToolsOpts.FIdentComplShowIcons;
907     FIdentComplAddParameterBrackets:=CodeToolsOpts.FIdentComplAddParameterBrackets;
908     FIdentComplReplaceIdentifier:=CodeToolsOpts.FIdentComplReplaceIdentifier;
909     FIdentComplJumpToError:=CodeToolsOpts.FIdentComplJumpToError;
910     FIdentComplShowHelp:=CodeToolsOpts.FIdentComplShowHelp;
911     FIdentComplSortForHistory:=CodeToolsOpts.FIdentComplSortForHistory;
912     FIdentComplSortForScope:=CodeToolsOpts.FIdentComplSortForScope;
913   end
914   else
915     Clear;
916 end;
917 
918 procedure TCodeToolsOptions.Clear;
919 // !!! Does not reset Filename !!!
920 begin
921   // General
922   FAdjustTopLineDueToComment:=true;
923   FJumpSingleLinePos:=50;
924   FJumpCodeBlockPos:=0;
925   FAvoidUnnecessaryJumps:=true;
926   FCursorBeyondEOL:=true;
927 
928   // define templates
929   ClearGlobalDefineTemplates;
930   FDefinesEditMainSplitterTop:=100;
931   FDefinesPreviewMainSplitterPos:=280;
932   FDefinesPreviewTemplSplitterPos:=100;
933 
934   // CodeCreation
935   FAddInheritedCodeToOverrideMethod:=true;
936   FCompleteProperties:=true;
937   FLineLength:=80;
938   FClassPartInsertPolicy:=cpipLast;
939   FMixMethodsAndProperties:=false;
940   FUpdateAllMethodSignatures:=true;
941   FForwardProcBodyInsertPolicy:=fpipInFrontOfMethods;
942   FKeepForwardProcOrder:=true;
943   FUpdateMultiProcSignatures:=true;
944   FUpdateOtherProcSignaturesCase:=true;
945   FGroupLocalVariables:=true;
946   FOverrideStringTypesWithFirstParamType:=true;
947   FClassHeaderComments:=true;
948   FClassImplementationComments:=true;
949   FMethodInsertPolicy:=mipClassOrder;
950   FMethodDefaultSection:=DefaultMethodDefaultSection;
951   FKeyWordPolicy:=wpLowerCase;
952   FIdentifierPolicy:=wpNone;
953   FDoNotSplitLineInFront:=DefaultDoNotSplitLineInFront;
954   FDoNotSplitLineAfter:=DefaultDoNotSplitLineAfter;
955   FDoInsertSpaceInFront:=DefaultDoInsertSpaceInFront;
956   FDoInsertSpaceAfter:=DefaultDoInsertSpaceAfter;
957   FPropertyReadIdentPrefix:='Get';
958   FPropertyWriteIdentPrefix:='Set';
959   FPropertyStoredIdentPostfix:='IsStored';
960   FPrivateVariablePrefix:='f';
961   FSetPropertyVariablename:='AValue';
962   FSetPropertyVariableIsPrefix:=false;
963   FSetPropertyVariableUseConst:=false;
964   FUsesInsertPolicy:=DefaultUsesInsertPolicy;
965 
966   // identifier completion
967   FIdentComplAddSemicolon:=true;
968   FIdentComplAddAssignOperator:=true;
969   FIdentComplAddDo:=true;
970   FIdentComplAutoStartAfterPoint:=true;
971   FIdentComplAutoUseSingleIdent:=true;
972   FIdentComplUseContainsFilter:=true;
973   FIdentComplShowIcons:=false;
974   FIdentComplAddParameterBrackets:=true;
975   FIdentComplReplaceIdentifier:=true;
976   FIdentComplJumpToError:=true;
977   FIdentComplShowHelp:=false;
978   FIdentComplSortForHistory:=true;
979   FIdentComplSortForScope:=true;
980 
981   // indentation
982   FIndentOnLineBreak:=true;
983   FIndentOnPaste:=true;
984   fIndentationFilename:=
985     TrimFilename(AppendPathDelim(GetPrimaryConfigPath)+DefaultIndentationFilename);
986   FIndentContextSensitive:=true;
987 
988   // code completion templates
989   fCodeCompletionTemplateFileName := DefaultCodeCompletionFilename;
990 end;
991 
992 procedure TCodeToolsOptions.ClearGlobalDefineTemplates;
993 begin
994   if FGlobalDefineTemplates<>nil then begin
995     FGlobalDefineTemplates.Clear(true);
996     FGlobalDefineTemplates.Free;
997     FGlobalDefineTemplates:=nil;
998   end;
999 end;
1000 
TCodeToolsOptions.IsEqualnull1001 function TCodeToolsOptions.IsEqual(CodeToolsOpts: TCodeToolsOptions): boolean;
1002 begin
1003   Result:=
1004     // General
1005         (FAdjustTopLineDueToComment=CodeToolsOpts.FAdjustTopLineDueToComment)
1006     and (FJumpSingleLinePos=CodeToolsOpts.FJumpSingleLinePos)
1007     and (FJumpCodeBlockPos=CodeToolsOpts.FJumpCodeBlockPos)
1008     and (FAvoidUnnecessaryJumps=CodeToolsOpts.FAvoidUnnecessaryJumps)
1009     and (FCursorBeyondEOL=CodeToolsOpts.FCursorBeyondEOL)
1010     and (AddInheritedCodeToOverrideMethod=CodeToolsOpts.AddInheritedCodeToOverrideMethod)
1011     and (CompleteProperties=CodeToolsOpts.CompleteProperties)
1012     and (FSkipForwardDeclarations=CodeToolsOpts.FSkipForwardDeclarations)
1013     and (FJumpToMethodBody=CodeToolsOpts.FJumpToMethodBody)
1014 
1015     // define templates
1016     and (FGlobalDefineTemplates.IsEqual(
1017                                 CodeToolsOpts.FGlobalDefineTemplates,true,true))
1018     and (FDefinesEditMainSplitterTop=CodeToolsOpts.fDefinesEditMainSplitterTop)
1019     and (FDefinesPreviewMainSplitterPos=CodeToolsOpts.FDefinesPreviewMainSplitterPos)
1020     and (FDefinesPreviewTemplSplitterPos=CodeToolsOpts.FDefinesPreviewTemplSplitterPos)
1021 
1022     // CodeCreation
1023     and (FLineLength=CodeToolsOpts.FLineLength)
1024     and (FClassPartInsertPolicy=CodeToolsOpts.FClassPartInsertPolicy)
1025     and (FMixMethodsAndProperties=CodeToolsOpts.MixMethodsAndProperties)
1026     and (FUpdateAllMethodSignatures=CodeToolsOpts.UpdateAllMethodSignatures)
1027     and (FForwardProcBodyInsertPolicy=CodeToolsOpts.ForwardProcBodyInsertPolicy)
1028     and (FKeepForwardProcOrder=CodeToolsOpts.KeepForwardProcOrder)
1029     and (FUpdateMultiProcSignatures=CodeToolsOpts.UpdateMultiProcSignatures)
1030     and (FUpdateOtherProcSignaturesCase=CodeToolsOpts.UpdateOtherProcSignaturesCase)
1031     and (FGroupLocalVariables=CodeToolsOpts.GroupLocalVariables)
1032     and (FOverrideStringTypesWithFirstParamType=CodeToolsOpts.OverrideStringTypesWithFirstParamType)
1033     and (FClassHeaderComments=CodeToolsOpts.ClassHeaderComments)
1034     and (FClassImplementationComments=CodeToolsOpts.ClassImplementationComments)
1035     and (FMethodInsertPolicy=CodeToolsOpts.FMethodInsertPolicy)
1036     and (FMethodDefaultSection=CodeToolsOpts.FMethodDefaultSection)
1037     and (FKeyWordPolicy=CodeToolsOpts.FKeyWordPolicy)
1038     and (FIdentifierPolicy=CodeToolsOpts.FIdentifierPolicy)
1039     and (FDoNotSplitLineInFront=CodeToolsOpts.FDoNotSplitLineInFront)
1040     and (FDoNotSplitLineAfter=CodeToolsOpts.FDoNotSplitLineAfter)
1041     and (FDoInsertSpaceInFront=CodeToolsOpts.FDoInsertSpaceInFront)
1042     and (FDoInsertSpaceAfter=CodeToolsOpts.FDoInsertSpaceAfter)
1043     and (FPropertyReadIdentPrefix=CodeToolsOpts.FPropertyReadIdentPrefix)
1044     and (FPropertyWriteIdentPrefix=CodeToolsOpts.FPropertyWriteIdentPrefix)
1045     and (FPropertyStoredIdentPostfix=CodeToolsOpts.FPropertyStoredIdentPostfix)
1046     and (FPrivateVariablePrefix=CodeToolsOpts.FPrivateVariablePrefix)
1047     and (FSetPropertyVariablename=CodeToolsOpts.FSetPropertyVariablename)
1048     and (FSetPropertyVariableIsPrefix=CodeToolsOpts.FSetPropertyVariableIsPrefix)
1049     and (FSetPropertyVariableUseConst=CodeToolsOpts.FSetPropertyVariableUseConst)
1050     and (FUsesInsertPolicy=CodeToolsOpts.FUsesInsertPolicy)
1051 
1052     // identifier completion
1053     and (FIdentComplAddSemicolon=CodeToolsOpts.FIdentComplAddSemicolon)
1054     and (FIdentComplAddAssignOperator=CodeToolsOpts.FIdentComplAddAssignOperator)
1055     and (FIdentComplAddDo=CodeToolsOpts.FIdentComplAddDo)
1056     and (FIdentComplAutoStartAfterPoint=CodeToolsOpts.FIdentComplAutoStartAfterPoint)
1057     and (FIdentComplAutoUseSingleIdent=CodeToolsOpts.FIdentComplAutoUseSingleIdent)
1058     and (FIdentComplUseContainsFilter=CodeToolsOpts.FIdentComplUseContainsFilter)
1059     and (FIdentComplShowIcons=CodeToolsOpts.FIdentComplShowIcons)
1060     and (FIdentComplAddParameterBrackets=CodeToolsOpts.FIdentComplAddParameterBrackets)
1061     and (FIdentComplReplaceIdentifier=CodeToolsOpts.FIdentComplReplaceIdentifier)
1062     and (FIdentComplJumpToError=CodeToolsOpts.FIdentComplJumpToError)
1063     and (FIdentComplShowHelp=CodeToolsOpts.FIdentComplShowHelp)
1064     and (FIdentComplSortForHistory=CodeToolsOpts.FIdentComplSortForHistory)
1065     and (FIdentComplSortForScope=CodeToolsOpts.FIdentComplSortForScope)
1066    ;
1067 end;
1068 
TCodeToolsOptions.CreateCopynull1069 function TCodeToolsOptions.CreateCopy: TCodeToolsOptions;
1070 begin
1071   Result:=TCodeToolsOptions.Create;
1072   Result.Assign(Self);
1073   Result.Filename:=Filename;
1074 end;
1075 
1076 procedure TCodeToolsOptions.ReadGlobalDefinesTemplatesFromTree(Tree: TDefineTree);
1077 begin
1078   ClearGlobalDefineTemplates;
1079   FGlobalDefineTemplates:=
1080     Tree.ExtractTemplatesOwnedBy(Self,[],[dtfAutoGenerated]);
1081   if FGlobalDefineTemplates<>nil then begin
1082     FGlobalDefineTemplates.SetDefineOwner(Self,true);
1083   end;
1084 end;
1085 
1086 procedure TCodeToolsOptions.CreateDefaultIndentationFile;
1087 var
1088   res: TResourceStream;
1089   fs: TFileStreamUTF8;
1090 begin
1091   // indentations (laz_indentation.pas)
1092   CopySecondaryConfigFile(DefaultIndentationFilename);
1093   if not FileExistsUTF8(IndentationFilename) then
1094   begin
1095     res := TResourceStream.Create(HInstance, PChar('indentation'), PChar(RT_RCDATA));
1096     try
1097       InvalidateFileStateCache;
1098       fs := TFileStreamUTF8.Create(IndentationFilename, fmCreate);
1099       try
1100         fs.CopyFrom(res, res.Size);
1101       finally
1102         fs.Free;
1103       end;
1104     except
1105       DebugLn('WARNING: unable to write indentation file "',
1106         IndentationFilename, '"');
1107     end;
1108     res.Free;
1109   end;
1110 end;
1111 
1112 procedure TCodeToolsOptions.AssignTo(Dest: TPersistent);
1113 var
1114   Boss: TCodeToolManager absolute Dest;
1115   Beauty: TBeautifyCodeOptions absolute Dest;
1116   aFilename: String;
1117 begin
1118   if Dest is TCodeToolManager then
1119   begin
1120     // General - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1121     Boss.AdjustTopLineDueToComment:=AdjustTopLineDueToComment;
1122     Boss.JumpSingleLinePos:=JumpSingleLinePos;
1123     Boss.JumpCodeBlockPos:=JumpCodeBlockPos;
1124     Boss.CursorBeyondEOL:=CursorBeyondEOL;
1125     Boss.AddInheritedCodeToOverrideMethod:=AddInheritedCodeToOverrideMethod;
1126     Boss.CompleteProperties:=CompleteProperties;
1127 
1128     // CreateCode - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1129     AssignTo(Boss.SourceChangeCache.BeautifyCodeOptions);
1130     Boss.SetPropertyVariablename:=SetPropertyVariablename;
1131     Boss.SetPropertyVariableIsPrefix:=SetPropertyVariableIsPrefix;
1132     Boss.SetPropertyVariableUseConst:=SetPropertyVariableUseConst;
1133 
1134     // Identifier Completion - - - - - - - - - - - - - - - - - - - - - - - - - -
1135     Boss.IdentifierList.SortForHistory:=IdentComplSortForHistory;
1136     Boss.IdentifierList.SortForScope:=IdentComplSortForScope;
1137 
1138     // Code Templates- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1139     aFilename:=CodeCompletionTemplateFileName;
1140     IDEMacros.SubstituteMacros(aFilename);
1141     aFilename:=TrimFilename(aFilename);
1142     if (aFilename<>'') and not FilenameIsAbsolute(aFilename) then
1143       aFilename:=TrimFilename(AppendPathDelim(GetPrimaryConfigPath)+aFilename);
1144     Boss.CodeCompletionTemplateFileName:=aFilename;
1145   end
1146   else
1147   if Dest is TBeautifyCodeOptions then
1148   begin
1149     Beauty.LineLength:=LineLength;
1150     Beauty.ClassPartInsertPolicy:=ClassPartInsertPolicy;
1151     Beauty.MixMethodsAndProperties:=MixMethodsAndProperties;
1152     Beauty.UpdateAllMethodSignatures:=UpdateAllMethodSignatures;
1153     Beauty.ForwardProcBodyInsertPolicy:=ForwardProcBodyInsertPolicy;
1154     Beauty.KeepForwardProcOrder:=KeepForwardProcOrder;
1155     Beauty.UpdateMultiProcSignatures:=UpdateMultiProcSignatures;
1156     Beauty.UpdateOtherProcSignaturesCase:=UpdateOtherProcSignaturesCase;
1157     Beauty.GroupLocalVariables:=GroupLocalVariables;
1158     Beauty.OverrideStringTypesWithFirstParamType:=OverrideStringTypesWithFirstParamType;
1159     Beauty.ClassHeaderComments:=ClassHeaderComments;
1160     Beauty.ClassImplementationComments:=ClassImplementationComments;
1161     Beauty.MethodInsertPolicy:=MethodInsertPolicy;
1162     Beauty.MethodDefaultSection:=MethodDefaultSection;
1163     Beauty.KeyWordPolicy:=KeyWordPolicy;
1164     Beauty.IdentifierPolicy:=IdentifierPolicy;
1165     Beauty.SetupWordPolicyExceptions(WordPolicyExceptions);
1166     Beauty.DoNotSplitLineInFront:=DoNotSplitLineInFront;
1167     Beauty.DoNotSplitLineAfter:=DoNotSplitLineAfter;
1168     Beauty.DoInsertSpaceInFront:=DoInsertSpaceInFront;
1169     Beauty.DoInsertSpaceAfter:=DoInsertSpaceAfter;
1170     Beauty.PropertyReadIdentPrefix:=PropertyReadIdentPrefix;
1171     Beauty.PropertyWriteIdentPrefix:=PropertyWriteIdentPrefix;
1172     Beauty.PropertyStoredIdentPostfix:=PropertyStoredIdentPostfix;
1173     Beauty.PrivateVariablePrefix:=PrivateVariablePrefix;
1174     Beauty.UsesInsertPolicy:=UsesInsertPolicy;
1175   end
1176   else
1177     inherited AssignTo(Dest);
1178 end;
1179 
1180 procedure TCodeToolsOptions.AssignGlobalDefineTemplatesToTree(Tree: TDefineTree);
1181 begin
1182   // Define templates - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1183   // remove old custom define templates
1184   Tree.RemoveTemplatesOwnedBy(Self,[],[dtfAutoGenerated]);
1185   // merge current custom define templates
1186   if FGlobalDefineTemplates<>nil then
1187     Tree.MergeDefineTemplates(FGlobalDefineTemplates,'');
1188 end;
1189 
1190 initialization
1191   RegisterIDEOptionsGroup(GroupCodetools, TCodeToolsOptions);
1192 end.
1193 
1194