View Issue Details

IDProjectCategoryView StatusLast Update
0038081LazarusPackagespublic2020-12-07 12:30
ReporterDomingo Galmés Assigned ToJuha Manninen  
PrioritynormalSeverityminorReproducibilityhave not tried
Status closedResolutionfixed 
Summary0038081: [patch] Jedi code format improvement. Added support for Threadvar in classes and records.
DescriptionThis patch adds support for threadvars in classes and records.

I have encountered a problem formatting the whole document, JCF insert blank lines in random position when tries to synchonize the editor text with the already formatted text. The old code tries to keep the original lines that have not changed, but it is enough for JCF to insert or delete a blank line for the synchronization not to work. I have changed the code and now it replaces all the code in the editor.

I have also included another patch with a quick and dirty application to test the changes and debug JCF in case you consider it interesting to include it to facilitate future changes. It is easier to debug the changes with the application than with the IDE component. The app needs the other patch for compile.

Ps. sorry for my bad english.
Steps To Reproduce// sample unit for testing.
{ %norun }
unit terecs_u1;

{$mode delphi}

interface
type
  HWND = integer;
  TFoo = record
    hWnd : HWND;
    reg: record
      AnonimousRecord:string;
      Age:integer;
    end;
  private
    F1: Integer;
    F2: Byte;
  public
    type
      TBar = Integer;
      Name=boolean;
      TYY = record
        Name:string;
        Age:integer;
            type
              TN2=class
                Name:string;
                protected
                Age:integer;
              end;
      end;
      TYZ = record
        Name:string;
        Age:integer;
            private
            class threadvar
              hola:integer;
              dos:boolean;
              tres:integer;
            class var
              lola:integer;
              tres:integer;
              cuatro:integer;
            const
            aa:integer=2;
       procedure Uno;
           function Dos:integer;
      end;
    const
      C: TBar = 1;
    var
      F3: TBar;
      F4: Byte;
    class var
      F5: TBar;
    function Test(n: TBar): TBar;
    class function Test1(n: TBar): TBar; static;

    procedure Set3(const Value: TBar);
    class procedure Set5(const Value: TBar); static;

    property P3: TBar read F3 write Set3;
    class property P5: TBar read F5 write Set5;

    class constructor Create;
    class destructor Destroy;

    procedure Test2;
    procedure Test3;
  end;

procedure Test4(AFoo: TFoo);

implementation

type

    TMaritalState = (unmarried, married, widowed, divorced);
    TPerson = record
        // CONSTANT PART
        // of course records may be nested
        name: record
            first, middle, last: string;
        end;
        sex: (male, female);
        // date of birth
        dob: TDateTime;
        // VARIABLE PART
        case maritalState: TMaritalState of
            unmarried: ( );
            married, widowed: (marriageDate: TDateTime);
            divorced: (marriageDateDivorced, divorceDate: TDateTime;
                isFirstDivorce: boolean)
    end;


function TFoo.Test(n: TBar): TBar;
begin
  Result := F3 + F4 + n;
end;

class function TFoo.Test1(n: TBar): TBar;
begin
  Result := C + n;
end;

class constructor TFoo.Create;
begin
  F5 := 6;
end;

class destructor TFoo.Destroy;
begin
  WriteLn('TFoo.Destroy');
end;

procedure TFoo.Set3(const Value: TBar);
begin
  F3 := Value;
end;

class procedure TFoo.Set5(const Value: TBar); static;
begin
  F5 := Value;
end;

procedure TFoo.Test2;
begin
  if Self.C <> 1 then
    halt(50);
  if Self.F3 <> 7 then
    halt(51);
end;

procedure TFoo.Test3;
begin
  Test4(Self);
end;

procedure Test4(AFoo: TFoo);
begin
  if AFoo.C <> 1 then
    halt(100);
  if AFoo.P3 <> 7 then
    halt(101);
end;

end.
TagsNo tags attached.
Fixed in Revisionr64136, r64139
LazTarget-
Widgetset
Attached Files

Relationships

related to 0038178 resolvedJuha Manninen JCF set the cursor at the file beginning after each format 

Activities

Domingo Galmés

2020-11-14 15:40

reporter  

JCF_ThreadVars.patch (11,313 bytes)   
From fec6f52c6b88b26468993ecc18e7287b15be6ea7 Mon Sep 17 00:00:00 2001
From: DomingoGP <dgalmesp@gmail.com>
Date: Sat, 14 Nov 2020 14:35:03 +0100
Subject: [PATCH] support for threadvar in records and classes

---
 components/jcf2/Parse/BuildParseTree.pas      | 77 +++++++++----------
 components/jcf2/Process/Indent/Indenter.pas   |  6 +-
 .../jcf2/Process/Returns/ReturnAfter.pas      |  3 +-
 .../jcf2/Process/Returns/ReturnBefore.pas     |  4 +-
 components/jcf2/ReadWrite/Converter.pas       |  6 +-
 components/jcf2/ReadWrite/EditorConverter.pas | 25 +++++-
 6 files changed, 71 insertions(+), 50 deletions(-)

diff --git a/components/jcf2/Parse/BuildParseTree.pas b/components/jcf2/Parse/BuildParseTree.pas
index 1c248c839c..9cec7bb3ef 100644
--- a/components/jcf2/Parse/BuildParseTree.pas
+++ b/components/jcf2/Parse/BuildParseTree.pas
@@ -105,7 +105,6 @@ type
 
     procedure RecogniseTypeSection(const pbNestedInCLass: Boolean);
     procedure RecogniseVarSection(const pbClassVars: boolean);
-    procedure RecogniseClassVars;
     procedure RecogniseProcedureDeclSection;
     procedure RecogniseClassOperator(const pbHasBody: boolean);
     procedure RecogniseOperator(const pbHasBody: boolean);
@@ -775,7 +774,7 @@ begin
 
   }
   while fcTokenList.FirstSolidTokenType in [ttConst, ttResourceString,
-      ttType, ttVar, ttThreadVar, ttOpenSquareBracket, ttExports, ttOperator, ttProperty] + ProcedureWords do
+      ttType, ttVar, ttThreadVar, ttOpenSquareBracket, ttExports, ttOperator, ttProperty,ttGeneric] + ProcedureWords do
     RecogniseInterfaceDecl;
 end;
 
@@ -1035,7 +1034,7 @@ begin
     begin
       if (leFirstTokenType in ClassVisibility) then
         break;
-      if leFirstTokenType in [ttClass,ttVar,ttConst,ttFunction,ttProcedure,ttOperator,ttConstructor,ttDestructor,ttProperty] then
+      if leFirstTokenType in [ttClass,ttVar,ttThreadVar,ttConst,ttFunction,ttProcedure,ttOperator,ttConstructor,ttDestructor,ttProperty] then
         break;
     end;
 
@@ -1111,7 +1110,7 @@ begin
     begin
       if (fcTokenList.FirstSolidTokenType in ClassVisibility) then
         break;
-      if fcTokenList.FirstSolidTokenType in [ttClass,ttVar,ttConst,ttFunction,ttProcedure,ttOperator,ttConstructor,ttDestructor,ttProperty] then
+      if fcTokenList.FirstSolidTokenType in [ttClass,ttVar,ttThreadVar, ttConst,ttFunction,ttProcedure,ttOperator,ttConstructor,ttDestructor,ttProperty] then
         break;
     end;
 
@@ -2049,6 +2048,7 @@ end;
 procedure TBuildParseTree.RecogniseFieldList;
 var
   lcNextToken: TSourceToken;
+  lcVarSection:boolean;  
 begin
   // FieldList ->  FieldDecl/';'... [VariantSection] [';']
   lcNextToken := fcTokenList.FirstSolidToken;
@@ -2065,7 +2065,15 @@ begin
       ttDestructor:
         RecogniseDestructorHeading(True);
       ttClass:
+	  begin
+	    lcVarSection:=fcTokenList.SolidTokenType(2) in [ttVar,ttThreadVar];
         RecogniseRecordStaticItem;
+        if lcVarSection then
+        begin
+          lcNextToken := fcTokenList.FirstSolidToken;
+          continue;
+        end;		
+	  end;
       ttProperty:
         RecogniseProperty;
       // nested types.
@@ -2075,9 +2083,9 @@ begin
         lcNextToken := fcTokenList.FirstSolidToken;
         continue;
       end;
-      ttVar:
+      ttVar, ttThreadVar:
       begin
-        RecogniseVarSection(true);
+        RecogniseVarSection(True);
         lcNextToken := fcTokenList.FirstSolidToken;
         continue;
       end;
@@ -2150,9 +2158,11 @@ begin
       PushNode(nProperty);
       RecogniseProperty;
       PopNode;
-    end
-    else
-      RecogniseClassVars;
+    end;
+    ttVar,ttThreadVar:
+    begin
+      RecogniseVarSection(true);
+    end;
   end;
 end;
 
@@ -2304,7 +2314,7 @@ const
   END_VAR_SECTION: TTokenTypeSet =
     [ttVar, ttThreadVar, ttConst, ttLabel, ttResourceString, ttType,
     ttBegin, ttEnd, ttImplementation, ttInitialization,
-    ttProcedure, ttFunction, ttOperator, ttConstructor, ttDestructor, ttClass, ttAsm];
+    ttProcedure, ttFunction, ttOperator, ttConstructor, ttDestructor, ttClass, ttAsm, ttGeneric];
 var
   leEndVarSection: TTokenTypeSet;
 begin
@@ -2312,8 +2322,13 @@ begin
   if pbClassVars then
     leEndVarSection := leEndVarSection + ClassVisibility;
 
-
-  PushNode(nVarSection);
+  if pbClassVars and (fcTokenList.FirstSolidTokenType=ttClass) then
+  begin
+    PushNode(nClassVars);
+    Recognise(ttClass);
+  end
+  else
+    PushNode(nVarSection);
 
   // VarSection -> VAR (VarDecl ';')...
   Recognise([ttVar, ttThreadvar]);
@@ -2328,30 +2343,6 @@ begin
   PopNode;
 end;
 
-procedure TBuildParseTree.RecogniseClassVars;
-var
-  lbHasVars: Boolean;
-begin
-  PushNode(nClassVars);
-
-  Recognise(ttClass);
-  Recognise(ttVar);
-
-  // can be an empty section
-  lbHasVars := True;
-  if fcTokenList.FirstSolidTokenType in ClassVisibility + [ttEnd] then
-  begin
-    lbHasVars := False;
-  end;
-
-  if lbHasVars then
-  begin
-    RecogniseVarDecl;
-  end;
-
-  PopNode;
-end;
-
 procedure TBuildParseTree.RecogniseClassOperator(const pbHasBody: boolean);
 begin
   PushNode(nFunctionDecl);
@@ -4481,8 +4472,9 @@ end;
 procedure TBuildParseTree.RecogniseClassDeclarations(const pbInterface: boolean);
 const
   // can declare thse things in a class
-  CLASS_DECL_WORDS = [ttProcedure, ttFunction,
-    ttConstructor, ttDestructor, ttProperty, ttClass, ttConst, ttType, ttVar];
+  CLASS_DECL_WORDS = [ttProcedure, ttFunction, ttConstructor, ttDestructor,
+    ttProperty, ttClass, ttConst, ttType, ttVar, ttThreadVar];
+	
 var
   lc: TSourceToken;
   lbStarted: boolean;
@@ -4561,8 +4553,11 @@ begin
             RecogniseProcedureHeading(False, True);
           ttFunction:
             RecogniseFunctionHeading(False, True);
-          ttVar:
-            RecogniseClassVars;
+          ttVar, ttThreadVar:
+          begin
+            RecogniseVarSection(True);
+            lbHasTrailingSemicolon := False;
+          end;
           ttProperty:
           begin
             RecogniseProperty;
@@ -4599,7 +4594,7 @@ begin
         RecogniseTypeSection(true);
         lbHasTrailingSemicolon := False;
       end;
-      ttVar:
+      ttVar, ttThreadVar:
       begin
         RecogniseVarSection(True);
         lbHasTrailingSemicolon := False;
diff --git a/components/jcf2/Process/Indent/Indenter.pas b/components/jcf2/Process/Indent/Indenter.pas
index 66e11b5072..1be188d7ba 100644
--- a/components/jcf2/Process/Indent/Indenter.pas
+++ b/components/jcf2/Process/Indent/Indenter.pas
@@ -337,9 +337,9 @@ begin
     else if  pt.HasParentNode(nConstSection, 3) then
       liIndentCount := liVarConstIndent + byte(pt.TokenType<>ttConst)
     else if pt.HasParentNode(nVarSection, 4) then
-      liIndentCount := liVarConstIndent + byte(pt.TokenType<>ttVar)
-    else if  pt.HasParentNode(nClassVars, 4) then
-      liIndentCount := liVarConstIndent + byte(pt.TokenType<>ttClass)
+      liIndentCount := liVarConstIndent + byte(not (pt.TokenType in [ttVar,ttThreadVar]))
+    else if  pt.HasParentNode(nClassVars, 5) then
+	        liIndentCount := liVarConstIndent + byte(pt.TokenType<>ttClass)
 
     else if pt.TokenType = ttEnd then
     begin
diff --git a/components/jcf2/Process/Returns/ReturnAfter.pas b/components/jcf2/Process/Returns/ReturnAfter.pas
index 964cb8ad9f..f442937220 100644
--- a/components/jcf2/Process/Returns/ReturnAfter.pas
+++ b/components/jcf2/Process/Returns/ReturnAfter.pas
@@ -229,7 +229,8 @@ begin
        procedure foo;
     }
     if pt.HasParentNode([nVarSection, nConstSection]) and
-      (ptNext.TokenType in ProcedureWords) then
+      (ptNext.TokenType in ProcedureWords) and
+      (not pt.HasParentNode([nClassType,nRecordType])) then   // not in class methods
     begin
       Result := True;
       exit;
diff --git a/components/jcf2/Process/Returns/ReturnBefore.pas b/components/jcf2/Process/Returns/ReturnBefore.pas
index c7156dd076..7dc5c125d3 100644
--- a/components/jcf2/Process/Returns/ReturnBefore.pas
+++ b/components/jcf2/Process/Returns/ReturnBefore.pas
@@ -298,7 +298,7 @@ begin
 
   { procedure & function in class def get return but not blank line before }
   if (pt.TokenType in ProcedureWords + [ttProperty]) and
-    (pt.HasParentNode([nClassType])) and
+    (pt.HasParentNode([nClassType, nRecordType])) and
     (not IsGenericFunctionOrProperty(pt)) and
     (not IsClassFunctionOrProperty(pt)) then
   begin
@@ -335,7 +335,7 @@ begin
   end;
 
   { access specifiying directive (private, public et al) in a class def }
-  if pt.HasParentNode(nClassType) and IsClassDirective(pt) then
+  if pt.HasParentNode([nClassType, nRecordType]) and IsClassDirective(pt) then
   begin
     { no return before the "private" in "strict private" }
     if (pt.TokenType in [ttPrivate, ttProtected]) then
diff --git a/components/jcf2/ReadWrite/Converter.pas b/components/jcf2/ReadWrite/Converter.pas
index 2b2b39dd68..9a3c51bd33 100644
--- a/components/jcf2/ReadWrite/Converter.pas
+++ b/components/jcf2/ReadWrite/Converter.pas
@@ -66,7 +66,7 @@ type
     { false for commandline UI - don't put up a parse fail dialog
       This could be in  batch file on a server }
     fbGuiMessages: Boolean;
-
+    fbShowParseTree: Boolean;
     {$IFNDEF COMMAND_LINE}
     leOldCursor: TCursor;
     {$ENDIF}
@@ -108,6 +108,7 @@ type
 
     property OnStatusMessage: TStatusMessageProc Read GetOnStatusMessage Write SetOnStatusMessage;
     property SingleProcess: TTreeNodeVisitorType Read fcSingleProcess Write fcSingleProcess;
+    property ShowTree: boolean Read fbShowParseTree Write fbShowParseTree;	
   end;
 
 implementation
@@ -178,7 +179,8 @@ begin
         // make a parse tree from it
         fcBuildParseTree.TokenList := lcTokenList;
         fcBuildParseTree.BuildParseTree;
-
+        if fbShowParseTree then
+           ShowParseTree;
       except
         on E: Exception do
         begin
diff --git a/components/jcf2/ReadWrite/EditorConverter.pas b/components/jcf2/ReadWrite/EditorConverter.pas
index 79f49db1a6..c02dd231a1 100644
--- a/components/jcf2/ReadWrite/EditorConverter.pas
+++ b/components/jcf2/ReadWrite/EditorConverter.pas
@@ -135,6 +135,29 @@ begin
   Result := pcUnit.Lines.Text;
 end;
 
+procedure TEditorConverter.WriteToIDE(const pcUnit: TSourceEditorInterface; const psText: string);
+begin
+  if pcUnit = nil then
+    exit;
+  if psText <> fcConverter.InputCode then
+  begin
+    try
+      pcUnit.BeginUpdate;
+      pcUnit.BeginUndoBlock;
+      pcUnit.Lines.Text := psText;
+      pcUnit.Modified := True;
+    finally
+      pcUnit.EndUndoBlock;  
+      pcUnit.EndUpdate;
+    end;
+  end;
+end;
+
+//BUGGY: inserts empty blank lines in "random" position in the editor.
+// and if only one line es added or deleted after formatting then doesn't syncronize well.
+// i think is better change all text in the editor.
+// TODO: delete
+{
 procedure TEditorConverter.WriteToIDE(const pcUnit: TSourceEditorInterface; const psText: string);
 var
   lcSourceLines, lcDestLines: TStrings;
@@ -145,7 +168,6 @@ var
 begin
   if pcUnit = nil then
     exit;
-
   lcSourceLines := TStringList.Create;
   lcSourceLines.Text := fcConverter.InputCode;
   lcDestLines := TStringList.Create;
@@ -192,6 +214,7 @@ begin
     lcSameEnd.Free;
    end;
 end;
+}
 
 procedure TEditorConverter.AfterConvert;
 begin
-- 
2.29.1.windows.1

JCF_ThreadVars.patch (11,313 bytes)   
JCF_TestApplication.patch (78,266 bytes)   
From a40f994073eabb08787597bc840e8f016ab40ca2 Mon Sep 17 00:00:00 2001
From: DomingoGP <dgalmesp@gmail.com>
Date: Sat, 14 Nov 2020 15:17:15 +0100
Subject: [PATCH] Quick and dirty application for testing and debugging

---
 .../TestApplication/Lazarus/JCFSettings.cfg   |  185 +++
 .../TestApplication/Lazarus/JcfSettings.pas   |  536 +++++++
 .../jcf2/TestApplication/Lazarus/TestJCF.lpi  |  191 +++
 .../jcf2/TestApplication/Lazarus/TestJCF.lpr  |   35 +
 .../jcf2/TestApplication/Lazarus/unit1.lfm    | 1249 +++++++++++++++++
 .../jcf2/TestApplication/Lazarus/unit1.pas    |  265 ++++
 6 files changed, 2461 insertions(+)
 create mode 100644 components/jcf2/TestApplication/Lazarus/JCFSettings.cfg
 create mode 100644 components/jcf2/TestApplication/Lazarus/JcfSettings.pas
 create mode 100644 components/jcf2/TestApplication/Lazarus/TestJCF.lpi
 create mode 100644 components/jcf2/TestApplication/Lazarus/TestJCF.lpr
 create mode 100644 components/jcf2/TestApplication/Lazarus/unit1.lfm
 create mode 100644 components/jcf2/TestApplication/Lazarus/unit1.pas

diff --git a/components/jcf2/TestApplication/Lazarus/JCFSettings.cfg b/components/jcf2/TestApplication/Lazarus/JCFSettings.cfg
new file mode 100644
index 0000000000..8410bc4b64
--- /dev/null
+++ b/components/jcf2/TestApplication/Lazarus/JCFSettings.cfg
@@ -0,0 +1,185 @@
+<?xml version="1.0" ?>
+<JediCodeFormatSettings>
+    <WriteVersion> 2.44 </WriteVersion>
+    <WriteDateTime> 44142.8882100347 </WriteDateTime>
+    <Description> format settings for use with Lazarus </Description>
+    <ConfirmFormat> True </ConfirmFormat>
+  <Obfuscate>
+      <Enabled> False </Enabled>
+      <Caps> 1 </Caps>
+      <RemoveComments> True </RemoveComments>
+      <RemoveWhiteSpace> True </RemoveWhiteSpace>
+      <RemoveIndent> True </RemoveIndent>
+      <RebreakLines> True </RebreakLines>
+  </Obfuscate>
+  <Clarify>
+      <OnceOffs> 0 </OnceOffs>
+      <Warnings> True </Warnings>
+      <WarnUnusedParams> False </WarnUnusedParams>
+      <IgnoreUnusedParams> Sender </IgnoreUnusedParams>
+      <FileExtensions> dpr,lpr,pas,pp </FileExtensions>
+  </Clarify>
+  <Indent>
+      <IndentationSpaces> 2 </IndentationSpaces>
+      <FirstLevelIndent> 0 </FirstLevelIndent>
+      <HasFirstLevelIndent> False </HasFirstLevelIndent>
+      <IndentBeginEnd> False </IndentBeginEnd>
+      <IndentbeginEndSpaces> 2 </IndentbeginEndSpaces>
+      <IndentLibraryProcs> True </IndentLibraryProcs>
+      <IndentProcedureBody> False </IndentProcedureBody>
+      <KeepCommentsWithCodeInGlobals> True </KeepCommentsWithCodeInGlobals>
+      <KeepCommentsWithCodeInProcs> True </KeepCommentsWithCodeInProcs>
+      <KeepCommentsWithCodeInClassDef> True </KeepCommentsWithCodeInClassDef>
+      <KeepCommentsWithCodeElsewhere> True </KeepCommentsWithCodeElsewhere>
+      <IndentElse> False </IndentElse>
+      <IndentCaseElse> True </IndentCaseElse>
+      <IndentNestedTypes> True </IndentNestedTypes>
+      <IndentVarAndConstInClass> True </IndentVarAndConstInClass>
+  </Indent>
+  <Spaces>
+      <TabsToSpaces> True </TabsToSpaces>
+      <SpacesToTabs> False </SpacesToTabs>
+      <SpacesPerTab> 2 </SpacesPerTab>
+      <SpacesForTab> 2 </SpacesForTab>
+      <FixSpacing> True </FixSpacing>
+      <SpaceBeforeClassHeritage> False </SpaceBeforeClassHeritage>
+      <SpacesBeforeColonVar> 0 </SpacesBeforeColonVar>
+      <SpacesBeforeColonConst> 0 </SpacesBeforeColonConst>
+      <SpacesBeforeColonParam> 0 </SpacesBeforeColonParam>
+      <SpacesBeforeColonFn> 0 </SpacesBeforeColonFn>
+      <SpacesBeforeColonClassVar> 0 </SpacesBeforeColonClassVar>
+      <SpacesBeforeColonRecordField> 0 </SpacesBeforeColonRecordField>
+      <SpacesBeforeColonCaseLabel> 0 </SpacesBeforeColonCaseLabel>
+      <SpacesBeforeColonLabel> 0 </SpacesBeforeColonLabel>
+      <SpacesBeforeColonInGeneric> 0 </SpacesBeforeColonInGeneric>
+      <MaxSpacesInCode> 2 </MaxSpacesInCode>
+      <UseMaxSpacesInCode> True </UseMaxSpacesInCode>
+      <SpaceForOperator> 0 </SpaceForOperator>
+      <SpaceBeforeOpenBracketsInFunctionDeclaration> False </SpaceBeforeOpenBracketsInFunctionDeclaration>
+      <SpaceBeforeOpenBracketsInFunctionCall> False </SpaceBeforeOpenBracketsInFunctionCall>
+      <SpaceBeforeOpenSquareBracketsInExpression> False </SpaceBeforeOpenSquareBracketsInExpression>
+      <SpaceAfterOpenBrackets> False </SpaceAfterOpenBrackets>
+      <SpaceBeforeCloseBrackets> False </SpaceBeforeCloseBrackets>
+      <MoveSpaceToBeforeColon> False </MoveSpaceToBeforeColon>
+  </Spaces>
+  <Returns>
+      <WhenRebreakLines> 1 </WhenRebreakLines>
+      <MaxLineLength> 150 </MaxLineLength>
+      <NumReturnsAfterFinalEnd> 1 </NumReturnsAfterFinalEnd>
+      <RemoveBadReturns> True </RemoveBadReturns>
+      <AddGoodReturns> True </AddGoodReturns>
+      <UsesOnePerLine> False </UsesOnePerLine>
+      <BreakAfterUses> False </BreakAfterUses>
+      <RemoveExpressionReturns> True </RemoveExpressionReturns>
+      <RemoveVarReturns> True </RemoveVarReturns>
+      <NoReturnsInProperty> True </NoReturnsInProperty>
+      <RemoveProcedureDefReturns> True </RemoveProcedureDefReturns>
+      <RemoveReturns> True </RemoveReturns>
+      <RemoveVarBlankLines> True </RemoveVarBlankLines>
+      <RemoveProcHeaderBlankLines> True </RemoveProcHeaderBlankLines>
+      <Block> 1 </Block>
+      <BlockBegin> 0 </BlockBegin>
+      <Label> 1 </Label>
+      <LabelBegin> 1 </LabelBegin>
+      <CaseLabel> 1 </CaseLabel>
+      <CaseBegin> 1 </CaseBegin>
+      <CaseElse> 0 </CaseElse>
+      <CaseElseBegin> 0 </CaseElseBegin>
+      <EndElse> 0 </EndElse>
+      <ElseIf> 1 </ElseIf>
+      <ElseBegin> 0 </ElseBegin>
+      <BeforeCompilerDirectUses> 1 </BeforeCompilerDirectUses>
+      <BeforeCompilerDirectStatements> 0 </BeforeCompilerDirectStatements>
+      <BeforeCompilerDirectGeneral> 1 </BeforeCompilerDirectGeneral>
+      <AfterCompilerDirectUses> 1 </AfterCompilerDirectUses>
+      <AfterCompilerDirectStatements> 0 </AfterCompilerDirectStatements>
+      <AfterCompilerDirectGeneral> 1 </AfterCompilerDirectGeneral>
+      <ReturnChars> 0 </ReturnChars>
+      <RemoveConsecutiveBlankLines> True </RemoveConsecutiveBlankLines>
+      <MaxConsecutiveBlankLines> 4 </MaxConsecutiveBlankLines>
+      <MaxBlankLinesInSection> 1 </MaxBlankLinesInSection>
+      <LinesBeforeProcedure> 1 </LinesBeforeProcedure>
+  </Returns>
+  <Comments>
+      <RemoveEmptyDoubleSlashComments> True </RemoveEmptyDoubleSlashComments>
+      <RemoveEmptyCurlyBraceComments> True </RemoveEmptyCurlyBraceComments>
+  </Comments>
+  <Capitalisation>
+      <Enabled> True </Enabled>
+      <ReservedWords> 1 </ReservedWords>
+      <Operators> 1 </Operators>
+      <Directives> 1 </Directives>
+      <Constants> 1 </Constants>
+      <Types> 1 </Types>
+  </Capitalisation>
+  <SpecificWordCaps>
+      <Enabled> True </Enabled>
+      <Words>  </Words>
+  </SpecificWordCaps>
+  <Identifiers>
+      <Enabled> True </Enabled>
+      <Words> ActivePage,AnsiCompareStr,AnsiCompareText,AnsiUpperCase,AsBoolean,AsDateTime,AsFloat,AsInteger,Assign,AsString,AsVariant,BeginDrag,Buttons,Caption,Checked,Classes,ClassName,Clear,Close,Components,Controls,Count,Create,Data,Dec,Delete,Destroy,Dialogs,Enabled,EndDrag,EOF,Exception,Execute,False,FieldByName,First,Forms,Free,FreeAndNil,GetFirstChild,Graphics,Height,idAbort,idCancel,idIgnore,IDispatch,idNo,idOk,idRetry,idYes,Inc,Initialize,IntToStr,ItemIndex,IUnknown,Lines,Math,MaxValue,mbAbort,mbAll,mbCancel,mbHelp,mbIgnore,mbNo,mbOK,mbRetry,mbYes,mbYesToAll,Messages,MinValue,mnNoToAll,mrAbort,mrAll,mrCancel,mrIgnore,mrNo,mrNone,mrNoToAll,mrOk,mrRetry,mrYes,mrYesToAll,mtConfirmation,mtCustom,mtError,mtInformation,mtWarning,Name,Next,Open,Ord,ParamStr,PChar,Perform,ProcessMessages,Read,ReadOnly,RecordCount,Register,Release,Result,Sender,SetFocus,Show,ShowMessage,Source,StdCtrls,StrToInt,SysUtils,TAutoObject,TButton,TComponent,TDataModule,Text,TForm,TFrame,TList,TNotifyEvent,TObject,TObjectList,TPageControl,TPersistent,True,TStringList,TStrings,TTabSheet,Unassigned,Value,Visible,WideString,Width,Windows,Write </Words>
+  </Identifiers>
+  <NotIdent>
+      <Enabled> True </Enabled>
+      <Words> False,Name,nil,PChar,read,ReadOnly,True,WideString,write </Words>
+  </NotIdent>
+  <UnitNameCaps>
+      <Enabled> True </Enabled>
+      <Words> ActnColorMaps,ActnCtrls,ActnList,ActnMan,ActnMenus,ActnPopup,ActnRes,ADOConst,ADODB,ADOInt,AppEvnts,AxCtrls,BandActn,bdeconst,bdemts,Buttons,CheckLst,Classes,Clipbrd.pas,CmAdmCtl,ComCtrls,ComStrs,Consts,Controls,CtlConsts,CtlPanel,CustomizeDlg,DataBkr,DB,DBActns,dbcgrids,DBClient,DBClientActnRes,DBClientActns,DBCommon,DBConnAdmin,DBConsts,DBCtrls,DbExcept,DBGrids,DBLocal,DBLocalI,DBLogDlg,dblookup,DBOleCtl,DBPWDlg,DBTables,DBXpress,DdeMan,Dialogs,DrTable,DSIntf,ExtActns,ExtCtrls,ExtDlgs,FileCtrl,FMTBcd,Forms,Graphics,GraphUtil,Grids,HTTPIntr,IB,IBBlob,IBCustomDataSet,IBDatabase,IBDatabaseInfo,IBDCLConst,IBErrorCodes,IBEvents,IBExternals,IBExtract,IBGeneratorEditor,IBHeader,IBIntf,IBQuery,IBRestoreEditor,IBSecurityEditor,IBServiceEditor,IBSQL,IBSQLMonitor,IBStoredProc,IBTable,IBUpdateSQL,IBUtils,IBXConst,ImgList,Jcl8087,JclAbstractContainers,JclAlgorithms,JclAnsiStrings,JclAppInst,JclArrayLists,JclArraySets,JclBase,JclBinaryTrees,JclBorlandTools,JclCIL,JclCLR,JclCOM,JclComplex,JclCompression,JclConsole,JclContainerIntf,JclCounter,JclDateTime,JclDebug,JclDotNet,JclEDI,JclEDI_ANSIX12,JclEDI_ANSIX12_Ext,JclEDI_UNEDIFACT,JclEDI_UNEDIFACT_Ext,JclEDISEF,JclEDITranslators,JclEDIXML,JclExprEval,JclFileUtils,JclFont,JclGraphics,JclGraphUtils,JclHashMaps,JclHashSets,JclHookExcept,JclIniFiles,JclLANMan,JclLinkedLists,JclLocales,JclLogic,JclMapi,JclMath,JclMetadata,JclMIDI,JclMime,JclMiscel,JclMsdosSys,JclMultimedia,JclNTFS,JclPCRE,JclPeImage,JclPrint,JclQGraphics,JclQGraphUtils,JclQueues,JclRegistry,JclResources,JclRTTI,JclSchedule,JclSecurity,JclShell,JclSimpleXml,JclStacks,JclStatistics,JclStreams,JclStrHashMap,JclStringLists,JclStrings,JclStructStorage,JclSvcCtrl,JclSynch,JclSysInfo,JclSysUtils,JclTask,JclTD32,JclUnicode,JclUnitConv,JclUnitVersioning,JclUnitVersioningProviders,JclValidation,JclVectors,JclWideFormat,JclWideStrings,JclWin32,JclWin32Ex,JclWinMIDI,ListActns,Mask,MConnect,Menus,Midas,MidasCon,MidConst,MPlayer,MtsRdm,Mxconsts,ObjBrkr,OleAuto,OleConst,OleCtnrs,OleCtrls,OleDB,OleServer,Outline,Printers,Provider,recerror,ScktCnst,ScktComp,ScktMain,SConnect,ShadowWnd,SimpleDS,SMINTF,SqlConst,SqlExpr,SqlTimSt,StdActnMenus,StdActns,StdCtrls,StdStyleActnCtrls,SvcMgr,SysUtils,TabNotBk,Tabs,TConnect,Themes,ToolWin,ValEdit,VDBConsts,WinHelpViewer,XPActnCtrls,XPMan,XPStyleActnCtrls </Words>
+  </UnitNameCaps>
+  <Asm>
+      <Caps> 0 </Caps>
+      <BreaksAfterLabel> 1 </BreaksAfterLabel>
+      <BreaksAfterLabelEnabled> True </BreaksAfterLabelEnabled>
+      <StatementIndentEnabled> True </StatementIndentEnabled>
+      <StatementIndent> 7 </StatementIndent>
+      <ParamsIndentEnabled> True </ParamsIndentEnabled>
+      <ParamsIndent> 15 </ParamsIndent>
+  </Asm>
+  <PreProcessor>
+      <Enabled> False </Enabled>
+      <DefinedSymbols> MSWINDOWS </DefinedSymbols>
+      <DefinedOptions>  </DefinedOptions>
+  </PreProcessor>
+  <Align>
+      <AlignAssign> False </AlignAssign>
+      <AlignConst> False </AlignConst>
+      <AlignTypedef> False </AlignTypedef>
+      <AlignVars> False </AlignVars>
+      <AlignComment> False </AlignComment>
+      <AlignFields> False </AlignFields>
+      <InterfaceOnly> False </InterfaceOnly>
+      <MinColumn> 2 </MinColumn>
+      <MaxColumn> 60 </MaxColumn>
+      <MaxVariance> 5 </MaxVariance>
+      <MaxVarianceInterface> 5 </MaxVarianceInterface>
+      <MaxUnalignedStatements> 0 </MaxUnalignedStatements>
+  </Align>
+  <Replace>
+      <Enabled> False </Enabled>
+      <Words>  </Words>
+  </Replace>
+  <Uses>
+      <RemoveEnabled> False </RemoveEnabled>
+      <InsertInterfaceEnabled> False </InsertInterfaceEnabled>
+      <InsertImplementationEnabled> False </InsertImplementationEnabled>
+      <FindReplaceEnabled> False </FindReplaceEnabled>
+      <Remove>  </Remove>
+      <InsertInterface>  </InsertInterface>
+      <InsertImplementation>  </InsertImplementation>
+      <Find>  </Find>
+      <Replace>  </Replace>
+  </Uses>
+  <Transform>
+      <BeginEndStyle> 1 </BeginEndStyle>
+      <AddBlockEndSemicolon> True </AddBlockEndSemicolon>
+      <SortUsesInterface> False </SortUsesInterface>
+      <SortUsesImplmentation> False </SortUsesImplmentation>
+      <SortUsesProgram> False </SortUsesProgram>
+      <SortUsesBreakOnReturn> False </SortUsesBreakOnReturn>
+      <SortUsesBreakOnComment> False </SortUsesBreakOnComment>
+      <SortUsesSortOrder> 0 </SortUsesSortOrder>
+      <SortUsesNoComments> False </SortUsesNoComments>
+  </Transform>
+</JediCodeFormatSettings>
diff --git a/components/jcf2/TestApplication/Lazarus/JcfSettings.pas b/components/jcf2/TestApplication/Lazarus/JcfSettings.pas
new file mode 100644
index 0000000000..2734c8e7bf
--- /dev/null
+++ b/components/jcf2/TestApplication/Lazarus/JcfSettings.pas
@@ -0,0 +1,536 @@
+{(*}
+(*------------------------------------------------------------------------------
+ Delphi Code formatter source code 
+
+The Original Code is Settings.pas, released April 2000.
+The Initial Developer of the Original Code is Anthony Steele. 
+Portions created by Anthony Steele are Copyright (C) 1999-2008 Anthony Steele.
+All Rights Reserved. 
+Contributor(s): Anthony Steele. 
+
+The contents of this file are subject to the Mozilla Public License Version 1.1
+(the "License"). you may not use this file except in compliance with the License.
+You may obtain a copy of the License at http://www.mozilla.org/NPL/
+
+Software distributed under the License is distributed on an "AS IS" basis,
+WITHOUT WARRANTY OF ANY KIND, either express or implied.
+See the License for the specific language governing rights and limitations
+under the License.
+
+Alternatively, the contents of this file may be used under the terms of
+the GNU General Public License Version 2 or later (the "GPL") 
+See http://www.gnu.org/licenses/gpl.html
+------------------------------------------------------------------------------*)
+{*)}
+
+unit JcfSettings;
+
+{ this is the settings on how to parse. As of 2.0 this is always from a file
+  The file name is stored in registry
+  This allows centralised settings on a shared dir }
+
+{$I JcfGlobal.inc}
+
+interface
+
+uses
+  { local }
+  SetObfuscate, SetClarify,
+  SetIndent, SetSpaces, SetReturns,
+  SetComments, SetCaps, SetWordList,
+  SetAlign, SetReplace, SetUses, SetPreProcessor,
+  SettingsStream, SetTransform,  SetAsm,
+  JcfVersionConsts; //, IDEOptionsIntf;
+
+type
+
+  { TFormatSettings }
+
+  //TFormatSettings = class(TAbstractIDEEnvironmentOptions)
+  TFormatSettings = class(TObject)
+  private
+    fcObfuscate: TSetObfuscate;
+    fcClarify: TSetClarify;
+    fcSpaces: TSetSpaces;
+    fcIndent: TSetIndent;
+    fcReturns: TSetReturns;
+    fcComments: TSetComments;
+ 
+    fcCaps: TSetCaps;
+    fcSpecificWordCaps: TSetWordList;
+    fcIdentifierCaps: TSetWordList;
+    fcNotIdentifierCaps: TSetWordList;
+    fcUnitNameCaps: TSetWordList;
+
+    fcSetAsm: TSetAsm;
+
+    fcPreProcessor: TSetPreProcessor;
+    fcAlign: TSetAlign;
+    fcUses: TSetUses;
+
+    fcReplace: TSetReplace;
+
+    fcTransform: TSetTransform;
+
+    fbWriteOnExit: boolean;
+    fbHasRead: boolean;
+    fbDirty: boolean;
+
+    fsDescription: string;
+    fdtWriteDateTime: TDateTime;
+    fsWriteVersion: string;
+
+    procedure FromStream(const pcStream: TSettingsInput);
+  public
+    constructor Create(const pbReadRegFile: boolean);
+    destructor Destroy; override;
+    //class function GetGroupCaption: String; override;
+    //class function GetInstance: TAbstractIDEOptions; override;
+    //procedure DoAfterWrite({%H-}Restore: boolean); override;
+
+    procedure Read;
+    procedure ReadFromFile(const psFileName: string; const pbMustExist: boolean);
+    procedure ReadDefaults;
+    procedure Write;
+
+    procedure MakeConsistent;
+
+    procedure ToStream(const pcStream: TSettingsOutput);
+
+    property Description: string Read fsDescription Write fsDescription;
+    property WriteDateTime: TDateTime Read fdtWriteDateTime Write fdtWriteDateTime;
+    property WriteVersion: string Read fsWriteVersion Write fsWriteVersion;
+
+    property Obfuscate: TSetObfuscate Read fcObfuscate;
+    property Clarify: TSetClarify Read fcClarify;
+    property Indent: TSetIndent Read fcIndent;
+    property Spaces: TSetSpaces Read fcSpaces;
+    property Returns: TSetReturns Read fcReturns;
+    property Comments: TSetComments Read fcComments;
+
+    property Caps: TSetCaps Read fcCaps;
+    property SpecificWordCaps: TSetWordList Read fcSpecificWordCaps;
+    property IdentifierCaps: TSetWordList Read fcIdentifierCaps;
+    property NotIdentifierCaps: TSetWordList Read fcNotIdentifierCaps;
+    property UnitNameCaps: TSetWordList Read fcUnitNameCaps;
+    property SetAsm: TSetAsm Read fcSetAsm;
+
+    property PreProcessor: TSetPreProcessor Read fcPreProcessor;
+
+
+    property Align: TSetAlign Read fcAlign;
+    property Replace: TSetReplace Read fcReplace;
+    property UsesClause: TSetUses Read fcUses;
+
+    property Transform: TSetTransform read fcTransform;
+ 
+    property WriteOnExit: boolean Read fbWriteOnExit Write fbWriteOnExit;
+    property Dirty: boolean Read fbDirty Write fbDirty;
+    property HasRead: boolean read fbHasRead write fbHasRead;
+  end;
+
+function FormattingSettings: TFormatSettings;
+
+// create from a settings file
+function FormatSettingsFromFile(const psFileName: string): TFormatSettings;
+
+var
+  JCFOptionsGroup: Integer;
+const
+  JCFOptionFormatFile = 1;
+  JCFOptionObfuscate = 2;
+  JCFOptionClarify = 3;
+  JCFOptionSpaces = 4;
+  JCFOptionIndentation = 5;
+  JCFOptionBlankLines = 6;
+  JCFOptionAlign = 7;
+  JCFOptionLongLines = 8;
+  JCFOptionReturns = 9;
+  JCFOptionCaseBlocks = 10;
+  JCFOptionBlocks = 11;
+  JCFOptionCompilerDirectives = 12;
+  JCFOptionComments = 13;
+  JCFOptionWarnings = 14;
+  JCFOptionObjectPascal = 15;
+  JCFOptionAnyWord = 16;
+  JCFOptionIdentifiers = 17;
+  JCFOptionNotIdentifiers = 18;
+  JCFOptionUnitName = 19;
+  JCFOptionFindAndReplace = 20;
+  JCFOptionUses = 21;
+  JCFOptionBasic = 22;
+  JCFOptionTransform = 23;
+  JCFOptionAsm = 24;
+  JCFOptionPreProcessor = 25;
+
+const
+  GUI_PAD = 3;
+
+implementation
+
+uses
+  { delphi }
+  {$IFNDEF FPC}Windows,{$ELSE}LazFileUtils, LazUTF8,{$ENDIF} SysUtils, Dialogs,
+  { local }
+  JcfStringUtils,
+  JcfSetBase,
+  JcfRegistrySettings,
+  jcfuiconsts in '../../IdePlugin/lazarus/jcfuiconsts.pas';
+
+
+constructor TFormatSettings.Create(const pbReadRegFile: boolean);
+begin
+  inherited Create();
+
+  fcObfuscate := TSetObfuscate.Create;
+  fcClarify   := TSetClarify.Create;
+  fcIndent    := TSetIndent.Create;
+  fcSpaces    := TSetSpaces.Create;
+  fcReturns   := TSetReturns.Create;
+
+  fcComments := TSetComments.Create;
+
+  fcCaps := TSetCaps.Create;
+  fcSpecificWordCaps := TSetWordList.Create('SpecificWordCaps');
+  fcIdentifierCaps := TSetWordList.Create('Identifiers');
+  fcNotIdentifierCaps := TSetWordList.Create('NotIdent');
+  fcUnitNameCaps := TSetWordList.Create('UnitNameCaps');
+
+  fcSetAsm := TSetAsm.Create();
+
+  fcPreProcessor := TSetPreProcessor.Create;
+
+  fcAlign   := TSetAlign.Create;
+  fcReplace := TSetReplace.Create;
+  fcUses    := TSetUses.Create;
+  fcTransform := TSetTransform.Create;
+
+  if pbReadRegFile then
+  begin
+    Read;
+  end;
+
+  fbWriteOnExit := True;
+  fbDirty := False;
+end;
+
+destructor TFormatSettings.Destroy;
+begin
+  if WriteOnExit then
+    Write;
+
+  FreeAndNil(fcObfuscate);
+  FreeAndNil(fcClarify);
+  FreeAndNil(fcIndent);
+  FreeAndNil(fcSpaces);
+  FreeAndNil(fcReturns);
+  FreeAndNil(fcComments);
+
+  FreeAndNil(fcCaps);
+  FreeAndNil(fcSpecificWordCaps);
+  FreeAndNil(fcIdentifierCaps);
+  FreeAndNil(fcNotIdentifierCaps);
+  FreeAndNil(fcUnitNameCaps);
+  FreeAndNil(fcSetAsm);
+
+  FreeAndNil(fcPreProcessor);
+
+  FreeAndNil(fcReplace);
+  FreeAndNil(fcAlign);
+  FreeAndNil(fcUses);
+  FreeAndNil(fcTransform);
+  
+  inherited;
+end;
+
+//class function TFormatSettings.GetGroupCaption: String;
+//begin
+//  Result := lisJCFFormatSettings;
+//end;
+//
+//class function TFormatSettings.GetInstance: TAbstractIDEOptions;
+//begin
+//  Result := FormatSettings;
+//end;
+//
+//procedure TFormatSettings.DoAfterWrite(Restore: boolean);
+//begin
+//  { settings are now in need of saving }
+//  Dirty := True;
+//  { check consistency of settings }
+//  MakeConsistent;
+//  { save to file }
+//  Write;
+//end;
+
+const
+  CODEFORMAT_SETTINGS_SECTION = 'JediCodeFormatSettings';
+
+  REG_VERSION     = 'WriteVersion';
+  REG_WRITE_DATETIME = 'WriteDateTime';
+  REG_DESCRIPTION = 'Description';
+
+procedure TFormatSettings.Read;
+var
+  lcReg: TJCFRegistrySettings;
+begin
+  // use the Settings File if it exists
+  lcReg := GetRegSettings;
+  ReadFromFile(lcReg.FormatConfigFileName, lcReg.FormatConfigNameSpecified);
+end;
+
+procedure TFormatSettings.ReadFromFile(const psFileName: string; const pbMustExist: boolean);
+var
+  lsText: string;
+  lcFile: TSettingsInputString;
+begin
+  if {$ifdef FPC}FileExistsUTF8(psFileName){$else}FileExists(psFileName){$endif} then
+  begin
+    // debug ShowMessage('Reading settings from file ' + lsSettingsFileName);
+
+    // now we know the file exists - try get settings from it
+    {$ifdef FPC}
+    lsText := string(FileToString(UTF8ToSys(psFileName)));
+    {$else}
+    lsText := string(FileToString(psFileName));
+    {$endif}
+    lcFile := TSettingsInputString.Create(lsText);
+    try
+      FromStream(lcFile);
+    finally
+      lcFile.Free;
+    end;
+  end
+  else
+  begin
+    if pbMustExist then
+    begin
+      //MessageDlg(Format(lisTheSettingsFileDoesNotExist, [psFileName, NativeLineBreak]), mtError, [mbOK], 0);
+      writeln(Format(lisTheSettingsFileDoesNotExist, [psFileName, NativeLineBreak]));
+    end;
+  end;
+end;
+
+
+procedure TFormatSettings.ReadDefaults;
+var
+  lcSetDummy: TSettingsInputDummy;
+begin
+  lcSetDummy := TSettingsInputDummy.Create;
+  try
+    FromStream(lcSetDummy);
+  finally
+    lcSetDummy.Free;
+  end;
+end;
+
+procedure TFormatSettings.Write;
+var
+  lcReg: TJCFRegistrySettings;
+  lcFile: TSettingsStreamOutput;
+begin
+   if not Dirty then
+    exit;
+
+  { user may have specified no-write }
+  lcReg := GetRegSettings;
+  if lcReg.FormatFileWriteOption = eNeverWrite then
+    exit;
+
+  if lcReg.FormatConfigFileName = '' then
+    exit;
+
+  {$ifdef FPC}
+  if FileExistsUTF8(lcReg.FormatConfigFileName) and FileIsReadOnlyUTF8(lcReg.FormatConfigFileName) then
+  {$else}
+  if FileExists(lcReg.FormatConfigFileName) and FileIsReadOnly(lcReg.FormatConfigFileName) then
+  {$endif}
+  begin
+    { fail quietly? }
+    if lcReg.FormatFileWriteOption = eAlwaysWrite then
+      //MessageDlg(Format(lisErrorWritingSettingsFileReadOnly, [lcReg.FormatConfigFileName]), mtError, [mbOK], 0);
+    writeln(Format(lisErrorWritingSettingsFileReadOnly, [lcReg.FormatConfigFileName]));
+    exit;
+  end;
+
+  try
+    // use the Settings file name
+    {$ifdef FPC}
+    lcFile := TSettingsStreamOutput.Create(UTF8ToSys(GetRegSettings.FormatConfigFileName));
+    {$else}
+    lcFile := TSettingsStreamOutput.Create(GetRegSettings.FormatConfigFileName);
+    {$endif}
+    try
+      ToStream(lcFile);
+
+      // not dirty any more
+      fbDirty := False;
+    finally
+      lcFile.Free;
+    end;
+  except
+    on e: Exception do
+    begin
+      if lcReg.FormatFileWriteOption = eAlwaysWrite then
+      begin
+        //MessageDlg(Format(lisErrorWritingSettingsException, [GetRegSettings.FormatConfigFileName, NativeLineBreak, E.Message]), mtError, [mbOK], 0);
+        writeln(Format(lisErrorWritingSettingsException, [GetRegSettings.FormatConfigFileName, NativeLineBreak, E.Message]));
+      end;
+    end;
+  end;
+end;
+
+
+procedure TFormatSettings.ToStream(const pcStream: TSettingsOutput);
+
+  procedure WriteToStream(const pcSet: TSetBase);
+  begin
+    Assert(pcSet <> nil);
+    pcStream.OpenSection(pcSet.Section);
+    pcSet.WriteToStream(pcStream);
+    pcStream.CloseSection(pcSet.Section);
+  end;
+
+begin
+  Assert(pcStream <> nil);
+  pcStream.WriteXMLHeader;
+
+  pcStream.OpenSection(CODEFORMAT_SETTINGS_SECTION);
+
+  pcStream.Write(REG_VERSION, PROGRAM_VERSION);
+  pcStream.Write(REG_WRITE_DATETIME, Now);
+  pcStream.Write(REG_DESCRIPTION, Description);
+
+  WriteToStream(fcObfuscate);
+  WriteToStream(fcClarify);
+  WriteToStream(fcIndent);
+  WriteToStream(fcSpaces);
+  WriteToStream(fcReturns);
+  WriteToStream(fcComments);
+
+  WriteToStream(fcCaps);
+  WriteToStream(fcSpecificWordCaps);
+  WriteToStream(fcIdentifierCaps);
+  WriteToStream(fcNotIdentifierCaps);
+  WriteToStream(fcUnitNameCaps);
+  WriteToStream(fcSetAsm);
+
+  WriteToStream(fcPreProcessor);
+  WriteToStream(fcAlign);
+  WriteToStream(fcReplace);
+  WriteToStream(fcUses);
+  WriteToStream(fcTransform);
+
+  pcStream.CloseSection(CODEFORMAT_SETTINGS_SECTION);
+end;
+
+procedure TFormatSettings.FromStream(const pcStream: TSettingsInput);
+var
+  lcAllSettings: TSettingsInput;
+
+  procedure ReadFromStream(const pcSet: TSetBase);
+  var
+    lcSection: TSettingsInput;
+  begin
+    Assert(pcSet <> nil);
+
+    lcSection := lcAllSettings.ExtractSection(pcSet.Section);
+    if lcSection <> nil then
+    begin
+      pcSet.ReadFromStream(lcSection);
+      lcSection.Free;
+    end
+    else
+    begin
+      lcSection :=  TSettingsInputDummy.Create;
+      try
+        pcSet.ReadFromStream(lcSection);
+      finally
+        lcSection.Free;
+      end;
+      //ShowMessage('Skipping section ' + pcSet.Section + ' as it was not found');
+    end;
+  end;
+
+begin
+
+  { basic test - we are only interested in the
+    <JediCodeFormaTFormatSettings> ... </JediCodeFormaTFormatSettings> part of the file
+    If this start & end is not present, then is is the wrong file }
+  lcAllSettings := pcStream.ExtractSection(CODEFORMAT_SETTINGS_SECTION);
+  if lcAllSettings = nil then
+  begin
+    //ShowMessage(lisNoSettingsFound);
+    writeln(lisNoSettingsFound);
+    exit;
+  end;
+
+  try
+    fsWriteVersion   := pcStream.Read(REG_VERSION, '');
+    fsDescription    := pcStream.Read(REG_DESCRIPTION, '');
+    fdtWriteDateTime := pcStream.Read(REG_WRITE_DATETIME, 0.0);
+
+    ReadFromStream(fcObfuscate);
+    ReadFromStream(fcClarify);
+    ReadFromStream(fcIndent);
+    ReadFromStream(fcSpaces);
+    ReadFromStream(fcReturns);
+    ReadFromStream(fcComments);
+    ReadFromStream(fcCaps);
+    ReadFromStream(fcSpecificWordCaps);
+    ReadFromStream(fcIdentifierCaps);
+    ReadFromStream(fcNotIdentifierCaps);
+    ReadFromStream(fcUnitNameCaps);
+    ReadFromStream(fcSetAsm);
+
+    ReadFromStream(fcPreProcessor);
+
+    ReadFromStream(fcAlign);
+    ReadFromStream(fcReplace);
+    ReadFromStream(fcUses);
+    ReadFromStream(fcTransform);
+
+    fbHasRead := True;
+  finally
+    lcAllSettings.Free;
+  end;
+end;
+
+
+var
+  // a module var
+  mcFormatSettings: TFormatSettings = nil;
+
+function FormattingSettings: TFormatSettings;
+begin
+  if mcFormatSettings = nil then
+    mcFormatSettings := TFormatSettings.Create(true);
+
+  Result := mcFormatSettings;
+end;
+
+function FormatSettingsFromFile(const psFileName: string): TFormatSettings;
+begin
+  if mcFormatSettings = nil then
+    mcFormatSettings := TFormatSettings.Create(false);
+
+  mcFormatSettings.ReadFromFile(psFileName, true);
+  Result := mcFormatSettings;
+end;
+
+
+procedure TFormatSettings.MakeConsistent;
+begin
+  { one consistency check so far
+    - if linebreaking is off, then "remove returns in expressions" must also be off }
+
+  if Returns.RebreakLines = rbOff then
+    Returns.RemoveExpressionReturns := False;
+end;
+
+initialization
+  //JCFOptionsGroup := GetFreeIDEOptionsGroupIndex(GroupEditor);
+  //RegisterIDEOptionsGroup(JCFOptionsGroup, TFormatSettings);
+finalization
+  FreeAndNil(mcFormatSettings);
+end.
diff --git a/components/jcf2/TestApplication/Lazarus/TestJCF.lpi b/components/jcf2/TestApplication/Lazarus/TestJCF.lpi
new file mode 100644
index 0000000000..2454014ae6
--- /dev/null
+++ b/components/jcf2/TestApplication/Lazarus/TestJCF.lpi
@@ -0,0 +1,191 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<CONFIG>
+  <ProjectOptions>
+    <Version Value="12"/>
+    <PathDelim Value="\"/>
+    <General>
+      <Flags>
+        <CompatibilityMode Value="True"/>
+      </Flags>
+      <SessionStorage Value="InProjectDir"/>
+      <Title Value="TestJCF"/>
+      <Scaled Value="True"/>
+      <ResourceType Value="res"/>
+      <UseXPManifest Value="True"/>
+      <XPManifest>
+        <DpiAware Value="True"/>
+      </XPManifest>
+    </General>
+    <BuildModes Count="1">
+      <Item1 Name="Default" Default="True"/>
+    </BuildModes>
+    <PublishOptions>
+      <Version Value="2"/>
+      <UseFileFilters Value="True"/>
+    </PublishOptions>
+    <RunParams>
+      <FormatVersion Value="2"/>
+    </RunParams>
+    <RequiredPackages Count="2">
+      <Item1>
+        <PackageName Value="SynEdit"/>
+      </Item1>
+      <Item2>
+        <PackageName Value="LCL"/>
+      </Item2>
+    </RequiredPackages>
+    <Units Count="28">
+      <Unit0>
+        <Filename Value="TestJCF.lpr"/>
+        <IsPartOfProject Value="True"/>
+      </Unit0>
+      <Unit1>
+        <Filename Value="unit1.pas"/>
+        <IsPartOfProject Value="True"/>
+        <ComponentName Value="Form1"/>
+        <HasResources Value="True"/>
+        <ResourceBaseClass Value="Form"/>
+        <UnitName Value="Unit1"/>
+      </Unit1>
+      <Unit2>
+        <Filename Value="..\..\Parse\BuildParseTree.pas"/>
+        <IsPartOfProject Value="True"/>
+      </Unit2>
+      <Unit3>
+        <Filename Value="..\..\Parse\AsmKeywords.pas"/>
+        <IsPartOfProject Value="True"/>
+      </Unit3>
+      <Unit4>
+        <Filename Value="..\..\Parse\BuildTokenList.pas"/>
+        <IsPartOfProject Value="True"/>
+      </Unit4>
+      <Unit5>
+        <Filename Value="..\..\Parse\ParseError.pas"/>
+        <IsPartOfProject Value="True"/>
+      </Unit5>
+      <Unit6>
+        <Filename Value="..\..\Parse\ParseTreeNode.pas"/>
+        <IsPartOfProject Value="True"/>
+      </Unit6>
+      <Unit7>
+        <Filename Value="..\..\Parse\ParseTreeNodeType.pas"/>
+        <IsPartOfProject Value="True"/>
+      </Unit7>
+      <Unit8>
+        <Filename Value="..\..\Parse\SourceToken.pas"/>
+        <IsPartOfProject Value="True"/>
+      </Unit8>
+      <Unit9>
+        <Filename Value="..\..\Parse\SourceTokenList.pas"/>
+        <IsPartOfProject Value="True"/>
+      </Unit9>
+      <Unit10>
+        <Filename Value="..\..\Parse\Tokens.pas"/>
+        <IsPartOfProject Value="True"/>
+      </Unit10>
+      <Unit11>
+        <Filename Value="..\..\Parse\TokenUtils.pas"/>
+        <IsPartOfProject Value="True"/>
+      </Unit11>
+      <Unit12>
+        <Filename Value="..\..\Settings\SettingsTypes.pas"/>
+        <IsPartOfProject Value="True"/>
+      </Unit12>
+      <Unit13>
+        <Filename Value="..\..\Process\FormatFlags.pas"/>
+        <IsPartOfProject Value="True"/>
+      </Unit13>
+      <Unit14>
+        <Filename Value="..\..\Process\Returns\ReturnBefore.pas"/>
+        <IsPartOfProject Value="True"/>
+      </Unit14>
+      <Unit15>
+        <Filename Value="..\..\Process\Spacing\MoveSpaceToBeforeColon.pas"/>
+        <IsPartOfProject Value="True"/>
+      </Unit15>
+      <Unit16>
+        <Filename Value="..\..\ReadWrite\Converter.pas"/>
+        <IsPartOfProject Value="True"/>
+      </Unit16>
+      <Unit17>
+        <Filename Value="..\..\Process\Indent\Indenter.pas"/>
+        <IsPartOfProject Value="True"/>
+      </Unit17>
+      <Unit18>
+        <Filename Value="..\..\Process\Obfuscate\FixCase.pas"/>
+        <IsPartOfProject Value="True"/>
+      </Unit18>
+      <Unit19>
+        <Filename Value="..\..\Process\Transform\UsesClauseInsert.pas"/>
+        <IsPartOfProject Value="True"/>
+      </Unit19>
+      <Unit20>
+        <Filename Value="..\..\Process\Warnings\Warning.pas"/>
+        <IsPartOfProject Value="True"/>
+      </Unit20>
+      <Unit21>
+        <Filename Value="..\..\Process\Capitalisation\UnitNameCaps.pas"/>
+        <IsPartOfProject Value="True"/>
+      </Unit21>
+      <Unit22>
+        <Filename Value="..\..\Process\Info\BasicStats.pas"/>
+        <IsPartOfProject Value="True"/>
+      </Unit22>
+      <Unit23>
+        <Filename Value="..\..\Process\Align\AlignBase.pas"/>
+        <IsPartOfProject Value="True"/>
+      </Unit23>
+      <Unit24>
+        <Filename Value="..\..\Parse\UI\fShowParseTree.pas"/>
+        <IsPartOfProject Value="True"/>
+        <ComponentName Value="frmShowParseTree"/>
+        <HasResources Value="True"/>
+        <ResourceBaseClass Value="Form"/>
+      </Unit24>
+      <Unit25>
+        <Filename Value="..\..\Parse\PreProcessor\PreProcessorParseTree.pas"/>
+        <IsPartOfProject Value="True"/>
+      </Unit25>
+      <Unit26>
+        <Filename Value="JcfSettings.pas"/>
+        <IsPartOfProject Value="True"/>
+      </Unit26>
+      <Unit27>
+        <Filename Value="..\..\Include\JcfGlobal.inc"/>
+        <IsPartOfProject Value="True"/>
+      </Unit27>
+    </Units>
+  </ProjectOptions>
+  <CompilerOptions>
+    <Version Value="11"/>
+    <PathDelim Value="\"/>
+    <Target>
+      <Filename Value="TestJCF"/>
+    </Target>
+    <SearchPaths>
+      <IncludeFiles Value="$(ProjOutDir);..\..\include"/>
+      <OtherUnitFiles Value="..\..\Parse;..\..\Utils;..\..\Settings;..\..\Process;..\..\Process\Returns;..\..\Process\Spacing;..\..\ReadWrite;..\..\Process\Indent;..\..\Process\Obfuscate;..\..\Process\Transform;..\..\Process\Warnings;..\..\Process\Capitalisation;..\..\Process\Info;..\..\Process\Align;..\..\Parse\UI;..\..\Parse\PreProcessor"/>
+      <UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/>
+    </SearchPaths>
+    <Linking>
+      <Options>
+        <Win32>
+          <GraphicApplication Value="True"/>
+        </Win32>
+      </Options>
+    </Linking>
+  </CompilerOptions>
+  <Debugging>
+    <Exceptions Count="3">
+      <Item1>
+        <Name Value="EAbort"/>
+      </Item1>
+      <Item2>
+        <Name Value="ECodetoolError"/>
+      </Item2>
+      <Item3>
+        <Name Value="EFOpenError"/>
+      </Item3>
+    </Exceptions>
+  </Debugging>
+</CONFIG>
diff --git a/components/jcf2/TestApplication/Lazarus/TestJCF.lpr b/components/jcf2/TestApplication/Lazarus/TestJCF.lpr
new file mode 100644
index 0000000000..336327704e
--- /dev/null
+++ b/components/jcf2/TestApplication/Lazarus/TestJCF.lpr
@@ -0,0 +1,35 @@
+program TestJCF;
+
+{$mode objfpc}{$H+}
+
+uses {$IFDEF UNIX}
+  cthreads, {$ENDIF} {$IFDEF HASAMIGA}
+  athreads, {$ENDIF}
+  Interfaces, // this includes the LCL widgetset
+  Forms,
+  unit1,
+  BuildParseTree,
+  fShowParseTree,
+  Converter,
+  ReturnBefore,
+  MoveSpaceToBeforeColon,
+  Indenter,//  { you can add units after this };
+ {$IFDEF UNIX} {$IFDEF UseCThreads}
+  cthreads, {$ENDIF} {$ENDIF}
+  //Interfaces, // this includes the LCL widgetset
+  //Forms,
+  //  CustApp,
+  SysUtils;
+
+//FileCtrl,
+
+{$R *.res}
+
+begin
+  RequireDerivedFormResource := True;
+  Application.Scaled := True;
+  Application.Initialize;
+  Application.CreateForm(TForm1, Form1);
+  Application.Run;
+end.
+
diff --git a/components/jcf2/TestApplication/Lazarus/unit1.lfm b/components/jcf2/TestApplication/Lazarus/unit1.lfm
new file mode 100644
index 0000000000..6856ef7a07
--- /dev/null
+++ b/components/jcf2/TestApplication/Lazarus/unit1.lfm
@@ -0,0 +1,1249 @@
+object Form1: TForm1
+  Left = 261
+  Height = 594
+  Top = 158
+  Width = 1301
+  Caption = 'JCF'
+  ClientHeight = 594
+  ClientWidth = 1301
+  LCLVersion = '2.1.0.0'
+  object Button1: TButton
+    Left = 616
+    Height = 25
+    Top = 64
+    Width = 75
+    Caption = 'Format'
+    OnClick = Button1Click
+    TabOrder = 0
+  end
+  object Memo3: TMemo
+    Left = 11
+    Height = 90
+    Top = 491
+    Width = 1277
+    Anchors = [akLeft, akRight, akBottom]
+    Lines.Strings = (
+      ''
+    )
+    TabOrder = 1
+  end
+  inline Memo1: TSynEdit
+    Left = 16
+    Height = 424
+    Top = 32
+    Width = 592
+    Anchors = [akTop, akLeft, akBottom]
+    Font.Height = -13
+    Font.Name = 'Courier New'
+    Font.Pitch = fpFixed
+    Font.Quality = fqNonAntialiased
+    ParentColor = False
+    ParentFont = False
+    PopupMenu = PopupMenu1
+    TabOrder = 2
+    Gutter.Width = 57
+    Gutter.MouseActions = <>
+    RightGutter.Width = 0
+    RightGutter.MouseActions = <>
+    Highlighter = SynPasSyn1
+    Keystrokes = <    
+      item
+        Command = ecUp
+        ShortCut = 38
+      end    
+      item
+        Command = ecSelUp
+        ShortCut = 8230
+      end    
+      item
+        Command = ecScrollUp
+        ShortCut = 16422
+      end    
+      item
+        Command = ecDown
+        ShortCut = 40
+      end    
+      item
+        Command = ecSelDown
+        ShortCut = 8232
+      end    
+      item
+        Command = ecScrollDown
+        ShortCut = 16424
+      end    
+      item
+        Command = ecLeft
+        ShortCut = 37
+      end    
+      item
+        Command = ecSelLeft
+        ShortCut = 8229
+      end    
+      item
+        Command = ecWordLeft
+        ShortCut = 16421
+      end    
+      item
+        Command = ecSelWordLeft
+        ShortCut = 24613
+      end    
+      item
+        Command = ecRight
+        ShortCut = 39
+      end    
+      item
+        Command = ecSelRight
+        ShortCut = 8231
+      end    
+      item
+        Command = ecWordRight
+        ShortCut = 16423
+      end    
+      item
+        Command = ecSelWordRight
+        ShortCut = 24615
+      end    
+      item
+        Command = ecPageDown
+        ShortCut = 34
+      end    
+      item
+        Command = ecSelPageDown
+        ShortCut = 8226
+      end    
+      item
+        Command = ecPageBottom
+        ShortCut = 16418
+      end    
+      item
+        Command = ecSelPageBottom
+        ShortCut = 24610
+      end    
+      item
+        Command = ecPageUp
+        ShortCut = 33
+      end    
+      item
+        Command = ecSelPageUp
+        ShortCut = 8225
+      end    
+      item
+        Command = ecPageTop
+        ShortCut = 16417
+      end    
+      item
+        Command = ecSelPageTop
+        ShortCut = 24609
+      end    
+      item
+        Command = ecLineStart
+        ShortCut = 36
+      end    
+      item
+        Command = ecSelLineStart
+        ShortCut = 8228
+      end    
+      item
+        Command = ecEditorTop
+        ShortCut = 16420
+      end    
+      item
+        Command = ecSelEditorTop
+        ShortCut = 24612
+      end    
+      item
+        Command = ecLineEnd
+        ShortCut = 35
+      end    
+      item
+        Command = ecSelLineEnd
+        ShortCut = 8227
+      end    
+      item
+        Command = ecEditorBottom
+        ShortCut = 16419
+      end    
+      item
+        Command = ecSelEditorBottom
+        ShortCut = 24611
+      end    
+      item
+        Command = ecToggleMode
+        ShortCut = 45
+      end    
+      item
+        Command = ecCopy
+        ShortCut = 16429
+      end    
+      item
+        Command = ecPaste
+        ShortCut = 8237
+      end    
+      item
+        Command = ecDeleteChar
+        ShortCut = 46
+      end    
+      item
+        Command = ecCut
+        ShortCut = 8238
+      end    
+      item
+        Command = ecDeleteLastChar
+        ShortCut = 8
+      end    
+      item
+        Command = ecDeleteLastChar
+        ShortCut = 8200
+      end    
+      item
+        Command = ecDeleteLastWord
+        ShortCut = 16392
+      end    
+      item
+        Command = ecUndo
+        ShortCut = 32776
+      end    
+      item
+        Command = ecRedo
+        ShortCut = 40968
+      end    
+      item
+        Command = ecLineBreak
+        ShortCut = 13
+      end    
+      item
+        Command = ecSelectAll
+        ShortCut = 16449
+      end    
+      item
+        Command = ecCopy
+        ShortCut = 16451
+      end    
+      item
+        Command = ecBlockIndent
+        ShortCut = 24649
+      end    
+      item
+        Command = ecLineBreak
+        ShortCut = 16461
+      end    
+      item
+        Command = ecInsertLine
+        ShortCut = 16462
+      end    
+      item
+        Command = ecDeleteWord
+        ShortCut = 16468
+      end    
+      item
+        Command = ecBlockUnindent
+        ShortCut = 24661
+      end    
+      item
+        Command = ecPaste
+        ShortCut = 16470
+      end    
+      item
+        Command = ecCut
+        ShortCut = 16472
+      end    
+      item
+        Command = ecDeleteLine
+        ShortCut = 16473
+      end    
+      item
+        Command = ecDeleteEOL
+        ShortCut = 24665
+      end    
+      item
+        Command = ecUndo
+        ShortCut = 16474
+      end    
+      item
+        Command = ecRedo
+        ShortCut = 24666
+      end    
+      item
+        Command = ecGotoMarker0
+        ShortCut = 16432
+      end    
+      item
+        Command = ecGotoMarker1
+        ShortCut = 16433
+      end    
+      item
+        Command = ecGotoMarker2
+        ShortCut = 16434
+      end    
+      item
+        Command = ecGotoMarker3
+        ShortCut = 16435
+      end    
+      item
+        Command = ecGotoMarker4
+        ShortCut = 16436
+      end    
+      item
+        Command = ecGotoMarker5
+        ShortCut = 16437
+      end    
+      item
+        Command = ecGotoMarker6
+        ShortCut = 16438
+      end    
+      item
+        Command = ecGotoMarker7
+        ShortCut = 16439
+      end    
+      item
+        Command = ecGotoMarker8
+        ShortCut = 16440
+      end    
+      item
+        Command = ecGotoMarker9
+        ShortCut = 16441
+      end    
+      item
+        Command = ecSetMarker0
+        ShortCut = 24624
+      end    
+      item
+        Command = ecSetMarker1
+        ShortCut = 24625
+      end    
+      item
+        Command = ecSetMarker2
+        ShortCut = 24626
+      end    
+      item
+        Command = ecSetMarker3
+        ShortCut = 24627
+      end    
+      item
+        Command = ecSetMarker4
+        ShortCut = 24628
+      end    
+      item
+        Command = ecSetMarker5
+        ShortCut = 24629
+      end    
+      item
+        Command = ecSetMarker6
+        ShortCut = 24630
+      end    
+      item
+        Command = ecSetMarker7
+        ShortCut = 24631
+      end    
+      item
+        Command = ecSetMarker8
+        ShortCut = 24632
+      end    
+      item
+        Command = ecSetMarker9
+        ShortCut = 24633
+      end    
+      item
+        Command = EcFoldLevel1
+        ShortCut = 41009
+      end    
+      item
+        Command = EcFoldLevel2
+        ShortCut = 41010
+      end    
+      item
+        Command = EcFoldLevel3
+        ShortCut = 41011
+      end    
+      item
+        Command = EcFoldLevel4
+        ShortCut = 41012
+      end    
+      item
+        Command = EcFoldLevel5
+        ShortCut = 41013
+      end    
+      item
+        Command = EcFoldLevel6
+        ShortCut = 41014
+      end    
+      item
+        Command = EcFoldLevel7
+        ShortCut = 41015
+      end    
+      item
+        Command = EcFoldLevel8
+        ShortCut = 41016
+      end    
+      item
+        Command = EcFoldLevel9
+        ShortCut = 41017
+      end    
+      item
+        Command = EcFoldLevel0
+        ShortCut = 41008
+      end    
+      item
+        Command = EcFoldCurrent
+        ShortCut = 41005
+      end    
+      item
+        Command = EcUnFoldCurrent
+        ShortCut = 41003
+      end    
+      item
+        Command = EcToggleMarkupWord
+        ShortCut = 32845
+      end    
+      item
+        Command = ecNormalSelect
+        ShortCut = 24654
+      end    
+      item
+        Command = ecColumnSelect
+        ShortCut = 24643
+      end    
+      item
+        Command = ecLineSelect
+        ShortCut = 24652
+      end    
+      item
+        Command = ecTab
+        ShortCut = 9
+      end    
+      item
+        Command = ecShiftTab
+        ShortCut = 8201
+      end    
+      item
+        Command = ecMatchBracket
+        ShortCut = 24642
+      end    
+      item
+        Command = ecColSelUp
+        ShortCut = 40998
+      end    
+      item
+        Command = ecColSelDown
+        ShortCut = 41000
+      end    
+      item
+        Command = ecColSelLeft
+        ShortCut = 40997
+      end    
+      item
+        Command = ecColSelRight
+        ShortCut = 40999
+      end    
+      item
+        Command = ecColSelPageDown
+        ShortCut = 40994
+      end    
+      item
+        Command = ecColSelPageBottom
+        ShortCut = 57378
+      end    
+      item
+        Command = ecColSelPageUp
+        ShortCut = 40993
+      end    
+      item
+        Command = ecColSelPageTop
+        ShortCut = 57377
+      end    
+      item
+        Command = ecColSelLineStart
+        ShortCut = 40996
+      end    
+      item
+        Command = ecColSelLineEnd
+        ShortCut = 40995
+      end    
+      item
+        Command = ecColSelEditorTop
+        ShortCut = 57380
+      end    
+      item
+        Command = ecColSelEditorBottom
+        ShortCut = 57379
+      end>
+    MouseActions = <>
+    MouseTextActions = <>
+    MouseSelActions = <>
+    Lines.Strings = (
+      'unit unit4;'
+      ''
+      '{$mode objfpc}{$H+}'
+      ''
+      'interface'
+      ''
+      'implementation'
+      ''
+      'type'
+      '  generic TFakeClass<_GT> = class'
+      '    class function gmax(a, b: _GT): _GT;'
+      '  end;'
+      ''
+      '  TFakeClassInt = specialize TFakeClass<integer>;'
+      '  TFakeClassDouble = specialize TFakeClass<double>;'
+      ''
+      'class function TFakeClass.gmax(a, b: _GT): _GT;'
+      'begin'
+      '  if a > b then'
+      '    Result := a'
+      '  else'
+      '    Result := b;'
+      'end;'
+      ''
+      '  generic'
+      'function f<T>(a: T): T;'
+      'begin'
+      '  Result := a + a;'
+      'end;'
+      ''
+      'class function f<T>(a: T): T;'
+      'begin'
+      '  Result := a + a;'
+      'end;'
+      ''
+      ''
+      'generic function f<T>(a: T): T;'
+      'begin'
+      '  Result := a + a;'
+      'end;'
+      ''
+      'generic class function f<T>(a: T): T;'
+      'begin'
+      '  Result := a + a;'
+      'end;'
+      ''
+      ''
+      '//generic'
+      'function Add<T>(aLeft, aRight: T): T;'
+      'begin'
+      '  Result := aLeft + aRight;'
+      'end;'
+      ''
+      'procedure test;'
+      'begin'
+      'Writeln(specialize Add<String>(''Generic '', ''routines'') + specialize Add<String>('' with '', ''Free Pascal''));'
+      'end;'
+      ''
+      ''
+      'procedure test2;'
+      'begin'
+      'writeln( specialize f<integer>(1));'
+      '// show max of two integers'
+      'writeln(''Integer GMax:'', TFakeClassInt.gmax(23, 56));'
+      '// show max of two doubles'
+      'writeln(''Double GMax:'', TFakeClassDouble.gmax(23.89, 56.5));'
+      'readln();'
+      'end;'
+      ''
+      'end.'
+    )
+    VisibleSpecialChars = [vscSpace, vscTabAtLast]
+    SelectedColor.BackPriority = 50
+    SelectedColor.ForePriority = 50
+    SelectedColor.FramePriority = 50
+    SelectedColor.BoldPriority = 50
+    SelectedColor.ItalicPriority = 50
+    SelectedColor.UnderlinePriority = 50
+    SelectedColor.StrikeOutPriority = 50
+    ScrollOnEditLeftOptions.ScrollExtraPercent = 20
+    ScrollOnEditLeftOptions.ScrollExtraMax = 10
+    ScrollOnEditRightOptions.ScrollExtraPercent = 30
+    ScrollOnEditRightOptions.ScrollExtraMax = 25
+    BracketHighlightStyle = sbhsBoth
+    BracketMatchColor.Background = clNone
+    BracketMatchColor.Foreground = clNone
+    BracketMatchColor.Style = [fsBold]
+    FoldedCodeColor.Background = clNone
+    FoldedCodeColor.Foreground = clGray
+    FoldedCodeColor.FrameColor = clGray
+    MouseLinkColor.Background = clNone
+    MouseLinkColor.Foreground = clBlue
+    LineHighlightColor.Background = clNone
+    LineHighlightColor.Foreground = clNone
+    OnStatusChange = Memo1StatusChange
+    inline SynLeftGutterPartList1: TSynGutterPartList
+      object SynGutterMarks1: TSynGutterMarks
+        Width = 24
+        MouseActions = <>
+      end
+      object SynGutterLineNumber1: TSynGutterLineNumber
+        Width = 17
+        MouseActions = <>
+        MarkupInfo.Background = clBtnFace
+        MarkupInfo.Foreground = clNone
+        DigitCount = 2
+        ShowOnlyLineNumbersMultiplesOf = 1
+        ZeroStart = False
+        LeadingZeros = False
+      end
+      object SynGutterChanges1: TSynGutterChanges
+        Width = 4
+        MouseActions = <>
+        ModifiedColor = 59900
+        SavedColor = clGreen
+      end
+      object SynGutterSeparator1: TSynGutterSeparator
+        Width = 2
+        MouseActions = <>
+        MarkupInfo.Background = clWhite
+        MarkupInfo.Foreground = clGray
+      end
+      object SynGutterCodeFolding1: TSynGutterCodeFolding
+        MouseActions = <>
+        MarkupInfo.Background = clNone
+        MarkupInfo.Foreground = clGray
+        MouseActionsExpanded = <>
+        MouseActionsCollapsed = <>
+      end
+    end
+  end
+  inline Memo2: TSynEdit
+    Left = 704
+    Height = 472
+    Top = 8
+    Width = 587
+    Anchors = [akTop, akLeft, akRight, akBottom]
+    Font.Height = -13
+    Font.Name = 'Courier New'
+    Font.Pitch = fpFixed
+    Font.Quality = fqNonAntialiased
+    ParentColor = False
+    ParentFont = False
+    TabOrder = 3
+    Gutter.Width = 57
+    Gutter.MouseActions = <>
+    RightGutter.Width = 0
+    RightGutter.MouseActions = <>
+    Highlighter = SynPasSyn1
+    Keystrokes = <    
+      item
+        Command = ecUp
+        ShortCut = 38
+      end    
+      item
+        Command = ecSelUp
+        ShortCut = 8230
+      end    
+      item
+        Command = ecScrollUp
+        ShortCut = 16422
+      end    
+      item
+        Command = ecDown
+        ShortCut = 40
+      end    
+      item
+        Command = ecSelDown
+        ShortCut = 8232
+      end    
+      item
+        Command = ecScrollDown
+        ShortCut = 16424
+      end    
+      item
+        Command = ecLeft
+        ShortCut = 37
+      end    
+      item
+        Command = ecSelLeft
+        ShortCut = 8229
+      end    
+      item
+        Command = ecWordLeft
+        ShortCut = 16421
+      end    
+      item
+        Command = ecSelWordLeft
+        ShortCut = 24613
+      end    
+      item
+        Command = ecRight
+        ShortCut = 39
+      end    
+      item
+        Command = ecSelRight
+        ShortCut = 8231
+      end    
+      item
+        Command = ecWordRight
+        ShortCut = 16423
+      end    
+      item
+        Command = ecSelWordRight
+        ShortCut = 24615
+      end    
+      item
+        Command = ecPageDown
+        ShortCut = 34
+      end    
+      item
+        Command = ecSelPageDown
+        ShortCut = 8226
+      end    
+      item
+        Command = ecPageBottom
+        ShortCut = 16418
+      end    
+      item
+        Command = ecSelPageBottom
+        ShortCut = 24610
+      end    
+      item
+        Command = ecPageUp
+        ShortCut = 33
+      end    
+      item
+        Command = ecSelPageUp
+        ShortCut = 8225
+      end    
+      item
+        Command = ecPageTop
+        ShortCut = 16417
+      end    
+      item
+        Command = ecSelPageTop
+        ShortCut = 24609
+      end    
+      item
+        Command = ecLineStart
+        ShortCut = 36
+      end    
+      item
+        Command = ecSelLineStart
+        ShortCut = 8228
+      end    
+      item
+        Command = ecEditorTop
+        ShortCut = 16420
+      end    
+      item
+        Command = ecSelEditorTop
+        ShortCut = 24612
+      end    
+      item
+        Command = ecLineEnd
+        ShortCut = 35
+      end    
+      item
+        Command = ecSelLineEnd
+        ShortCut = 8227
+      end    
+      item
+        Command = ecEditorBottom
+        ShortCut = 16419
+      end    
+      item
+        Command = ecSelEditorBottom
+        ShortCut = 24611
+      end    
+      item
+        Command = ecToggleMode
+        ShortCut = 45
+      end    
+      item
+        Command = ecCopy
+        ShortCut = 16429
+      end    
+      item
+        Command = ecPaste
+        ShortCut = 8237
+      end    
+      item
+        Command = ecDeleteChar
+        ShortCut = 46
+      end    
+      item
+        Command = ecCut
+        ShortCut = 8238
+      end    
+      item
+        Command = ecDeleteLastChar
+        ShortCut = 8
+      end    
+      item
+        Command = ecDeleteLastChar
+        ShortCut = 8200
+      end    
+      item
+        Command = ecDeleteLastWord
+        ShortCut = 16392
+      end    
+      item
+        Command = ecUndo
+        ShortCut = 32776
+      end    
+      item
+        Command = ecRedo
+        ShortCut = 40968
+      end    
+      item
+        Command = ecLineBreak
+        ShortCut = 13
+      end    
+      item
+        Command = ecSelectAll
+        ShortCut = 16449
+      end    
+      item
+        Command = ecCopy
+        ShortCut = 16451
+      end    
+      item
+        Command = ecBlockIndent
+        ShortCut = 24649
+      end    
+      item
+        Command = ecLineBreak
+        ShortCut = 16461
+      end    
+      item
+        Command = ecInsertLine
+        ShortCut = 16462
+      end    
+      item
+        Command = ecDeleteWord
+        ShortCut = 16468
+      end    
+      item
+        Command = ecBlockUnindent
+        ShortCut = 24661
+      end    
+      item
+        Command = ecPaste
+        ShortCut = 16470
+      end    
+      item
+        Command = ecCut
+        ShortCut = 16472
+      end    
+      item
+        Command = ecDeleteLine
+        ShortCut = 16473
+      end    
+      item
+        Command = ecDeleteEOL
+        ShortCut = 24665
+      end    
+      item
+        Command = ecUndo
+        ShortCut = 16474
+      end    
+      item
+        Command = ecRedo
+        ShortCut = 24666
+      end    
+      item
+        Command = ecGotoMarker0
+        ShortCut = 16432
+      end    
+      item
+        Command = ecGotoMarker1
+        ShortCut = 16433
+      end    
+      item
+        Command = ecGotoMarker2
+        ShortCut = 16434
+      end    
+      item
+        Command = ecGotoMarker3
+        ShortCut = 16435
+      end    
+      item
+        Command = ecGotoMarker4
+        ShortCut = 16436
+      end    
+      item
+        Command = ecGotoMarker5
+        ShortCut = 16437
+      end    
+      item
+        Command = ecGotoMarker6
+        ShortCut = 16438
+      end    
+      item
+        Command = ecGotoMarker7
+        ShortCut = 16439
+      end    
+      item
+        Command = ecGotoMarker8
+        ShortCut = 16440
+      end    
+      item
+        Command = ecGotoMarker9
+        ShortCut = 16441
+      end    
+      item
+        Command = ecSetMarker0
+        ShortCut = 24624
+      end    
+      item
+        Command = ecSetMarker1
+        ShortCut = 24625
+      end    
+      item
+        Command = ecSetMarker2
+        ShortCut = 24626
+      end    
+      item
+        Command = ecSetMarker3
+        ShortCut = 24627
+      end    
+      item
+        Command = ecSetMarker4
+        ShortCut = 24628
+      end    
+      item
+        Command = ecSetMarker5
+        ShortCut = 24629
+      end    
+      item
+        Command = ecSetMarker6
+        ShortCut = 24630
+      end    
+      item
+        Command = ecSetMarker7
+        ShortCut = 24631
+      end    
+      item
+        Command = ecSetMarker8
+        ShortCut = 24632
+      end    
+      item
+        Command = ecSetMarker9
+        ShortCut = 24633
+      end    
+      item
+        Command = EcFoldLevel1
+        ShortCut = 41009
+      end    
+      item
+        Command = EcFoldLevel2
+        ShortCut = 41010
+      end    
+      item
+        Command = EcFoldLevel3
+        ShortCut = 41011
+      end    
+      item
+        Command = EcFoldLevel4
+        ShortCut = 41012
+      end    
+      item
+        Command = EcFoldLevel5
+        ShortCut = 41013
+      end    
+      item
+        Command = EcFoldLevel6
+        ShortCut = 41014
+      end    
+      item
+        Command = EcFoldLevel7
+        ShortCut = 41015
+      end    
+      item
+        Command = EcFoldLevel8
+        ShortCut = 41016
+      end    
+      item
+        Command = EcFoldLevel9
+        ShortCut = 41017
+      end    
+      item
+        Command = EcFoldLevel0
+        ShortCut = 41008
+      end    
+      item
+        Command = EcFoldCurrent
+        ShortCut = 41005
+      end    
+      item
+        Command = EcUnFoldCurrent
+        ShortCut = 41003
+      end    
+      item
+        Command = EcToggleMarkupWord
+        ShortCut = 32845
+      end    
+      item
+        Command = ecNormalSelect
+        ShortCut = 24654
+      end    
+      item
+        Command = ecColumnSelect
+        ShortCut = 24643
+      end    
+      item
+        Command = ecLineSelect
+        ShortCut = 24652
+      end    
+      item
+        Command = ecTab
+        ShortCut = 9
+      end    
+      item
+        Command = ecShiftTab
+        ShortCut = 8201
+      end    
+      item
+        Command = ecMatchBracket
+        ShortCut = 24642
+      end    
+      item
+        Command = ecColSelUp
+        ShortCut = 40998
+      end    
+      item
+        Command = ecColSelDown
+        ShortCut = 41000
+      end    
+      item
+        Command = ecColSelLeft
+        ShortCut = 40997
+      end    
+      item
+        Command = ecColSelRight
+        ShortCut = 40999
+      end    
+      item
+        Command = ecColSelPageDown
+        ShortCut = 40994
+      end    
+      item
+        Command = ecColSelPageBottom
+        ShortCut = 57378
+      end    
+      item
+        Command = ecColSelPageUp
+        ShortCut = 40993
+      end    
+      item
+        Command = ecColSelPageTop
+        ShortCut = 57377
+      end    
+      item
+        Command = ecColSelLineStart
+        ShortCut = 40996
+      end    
+      item
+        Command = ecColSelLineEnd
+        ShortCut = 40995
+      end    
+      item
+        Command = ecColSelEditorTop
+        ShortCut = 57380
+      end    
+      item
+        Command = ecColSelEditorBottom
+        ShortCut = 57379
+      end>
+    MouseActions = <>
+    MouseTextActions = <>
+    MouseSelActions = <>
+    Lines.Strings = (
+      ''
+    )
+    VisibleSpecialChars = [vscSpace, vscTabAtLast]
+    SelectedColor.BackPriority = 50
+    SelectedColor.ForePriority = 50
+    SelectedColor.FramePriority = 50
+    SelectedColor.BoldPriority = 50
+    SelectedColor.ItalicPriority = 50
+    SelectedColor.UnderlinePriority = 50
+    SelectedColor.StrikeOutPriority = 50
+    ScrollOnEditLeftOptions.ScrollExtraPercent = 20
+    ScrollOnEditLeftOptions.ScrollExtraMax = 10
+    ScrollOnEditRightOptions.ScrollExtraPercent = 30
+    ScrollOnEditRightOptions.ScrollExtraMax = 25
+    BracketHighlightStyle = sbhsBoth
+    BracketMatchColor.Background = clNone
+    BracketMatchColor.Foreground = clNone
+    BracketMatchColor.Style = [fsBold]
+    FoldedCodeColor.Background = clNone
+    FoldedCodeColor.Foreground = clGray
+    FoldedCodeColor.FrameColor = clGray
+    MouseLinkColor.Background = clNone
+    MouseLinkColor.Foreground = clBlue
+    LineHighlightColor.Background = clNone
+    LineHighlightColor.Foreground = clNone
+    inline SynLeftGutterPartList1: TSynGutterPartList
+      object SynGutterMarks1: TSynGutterMarks
+        Width = 24
+        MouseActions = <>
+      end
+      object SynGutterLineNumber1: TSynGutterLineNumber
+        Width = 17
+        MouseActions = <>
+        MarkupInfo.Background = clBtnFace
+        MarkupInfo.Foreground = clNone
+        DigitCount = 2
+        ShowOnlyLineNumbersMultiplesOf = 1
+        ZeroStart = False
+        LeadingZeros = False
+      end
+      object SynGutterChanges1: TSynGutterChanges
+        Width = 4
+        MouseActions = <>
+        ModifiedColor = 59900
+        SavedColor = clGreen
+      end
+      object SynGutterSeparator1: TSynGutterSeparator
+        Width = 2
+        MouseActions = <>
+        MarkupInfo.Background = clWhite
+        MarkupInfo.Foreground = clGray
+      end
+      object SynGutterCodeFolding1: TSynGutterCodeFolding
+        MouseActions = <>
+        MarkupInfo.Background = clNone
+        MarkupInfo.Foreground = clGray
+        MouseActionsExpanded = <>
+        MouseActionsCollapsed = <>
+      end
+    end
+  end
+  object edFileName: TFileNameEdit
+    Left = 18
+    Height = 23
+    Top = 6
+    Width = 350
+    OnAcceptFileName = edFileNameAcceptFileName
+    FilterIndex = 0
+    HideDirectories = False
+    ButtonWidth = 23
+    NumGlyphs = 1
+    MaxLength = 0
+    TabOrder = 4
+    TextHint = 'filename.pas to load'
+  end
+  object Button2: TButton
+    Left = 376
+    Height = 25
+    Top = 4
+    Width = 75
+    Caption = 'Load'
+    OnClick = Button2Click
+    TabOrder = 5
+  end
+  object cbShowTree: TCheckBox
+    Left = 616
+    Height = 19
+    Top = 40
+    Width = 75
+    Caption = 'Show Tree'
+    TabOrder = 6
+  end
+  object btnClearAndPaste: TButton
+    Left = 520
+    Height = 25
+    Top = 4
+    Width = 88
+    Caption = 'Clear and Paste'
+    OnClick = btnClearAndPasteClick
+    TabOrder = 7
+  end
+  object lbPos: TLabel
+    Left = 18
+    Height = 15
+    Top = 465
+    Width = 80
+    Anchors = [akLeft, akBottom]
+    AutoSize = False
+    ParentColor = False
+  end
+  object SynPasSyn1: TSynPasSyn
+    Enabled = False
+    AsmAttri.BackPriority = 0
+    AsmAttri.ForePriority = 0
+    AsmAttri.FramePriority = 0
+    AsmAttri.BoldPriority = 0
+    AsmAttri.ItalicPriority = 0
+    AsmAttri.UnderlinePriority = 0
+    AsmAttri.StrikeOutPriority = 0
+    CommentAttri.BackPriority = 0
+    CommentAttri.ForePriority = 0
+    CommentAttri.FramePriority = 0
+    CommentAttri.BoldPriority = 0
+    CommentAttri.ItalicPriority = 0
+    CommentAttri.UnderlinePriority = 0
+    CommentAttri.StrikeOutPriority = 0
+    IdentifierAttri.BackPriority = 0
+    IdentifierAttri.ForePriority = 0
+    IdentifierAttri.FramePriority = 0
+    IdentifierAttri.BoldPriority = 0
+    IdentifierAttri.ItalicPriority = 0
+    IdentifierAttri.UnderlinePriority = 0
+    IdentifierAttri.StrikeOutPriority = 0
+    KeyAttri.BackPriority = 0
+    KeyAttri.ForePriority = 0
+    KeyAttri.FramePriority = 0
+    KeyAttri.BoldPriority = 0
+    KeyAttri.ItalicPriority = 0
+    KeyAttri.UnderlinePriority = 0
+    KeyAttri.StrikeOutPriority = 0
+    NumberAttri.BackPriority = 0
+    NumberAttri.ForePriority = 0
+    NumberAttri.FramePriority = 0
+    NumberAttri.BoldPriority = 0
+    NumberAttri.ItalicPriority = 0
+    NumberAttri.UnderlinePriority = 0
+    NumberAttri.StrikeOutPriority = 0
+    SpaceAttri.BackPriority = 0
+    SpaceAttri.ForePriority = 0
+    SpaceAttri.FramePriority = 0
+    SpaceAttri.BoldPriority = 0
+    SpaceAttri.ItalicPriority = 0
+    SpaceAttri.UnderlinePriority = 0
+    SpaceAttri.StrikeOutPriority = 0
+    StringAttri.BackPriority = 0
+    StringAttri.ForePriority = 0
+    StringAttri.FramePriority = 0
+    StringAttri.BoldPriority = 0
+    StringAttri.ItalicPriority = 0
+    StringAttri.UnderlinePriority = 0
+    StringAttri.StrikeOutPriority = 0
+    SymbolAttri.BackPriority = 0
+    SymbolAttri.ForePriority = 0
+    SymbolAttri.FramePriority = 0
+    SymbolAttri.BoldPriority = 0
+    SymbolAttri.ItalicPriority = 0
+    SymbolAttri.UnderlinePriority = 0
+    SymbolAttri.StrikeOutPriority = 0
+    DirectiveAttri.BackPriority = 0
+    DirectiveAttri.ForePriority = 0
+    DirectiveAttri.FramePriority = 0
+    DirectiveAttri.BoldPriority = 0
+    DirectiveAttri.ItalicPriority = 0
+    DirectiveAttri.UnderlinePriority = 0
+    DirectiveAttri.StrikeOutPriority = 0
+    CompilerMode = pcmObjFPC
+    NestedComments = True
+    TypeHelpers = False
+    Left = 644
+    Top = 120
+  end
+  object PopupMenu1: TPopupMenu
+    Left = 632
+    Top = 300
+    object miCut: TMenuItem
+      Caption = 'Cut'
+      OnClick = miCutClick
+    end
+    object miCopy: TMenuItem
+      Caption = 'Copy'
+      OnClick = miCopyClick
+    end
+    object miPaste: TMenuItem
+      Caption = 'Paste'
+      OnClick = miPasteClick
+    end
+    object miSelectAll: TMenuItem
+      Caption = 'Select all'
+      OnClick = miSelectAllClick
+    end
+  end
+end
diff --git a/components/jcf2/TestApplication/Lazarus/unit1.pas b/components/jcf2/TestApplication/Lazarus/unit1.pas
new file mode 100644
index 0000000000..c0ab7480ba
--- /dev/null
+++ b/components/jcf2/TestApplication/Lazarus/unit1.pas
@@ -0,0 +1,265 @@
+{   Quick and dirty app for testing and debugging porpouses.
+
+}
+
+unit Unit1;
+
+{$mode objfpc}{$H+}
+
+interface
+
+uses
+  Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls, EditBtn,
+  Menus, SynEdit, SynHighlighterPas, ConvertTypes, SynEditTypes;
+
+type
+
+  { TForm1 }
+
+  TForm1 = class(TForm)
+    Button1: TButton;
+    Button2: TButton;
+    btnClearAndPaste: TButton;
+    cbShowTree: TCheckBox;
+    edFileName: TFileNameEdit;
+    lbPos: TLabel;
+    Memo3: TMemo;
+    Memo1: TSynEdit;
+    Memo2: TSynEdit;
+    miCut: TMenuItem;
+    miCopy: TMenuItem;
+    miPaste: TMenuItem;
+    miSelectAll: TMenuItem;
+    PopupMenu1: TPopupMenu;
+    SynPasSyn1: TSynPasSyn;
+    procedure btnClearAndPasteClick(Sender: TObject);
+    procedure Button1Click(Sender: TObject);
+    procedure Button2Click(Sender: TObject);
+    procedure edFileNameAcceptFileName(Sender: TObject; var Value: string);
+    procedure Memo1StatusChange(Sender: TObject; Changes: TSynStatusChanges);
+    procedure miCopyClick(Sender: TObject);
+    procedure miCutClick(Sender: TObject);
+    procedure miPasteClick(Sender: TObject);
+    procedure miSelectAllClick(Sender: TObject);
+  private
+
+  public
+    procedure LogIDEMessage(const psFile, psMessage: string; const peMessageType: TStatusMessageType; const piY, piX: integer);
+  end;
+
+
+var
+  Form1: TForm1;
+
+implementation
+
+{$R *.lfm}
+
+{ TForm1 }
+
+uses
+  JcfStringUtils in '..\..\Utils\JcfStringUtils.pas',
+  //JcfFileUtils in '..\..\Utils\JcfFileUtils.pas',
+  JcfSystemUtils in '..\..\Utils\JcfSystemUtils.pas',
+  Converter in '..\..\ReadWrite\Converter.pas',
+  FileConverter in '..\..\ReadWrite\FileConverter.pas',
+  //  ConvertTypes in '..\..\ReadWrite\ConvertTypes.pas',
+  BuildParseTree in '..\..\Parse\BuildParseTree.pas',
+  BuildTokenList in '..\..\Parse\BuildTokenList.pas',
+  ParseError in '..\..\Parse\ParseError.pas',
+  ParseTreeNode in '..\..\Parse\ParseTreeNode.pas',
+  ParseTreeNodeType in '..\..\Parse\ParseTreeNodeType.pas',
+  SourceToken in '..\..\Parse\SourceToken.pas',
+  SourceTokenList in '..\..\Parse\SourceTokenList.pas',
+  VisitSetXY in '..\..\Process\VisitSetXY.pas',
+  BaseVisitor in '..\..\Process\BaseVisitor.pas',
+  JcfMiscFunctions in '..\..\Utils\JcfMiscFunctions.pas',
+  //FileUtils in '..\..\Utils\FileUtils.pas',
+  JcfLog in '..\..\Utils\JcfLog.pas',
+  //fShowParseTree in '..\..\Parse\UI\fShowParseTree.pas' {frmShowParseTree},
+  SetUses in '..\..\Settings\SetUses.pas',
+  JcfSetBase in '..\..\Settings\JcfSetBase.pas',
+  JcfSettings,
+  SetAlign in '..\..\Settings\SetAlign.pas',
+  SetCaps in '..\..\Settings\SetCaps.pas',
+  SetClarify in '..\..\Settings\SetClarify.pas',
+  SetFile in '..\..\Settings\SetFile.pas',
+  SetIndent in '..\..\Settings\SetIndent.pas',
+  SetObfuscate in '..\..\Settings\SetObfuscate.pas',
+  SetReplace in '..\..\Settings\SetReplace.pas',
+  SetReturns in '..\..\Settings\SetReturns.pas',
+  SetSpaces in '..\..\Settings\SetSpaces.pas',
+  SettingsStream in '..\..\Settings\Streams\SettingsStream.pas',
+  RegistrySettings in '..\..\Settings\Streams\RegistrySettings.pas',
+  RemoveUnneededWhiteSpace in '..\..\Process\Obfuscate\RemoveUnneededWhiteSpace.pas',
+  FixCase in '..\..\Process\Obfuscate\FixCase.pas',
+  RebreakLines in '..\..\Process\Obfuscate\RebreakLines.pas',
+  ReduceWhiteSpace in '..\..\Process\Obfuscate\ReduceWhiteSpace.pas',
+  RemoveComment in '..\..\Process\Obfuscate\RemoveComment.pas',
+  RemoveConsecutiveWhiteSpace in '..\..\Process\Obfuscate\RemoveConsecutiveWhiteSpace.pas',
+  RemoveReturn in '..\..\Process\Obfuscate\RemoveReturn.pas',
+  WarnRealType in '..\..\Process\Warnings\WarnRealType.pas',
+  WarnAssignToFunctionName in '..\..\Process\Warnings\WarnAssignToFunctionName.pas',
+  WarnCaseNoElse in '..\..\Process\Warnings\WarnCaseNoElse.pas',
+  WarnDestroy in '..\..\Process\Warnings\WarnDestroy.pas',
+  WarnEmptyBlock in '..\..\Process\Warnings\WarnEmptyBlock.pas',
+  Warning in '..\..\Process\Warnings\Warning.pas',
+  JcfVersionConsts in '..\..\JcfVersionConsts.pas',
+  JcfRegistrySettings in '..\..\Settings\JcfRegistrySettings.pas',
+  TokenUtils in '..\..\Parse\TokenUtils.pas',
+  NoSpaceBefore in '..\..\Process\Spacing\NoSpaceBefore.pas',
+  NoSpaceAfter in '..\..\Process\Spacing\NoSpaceAfter.pas',
+  SingleSpaceAfter in '..\..\Process\Spacing\SingleSpaceAfter.pas',
+  SingleSpaceBefore in '..\..\Process\Spacing\SingleSpaceBefore.pas',
+  ReturnAfter in '..\..\Process\Returns\ReturnAfter.pas',
+  Nesting in '..\..\Process\Nesting.pas',
+  VisitSetNesting in '..\..\Process\VisitSetNesting.pas',
+  ReturnBefore in '..\..\Process\Returns\ReturnBefore.pas',
+  NoReturnAfter in '..\..\Process\Returns\NoReturnAfter.pas',
+  NoReturnBefore in '..\..\Process\Returns\NoReturnBefore.pas',
+  AllProcesses in '..\..\Process\AllProcesses.pas',
+  RemoveBlankLine in '..\..\Process\Obfuscate\RemoveBlankLine.pas',
+  BlockStyles in '..\..\Process\Returns\BlockStyles.pas',
+  SwitchableVisitor in '..\..\Process\SwitchableVisitor.pas',
+  FormatFlags in '..\..\Process\FormatFlags.pas',
+  TabToSpace in '..\..\Process\Spacing\TabToSpace.pas',
+  SpaceToTab in '..\..\Process\Spacing\SpaceToTab.pas',
+  SpecificWordCaps in '..\..\Process\Capitalisation\SpecificWordCaps.pas',
+  Capitalisation in '..\..\Process\Capitalisation\Capitalisation.pas',
+  Indenter in '..\..\Process\Indent\Indenter.pas',
+  PropertyOnOneLine in '..\..\Process\Returns\PropertyOnOneLine.pas',
+  SpaceBeforeColon in '..\..\Process\Spacing\SpaceBeforeColon.pas',
+  VisitStripEmptySpace in '..\..\Process\VisitStripEmptySpace.pas',
+  RemoveBlankLinesAfterProcHeader in '..\..\Process\Returns\RemoveBlankLinesAfterProcHeader.pas',
+  RemoveBlankLinesInVars in '..\..\Process\Returns\RemoveBlankLinesInVars.pas',
+  ReturnChars in '..\..\Process\Returns\ReturnChars.pas',
+  RemoveReturnsBeforeEnd in '..\..\Process\Returns\RemoveReturnsBeforeEnd.pas',
+  RemoveReturnsAfterBegin in '..\..\Process\Returns\RemoveReturnsAfterBegin.pas',
+  LongLineBreaker in '..\..\Process\Returns\LongLineBreaker.pas',
+  IntList in '..\..\Utils\IntList.pas',
+  BasicStats in '..\..\Process\Info\BasicStats.pas',
+  AlignConst in '..\..\Process\Align\AlignConst.pas',
+  AlignBase in '..\..\Process\Align\AlignBase.pas',
+  AlignAssign in '..\..\Process\Align\AlignAssign.pas',
+  AlignVars in '..\..\Process\Align\AlignVars.pas',
+  AlignTypedef in '..\..\Process\Align\AlignTypedef.pas',
+  AlignComment in '..\..\Process\Align\AlignComment.pas',
+  Tokens in '..\..\Parse\Tokens.pas',
+  SetWordList in '..\..\Settings\SetWordList.pas',
+  PreProcessorExpressionTokens in '..\..\Parse\PreProcessor\PreProcessorExpressionTokens.pas',
+  PreProcessorExpressionParser in '..\..\Parse\PreProcessor\PreProcessorExpressionParser.pas',
+  PreProcessorExpressionTokenise in '..\..\Parse\PreProcessor\PreProcessorExpressionTokenise.pas',
+  JcfHelp in '..\..\Utils\JcfHelp.pas',
+  SettingsTypes in '..\..\Settings\SettingsTypes.pas',
+  SetPreProcessor in '..\..\Settings\SetPreProcessor.pas',
+  UnitNameCaps in '..\..\Process\Capitalisation\UnitNameCaps.pas',
+  RemoveSpaceAtLineEnd in '..\..\Process\Spacing\RemoveSpaceAtLineEnd.pas',
+  FindReplace in '..\..\Process\Transform\FindReplace.pas',
+  //fJcfErrorDisplay in '..\..\Ui\fJcfErrorDisplay.pas' {ExceptionDialog},
+  ReturnsAfterFinalEnd in '..\..\Process\Returns\ReturnsAfterFinalEnd.pas',
+  PreProcessorParseTree in '..\..\Parse\PreProcessor\PreProcessorParseTree.pas',
+  RemoveEmptyComment in '..\..\Process\RemoveEmptyComment.pas',
+  RemoveConsecutiveReturns in '..\..\Process\Returns\RemoveConsecutiveReturns.pas',
+  UsesClauseFindReplace in '..\..\Process\Transform\UsesClauseFindReplace.pas',
+  UsesClauseInsert in '..\..\Process\Transform\UsesClauseInsert.pas',
+  UsesClauseRemove in '..\..\Process\Transform\UsesClauseRemove.pas',
+  MaxSpaces in '..\..\Process\Spacing\MaxSpaces.pas',
+  SetComments in '..\..\Settings\SetComments.pas',
+  TreeWalker in '..\..\Process\TreeWalker.pas',
+  AddBlockEndSemicolon in '..\..\Process\Transform\AddBlockEndSemicolon.pas',
+  AddBeginEnd in '..\..\Process\Transform\AddBeginEnd.pas',
+  SetTransform in '..\..\Settings\SetTransform.pas',
+  AlignField in '..\..\Process\Align\AlignField.pas',
+  SortUses in '..\..\Process\Transform\SortUses.pas',
+  SortUsesData in '..\..\Process\Transform\SortUsesData.pas',
+  IdentifierCaps in '..\..\Process\Capitalisation\IdentifierCaps.pas',
+  WarnUnusedParam in '..\..\Process\Warnings\WarnUnusedParam.pas',
+  //JcfFontSetFunctions in '..\..\Utils\JcfFontSetFunctions.pas',
+  SetAsm in '..\..\Settings\SetAsm.pas',
+  RemoveReturnsAfter in '..\..\Process\Returns\RemoveReturnsAfter.pas',
+  IndentAsmParam in '..\..\Process\Indent\IndentAsmParam.pas',
+  AsmKeywords in '..\..\Parse\AsmKeywords.pas';
+
+procedure TForm1.Button1Click(Sender: TObject);
+var
+  fcConverter: TConverter;
+begin
+  Memo3.Lines.Clear;
+  fcConverter := TConverter.Create;
+  try
+    fcConverter.OnStatusMessage := @LogIDEMessage;
+    fcConverter.InputCode := Memo1.Text;
+    fcConverter.GuiMessages := True;
+    fcConverter.ShowTree:=cbShowTree.Checked;
+    fcConverter.Convert;
+    if not fcConverter.ConvertError then
+    begin
+      Memo2.Text := fcConverter.OutputCode;
+    end;
+  finally
+    fcConverter.Free;
+  end;
+end;
+
+procedure TForm1.btnClearAndPasteClick(Sender: TObject);
+begin
+  Memo1.Lines.Clear;
+  Memo1.PasteFromClipboard;
+end;
+
+procedure TForm1.Button2Click(Sender: TObject);
+begin
+  if Trim(edFileName.Text)<>'' then
+    Memo1.Lines.LoadFromFile(edFileName.Text);
+end;
+
+procedure TForm1.edFileNameAcceptFileName(Sender: TObject; var Value: string);
+begin
+  Memo1.Lines.LoadFromFile(Value);
+end;
+
+procedure TForm1.Memo1StatusChange(Sender: TObject; Changes: TSynStatusChanges);
+begin
+  lbPos.Caption := 'Line: ' + IntToStr(Memo1.CaretY) + ' Col: ' + IntToStr(Memo1.CaretX);
+end;
+
+procedure TForm1.miCopyClick(Sender: TObject);
+begin
+  Memo1.CopyToClipboard;
+end;
+
+procedure TForm1.miCutClick(Sender: TObject);
+begin
+  Memo1.CutToClipboard;
+end;
+
+procedure TForm1.miPasteClick(Sender: TObject);
+begin
+  Memo1.PasteFromClipboard;
+end;
+
+procedure TForm1.miSelectAllClick(Sender: TObject);
+begin
+  Memo1.SelectAll;
+end;
+
+procedure TForm1.LogIDEMessage(const psFile, psMessage: string; const peMessageType: TStatusMessageType; const piY, piX: integer);
+//var
+//  Urgency: TMessageLineUrgency;
+begin
+  { no empty lines in this log }
+  if psMessage = '' then
+    exit;
+  //case peMessageType of
+  //mtException,mtInputError,mtParseError: Urgency:=mluError;
+  //mtCodeWarning: Urgency:=mluWarning;
+  //mtFinalSummary: Urgency:=mluImportant;
+  //mtProgress: Urgency:=mluProgress;
+  //end;
+  Memo3.Lines.Add(format('%d,%d : %s ', [piY, piX, psMessage]));
+  //lazMessages.AddCustomMessage(Urgency,psMessage, psFile, piY, piX, 'JCF')
+end;
+
+end.
+
+
-- 
2.29.1.windows.1

JCF_TestApplication.patch (78,266 bytes)   

Juha Manninen

2020-11-14 21:49

developer   ~0126942

I applied the ThreadVar patch in r64136. Thanks.

The test application does not compile.
 ConvertTypes.pas(28,2) Fatal: Cannot open include file "JcfGlobal.inc"

Domingo Galmés

2020-11-14 22:59

reporter   ~0126949

Sorry, i work on windows and compile and build well.
The bug , i thing, is that the path in project options include files '..\..\include' is lowercase (my fault) must be '..\..\Include'.

This patch solves it, i hope.
Thanks for apply the other patch.
BugCaseInsensitiveIncludePath.patch (1,636 bytes)   
From a22f85b6307c49459d3d495a505ca74fb9452275 Mon Sep 17 00:00:00 2001
From: DomingoGP <dgalmesp@gmail.com>
Date: Sat, 14 Nov 2020 22:51:10 +0100
Subject: [PATCH] bug case sensitive path ..\..\Include

---
 components/jcf2/TestApplication/Lazarus/TestJCF.lpi | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/components/jcf2/TestApplication/Lazarus/TestJCF.lpi b/components/jcf2/TestApplication/Lazarus/TestJCF.lpi
index 2454014ae6..6371f66df3 100644
--- a/components/jcf2/TestApplication/Lazarus/TestJCF.lpi
+++ b/components/jcf2/TestApplication/Lazarus/TestJCF.lpi
@@ -163,8 +163,8 @@
       <Filename Value="TestJCF"/>
     </Target>
     <SearchPaths>
-      <IncludeFiles Value="$(ProjOutDir);..\..\include"/>
-      <OtherUnitFiles Value="..\..\Parse;..\..\Utils;..\..\Settings;..\..\Process;..\..\Process\Returns;..\..\Process\Spacing;..\..\ReadWrite;..\..\Process\Indent;..\..\Process\Obfuscate;..\..\Process\Transform;..\..\Process\Warnings;..\..\Process\Capitalisation;..\..\Process\Info;..\..\Process\Align;..\..\Parse\UI;..\..\Parse\PreProcessor"/>
+      <IncludeFiles Value="$(ProjOutDir);..\..\Include"/>
+      <OtherUnitFiles Value="..\..\Parse;..\..\Utils;..\..\Settings;..\..\Process;..\..\Process\Returns;..\..\Process\Spacing;..\..\ReadWrite;..\..\Process\Indent;..\..\Process\Obfuscate;..\..\Process\Transform;..\..\Process\Warnings;..\..\Process\Capitalisation;..\..\Process\Info;..\..\Process\Align;..\..\Parse\UI;..\..\Parse\PreProcessor;..\..\Include"/>
       <UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/>
     </SearchPaths>
     <Linking>
-- 
2.29.1.windows.1

Juha Manninen

2020-11-15 14:27

developer   ~0126956

I added the test application after moving it a step up in directory structure. The "Lazarus" directory is useless because this whole project is Lazarus. We have already removed IFDEFs for Delphi. I don't think our fork works with Delphi any more.
If the test application is needed for Delphi, it can be modified to support it quite easily.
I know there are other "Lazarus" subdirectories for historical reasons. They could be cleaned out but I have no plans to do it. Not important.

Domingo Galmés

2020-11-15 16:00

reporter   ~0126962

i agree. thanks

Issue History

Date Modified Username Field Change
2020-11-14 15:40 Domingo Galmés New Issue
2020-11-14 15:40 Domingo Galmés File Added: JCF_ThreadVars.patch
2020-11-14 15:40 Domingo Galmés File Added: JCF_TestApplication.patch
2020-11-14 21:49 Juha Manninen Note Added: 0126942
2020-11-14 21:49 Juha Manninen Assigned To => Juha Manninen
2020-11-14 21:49 Juha Manninen Status new => assigned
2020-11-14 22:59 Domingo Galmés Note Added: 0126949
2020-11-14 22:59 Domingo Galmés File Added: BugCaseInsensitiveIncludePath.patch
2020-11-15 14:27 Juha Manninen Status assigned => resolved
2020-11-15 14:27 Juha Manninen Resolution open => fixed
2020-11-15 14:27 Juha Manninen Fixed in Revision => r64136, r64139
2020-11-15 14:27 Juha Manninen LazTarget => -
2020-11-15 14:27 Juha Manninen Note Added: 0126956
2020-11-15 16:00 Domingo Galmés Status resolved => closed
2020-11-15 16:00 Domingo Galmés Note Added: 0126962
2020-12-07 12:30 Juha Manninen Relationship added related to 0038178