mirror of
				https://gitlab.com/freepascal.org/lazarus/lazarus.git
				synced 2025-11-04 16:34:24 +01:00 
			
		
		
		
	SynEdit: Refactored fold-highlighters: unify methods to get fold-nest info
git-svn-id: trunk@35115 -
This commit is contained in:
		
							parent
							
								
									e10dc0f7ea
								
							
						
					
					
						commit
						7a03599f16
					
				
							
								
								
									
										2
									
								
								.gitattributes
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.gitattributes
									
									
									
									
										vendored
									
									
								
							@ -2438,6 +2438,8 @@ components/synedit/test/testbasicsynedit.pas svneol=native#text/pascal
 | 
				
			|||||||
components/synedit/test/testblockindent.pas svneol=native#text/pascal
 | 
					components/synedit/test/testblockindent.pas svneol=native#text/pascal
 | 
				
			||||||
components/synedit/test/testbookmarks.pas svneol=native#text/pascal
 | 
					components/synedit/test/testbookmarks.pas svneol=native#text/pascal
 | 
				
			||||||
components/synedit/test/testfoldedview.pas svneol=native#text/pascal
 | 
					components/synedit/test/testfoldedview.pas svneol=native#text/pascal
 | 
				
			||||||
 | 
					components/synedit/test/testhighlighterlfm.pas svneol=native#text/pascal
 | 
				
			||||||
 | 
					components/synedit/test/testhighlightfoldbase.pas svneol=native#text/pascal
 | 
				
			||||||
components/synedit/test/testhighlightmulti.pas svneol=native#text/pascal
 | 
					components/synedit/test/testhighlightmulti.pas svneol=native#text/pascal
 | 
				
			||||||
components/synedit/test/testhighlightpas.pas svneol=native#text/pascal
 | 
					components/synedit/test/testhighlightpas.pas svneol=native#text/pascal
 | 
				
			||||||
components/synedit/test/testhighlightxml.pas svneol=native#text/pascal
 | 
					components/synedit/test/testhighlightxml.pas svneol=native#text/pascal
 | 
				
			||||||
 | 
				
			|||||||
@ -284,6 +284,50 @@ type
 | 
				
			|||||||
  end;
 | 
					  end;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  TSynEditFoldProviderNodeInfoList = array of TSynEditFoldProviderNodeInfo;
 | 
					  TSynEditFoldProviderNodeInfoList = array of TSynEditFoldProviderNodeInfo;
 | 
				
			||||||
 | 
					  TSynEditFoldProvider = class;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  (* TLazSynEditNestedFoldsList
 | 
				
			||||||
 | 
					     Provides Info on all foldable-blocks containing a given line (0 based index).
 | 
				
			||||||
 | 
					     That are:
 | 
				
			||||||
 | 
					     - All foldable blocks opening on a previous line, that are still open
 | 
				
			||||||
 | 
					       at the start of the line. (May end on this line or later)
 | 
				
			||||||
 | 
					     - Foldable blocks opening on that line. (OpeningOnLineCount)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					     The data is NOT automatically invalidated.
 | 
				
			||||||
 | 
					  *)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  TLazSynEditNestedFoldsListEntry = record
 | 
				
			||||||
 | 
					    HNode: TSynFoldNodeInfo;    // Highlighter Node
 | 
				
			||||||
 | 
					    //FNode: TSynTextFoldAVLNode; // AvlFoldNode
 | 
				
			||||||
 | 
					    //Text, Keyword: String;
 | 
				
			||||||
 | 
					    LineIdx: TLineIdx;
 | 
				
			||||||
 | 
					     //ColIndex: Integer;
 | 
				
			||||||
 | 
					    //OpenCount: Integer;
 | 
				
			||||||
 | 
					  end;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  TLazSynEditNestedFoldsList = class
 | 
				
			||||||
 | 
					  private
 | 
				
			||||||
 | 
					    FFoldProvider: TSynEditFoldProvider;
 | 
				
			||||||
 | 
					    FFoldGroup: Integer;
 | 
				
			||||||
 | 
					    FLine: TLineIdx;
 | 
				
			||||||
 | 
					    procedure SetFoldGroup(AValue: Integer);
 | 
				
			||||||
 | 
					    procedure SetLines(AValue: TLineIdx);
 | 
				
			||||||
 | 
					  private
 | 
				
			||||||
 | 
					    FGroupCount: Integer;
 | 
				
			||||||
 | 
					    FGroupEndLevels, FGroupEndLevelsAtEval: Array of integer;
 | 
				
			||||||
 | 
					    FCount, FOpeningOnLineCount: Integer;
 | 
				
			||||||
 | 
					    FNestInfo: Array of TLazSynEditNestedFoldsListEntry;
 | 
				
			||||||
 | 
					    FEvaluationIndex: Integer;
 | 
				
			||||||
 | 
					    procedure InitSubGroupEndLevels;
 | 
				
			||||||
 | 
					    procedure InitNestInfoForIndex(AnIndex: Integer);
 | 
				
			||||||
 | 
					  public
 | 
				
			||||||
 | 
					    constructor Create(aFoldProvider: TSynEditFoldProvider);
 | 
				
			||||||
 | 
					    procedure Clear;
 | 
				
			||||||
 | 
					    function Count: Integer;
 | 
				
			||||||
 | 
					    function OpeningOnLineCount: Integer;
 | 
				
			||||||
 | 
					    property Line: TLineIdx read FLine write SetLines;
 | 
				
			||||||
 | 
					    property FoldGroup: Integer read FFoldGroup write SetFoldGroup;
 | 
				
			||||||
 | 
					  end;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  TSynEditFoldProvider = class
 | 
					  TSynEditFoldProvider = class
 | 
				
			||||||
  private
 | 
					  private
 | 
				
			||||||
@ -292,17 +336,21 @@ type
 | 
				
			|||||||
    FSelection: TSynEditSelection;
 | 
					    FSelection: TSynEditSelection;
 | 
				
			||||||
    FFoldTree : TSynTextFoldAVLTree;
 | 
					    FFoldTree : TSynTextFoldAVLTree;
 | 
				
			||||||
    function GetFoldsAvailable: Boolean;
 | 
					    function GetFoldsAvailable: Boolean;
 | 
				
			||||||
 | 
					    function GetHighLighterWithLines: TSynCustomFoldHighlighter;
 | 
				
			||||||
    function GetLineCapabilities(ALineIdx: Integer): TSynEditFoldLineCapabilities;
 | 
					    function GetLineCapabilities(ALineIdx: Integer): TSynEditFoldLineCapabilities;
 | 
				
			||||||
    function GetLineClassification(ALineIdx: Integer): TFoldNodeClassifications;
 | 
					    function GetLineClassification(ALineIdx: Integer): TFoldNodeClassifications;
 | 
				
			||||||
    procedure SetHighLighter(const AValue: TSynCustomFoldHighlighter);
 | 
					    procedure SetHighLighter(const AValue: TSynCustomFoldHighlighter);
 | 
				
			||||||
 | 
					  protected
 | 
				
			||||||
 | 
					    property HighLighterWithLines: TSynCustomFoldHighlighter read GetHighLighterWithLines;
 | 
				
			||||||
  public
 | 
					  public
 | 
				
			||||||
    constructor Create(aTextView : TSynEditStrings; AFoldTree : TSynTextFoldAVLTree);
 | 
					    constructor Create(aTextView : TSynEditStrings; AFoldTree : TSynTextFoldAVLTree);
 | 
				
			||||||
    function FoldOpenCount(ALineIdx: Integer; AType: Integer = 0): Integer;
 | 
					
 | 
				
			||||||
    function FoldOpenInfo(ALineIdx, AFoldIdx: Integer; AType: Integer = 0): TSynFoldNodeInfo;
 | 
					    // Info about Folds opening on ALineIdx
 | 
				
			||||||
 | 
					    function  FoldOpenCount(ALineIdx: Integer; AType: Integer = 0): Integer;
 | 
				
			||||||
 | 
					    function  FoldOpenInfo(ALineIdx, AFoldIdx: Integer; AType: Integer = 0): TSynFoldNodeInfo;
 | 
				
			||||||
    //property FoldOpenInfo[ALineIdx, AColumnIdx: Integer]: Integer read GetFoldOpenInfo;
 | 
					    //property FoldOpenInfo[ALineIdx, AColumnIdx: Integer]: Integer read GetFoldOpenInfo;
 | 
				
			||||||
    //property FoldInfoCount[ALineIdx: Integer]: Integer read GetFoldInfoCount;
 | 
					
 | 
				
			||||||
    //property FoldInfo[ALineIdx, AColumnIdx: Integer]: Integer read GetFoldInfo;
 | 
					    function  FoldLineLength(ALine, AFoldIndex: Integer): integer;
 | 
				
			||||||
    function FoldLineLength(ALine, AFoldIndex: Integer): integer;
 | 
					 | 
				
			||||||
    function  InfoForFoldAtTextIndex(ALine, AFoldIndex : Integer;
 | 
					    function  InfoForFoldAtTextIndex(ALine, AFoldIndex : Integer;
 | 
				
			||||||
                                     HideLen: Boolean = False;
 | 
					                                     HideLen: Boolean = False;
 | 
				
			||||||
                                     NeedLen: Boolean = True): TSynEditFoldProviderNodeInfo;
 | 
					                                     NeedLen: Boolean = True): TSynEditFoldProviderNodeInfo;
 | 
				
			||||||
@ -2724,6 +2772,131 @@ begin
 | 
				
			|||||||
  fNestedNodesTree := nil;
 | 
					  fNestedNodesTree := nil;
 | 
				
			||||||
end;
 | 
					end;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					{ TLazSynEditNestedFoldsList }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					procedure TLazSynEditNestedFoldsList.SetLines(AValue: TLineIdx);
 | 
				
			||||||
 | 
					begin
 | 
				
			||||||
 | 
					  if FLine = AValue then Exit;
 | 
				
			||||||
 | 
					  FLine := AValue;
 | 
				
			||||||
 | 
					  // Todo: might be able to re-use old data
 | 
				
			||||||
 | 
					  Clear;
 | 
				
			||||||
 | 
					end;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					procedure TLazSynEditNestedFoldsList.Clear;
 | 
				
			||||||
 | 
					begin
 | 
				
			||||||
 | 
					  FGroupCount := -1;
 | 
				
			||||||
 | 
					  FCount := -1;
 | 
				
			||||||
 | 
					  FOpeningOnLineCount := -1;
 | 
				
			||||||
 | 
					  FEvaluationIndex := -1;
 | 
				
			||||||
 | 
					  SetLength(FNestInfo, 0);
 | 
				
			||||||
 | 
					end;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					procedure TLazSynEditNestedFoldsList.InitSubGroupEndLevels;
 | 
				
			||||||
 | 
					var
 | 
				
			||||||
 | 
					  hl: TSynCustomFoldHighlighter;
 | 
				
			||||||
 | 
					  i: integer;
 | 
				
			||||||
 | 
					begin
 | 
				
			||||||
 | 
					  if FGroupCount > 0 then
 | 
				
			||||||
 | 
					    exit;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  hl := FFoldProvider.HighLighterWithLines;
 | 
				
			||||||
 | 
					  if hl = nil then exit;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if FFoldGroup = 0 then begin
 | 
				
			||||||
 | 
					    // special, join other groups (or some other...)
 | 
				
			||||||
 | 
					    FGroupCount := hl.FoldTypeCount;
 | 
				
			||||||
 | 
					    // start at 1, so FoldGroup can be used as index
 | 
				
			||||||
 | 
					    SetLength(FGroupEndLevels, FGroupCount + 1);
 | 
				
			||||||
 | 
					    SetLength(FGroupEndLevelsAtEval, FGroupCount + 1);
 | 
				
			||||||
 | 
					    for i := 1 to FGroupCount do
 | 
				
			||||||
 | 
					      FGroupEndLevels[i] := hl.FoldBlockEndLevel(FLine - 1, i) + OpeningOnLineCount;
 | 
				
			||||||
 | 
					      FGroupEndLevelsAtEval[i] := FGroupEndLevels[i];
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					  else begin
 | 
				
			||||||
 | 
					    FGroupCount := 1;
 | 
				
			||||||
 | 
					    SetLength(FGroupEndLevels, 1);
 | 
				
			||||||
 | 
					    SetLength(FGroupEndLevelsAtEval, 1);
 | 
				
			||||||
 | 
					    FGroupEndLevels[0] := Count;
 | 
				
			||||||
 | 
					    FGroupEndLevelsAtEval[0] := FGroupEndLevels[0];
 | 
				
			||||||
 | 
					  end;
 | 
				
			||||||
 | 
					end;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					procedure TLazSynEditNestedFoldsList.InitNestInfoForIndex(AnIndex: Integer);
 | 
				
			||||||
 | 
					var
 | 
				
			||||||
 | 
					  CurLine: TLineIdx;
 | 
				
			||||||
 | 
					  hl: TSynCustomFoldHighlighter;
 | 
				
			||||||
 | 
					  i: Integer;
 | 
				
			||||||
 | 
					begin
 | 
				
			||||||
 | 
					  if (AnIndex >= Count) or (AnIndex >= FEvaluationIndex) then exit;
 | 
				
			||||||
 | 
					  hl := FFoldProvider.HighLighterWithLines;
 | 
				
			||||||
 | 
					  if hl = nil then exit;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  InitSubGroupEndLevels;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if FEvaluationIndex = Count then
 | 
				
			||||||
 | 
					    CurLine := Line
 | 
				
			||||||
 | 
					  else
 | 
				
			||||||
 | 
					    CurLine := FNestInfo[FEvaluationIndex].LineIdx;
 | 
				
			||||||
 | 
					    // need index/column...
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  inc(CurLine);
 | 
				
			||||||
 | 
					  while CurLine > 0 do begin
 | 
				
			||||||
 | 
					    dec(CurLine);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if FFoldGroup = 0 then begin
 | 
				
			||||||
 | 
					      i := FGroupCount;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      while (i > 0) do begin
 | 
				
			||||||
 | 
					  //      hl.MinimumFoldLevel(CurLine, i)  // minimumPas
 | 
				
			||||||
 | 
					        dec(i);
 | 
				
			||||||
 | 
					      end;
 | 
				
			||||||
 | 
					      if i < 0 then continue;
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					    else begin
 | 
				
			||||||
 | 
					      //if ... continue
 | 
				
			||||||
 | 
					    end;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  end;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					end;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					procedure TLazSynEditNestedFoldsList.SetFoldGroup(AValue: Integer);
 | 
				
			||||||
 | 
					begin
 | 
				
			||||||
 | 
					  if FFoldGroup = AValue then Exit;
 | 
				
			||||||
 | 
					  FFoldGroup := AValue;
 | 
				
			||||||
 | 
					  Clear;
 | 
				
			||||||
 | 
					end;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					constructor TLazSynEditNestedFoldsList.Create(aFoldProvider: TSynEditFoldProvider);
 | 
				
			||||||
 | 
					begin
 | 
				
			||||||
 | 
					  FFoldProvider := aFoldProvider;
 | 
				
			||||||
 | 
					end;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function TLazSynEditNestedFoldsList.Count: Integer;
 | 
				
			||||||
 | 
					var
 | 
				
			||||||
 | 
					  hl: TSynCustomFoldHighlighter;
 | 
				
			||||||
 | 
					begin
 | 
				
			||||||
 | 
					  Result := FCount;
 | 
				
			||||||
 | 
					  if Result >= 0 then exit;
 | 
				
			||||||
 | 
					  hl := FFoldProvider.HighLighterWithLines;
 | 
				
			||||||
 | 
					  if hl = nil then exit(-1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  FCount := hl.FoldBlockEndLevel(FLine - 1, FFoldGroup) + OpeningOnLineCount;
 | 
				
			||||||
 | 
					  FEvaluationIndex := FCount;
 | 
				
			||||||
 | 
					  SetLength(FNestInfo, FCount);
 | 
				
			||||||
 | 
					  Result := FCount;
 | 
				
			||||||
 | 
					end;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function TLazSynEditNestedFoldsList.OpeningOnLineCount: Integer;
 | 
				
			||||||
 | 
					begin
 | 
				
			||||||
 | 
					  Result := FOpeningOnLineCount;
 | 
				
			||||||
 | 
					  if Result >= 0 then exit;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  FOpeningOnLineCount := FFoldProvider.FoldOpenCount(FLine);
 | 
				
			||||||
 | 
					  Result := FOpeningOnLineCount;
 | 
				
			||||||
 | 
					end;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
{ TSynEditFoldProvider }
 | 
					{ TSynEditFoldProvider }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function TSynEditFoldProvider.GetLineCapabilities(ALineIdx: Integer): TSynEditFoldLineCapabilities;
 | 
					function TSynEditFoldProvider.GetLineCapabilities(ALineIdx: Integer): TSynEditFoldLineCapabilities;
 | 
				
			||||||
@ -2744,8 +2917,8 @@ begin
 | 
				
			|||||||
    exit;
 | 
					    exit;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  FHighlighter.CurrentLines := FLines;
 | 
					  FHighlighter.CurrentLines := FLines;
 | 
				
			||||||
  if FHighlighter.FoldNestCount(ALineIdx - 1) > 0 then Result := Result + [cfFoldBody];
 | 
					  if FHighlighter.FoldBlockEndLevel(ALineIdx - 1) > 0 then Result := Result + [cfFoldBody];
 | 
				
			||||||
  if FHighlighter.FoldCloseCount(ALineIdx) > 0    then Result := Result + [cfFoldEnd, cfFoldBody];
 | 
					  if FHighlighter.FoldBlockClosingCount(ALineIdx) > 0    then Result := Result + [cfFoldEnd, cfFoldBody];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  c := FHighlighter.FoldNodeInfo[ALineIdx].CountEx([]);
 | 
					  c := FHighlighter.FoldNodeInfo[ALineIdx].CountEx([]);
 | 
				
			||||||
  if c > 0 then begin
 | 
					  if c > 0 then begin
 | 
				
			||||||
@ -2761,7 +2934,7 @@ begin
 | 
				
			|||||||
      Result := Result + [cfHideStart, cfSingleLineHide];
 | 
					      Result := Result + [cfHideStart, cfSingleLineHide];
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
  else
 | 
					  else
 | 
				
			||||||
    if FHighlighter.FoldOpenCount(ALineIdx) > 0 then include(Result, cfFoldStart);
 | 
					    if FHighlighter.FoldBlockOpeningCount(ALineIdx) > 0 then include(Result, cfFoldStart);
 | 
				
			||||||
end;
 | 
					end;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function TSynEditFoldProvider.GetLineClassification(ALineIdx: Integer): TFoldNodeClassifications;
 | 
					function TSynEditFoldProvider.GetLineClassification(ALineIdx: Integer): TFoldNodeClassifications;
 | 
				
			||||||
@ -2777,6 +2950,14 @@ begin
 | 
				
			|||||||
            ((FSelection <> nil) and FSelection.SelAvail);
 | 
					            ((FSelection <> nil) and FSelection.SelAvail);
 | 
				
			||||||
end;
 | 
					end;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function TSynEditFoldProvider.GetHighLighterWithLines: TSynCustomFoldHighlighter;
 | 
				
			||||||
 | 
					begin
 | 
				
			||||||
 | 
					  Result := FHighlighter;
 | 
				
			||||||
 | 
					  if (Result = nil) then
 | 
				
			||||||
 | 
					    exit;
 | 
				
			||||||
 | 
					  Result.CurrentLines := FLines;
 | 
				
			||||||
 | 
					end;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
procedure TSynEditFoldProvider.SetHighLighter(const AValue: TSynCustomFoldHighlighter);
 | 
					procedure TSynEditFoldProvider.SetHighLighter(const AValue: TSynCustomFoldHighlighter);
 | 
				
			||||||
begin
 | 
					begin
 | 
				
			||||||
  if FHighlighter = AValue then exit;
 | 
					  if FHighlighter = AValue then exit;
 | 
				
			||||||
@ -2790,30 +2971,18 @@ begin
 | 
				
			|||||||
end;
 | 
					end;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function TSynEditFoldProvider.FoldOpenCount(ALineIdx: Integer; AType: Integer = 0): Integer;
 | 
					function TSynEditFoldProvider.FoldOpenCount(ALineIdx: Integer; AType: Integer = 0): Integer;
 | 
				
			||||||
var
 | 
					 | 
				
			||||||
  i: Integer;
 | 
					 | 
				
			||||||
begin
 | 
					begin
 | 
				
			||||||
  if (FHighlighter = nil) or (ALineIdx < 0) then begin
 | 
					  if (FHighlighter = nil) or (ALineIdx < 0) then begin
 | 
				
			||||||
    if (AType=0) and (FSelection <> nil) and FSelection.SelAvail and (FSelection.FirstLineBytePos.Y=ALineIdx+1) then exit(1);
 | 
					    if (AType=0) and (FSelection <> nil) and FSelection.SelAvail and (FSelection.FirstLineBytePos.Y=ALineIdx+1) then exit(1);
 | 
				
			||||||
    exit(0);
 | 
					    exit(0);
 | 
				
			||||||
  end;
 | 
					  end;
 | 
				
			||||||
 | 
					  // Need to check alll nodes with FoldNodeInfoCount
 | 
				
			||||||
 | 
					  // Hide-able nodes can open and close on the same line "(* cmment *)"
 | 
				
			||||||
  FHighlighter.CurrentLines := FLines;
 | 
					  FHighlighter.CurrentLines := FLines;
 | 
				
			||||||
  Result := FHighlighter.FoldNodeInfo[ALineIdx].CountEx([sfaOpen, sfaFold]);
 | 
					  Result := FHighlighter.FoldNodeInfo[ALineIdx].CountEx([sfaOpen, sfaFold], AType);
 | 
				
			||||||
  if (result > 0) and (AType > 0) then begin
 | 
					  // fallback for HL without GetFoldNodeInfoCountEx
 | 
				
			||||||
    i := Result ;
 | 
					 | 
				
			||||||
    Result := 0;
 | 
					 | 
				
			||||||
    while i > 0 do begin
 | 
					 | 
				
			||||||
      dec(i);
 | 
					 | 
				
			||||||
      if FHighlighter.FoldNodeInfo[ALineIdx].NodeInfoEx(i, [sfaOpen, sfaFold]).FoldGroup = AType then
 | 
					 | 
				
			||||||
        inc(Result);
 | 
					 | 
				
			||||||
    end;
 | 
					 | 
				
			||||||
  end
 | 
					 | 
				
			||||||
  //Result := Result + FHighlighter.FoldNodeInfoCount[ALineIdx, [sfaOpen, sfaFoldHide]];
 | 
					 | 
				
			||||||
  //Result := Result + FHighlighter.FoldNodeInfoCount[ALineIdx, [sfaOneLineOpen, sfaFoldHide]];
 | 
					 | 
				
			||||||
  else
 | 
					 | 
				
			||||||
  if Result < 0 then
 | 
					  if Result < 0 then
 | 
				
			||||||
    Result := FHighlighter.FoldOpenCount(ALineIdx, AType);
 | 
					    Result := FHighlighter.FoldBlockOpeningCount(ALineIdx, AType);
 | 
				
			||||||
  if (AType=0) and (FSelection <> nil) and FSelection.SelAvail and (FSelection.FirstLineBytePos.Y=ALineIdx+1) then
 | 
					  if (AType=0) and (FSelection <> nil) and FSelection.SelAvail and (FSelection.FirstLineBytePos.Y=ALineIdx+1) then
 | 
				
			||||||
    inc(Result);
 | 
					    inc(Result);
 | 
				
			||||||
end;
 | 
					end;
 | 
				
			||||||
@ -2837,8 +3006,6 @@ function TSynEditFoldProvider.FoldOpenInfo(ALineIdx, AFoldIdx: Integer;
 | 
				
			|||||||
    Result.FoldGroup := -1;
 | 
					    Result.FoldGroup := -1;
 | 
				
			||||||
  end;
 | 
					  end;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var
 | 
					 | 
				
			||||||
  i, x: Integer;
 | 
					 | 
				
			||||||
begin
 | 
					begin
 | 
				
			||||||
  Result.FoldAction := [sfaInvalid];
 | 
					  Result.FoldAction := [sfaInvalid];
 | 
				
			||||||
  if (FHighlighter = nil) or (ALineIdx < 0) then begin
 | 
					  if (FHighlighter = nil) or (ALineIdx < 0) then begin
 | 
				
			||||||
@ -2848,27 +3015,13 @@ begin
 | 
				
			|||||||
  end;
 | 
					  end;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  FHighlighter.CurrentLines := FLines;
 | 
					  FHighlighter.CurrentLines := FLines;
 | 
				
			||||||
  if AType = 0 then
 | 
					  if (AType = 0) and (FSelection <> nil) and FSelection.SelAvail and
 | 
				
			||||||
    if (FSelection <> nil) and FSelection.SelAvail and (FSelection.FirstLineBytePos.Y=ALineIdx+1) and
 | 
					     (FSelection.FirstLineBytePos.Y=ALineIdx+1) and
 | 
				
			||||||
      (AFoldIdx = FoldOpenCount(ALineIdx, 0)-1)
 | 
					     (AFoldIdx = FoldOpenCount(ALineIdx, AType)-1)
 | 
				
			||||||
    then
 | 
					  then
 | 
				
			||||||
      Result := BlockSelInfo(AFoldIdx-1)
 | 
					    Result := BlockSelInfo(AFoldIdx)
 | 
				
			||||||
    else
 | 
					  else
 | 
				
			||||||
      Result := FHighlighter.FoldNodeInfo[ALineIdx].NodeInfoEx(AFoldIdx, [sfaOpen, sfaFold])
 | 
					    Result := FHighlighter.FoldNodeInfo[ALineIdx].NodeInfoEx(AFoldIdx, [sfaOpen, sfaFold], AType);
 | 
				
			||||||
  else begin
 | 
					 | 
				
			||||||
    x := FHighlighter.FoldNodeInfo[ALineIdx].CountEx([sfaOpen, sfaFold]);
 | 
					 | 
				
			||||||
    i := 0;
 | 
					 | 
				
			||||||
    while i < x do begin
 | 
					 | 
				
			||||||
      Result := FHighlighter.FoldNodeInfo[ALineIdx].NodeInfoEx(i, [sfaOpen, sfaFold]);
 | 
					 | 
				
			||||||
      if (Result.FoldGroup = AType) then begin
 | 
					 | 
				
			||||||
        if AFoldIdx = 0 then
 | 
					 | 
				
			||||||
          exit;
 | 
					 | 
				
			||||||
        dec(AFoldIdx);
 | 
					 | 
				
			||||||
      end;
 | 
					 | 
				
			||||||
      inc(i);
 | 
					 | 
				
			||||||
    end;
 | 
					 | 
				
			||||||
    Result.FoldAction := [sfaInvalid];
 | 
					 | 
				
			||||||
  end;
 | 
					 | 
				
			||||||
end;
 | 
					end;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function TSynEditFoldProvider.FoldLineLength(ALine, AFoldIndex: Integer): integer;
 | 
					function TSynEditFoldProvider.FoldLineLength(ALine, AFoldIndex: Integer): integer;
 | 
				
			||||||
@ -3369,7 +3522,7 @@ begin
 | 
				
			|||||||
  while i < fLines.Count do begin
 | 
					  while i < fLines.Count do begin
 | 
				
			||||||
     // Todo: Highlighter should return a list of types that can return default folded
 | 
					     // Todo: Highlighter should return a list of types that can return default folded
 | 
				
			||||||
     // Currently PascalHl Type 2 = Region
 | 
					     // Currently PascalHl Type 2 = Region
 | 
				
			||||||
    c := hl.FoldOpenCount(i, 2);
 | 
					    c := hl.FoldBlockOpeningCount(i, 2);
 | 
				
			||||||
    if c > 0 then begin
 | 
					    if c > 0 then begin
 | 
				
			||||||
      c := hl.FoldNodeInfo[i].CountEx([sfaOpen, sfaFold]);
 | 
					      c := hl.FoldNodeInfo[i].CountEx([sfaOpen, sfaFold]);
 | 
				
			||||||
      j := 0;
 | 
					      j := 0;
 | 
				
			||||||
@ -3855,9 +4008,9 @@ begin
 | 
				
			|||||||
  fFoldTree.Clear;
 | 
					  fFoldTree.Clear;
 | 
				
			||||||
  i := 0;
 | 
					  i := 0;
 | 
				
			||||||
  while i < fLines.Count do begin
 | 
					  while i < fLines.Count do begin
 | 
				
			||||||
    if (hl.FoldOpenCount(i, t) > 0)
 | 
					    if (hl.FoldBlockOpeningCount(i, t) > 0)
 | 
				
			||||||
    and (hl.FoldNestCount(i, t) > StartLevel) then begin
 | 
					    and (hl.FoldBlockEndLevel(i, t) > StartLevel) then begin
 | 
				
			||||||
      c := hl.FoldOpenCount(i) -1;
 | 
					      c := hl.FoldBlockOpeningCount(i) -1;
 | 
				
			||||||
      fldinf := FoldProvider.InfoForFoldAtTextIndex(i, c);
 | 
					      fldinf := FoldProvider.InfoForFoldAtTextIndex(i, c);
 | 
				
			||||||
      // i is 0-based
 | 
					      // i is 0-based
 | 
				
			||||||
      // FoldTree is 1-based AND first line remains visble
 | 
					      // FoldTree is 1-based AND first line remains visble
 | 
				
			||||||
@ -4111,7 +4264,7 @@ begin
 | 
				
			|||||||
  hl := TSynCustomFoldHighlighter(HighLighter);
 | 
					  hl := TSynCustomFoldHighlighter(HighLighter);
 | 
				
			||||||
  if not assigned(hl) then
 | 
					  if not assigned(hl) then
 | 
				
			||||||
    exit(-1);
 | 
					    exit(-1);
 | 
				
			||||||
  Result := hl.FoldNestCount(AStartIndex-1, AType) + FoldProvider.FoldOpenCount(AStartIndex);
 | 
					  Result := hl.FoldBlockEndLevel(AStartIndex-1, AType) + FoldProvider.FoldOpenCount(AStartIndex);
 | 
				
			||||||
end;
 | 
					end;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function TSynEditFoldedView.OpenFoldInfo(aStartIndex, ColIndex: Integer; AType: Integer = 0): TFoldViewNodeInfo;
 | 
					function TSynEditFoldedView.OpenFoldInfo(aStartIndex, ColIndex: Integer; AType: Integer = 0): TFoldViewNodeInfo;
 | 
				
			||||||
@ -4126,13 +4279,13 @@ var
 | 
				
			|||||||
  begin
 | 
					  begin
 | 
				
			||||||
    if AType = 0 then begin;
 | 
					    if AType = 0 then begin;
 | 
				
			||||||
      for i := 1 to TypeCnt do begin
 | 
					      for i := 1 to TypeCnt do begin
 | 
				
			||||||
        EndLvl[i] := hl.FoldNestCount(l-1, i);
 | 
					        EndLvl[i] := hl.FoldBlockEndLevel(l-1, i);
 | 
				
			||||||
        EndLvl[i] := EndLvl[i] + FoldProvider.FoldOpenCount(l, i);
 | 
					        EndLvl[i] := EndLvl[i] + FoldProvider.FoldOpenCount(l, i);
 | 
				
			||||||
        CurLvl[i] := EndLvl[i];
 | 
					        CurLvl[i] := EndLvl[i];
 | 
				
			||||||
      end;
 | 
					      end;
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
    else begin
 | 
					    else begin
 | 
				
			||||||
      EndLvl[0] := hl.FoldNestCount(l-1, AType);
 | 
					      EndLvl[0] := hl.FoldBlockEndLevel(l-1, AType);
 | 
				
			||||||
      EndLvl[0] := EndLvl[0] + FoldProvider.FoldOpenCount(l, AType);
 | 
					      EndLvl[0] := EndLvl[0] + FoldProvider.FoldOpenCount(l, AType);
 | 
				
			||||||
      CurLvl[0] := EndLvl[0];
 | 
					      CurLvl[0] := EndLvl[0];
 | 
				
			||||||
    end;
 | 
					    end;
 | 
				
			||||||
@ -4146,7 +4299,7 @@ begin
 | 
				
			|||||||
    TypeCnt := 1
 | 
					    TypeCnt := 1
 | 
				
			||||||
  else
 | 
					  else
 | 
				
			||||||
    TypeCnt := hl.FoldTypeCount;
 | 
					    TypeCnt := hl.FoldTypeCount;
 | 
				
			||||||
  Lvl := hl.FoldNestCount(AStartIndex-1, AType);
 | 
					  Lvl := hl.FoldBlockEndLevel(AStartIndex-1, AType);
 | 
				
			||||||
  if ColIndex >= Lvl then begin
 | 
					  if ColIndex >= Lvl then begin
 | 
				
			||||||
    n := ColIndex - Lvl;
 | 
					    n := ColIndex - Lvl;
 | 
				
			||||||
    if AType = 0 then begin
 | 
					    if AType = 0 then begin
 | 
				
			||||||
@ -4165,8 +4318,8 @@ begin
 | 
				
			|||||||
    aStartIndex := aStartIndex;
 | 
					    aStartIndex := aStartIndex;
 | 
				
			||||||
    while (ColIndex < Lvl) and (aStartIndex > 0) do begin
 | 
					    while (ColIndex < Lvl) and (aStartIndex > 0) do begin
 | 
				
			||||||
      dec(aStartIndex);
 | 
					      dec(aStartIndex);
 | 
				
			||||||
      o := hl.FoldOpenCount(AStartIndex, AType);
 | 
					      o := hl.FoldBlockOpeningCount(AStartIndex, AType);
 | 
				
			||||||
      if (o > 0) or (hl.FoldCloseCount(aStartIndex, AType) > 0) then begin
 | 
					      if (o > 0) or (hl.FoldBlockClosingCount(aStartIndex, AType) > 0) then begin
 | 
				
			||||||
        n := o;
 | 
					        n := o;
 | 
				
			||||||
        c := hl.FoldNodeInfo[aStartIndex].CountEx([], AType) - 1;
 | 
					        c := hl.FoldNodeInfo[aStartIndex].CountEx([], AType) - 1;
 | 
				
			||||||
        for i := c downto 0 do begin
 | 
					        for i := c downto 0 do begin
 | 
				
			||||||
@ -4194,7 +4347,7 @@ begin
 | 
				
			|||||||
        end;
 | 
					        end;
 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
      else
 | 
					      else
 | 
				
			||||||
      if hl.FoldNestCount(AStartIndex-1, AType) = 0 then break;
 | 
					      if hl.FoldBlockEndLevel(AStartIndex-1, AType) = 0 then break;
 | 
				
			||||||
    end;
 | 
					    end;
 | 
				
			||||||
  end;
 | 
					  end;
 | 
				
			||||||
  Result.HNode := nd;
 | 
					  Result.HNode := nd;
 | 
				
			||||||
@ -4220,7 +4373,7 @@ begin
 | 
				
			|||||||
    exit;
 | 
					    exit;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  i := ALine;
 | 
					  i := ALine;
 | 
				
			||||||
  l := hl.FoldOpenCount(i - 1);
 | 
					  l := hl.FoldBlockOpeningCount(i - 1);
 | 
				
			||||||
  if l > 0 then begin
 | 
					  if l > 0 then begin
 | 
				
			||||||
    node := fFoldTree.FindFoldForLine(ALine, true);
 | 
					    node := fFoldTree.FindFoldForLine(ALine, true);
 | 
				
			||||||
    if node.IsInFold and (node.StartLine = ALine +1) then begin
 | 
					    if node.IsInFold and (node.StartLine = ALine +1) then begin
 | 
				
			||||||
@ -4234,19 +4387,19 @@ begin
 | 
				
			|||||||
    else
 | 
					    else
 | 
				
			||||||
      exit(ALine);
 | 
					      exit(ALine);
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
  else if hl.FoldCloseCount(i - 1) > 0 then
 | 
					  else if hl.FoldBlockClosingCount(i - 1) > 0 then
 | 
				
			||||||
    dec(i);
 | 
					    dec(i);
 | 
				
			||||||
  if (i < 0) or (hl.FoldNestCount(i-1) = 0) then
 | 
					  if (i < 0) or (hl.FoldBlockEndLevel(i-1) = 0) then
 | 
				
			||||||
    exit;
 | 
					    exit;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  l := 0;
 | 
					  l := 0;
 | 
				
			||||||
  while (i > 0) and (l >= 0) do begin // (FoldMinLevel[i] >= l) do
 | 
					  while (i > 0) and (l >= 0) do begin // (FoldMinLevel[i] >= l) do
 | 
				
			||||||
    dec(i);
 | 
					    dec(i);
 | 
				
			||||||
    l := l - hl.FoldOpenCount(i);
 | 
					    l := l - hl.FoldBlockOpeningCount(i);
 | 
				
			||||||
    if l >= 0 then
 | 
					    if l >= 0 then
 | 
				
			||||||
      l := l + hl.FoldCloseCount(i);
 | 
					      l := l + hl.FoldBlockClosingCount(i);
 | 
				
			||||||
  end;
 | 
					  end;
 | 
				
			||||||
  if (hl.FoldNestCount(i) > 0) then // TODO, check for collapsed at index = 0
 | 
					  if (hl.FoldBlockEndLevel(i) > 0) then // TODO, check for collapsed at index = 0
 | 
				
			||||||
    Result := i + 1;
 | 
					    Result := i + 1;
 | 
				
			||||||
end;
 | 
					end;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -22,9 +22,25 @@ $Id: synedithighlighter.pp 19051 2009-03-21 00:47:33Z martin $
 | 
				
			|||||||
You may retrieve the latest version of this file at the SynEdit home page,
 | 
					You may retrieve the latest version of this file at the SynEdit home page,
 | 
				
			||||||
located at http://SynEdit.SourceForge.net
 | 
					located at http://SynEdit.SourceForge.net
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Known Issues:
 | 
					 | 
				
			||||||
-------------------------------------------------------------------------------}
 | 
					-------------------------------------------------------------------------------}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(* Naming Conventions:
 | 
				
			||||||
 | 
					   -  FoldBlock:
 | 
				
			||||||
 | 
					     A continuous range of lines, that can (optional) be folded.
 | 
				
			||||||
 | 
					     Which Foldblocks can be folded is decided by the Highlighter. It may be
 | 
				
			||||||
 | 
					     configurable.
 | 
				
			||||||
 | 
					     A Foldblock can contain other Foldbloccks (nested), but two Foldblocks can
 | 
				
			||||||
 | 
					     not overlap.
 | 
				
			||||||
 | 
					   -  FoldBlockLevel (FoldBlockNestLevel):
 | 
				
			||||||
 | 
					     The amount of FoldBlocks in which a line (or a point of text) is.
 | 
				
			||||||
 | 
					   -  FoldGroup:
 | 
				
			||||||
 | 
					     An independent set of FoldBlocks. FoldBlocks in different Groups may overlap.
 | 
				
			||||||
 | 
					     (e.g. IFDEF/REGION in the SynPasSyn allow for overlaps, rather than strict nesting)
 | 
				
			||||||
 | 
					     Some older code use "FoldType" instead
 | 
				
			||||||
 | 
					   -  FoldNode
 | 
				
			||||||
 | 
					     Start or End of a FoldBlock
 | 
				
			||||||
 | 
					*)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
unit SynEditHighlighterFoldBase;
 | 
					unit SynEditHighlighterFoldBase;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
{$I synedit.inc}
 | 
					{$I synedit.inc}
 | 
				
			||||||
@ -54,6 +70,42 @@ type
 | 
				
			|||||||
                   );
 | 
					                   );
 | 
				
			||||||
  TSynFoldActions = set of TSynFoldAction;
 | 
					  TSynFoldActions = set of TSynFoldAction;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  (* TSynFoldBlockFilter
 | 
				
			||||||
 | 
					     used to specify which folds to include for:
 | 
				
			||||||
 | 
					     - FoldOpenCount, FoldCloseCount, FoldNestCount
 | 
				
			||||||
 | 
					     - maybe in future TLazSynFoldNodeInfoList
 | 
				
			||||||
 | 
					       TLazSynFoldNodeInfoList has additional filters
 | 
				
			||||||
 | 
					       TLazSynFoldNodeInfoList always uses the full set (sfbIncludeDisabled)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					     A Highlighter is not required to implement this, or can choose to implement
 | 
				
			||||||
 | 
					     a subset only. For any field/value a Highlighter may simple assume default.
 | 
				
			||||||
 | 
					     - Highlighter that have only one "FoldGroup" do not require this.
 | 
				
			||||||
 | 
					     - Highlighter that do not store foldblocks that are unavailable (e.g. off by
 | 
				
			||||||
 | 
					       config) always return the same set
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					     Using a record, as argument is the virtual methods, allows to add further
 | 
				
			||||||
 | 
					     fields/values, without breaking inheritance.
 | 
				
			||||||
 | 
					     New fields values are expected to be ignored (handled as default) by existing
 | 
				
			||||||
 | 
					     highlighter.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					     Callers of the method can:
 | 
				
			||||||
 | 
					     - use InitFoldBlockFilter to make sure all fields are set to default
 | 
				
			||||||
 | 
					     - use (none virtual) wrapper methods
 | 
				
			||||||
 | 
					  *)
 | 
				
			||||||
 | 
					  TSynFoldBlockFilterFlag = (
 | 
				
			||||||
 | 
					    sfbIncludeDisabled // Foldable by config = off
 | 
				
			||||||
 | 
					  );
 | 
				
			||||||
 | 
					  TSynFoldBlockFilterFlags = set of TSynFoldBlockFilterFlag;
 | 
				
			||||||
 | 
					  TSynFoldBlockFilter = record
 | 
				
			||||||
 | 
					    FoldGroup: integer;
 | 
				
			||||||
 | 
					    Flags: TSynFoldBlockFilterFlags;
 | 
				
			||||||
 | 
					  end;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					procedure InitFoldBlockFilter(out AFilter: TSynFoldBlockFilter;
 | 
				
			||||||
 | 
					                              AFoldGroup: Integer = 0; AFlag: TSynFoldBlockFilterFlags = []);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  TSynFoldNodeInfo = record
 | 
					  TSynFoldNodeInfo = record
 | 
				
			||||||
    LineIndex: Integer;
 | 
					    LineIndex: Integer;
 | 
				
			||||||
    NodeIndex: Integer;          // Indicates the position within the list of info nodes (depends on search-Filter)
 | 
					    NodeIndex: Integer;          // Indicates the position within the list of info nodes (depends on search-Filter)
 | 
				
			||||||
@ -204,7 +256,7 @@ type
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  TSynCustomFoldHighlighter = class(TSynCustomHighlighter)
 | 
					  TSynCustomFoldHighlighter = class(TSynCustomHighlighter)
 | 
				
			||||||
  protected
 | 
					  protected
 | 
				
			||||||
    // Config
 | 
					    // Fold Config
 | 
				
			||||||
    FFoldConfig: Array of TSynCustomFoldConfig;
 | 
					    FFoldConfig: Array of TSynCustomFoldConfig;
 | 
				
			||||||
    function GetFoldConfig(Index: Integer): TSynCustomFoldConfig; virtual;
 | 
					    function GetFoldConfig(Index: Integer): TSynCustomFoldConfig; virtual;
 | 
				
			||||||
    procedure SetFoldConfig(Index: Integer; const AValue: TSynCustomFoldConfig); virtual;
 | 
					    procedure SetFoldConfig(Index: Integer; const AValue: TSynCustomFoldConfig); virtual;
 | 
				
			||||||
@ -220,36 +272,55 @@ type
 | 
				
			|||||||
    FRootCodeFoldBlock: TSynCustomCodeFoldBlock;
 | 
					    FRootCodeFoldBlock: TSynCustomCodeFoldBlock;
 | 
				
			||||||
    FFoldNodeInfoList: TLazSynFoldNodeInfoList;
 | 
					    FFoldNodeInfoList: TLazSynFoldNodeInfoList;
 | 
				
			||||||
  protected
 | 
					  protected
 | 
				
			||||||
    function CreateFoldNodeInfoList: TLazSynFoldNodeInfoList; virtual;
 | 
					    // "Range"
 | 
				
			||||||
    function GetFoldNodeInfo(Line: TLineIdx): TLazSynFoldNodeInfoList;
 | 
					 | 
				
			||||||
    procedure InitFoldNodeInfo(AList: TLazSynFoldNodeInfoList; Line: TLineIdx); virtual;
 | 
					 | 
				
			||||||
  protected
 | 
					 | 
				
			||||||
    property CodeFoldRange: TSynCustomHighlighterRange read FCodeFoldRange;
 | 
					 | 
				
			||||||
    function GetRangeClass: TSynCustomHighlighterRangeClass; virtual;
 | 
					    function GetRangeClass: TSynCustomHighlighterRangeClass; virtual;
 | 
				
			||||||
 | 
					    procedure CreateRootCodeFoldBlock; virtual; // set RootCodeFoldBlock
 | 
				
			||||||
 | 
					    property CodeFoldRange: TSynCustomHighlighterRange read FCodeFoldRange;
 | 
				
			||||||
    function TopCodeFoldBlockType(DownIndex: Integer = 0): Pointer;
 | 
					    function TopCodeFoldBlockType(DownIndex: Integer = 0): Pointer;
 | 
				
			||||||
 | 
					    property RootCodeFoldBlock: TSynCustomCodeFoldBlock read FRootCodeFoldBlock
 | 
				
			||||||
 | 
					      write FRootCodeFoldBlock;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Open/Close Folds
 | 
				
			||||||
    function StartCodeFoldBlock(ABlockType: Pointer;
 | 
					    function StartCodeFoldBlock(ABlockType: Pointer;
 | 
				
			||||||
              IncreaseLevel: Boolean = true): TSynCustomCodeFoldBlock; virtual;
 | 
					              IncreaseLevel: Boolean = true): TSynCustomCodeFoldBlock; virtual;
 | 
				
			||||||
    procedure EndCodeFoldBlock(DecreaseLevel: Boolean = True); virtual;
 | 
					    procedure EndCodeFoldBlock(DecreaseLevel: Boolean = True); virtual;
 | 
				
			||||||
    procedure CreateRootCodeFoldBlock; virtual;
 | 
					
 | 
				
			||||||
    property RootCodeFoldBlock: TSynCustomCodeFoldBlock read FRootCodeFoldBlock
 | 
					    // Info about Folds
 | 
				
			||||||
      write FRootCodeFoldBlock;
 | 
					    function CreateFoldNodeInfoList: TLazSynFoldNodeInfoList; virtual;
 | 
				
			||||||
 | 
					    function GetFoldNodeInfo(Line: TLineIdx): TLazSynFoldNodeInfoList;
 | 
				
			||||||
 | 
					    procedure InitFoldNodeInfo(AList: TLazSynFoldNodeInfoList; Line: TLineIdx); virtual;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Info about Folds, on currently set line/range (simply forwarding to range
 | 
				
			||||||
 | 
					    function MinimumCodeFoldBlockLevel: integer; virtual;
 | 
				
			||||||
 | 
					    function CurrentCodeFoldBlockLevel: integer; virtual;
 | 
				
			||||||
  public
 | 
					  public
 | 
				
			||||||
    constructor Create(AOwner: TComponent); override;
 | 
					    constructor Create(AOwner: TComponent); override;
 | 
				
			||||||
    destructor Destroy; override;
 | 
					    destructor Destroy; override;
 | 
				
			||||||
    function GetRange: Pointer; override;
 | 
					    function GetRange: Pointer; override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    function MinimumCodeFoldBlockLevel: integer; virtual;
 | 
					    // Info about Folds
 | 
				
			||||||
    function CurrentCodeFoldBlockLevel: integer; virtual;
 | 
					    function FoldBlockOpeningCount(ALineIndex: TLineIdx;
 | 
				
			||||||
 | 
					                                   const AFilter: TSynFoldBlockFilter): integer; virtual; overload;
 | 
				
			||||||
 | 
					    function FoldBlockClosingCount(ALineIndex: TLineIdx;
 | 
				
			||||||
 | 
					                                   const AFilter: TSynFoldBlockFilter): integer; virtual; overload;
 | 
				
			||||||
 | 
					    function FoldBlockEndLevel(ALineIndex: TLineIdx;
 | 
				
			||||||
 | 
					                               const AFilter: TSynFoldBlockFilter): integer; virtual; overload;
 | 
				
			||||||
 | 
					    function FoldBlockMinLevel(ALineIndex: TLineIdx;
 | 
				
			||||||
 | 
					                               const AFilter: TSynFoldBlockFilter): integer; virtual; overload;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // requires CurrentLines;
 | 
					    function FoldBlockOpeningCount(ALineIndex: TLineIdx; AFoldGroup: integer = 0;
 | 
				
			||||||
    function MinimumFoldLevel(Index: Integer): integer; virtual; abstract;      // TODO: Move to Fold*
 | 
					                                   AFlags: TSynFoldBlockFilterFlags = []): integer; overload;
 | 
				
			||||||
    function EndFoldLevel(Index: Integer): integer; virtual; abstract;          // TODO: Replace with FoldNestCount
 | 
					    function FoldBlockClosingCount(ALineIndex: TLineIdx; AFoldGroup: integer = 0;
 | 
				
			||||||
 | 
					                                   AFlags: TSynFoldBlockFilterFlags = []): integer; overload;
 | 
				
			||||||
 | 
					    function FoldBlockEndLevel(ALineIndex: TLineIdx; AFoldGroup: integer = 0;
 | 
				
			||||||
 | 
					                               AFlags: TSynFoldBlockFilterFlags = []): integer; overload;
 | 
				
			||||||
 | 
					    function FoldBlockMinLevel(ALineIndex: TLineIdx; AFoldGroup: integer = 0;
 | 
				
			||||||
 | 
					                               AFlags: TSynFoldBlockFilterFlags = []): integer; overload;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    function FoldOpenCount(ALineIndex: Integer; AType: Integer = 0): integer;  deprecated;
 | 
				
			||||||
 | 
					    function FoldCloseCount(ALineIndex: Integer; AType: Integer = 0): integer; deprecated;
 | 
				
			||||||
 | 
					    function FoldNestCount(ALineIndex: Integer; AType: Integer = 0): integer; deprecated;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // fold-nodes that can be collapsed
 | 
					 | 
				
			||||||
    // Highlighter can join several fold structures Or leave out some
 | 
					 | 
				
			||||||
    function FoldOpenCount(ALineIndex: Integer; AType: Integer = 0): integer; virtual;
 | 
					 | 
				
			||||||
    function FoldCloseCount(ALineIndex: Integer; AType: Integer = 0): integer; virtual;
 | 
					 | 
				
			||||||
    function FoldNestCount(ALineIndex: Integer; AType: Integer = 0): integer; virtual;
 | 
					 | 
				
			||||||
    function FoldTypeCount: integer; virtual;
 | 
					    function FoldTypeCount: integer; virtual;
 | 
				
			||||||
    function FoldTypeAtNodeIndex(ALineIndex, FoldIndex: Integer;
 | 
					    function FoldTypeAtNodeIndex(ALineIndex, FoldIndex: Integer;
 | 
				
			||||||
             UseCloseNodes: boolean = false): integer; virtual; // TODO: could be deprecated ./ only child-classes
 | 
					             UseCloseNodes: boolean = false): integer; virtual; // TODO: could be deprecated ./ only child-classes
 | 
				
			||||||
@ -296,6 +367,13 @@ function AllocateHighlighterRanges(
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
implementation
 | 
					implementation
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					procedure InitFoldBlockFilter(out AFilter: TSynFoldBlockFilter; AFoldGroup: Integer;
 | 
				
			||||||
 | 
					  AFlag: TSynFoldBlockFilterFlags = []);
 | 
				
			||||||
 | 
					begin
 | 
				
			||||||
 | 
					  AFilter.FoldGroup := AFoldGroup;
 | 
				
			||||||
 | 
					  AFilter.Flags     := AFlag;
 | 
				
			||||||
 | 
					end;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function CompareSynHighlighterRanges(Data1, Data2: Pointer): integer;
 | 
					function CompareSynHighlighterRanges(Data1, Data2: Pointer): integer;
 | 
				
			||||||
var
 | 
					var
 | 
				
			||||||
  Range1: TSynCustomHighlighterRange;
 | 
					  Range1: TSynCustomHighlighterRange;
 | 
				
			||||||
@ -597,6 +675,92 @@ begin
 | 
				
			|||||||
  Result:=fRanges.GetEqual(FCodeFoldRange);
 | 
					  Result:=fRanges.GetEqual(FCodeFoldRange);
 | 
				
			||||||
end;
 | 
					end;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function TSynCustomFoldHighlighter.FoldBlockOpeningCount(ALineIndex: TLineIdx;
 | 
				
			||||||
 | 
					  const AFilter: TSynFoldBlockFilter): integer;
 | 
				
			||||||
 | 
					begin
 | 
				
			||||||
 | 
					  if (ALineIndex < 0) or (ALineIndex >= CurrentLines.Count) then
 | 
				
			||||||
 | 
					    exit(0);
 | 
				
			||||||
 | 
					  Result := FoldBlockEndLevel(ALineIndex, AFilter) - FoldBlockMinLevel(ALineIndex, AFilter);
 | 
				
			||||||
 | 
					end;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function TSynCustomFoldHighlighter.FoldBlockClosingCount(ALineIndex: TLineIdx;
 | 
				
			||||||
 | 
					  const AFilter: TSynFoldBlockFilter): integer;
 | 
				
			||||||
 | 
					begin
 | 
				
			||||||
 | 
					  if (ALineIndex < 0) or (ALineIndex >= CurrentLines.Count) then
 | 
				
			||||||
 | 
					    exit(0);
 | 
				
			||||||
 | 
					  Result := FoldBlockEndLevel(ALineIndex - 1, AFilter) - FoldBlockMinLevel(ALineIndex, AFilter);
 | 
				
			||||||
 | 
					end;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function TSynCustomFoldHighlighter.FoldBlockEndLevel(ALineIndex: TLineIdx;
 | 
				
			||||||
 | 
					  const AFilter: TSynFoldBlockFilter): integer;
 | 
				
			||||||
 | 
					var
 | 
				
			||||||
 | 
					  r: Pointer;
 | 
				
			||||||
 | 
					begin
 | 
				
			||||||
 | 
					  Assert(CurrentRanges <> nil, 'TSynCustomFoldHighlighter.FoldBlockEndLevel requires CurrentRanges');
 | 
				
			||||||
 | 
					  if (ALineIndex < 0) or (ALineIndex >= CurrentLines.Count) then
 | 
				
			||||||
 | 
					    exit(0);
 | 
				
			||||||
 | 
					  r := CurrentRanges[ALineIndex];
 | 
				
			||||||
 | 
					  if (r <> nil) and (r <> NullRange) then
 | 
				
			||||||
 | 
					    Result := TSynCustomHighlighterRange(r).CodeFoldStackSize
 | 
				
			||||||
 | 
					  else
 | 
				
			||||||
 | 
					    Result:=0;
 | 
				
			||||||
 | 
					end;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function TSynCustomFoldHighlighter.FoldBlockMinLevel(ALineIndex: TLineIdx;
 | 
				
			||||||
 | 
					  const AFilter: TSynFoldBlockFilter): integer;
 | 
				
			||||||
 | 
					var
 | 
				
			||||||
 | 
					  r: Pointer;
 | 
				
			||||||
 | 
					begin
 | 
				
			||||||
 | 
					  Assert(CurrentRanges <> nil, 'TSynCustomFoldHighlighter.FoldBlockMinLevelrequires CurrentRanges');
 | 
				
			||||||
 | 
					  if (ALineIndex < 0) or (ALineIndex >= CurrentLines.Count) then
 | 
				
			||||||
 | 
					    exit(0);
 | 
				
			||||||
 | 
					  r := CurrentRanges[ALineIndex];
 | 
				
			||||||
 | 
					  if (r <> nil) and (r <> NullRange) then
 | 
				
			||||||
 | 
					    Result := TSynCustomHighlighterRange(r).MinimumCodeFoldBlockLevel
 | 
				
			||||||
 | 
					  else
 | 
				
			||||||
 | 
					    Result:=0;
 | 
				
			||||||
 | 
					end;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function TSynCustomFoldHighlighter.FoldBlockOpeningCount(ALineIndex: TLineIdx;
 | 
				
			||||||
 | 
					  AFoldGroup: integer; AFlags: TSynFoldBlockFilterFlags): integer;
 | 
				
			||||||
 | 
					var
 | 
				
			||||||
 | 
					  Filter: TSynFoldBlockFilter;
 | 
				
			||||||
 | 
					begin
 | 
				
			||||||
 | 
					  Filter.FoldGroup := AFoldGroup;
 | 
				
			||||||
 | 
					  Filter.Flags := AFlags;
 | 
				
			||||||
 | 
					  Result := FoldBlockOpeningCount(ALineIndex, Filter);
 | 
				
			||||||
 | 
					end;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function TSynCustomFoldHighlighter.FoldBlockClosingCount(ALineIndex: TLineIdx;
 | 
				
			||||||
 | 
					  AFoldGroup: integer; AFlags: TSynFoldBlockFilterFlags): integer;
 | 
				
			||||||
 | 
					var
 | 
				
			||||||
 | 
					  Filter: TSynFoldBlockFilter;
 | 
				
			||||||
 | 
					begin
 | 
				
			||||||
 | 
					  Filter.FoldGroup := AFoldGroup;
 | 
				
			||||||
 | 
					  Filter.Flags := AFlags;
 | 
				
			||||||
 | 
					  Result := FoldBlockClosingCount(ALineIndex, Filter);
 | 
				
			||||||
 | 
					end;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function TSynCustomFoldHighlighter.FoldBlockEndLevel(ALineIndex: TLineIdx;
 | 
				
			||||||
 | 
					  AFoldGroup: integer; AFlags: TSynFoldBlockFilterFlags): integer;
 | 
				
			||||||
 | 
					var
 | 
				
			||||||
 | 
					  Filter: TSynFoldBlockFilter;
 | 
				
			||||||
 | 
					begin
 | 
				
			||||||
 | 
					  Filter.FoldGroup := AFoldGroup;
 | 
				
			||||||
 | 
					  Filter.Flags := AFlags;
 | 
				
			||||||
 | 
					  Result := FoldBlockEndLevel(ALineIndex, Filter);
 | 
				
			||||||
 | 
					end;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function TSynCustomFoldHighlighter.FoldBlockMinLevel(ALineIndex: TLineIdx;
 | 
				
			||||||
 | 
					  AFoldGroup: integer; AFlags: TSynFoldBlockFilterFlags): integer;
 | 
				
			||||||
 | 
					var
 | 
				
			||||||
 | 
					  Filter: TSynFoldBlockFilter;
 | 
				
			||||||
 | 
					begin
 | 
				
			||||||
 | 
					  Filter.FoldGroup := AFoldGroup;
 | 
				
			||||||
 | 
					  Filter.Flags := AFlags;
 | 
				
			||||||
 | 
					  Result := FoldBlockMinLevel(ALineIndex, Filter);
 | 
				
			||||||
 | 
					end;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
procedure TSynCustomFoldHighlighter.ResetRange;
 | 
					procedure TSynCustomFoldHighlighter.ResetRange;
 | 
				
			||||||
begin
 | 
					begin
 | 
				
			||||||
  FCodeFoldRange.Clear;
 | 
					  FCodeFoldRange.Clear;
 | 
				
			||||||
@ -605,6 +769,7 @@ end;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
function TSynCustomFoldHighlighter.MinimumCodeFoldBlockLevel: integer;
 | 
					function TSynCustomFoldHighlighter.MinimumCodeFoldBlockLevel: integer;
 | 
				
			||||||
begin
 | 
					begin
 | 
				
			||||||
 | 
					  assert(FCodeFoldRange <> nil, 'MinimumCodeFoldBlockLevel requires FCodeFoldRange');
 | 
				
			||||||
  Result := FCodeFoldRange.MinimumCodeFoldBlockLevel;
 | 
					  Result := FCodeFoldRange.MinimumCodeFoldBlockLevel;
 | 
				
			||||||
end;
 | 
					end;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -625,25 +790,23 @@ end;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
function TSynCustomFoldHighlighter.CurrentCodeFoldBlockLevel: integer;
 | 
					function TSynCustomFoldHighlighter.CurrentCodeFoldBlockLevel: integer;
 | 
				
			||||||
begin
 | 
					begin
 | 
				
			||||||
  if CodeFoldRange<>nil then
 | 
					  assert(FCodeFoldRange <> nil, 'MinimumCodeFoldBlockLevel requires FCodeFoldRange');
 | 
				
			||||||
    Result:=CodeFoldRange.CodeFoldStackSize
 | 
					  Result := FCodeFoldRange.CodeFoldStackSize;
 | 
				
			||||||
  else
 | 
					 | 
				
			||||||
    Result:=0;
 | 
					 | 
				
			||||||
end;
 | 
					end;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function TSynCustomFoldHighlighter.FoldOpenCount(ALineIndex: Integer; AType: Integer = 0): integer;
 | 
					function TSynCustomFoldHighlighter.FoldOpenCount(ALineIndex: Integer; AType: Integer = 0): integer;
 | 
				
			||||||
begin
 | 
					begin
 | 
				
			||||||
  result := 0;
 | 
					  result := FoldBlockOpeningCount(ALineIndex, AType);
 | 
				
			||||||
end;
 | 
					end;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function TSynCustomFoldHighlighter.FoldCloseCount(ALineIndex: Integer; AType: Integer = 0): integer;
 | 
					function TSynCustomFoldHighlighter.FoldCloseCount(ALineIndex: Integer; AType: Integer = 0): integer;
 | 
				
			||||||
begin
 | 
					begin
 | 
				
			||||||
  result := 0;
 | 
					  result := FoldBlockClosingCount(ALineIndex, AType);
 | 
				
			||||||
end;
 | 
					end;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function TSynCustomFoldHighlighter.FoldNestCount(ALineIndex: Integer; AType: Integer = 0): integer;
 | 
					function TSynCustomFoldHighlighter.FoldNestCount(ALineIndex: Integer; AType: Integer = 0): integer;
 | 
				
			||||||
begin
 | 
					begin
 | 
				
			||||||
  Result := 0;
 | 
					  Result := FoldBlockEndLevel(ALineIndex, AType);
 | 
				
			||||||
end;
 | 
					end;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function TSynCustomFoldHighlighter.FoldTypeCount: integer;
 | 
					function TSynCustomFoldHighlighter.FoldTypeCount: integer;
 | 
				
			||||||
@ -661,7 +824,7 @@ function TSynCustomFoldHighlighter.FoldLineLength(ALineIndex, FoldIndex: Integer
 | 
				
			|||||||
begin
 | 
					begin
 | 
				
			||||||
  Result := FoldEndLine(ALineIndex, FoldIndex);
 | 
					  Result := FoldEndLine(ALineIndex, FoldIndex);
 | 
				
			||||||
  // check if fold last line of block (not mixed "end begin")
 | 
					  // check if fold last line of block (not mixed "end begin")
 | 
				
			||||||
  if (EndFoldLevel(Result) > MinimumFoldLevel(Result)) then
 | 
					  if (FoldBlockEndLevel(Result) > FoldBlockMinLevel(Result)) then
 | 
				
			||||||
    dec(Result);
 | 
					    dec(Result);
 | 
				
			||||||
  // Amount of lines, that will become invisible (excludes the cfCollapsed line)
 | 
					  // Amount of lines, that will become invisible (excludes the cfCollapsed line)
 | 
				
			||||||
  Result := Result - ALineIndex;
 | 
					  Result := Result - ALineIndex;
 | 
				
			||||||
@ -672,13 +835,12 @@ var
 | 
				
			|||||||
  lvl, cnt: Integer;
 | 
					  lvl, cnt: Integer;
 | 
				
			||||||
  e, m: Integer;
 | 
					  e, m: Integer;
 | 
				
			||||||
begin
 | 
					begin
 | 
				
			||||||
  //atype := FoldTypeAtNodeIndex(ALineIndex, FoldIndex);
 | 
					 | 
				
			||||||
  cnt := CurrentLines.Count;
 | 
					  cnt := CurrentLines.Count;
 | 
				
			||||||
  e := EndFoldLevel(ALineIndex);
 | 
					  e := FoldBlockEndLevel(ALineIndex);
 | 
				
			||||||
  m := MinimumFoldLevel(ALineIndex);
 | 
					  m := FoldBlockMinLevel(ALineIndex);
 | 
				
			||||||
  lvl := Min(m+1+FoldIndex, e);
 | 
					  lvl := Min(m+1+FoldIndex, e);
 | 
				
			||||||
  Result := ALineIndex + 1;
 | 
					  Result := ALineIndex + 1;
 | 
				
			||||||
  while (Result < cnt) and (MinimumFoldLevel(Result) >= lvl) do inc(Result);
 | 
					  while (Result < cnt) and (FoldBlockMinLevel(Result) >= lvl) do inc(Result);
 | 
				
			||||||
  if (Result = cnt) then
 | 
					  if (Result = cnt) then
 | 
				
			||||||
    dec(Result);
 | 
					    dec(Result);
 | 
				
			||||||
end;
 | 
					end;
 | 
				
			||||||
 | 
				
			|||||||
@ -75,13 +75,6 @@ type
 | 
				
			|||||||
    procedure EndXmlNodeCodeFoldBlock(ClosePos: Integer = -1; AName: String = '');
 | 
					    procedure EndXmlNodeCodeFoldBlock(ClosePos: Integer = -1; AName: String = '');
 | 
				
			||||||
  public
 | 
					  public
 | 
				
			||||||
    procedure SetLine({$IFDEF FPC}const {$ENDIF}NewValue: string; LineNumber:Integer); override;
 | 
					    procedure SetLine({$IFDEF FPC}const {$ENDIF}NewValue: string; LineNumber:Integer); override;
 | 
				
			||||||
  public
 | 
					 | 
				
			||||||
    function FoldOpenCount(ALineIndex: Integer; AType: Integer = 0): integer; override;
 | 
					 | 
				
			||||||
    function FoldCloseCount(ALineIndex: Integer; AType: Integer = 0): integer; override;
 | 
					 | 
				
			||||||
    function FoldNestCount(ALineIndex: Integer; AType: Integer = 0): integer; override;
 | 
					 | 
				
			||||||
    // TODO: make private
 | 
					 | 
				
			||||||
    function MinimumFoldLevel(ALineIndex: Integer): integer; override;
 | 
					 | 
				
			||||||
    function EndFoldLevel(ALineIndex: Integer): integer; override;
 | 
					 | 
				
			||||||
  end;
 | 
					  end;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
implementation
 | 
					implementation
 | 
				
			||||||
@ -122,50 +115,6 @@ begin
 | 
				
			|||||||
  FXmlRangeInfoClosePos := 0;
 | 
					  FXmlRangeInfoClosePos := 0;
 | 
				
			||||||
end;
 | 
					end;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function TSynCustomXmlHighlighter.FoldOpenCount(ALineIndex: Integer; AType: Integer): integer;
 | 
					 | 
				
			||||||
begin
 | 
					 | 
				
			||||||
  If AType <> 0 then exit(0);
 | 
					 | 
				
			||||||
  Result := EndFoldLevel(ALineIndex) - MinimumFoldLevel(ALineIndex);
 | 
					 | 
				
			||||||
end;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function TSynCustomXmlHighlighter.FoldCloseCount(ALineIndex: Integer; AType: Integer): integer;
 | 
					 | 
				
			||||||
begin
 | 
					 | 
				
			||||||
  If AType <> 0 then exit(0);
 | 
					 | 
				
			||||||
  Result := EndFoldLevel(ALineIndex - 1) - MinimumFoldLevel(ALineIndex);
 | 
					 | 
				
			||||||
end;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function TSynCustomXmlHighlighter.FoldNestCount(ALineIndex: Integer; AType: Integer): integer;
 | 
					 | 
				
			||||||
begin
 | 
					 | 
				
			||||||
  If AType <> 0 then exit(0);
 | 
					 | 
				
			||||||
  Result := EndFoldLevel(ALineIndex);
 | 
					 | 
				
			||||||
end;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function TSynCustomXmlHighlighter.MinimumFoldLevel(ALineIndex: Integer): integer;
 | 
					 | 
				
			||||||
var
 | 
					 | 
				
			||||||
  r: TSynCustomHighlighterRange;
 | 
					 | 
				
			||||||
begin
 | 
					 | 
				
			||||||
  if (ALineIndex < 0) or (ALineIndex >= CurrentLines.Count) then
 | 
					 | 
				
			||||||
    exit(0);
 | 
					 | 
				
			||||||
  r := TSynCustomHighlighterRange(CurrentRanges[ALineIndex]);
 | 
					 | 
				
			||||||
  if (r <> nil) and (Pointer(r) <> NullRange) then
 | 
					 | 
				
			||||||
    Result := r.MinimumCodeFoldBlockLevel
 | 
					 | 
				
			||||||
  else
 | 
					 | 
				
			||||||
    Result := 0;
 | 
					 | 
				
			||||||
end;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function TSynCustomXmlHighlighter.EndFoldLevel(ALineIndex: Integer): integer;
 | 
					 | 
				
			||||||
var
 | 
					 | 
				
			||||||
  r: TSynCustomHighlighterRange;
 | 
					 | 
				
			||||||
begin
 | 
					 | 
				
			||||||
  if (ALineIndex < 0) or (ALineIndex >= CurrentLines.Count) then
 | 
					 | 
				
			||||||
    exit(0);
 | 
					 | 
				
			||||||
  r := TSynCustomHighlighterRange(CurrentRanges[ALineIndex]);
 | 
					 | 
				
			||||||
  if (r <> nil) and (Pointer(r) <> NullRange) then
 | 
					 | 
				
			||||||
    Result := r.CodeFoldStackSize
 | 
					 | 
				
			||||||
  else
 | 
					 | 
				
			||||||
    Result := 0;
 | 
					 | 
				
			||||||
end;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function TSynCustomXmlHighlighter.StartXmlCodeFoldBlock(ABlockType: Integer): TSynCustomCodeFoldBlock;
 | 
					function TSynCustomXmlHighlighter.StartXmlCodeFoldBlock(ABlockType: Integer): TSynCustomCodeFoldBlock;
 | 
				
			||||||
var
 | 
					var
 | 
				
			||||||
  FoldBlock: Boolean;
 | 
					  FoldBlock: Boolean;
 | 
				
			||||||
@ -232,11 +181,11 @@ begin
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
      if i = 0 then begin
 | 
					      if i = 0 then begin
 | 
				
			||||||
        i := LineIndex - 1;
 | 
					        i := LineIndex - 1;
 | 
				
			||||||
        lvl := EndFoldLevel(i);
 | 
					        lvl := FoldBlockEndLevel(i);
 | 
				
			||||||
        while i >= 0 do begin
 | 
					        while i >= 0 do begin
 | 
				
			||||||
          if MinimumFoldLevel(i) < lvl then begin
 | 
					          if FoldBlockMinLevel(i) < lvl then begin
 | 
				
			||||||
            LInfo := TSynHighlighterXmlRangeList(CurrentRanges).XmlRangeInfo[i].ElementOpenList;
 | 
					            LInfo := TSynHighlighterXmlRangeList(CurrentRanges).XmlRangeInfo[i].ElementOpenList;
 | 
				
			||||||
            k := length(LInfo) - Max(EndFoldLevel(i) - lvl, 0) - 1;
 | 
					            k := length(LInfo) - Max(FoldBlockEndLevel(i) - lvl, 0) - 1;
 | 
				
			||||||
            while (k >= 0) do begin
 | 
					            while (k >= 0) do begin
 | 
				
			||||||
              if (LInfo[k] = AName) then
 | 
					              if (LInfo[k] = AName) then
 | 
				
			||||||
                break;
 | 
					                break;
 | 
				
			||||||
 | 
				
			|||||||
@ -140,7 +140,10 @@ var
 | 
				
			|||||||
      exit;
 | 
					      exit;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    inc(YIndex);
 | 
					    inc(YIndex);
 | 
				
			||||||
    while (YIndex < LCnt) and (HL.MinimumFoldLevel(YIndex) > StartNode.NestLvlStart) do
 | 
					    while (YIndex < LCnt) and
 | 
				
			||||||
 | 
					          (HL.FoldBlockMinLevel(YIndex, StartNode.FoldGroup, [sfbIncludeDisabled])
 | 
				
			||||||
 | 
					           > StartNode.NestLvlStart)
 | 
				
			||||||
 | 
					    do
 | 
				
			||||||
      inc(YIndex);
 | 
					      inc(YIndex);
 | 
				
			||||||
    if YIndex = LCnt then
 | 
					    if YIndex = LCnt then
 | 
				
			||||||
      exit;
 | 
					      exit;
 | 
				
			||||||
@ -172,7 +175,9 @@ var
 | 
				
			|||||||
      exit;
 | 
					      exit;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    dec(YIndex);
 | 
					    dec(YIndex);
 | 
				
			||||||
    while (YIndex >= 0) and (HL.MinimumFoldLevel(YIndex) > EndNode.NestLvlEnd) do
 | 
					    while (YIndex >= 0) and
 | 
				
			||||||
 | 
					          (HL.FoldBlockMinLevel(YIndex, EndNode.FoldGroup, [sfbIncludeDisabled]) > EndNode.NestLvlEnd)
 | 
				
			||||||
 | 
					    do
 | 
				
			||||||
      dec(YIndex);
 | 
					      dec(YIndex);
 | 
				
			||||||
    if YIndex < 0 then
 | 
					    if YIndex < 0 then
 | 
				
			||||||
      exit;
 | 
					      exit;
 | 
				
			||||||
 | 
				
			|||||||
@ -157,14 +157,6 @@ type
 | 
				
			|||||||
    function GetFoldConfigInstance(Index: Integer): TSynCustomFoldConfig; override;
 | 
					    function GetFoldConfigInstance(Index: Integer): TSynCustomFoldConfig; override;
 | 
				
			||||||
    function GetFoldConfigCount: Integer; override;
 | 
					    function GetFoldConfigCount: Integer; override;
 | 
				
			||||||
    function GetFoldConfigInternalCount: Integer; override;
 | 
					    function GetFoldConfigInternalCount: Integer; override;
 | 
				
			||||||
  public
 | 
					 | 
				
			||||||
    // folding
 | 
					 | 
				
			||||||
    function FoldOpenCount(ALineIndex: Integer; AType: Integer = 0): integer; override;
 | 
					 | 
				
			||||||
    function FoldCloseCount(ALineIndex: Integer; AType: Integer = 0): integer; override;
 | 
					 | 
				
			||||||
    function FoldNestCount(ALineIndex: Integer; AType: Integer = 0): integer; override;
 | 
					 | 
				
			||||||
    // TODO: make private
 | 
					 | 
				
			||||||
    function MinimumFoldLevel(ALineIndex: Integer): integer; override;
 | 
					 | 
				
			||||||
    function EndFoldLevel(ALineIndex: Integer): integer; override;
 | 
					 | 
				
			||||||
  published
 | 
					  published
 | 
				
			||||||
    property UnknownAttri: TSynHighlighterAttributes read FUnknownAttri write FUnknownAttri;
 | 
					    property UnknownAttri: TSynHighlighterAttributes read FUnknownAttri write FUnknownAttri;
 | 
				
			||||||
    property SpaceAttri: TSynHighlighterAttributes read FSpaceAttri write FSpaceAttri;
 | 
					    property SpaceAttri: TSynHighlighterAttributes read FSpaceAttri write FSpaceAttri;
 | 
				
			||||||
@ -747,56 +739,6 @@ begin
 | 
				
			|||||||
  Result := ord(high(TDiffCodeFoldBlockType)) - ord(low(TDiffCodeFoldBlockType)) + 1;
 | 
					  Result := ord(high(TDiffCodeFoldBlockType)) - ord(low(TDiffCodeFoldBlockType)) + 1;
 | 
				
			||||||
end;
 | 
					end;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// EndLvl = MinLvl(+1)
 | 
					 | 
				
			||||||
// MinLvl = Min(Min, Min(+1))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function TSynDiffSyn.FoldOpenCount(ALineIndex: Integer; AType: Integer): integer;
 | 
					 | 
				
			||||||
begin
 | 
					 | 
				
			||||||
  If AType <> 0 then exit(0);
 | 
					 | 
				
			||||||
  Result := Max(0, MinimumFoldLevel(ALineIndex+1) - MinimumFoldLevel(ALineIndex));
 | 
					 | 
				
			||||||
  //Result := EndFoldLevel(ALineIndex) - MinimumFoldLevel(ALineIndex);
 | 
					 | 
				
			||||||
end;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function TSynDiffSyn.FoldCloseCount(ALineIndex: Integer; AType: Integer): integer;
 | 
					 | 
				
			||||||
begin
 | 
					 | 
				
			||||||
  If AType <> 0 then exit(0);
 | 
					 | 
				
			||||||
  Result := Max(0, MinimumFoldLevel(ALineIndex) - MinimumFoldLevel(ALineIndex+1));
 | 
					 | 
				
			||||||
  //Result := EndFoldLevel(ALineIndex - 1) - MinimumFoldLevel(ALineIndex);
 | 
					 | 
				
			||||||
end;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function TSynDiffSyn.FoldNestCount(ALineIndex: Integer; AType: Integer): integer;
 | 
					 | 
				
			||||||
begin
 | 
					 | 
				
			||||||
  If AType <> 0 then exit(0);
 | 
					 | 
				
			||||||
  Result := MinimumFoldLevel(ALineIndex+1);
 | 
					 | 
				
			||||||
  //Result := EndFoldLevel(ALineIndex);
 | 
					 | 
				
			||||||
end;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function TSynDiffSyn.MinimumFoldLevel(ALineIndex: Integer): integer;
 | 
					 | 
				
			||||||
var
 | 
					 | 
				
			||||||
  r: TSynCustomHighlighterRange;
 | 
					 | 
				
			||||||
begin
 | 
					 | 
				
			||||||
  if (ALineIndex < 0) or (ALineIndex >= CurrentLines.Count) then
 | 
					 | 
				
			||||||
    exit(0);
 | 
					 | 
				
			||||||
  r := TSynCustomHighlighterRange(CurrentRanges[ALineIndex]);
 | 
					 | 
				
			||||||
  if (r <> nil) and (Pointer(r) <> NullRange) then
 | 
					 | 
				
			||||||
    Result := r.MinimumCodeFoldBlockLevel
 | 
					 | 
				
			||||||
  else
 | 
					 | 
				
			||||||
    Result := 0;
 | 
					 | 
				
			||||||
end;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function TSynDiffSyn.EndFoldLevel(ALineIndex: Integer): integer;
 | 
					 | 
				
			||||||
var
 | 
					 | 
				
			||||||
  r: TSynCustomHighlighterRange;
 | 
					 | 
				
			||||||
begin
 | 
					 | 
				
			||||||
  if (ALineIndex < 0) or (ALineIndex >= CurrentLines.Count) then
 | 
					 | 
				
			||||||
    exit(0);
 | 
					 | 
				
			||||||
  r := TSynCustomHighlighterRange(CurrentRanges[ALineIndex]);
 | 
					 | 
				
			||||||
  if (r <> nil) and (Pointer(r) <> NullRange) then
 | 
					 | 
				
			||||||
    Result := r.CodeFoldStackSize
 | 
					 | 
				
			||||||
  else
 | 
					 | 
				
			||||||
    Result := 0;
 | 
					 | 
				
			||||||
end;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
initialization
 | 
					initialization
 | 
				
			||||||
  RegisterPlaceableHighlighter(TSynDiffSyn);
 | 
					  RegisterPlaceableHighlighter(TSynDiffSyn);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -65,6 +65,7 @@ type
 | 
				
			|||||||
    // internal type / no config
 | 
					    // internal type / no config
 | 
				
			||||||
    cfbtLfmNone
 | 
					    cfbtLfmNone
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
 | 
					  TLfmCodeFoldBlockTypes = set of TLfmCodeFoldBlockType;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  TProcTableProc = procedure of object;
 | 
					  TProcTableProc = procedure of object;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -148,14 +149,6 @@ type
 | 
				
			|||||||
    procedure SetRange(Value: Pointer); override;
 | 
					    procedure SetRange(Value: Pointer); override;
 | 
				
			||||||
    procedure ResetRange; override;
 | 
					    procedure ResetRange; override;
 | 
				
			||||||
    property IdentChars;
 | 
					    property IdentChars;
 | 
				
			||||||
  public
 | 
					 | 
				
			||||||
    // folding
 | 
					 | 
				
			||||||
    function FoldOpenCount(ALineIndex: Integer; AType: Integer = 0): integer; override;
 | 
					 | 
				
			||||||
    function FoldCloseCount(ALineIndex: Integer; AType: Integer = 0): integer; override;
 | 
					 | 
				
			||||||
    function FoldNestCount(ALineIndex: Integer; AType: Integer = 0): integer; override;
 | 
					 | 
				
			||||||
    // TODO: make private
 | 
					 | 
				
			||||||
    function MinimumFoldLevel(ALineIndex: Integer): integer; override;
 | 
					 | 
				
			||||||
    function EndFoldLevel(ALineIndex: Integer): integer; override;
 | 
					 | 
				
			||||||
  published
 | 
					  published
 | 
				
			||||||
    property CommentAttri: TSynHighlighterAttributes read fCommentAttri
 | 
					    property CommentAttri: TSynHighlighterAttributes read fCommentAttri
 | 
				
			||||||
      write fCommentAttri;
 | 
					      write fCommentAttri;
 | 
				
			||||||
@ -612,50 +605,6 @@ begin
 | 
				
			|||||||
  fRange := rsUnknown;
 | 
					  fRange := rsUnknown;
 | 
				
			||||||
end;
 | 
					end;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function TSynLFMSyn.FoldOpenCount(ALineIndex: Integer; AType: Integer): integer;
 | 
					 | 
				
			||||||
begin
 | 
					 | 
				
			||||||
  If AType <> 0 then exit(0);
 | 
					 | 
				
			||||||
  Result := EndFoldLevel(ALineIndex) - MinimumFoldLevel(ALineIndex);
 | 
					 | 
				
			||||||
end;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function TSynLFMSyn.FoldCloseCount(ALineIndex: Integer; AType: Integer): integer;
 | 
					 | 
				
			||||||
begin
 | 
					 | 
				
			||||||
  If AType <> 0 then exit(0);
 | 
					 | 
				
			||||||
  Result := EndFoldLevel(ALineIndex - 1) - MinimumFoldLevel(ALineIndex);
 | 
					 | 
				
			||||||
end;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function TSynLFMSyn.FoldNestCount(ALineIndex: Integer; AType: Integer): integer;
 | 
					 | 
				
			||||||
begin
 | 
					 | 
				
			||||||
  If AType <> 0 then exit(0);
 | 
					 | 
				
			||||||
  Result := EndFoldLevel(ALineIndex);
 | 
					 | 
				
			||||||
end;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function TSynLFMSyn.MinimumFoldLevel(ALineIndex: Integer): integer;
 | 
					 | 
				
			||||||
var
 | 
					 | 
				
			||||||
  r: TSynCustomHighlighterRange;
 | 
					 | 
				
			||||||
begin
 | 
					 | 
				
			||||||
  if (ALineIndex < 0) or (ALineIndex >= CurrentLines.Count) then
 | 
					 | 
				
			||||||
    exit(0);
 | 
					 | 
				
			||||||
  r := TSynCustomHighlighterRange(CurrentRanges[ALineIndex]);
 | 
					 | 
				
			||||||
  if (r <> nil) and (Pointer(r) <> NullRange) then
 | 
					 | 
				
			||||||
    Result := r.MinimumCodeFoldBlockLevel
 | 
					 | 
				
			||||||
  else
 | 
					 | 
				
			||||||
    Result := 0;
 | 
					 | 
				
			||||||
end;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function TSynLFMSyn.EndFoldLevel(ALineIndex: Integer): integer;
 | 
					 | 
				
			||||||
var
 | 
					 | 
				
			||||||
  r: TSynCustomHighlighterRange;
 | 
					 | 
				
			||||||
begin
 | 
					 | 
				
			||||||
  if (ALineIndex < 0) or (ALineIndex >= CurrentLines.Count) then
 | 
					 | 
				
			||||||
    exit(0);
 | 
					 | 
				
			||||||
  r := TSynCustomHighlighterRange(CurrentRanges[ALineIndex]);
 | 
					 | 
				
			||||||
  if (r <> nil) and (Pointer(r) <> NullRange) then
 | 
					 | 
				
			||||||
    Result := r.CodeFoldStackSize
 | 
					 | 
				
			||||||
  else
 | 
					 | 
				
			||||||
    Result := 0;
 | 
					 | 
				
			||||||
end;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
procedure TSynLFMSyn.SetRange(Value: Pointer);
 | 
					procedure TSynLFMSyn.SetRange(Value: Pointer);
 | 
				
			||||||
begin
 | 
					begin
 | 
				
			||||||
  inherited;
 | 
					  inherited;
 | 
				
			||||||
 | 
				
			|||||||
@ -174,6 +174,11 @@ const
 | 
				
			|||||||
      cfbtNone
 | 
					      cfbtNone
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  FOLDGROUP_PASCAL = 1;
 | 
				
			||||||
 | 
					  FOLDGROUP_REGION = 2;
 | 
				
			||||||
 | 
					  FOLDGROUP_IFDEF  = 3;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type
 | 
					type
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  TPascalCompilerMode = (
 | 
					  TPascalCompilerMode = (
 | 
				
			||||||
@ -319,7 +324,9 @@ type
 | 
				
			|||||||
    fD4syntax: boolean;
 | 
					    fD4syntax: boolean;
 | 
				
			||||||
    FCatchNodeInfo: Boolean;
 | 
					    FCatchNodeInfo: Boolean;
 | 
				
			||||||
    FCatchNodeInfoList: TLazSynPasFoldNodeInfoList;
 | 
					    FCatchNodeInfoList: TLazSynPasFoldNodeInfoList;
 | 
				
			||||||
 | 
					    // Divider
 | 
				
			||||||
    FDividerDrawConfig: Array [TSynPasDividerDrawLocation] of TSynDividerDrawConfig;
 | 
					    FDividerDrawConfig: Array [TSynPasDividerDrawLocation] of TSynDividerDrawConfig;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    function GetPasCodeFoldRange: TSynPasSynRange;
 | 
					    function GetPasCodeFoldRange: TSynPasSynRange;
 | 
				
			||||||
    procedure SetCompilerMode(const AValue: TPascalCompilerMode);
 | 
					    procedure SetCompilerMode(const AValue: TPascalCompilerMode);
 | 
				
			||||||
    procedure SetExtendedKeywordsMode(const AValue: Boolean);
 | 
					    procedure SetExtendedKeywordsMode(const AValue: Boolean);
 | 
				
			||||||
@ -449,9 +456,10 @@ type
 | 
				
			|||||||
    procedure SymbolProc;
 | 
					    procedure SymbolProc;
 | 
				
			||||||
    procedure UnknownProc;
 | 
					    procedure UnknownProc;
 | 
				
			||||||
    procedure SetD4syntax(const Value: boolean);
 | 
					    procedure SetD4syntax(const Value: boolean);
 | 
				
			||||||
    procedure InitNode(var Node: TSynFoldNodeInfo; EndOffs: Integer;
 | 
					    procedure InitNode(out Node: TSynFoldNodeInfo; EndOffs: Integer;
 | 
				
			||||||
                       ABlockType: TPascalCodeFoldBlockType; aActions: TSynFoldActions;
 | 
					                       ABlockType: TPascalCodeFoldBlockType; aActions: TSynFoldActions;
 | 
				
			||||||
                       AIsFold: Boolean);
 | 
					                       AIsFold: Boolean);
 | 
				
			||||||
 | 
					    // Divider
 | 
				
			||||||
    procedure CreateDividerDrawConfig;
 | 
					    procedure CreateDividerDrawConfig;
 | 
				
			||||||
    procedure DestroyDividerDrawConfig;
 | 
					    procedure DestroyDividerDrawConfig;
 | 
				
			||||||
  protected
 | 
					  protected
 | 
				
			||||||
@ -459,11 +467,17 @@ type
 | 
				
			|||||||
    function GetIdentChars: TSynIdentChars; override;
 | 
					    function GetIdentChars: TSynIdentChars; override;
 | 
				
			||||||
    function IsFilterStored: boolean; override;                                 //mh 2000-10-08
 | 
					    function IsFilterStored: boolean; override;                                 //mh 2000-10-08
 | 
				
			||||||
  protected
 | 
					  protected
 | 
				
			||||||
 | 
					    // "Range"
 | 
				
			||||||
    function GetRangeClass: TSynCustomHighlighterRangeClass; override;
 | 
					    function GetRangeClass: TSynCustomHighlighterRangeClass; override;
 | 
				
			||||||
    procedure CreateRootCodeFoldBlock; override;
 | 
					    procedure CreateRootCodeFoldBlock; override;
 | 
				
			||||||
    function CreateRangeList(ALines: TSynEditStringsBase): TSynHighlighterRangeList; override;
 | 
					    function CreateRangeList(ALines: TSynEditStringsBase): TSynHighlighterRangeList; override;
 | 
				
			||||||
    function UpdateRangeInfoAtLine(Index: Integer): Boolean; override; // Returns true if range changed
 | 
					    function UpdateRangeInfoAtLine(Index: Integer): Boolean; override; // Returns true if range changed
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    property PasCodeFoldRange: TSynPasSynRange read GetPasCodeFoldRange;
 | 
				
			||||||
 | 
					    function TopPascalCodeFoldBlockType
 | 
				
			||||||
 | 
					             (DownIndex: Integer = 0): TPascalCodeFoldBlockType;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Open/Close Folds
 | 
				
			||||||
    function StartPascalCodeFoldBlock
 | 
					    function StartPascalCodeFoldBlock
 | 
				
			||||||
             (ABlockType: TPascalCodeFoldBlockType): TSynCustomCodeFoldBlock;
 | 
					             (ABlockType: TPascalCodeFoldBlockType): TSynCustomCodeFoldBlock;
 | 
				
			||||||
    procedure EndPascalCodeFoldBlock(NoMarkup: Boolean = False);
 | 
					    procedure EndPascalCodeFoldBlock(NoMarkup: Boolean = False);
 | 
				
			||||||
@ -473,24 +487,19 @@ type
 | 
				
			|||||||
    procedure StartCustomCodeFoldBlock(ABlockType: TPascalCodeFoldBlockType);
 | 
					    procedure StartCustomCodeFoldBlock(ABlockType: TPascalCodeFoldBlockType);
 | 
				
			||||||
    procedure EndCustomCodeFoldBlock(ABlockType: TPascalCodeFoldBlockType);
 | 
					    procedure EndCustomCodeFoldBlock(ABlockType: TPascalCodeFoldBlockType);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Info about Folds
 | 
				
			||||||
    function CreateFoldNodeInfoList: TLazSynFoldNodeInfoList; override;
 | 
					    function CreateFoldNodeInfoList: TLazSynFoldNodeInfoList; override;
 | 
				
			||||||
    procedure InitFoldNodeInfo(AList: TLazSynFoldNodeInfoList; Line: TLineIdx); override;
 | 
					    procedure InitFoldNodeInfo(AList: TLazSynFoldNodeInfoList; Line: TLineIdx); override;
 | 
				
			||||||
  protected
 | 
					 | 
				
			||||||
    property PasCodeFoldRange: TSynPasSynRange read GetPasCodeFoldRange;
 | 
					 | 
				
			||||||
    function TopPascalCodeFoldBlockType
 | 
					 | 
				
			||||||
             (DownIndex: Integer = 0): TPascalCodeFoldBlockType;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  public
 | 
					 | 
				
			||||||
    function MinimumPasFoldLevel(Index: Integer; AType: Integer = 1): integer;
 | 
					 | 
				
			||||||
    function EndPasFoldLevel(Index: Integer; AType: Integer = 1): integer;
 | 
					 | 
				
			||||||
  protected
 | 
					  protected
 | 
				
			||||||
    function LastLinePasFoldLevelFix(Index: Integer; AType: Integer = 1): integer; // foldable nodes
 | 
					    function LastLinePasFoldLevelFix(Index: Integer; AType: Integer = 1): integer; // TODO deprecated; // foldable nodes
 | 
				
			||||||
    function LastLineFoldLevelFix(Index: Integer): integer;                        // all nodes
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Divider
 | 
				
			||||||
    function GetDrawDivider(Index: integer): TSynDividerDrawConfigSetting; override;
 | 
					    function GetDrawDivider(Index: integer): TSynDividerDrawConfigSetting; override;
 | 
				
			||||||
    function GetDividerDrawConfig(Index: Integer): TSynDividerDrawConfig; override;
 | 
					    function GetDividerDrawConfig(Index: Integer): TSynDividerDrawConfig; override;
 | 
				
			||||||
    function GetDividerDrawConfigCount: Integer; override;
 | 
					    function GetDividerDrawConfigCount: Integer; override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Fold Config
 | 
				
			||||||
    function GetFoldConfigInstance(Index: Integer): TSynCustomFoldConfig; override;
 | 
					    function GetFoldConfigInstance(Index: Integer): TSynCustomFoldConfig; override;
 | 
				
			||||||
    function GetFoldConfigCount: Integer; override;
 | 
					    function GetFoldConfigCount: Integer; override;
 | 
				
			||||||
    function GetFoldConfigInternalCount: Integer; override;
 | 
					    function GetFoldConfigInternalCount: Integer; override;
 | 
				
			||||||
@ -523,19 +532,18 @@ type
 | 
				
			|||||||
    function UseUserSettings(settingIndex: integer): boolean; override;
 | 
					    function UseUserSettings(settingIndex: integer): boolean; override;
 | 
				
			||||||
    procedure EnumUserSettings(settings: TStrings); override;
 | 
					    procedure EnumUserSettings(settings: TStrings); override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // fold-nodes that can be collapsed
 | 
					    // Info about Folds
 | 
				
			||||||
    function FoldOpenCount(ALineIndex: Integer; AType: Integer = 0): integer; override;
 | 
					    //function FoldBlockOpeningCount(ALineIndex: TLineIdx; const AFilter: TSynFoldBlockFilter): integer; override; overload;
 | 
				
			||||||
    function FoldCloseCount(ALineIndex: Integer; AType: Integer = 0): integer; override;
 | 
					    //function FoldBlockClosingCount(ALineIndex: TLineIdx; const AFilter: TSynFoldBlockFilter): integer; override; overload;
 | 
				
			||||||
    function FoldNestCount(ALineIndex: Integer; AType: Integer = 0): integer; override;
 | 
					    function FoldBlockEndLevel(ALineIndex: TLineIdx; const AFilter: TSynFoldBlockFilter): integer; override; overload;
 | 
				
			||||||
 | 
					    function FoldBlockMinLevel(ALineIndex: TLineIdx; const AFilter: TSynFoldBlockFilter): integer; override; overload;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    function FoldTypeCount: integer; override;
 | 
					    function FoldTypeCount: integer; override;
 | 
				
			||||||
    function FoldTypeAtNodeIndex(ALineIndex, FoldIndex: Integer;                // accesses FoldNodeInfo
 | 
					    function FoldTypeAtNodeIndex(ALineIndex, FoldIndex: Integer;                // accesses FoldNodeInfo
 | 
				
			||||||
             UseCloseNodes: boolean = false): integer; override;
 | 
					             UseCloseNodes: boolean = false): integer; override;
 | 
				
			||||||
    function FoldLineLength(ALineIndex, FoldIndex: Integer): integer; override; // accesses FoldNodeInfo
 | 
					    function FoldLineLength(ALineIndex, FoldIndex: Integer): integer; override; // accesses FoldNodeInfo
 | 
				
			||||||
    function FoldEndLine(ALineIndex, FoldIndex: Integer): integer; override;    // accesses FoldNodeInfo
 | 
					    function FoldEndLine(ALineIndex, FoldIndex: Integer): integer; override;    // accesses FoldNodeInfo
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // All fold nodes // TODO: make private
 | 
					 | 
				
			||||||
    function MinimumFoldLevel(Index: Integer): integer; override;
 | 
					 | 
				
			||||||
    function EndFoldLevel(Index: Integer): integer; override;
 | 
					 | 
				
			||||||
  published
 | 
					  published
 | 
				
			||||||
    property AsmAttri: TSynHighlighterAttributes read fAsmAttri write fAsmAttri;
 | 
					    property AsmAttri: TSynHighlighterAttributes read fAsmAttri write fAsmAttri;
 | 
				
			||||||
    property CommentAttri: TSynHighlighterAttributes read fCommentAttri
 | 
					    property CommentAttri: TSynHighlighterAttributes read fCommentAttri
 | 
				
			||||||
@ -1091,7 +1099,6 @@ begin
 | 
				
			|||||||
    if TopPascalCodeFoldBlockType in [cfbtVarType, cfbtLocalVarType] then
 | 
					    if TopPascalCodeFoldBlockType in [cfbtVarType, cfbtLocalVarType] then
 | 
				
			||||||
      EndPascalCodeFoldBlockLastLine;
 | 
					      EndPascalCodeFoldBlockLastLine;
 | 
				
			||||||
    StartPascalCodeFoldBlock(cfbtAsm);
 | 
					    StartPascalCodeFoldBlock(cfbtAsm);
 | 
				
			||||||
    //debugln('TSynPasSyn.Func37 BEGIN ',dbgs(ord(TopPascalCodeFoldBlockType)),' LineNumber=',dbgs(fLineNumber),' ',dbgs(MinimumCodeFoldBlockLevel),' ',dbgs(CurrentCodeFoldBlockLevel));
 | 
					 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
  else Result := tkIdentifier;
 | 
					  else Result := tkIdentifier;
 | 
				
			||||||
end;
 | 
					end;
 | 
				
			||||||
@ -2361,7 +2368,7 @@ begin
 | 
				
			|||||||
  fLine:=PChar(Pointer(fLineStr));
 | 
					  fLine:=PChar(Pointer(fLineStr));
 | 
				
			||||||
  Run := 0;
 | 
					  Run := 0;
 | 
				
			||||||
  Inherited SetLine(NewValue,LineNumber);
 | 
					  Inherited SetLine(NewValue,LineNumber);
 | 
				
			||||||
  FStartCodeFoldBlockLevel := MinimumCodeFoldBlockLevel;
 | 
					  FStartCodeFoldBlockLevel := PasCodeFoldRange.MinimumCodeFoldBlockLevel;
 | 
				
			||||||
  PasCodeFoldRange.LastLineCodeFoldLevelFix := 0;
 | 
					  PasCodeFoldRange.LastLineCodeFoldLevelFix := 0;
 | 
				
			||||||
  PasCodeFoldRange.PasFoldFixLevel := 0;
 | 
					  PasCodeFoldRange.PasFoldFixLevel := 0;
 | 
				
			||||||
  PasCodeFoldRange.PasFoldMinLevel := PasCodeFoldRange.PasFoldEndLevel;
 | 
					  PasCodeFoldRange.PasFoldMinLevel := PasCodeFoldRange.PasFoldEndLevel;
 | 
				
			||||||
@ -3156,6 +3163,100 @@ begin
 | 
				
			|||||||
  end;
 | 
					  end;
 | 
				
			||||||
end;
 | 
					end;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function TSynPasSyn.FoldBlockEndLevel(ALineIndex: TLineIdx;
 | 
				
			||||||
 | 
					  const AFilter: TSynFoldBlockFilter): integer;
 | 
				
			||||||
 | 
					var
 | 
				
			||||||
 | 
					  inf: TSynPasRangeInfo;
 | 
				
			||||||
 | 
					  r, r2: Pointer;
 | 
				
			||||||
 | 
					begin
 | 
				
			||||||
 | 
					  Assert(CurrentRanges <> nil, 'TSynCustomFoldHighlighter.FoldBlockEndLevel requires CurrentRanges');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  Result := 0;
 | 
				
			||||||
 | 
					  if (ALineIndex < 0) or (ALineIndex >= CurrentLines.Count - 1) then
 | 
				
			||||||
 | 
					    exit;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if AFilter.FoldGroup  in [0, FOLDGROUP_REGION, FOLDGROUP_IFDEF] then
 | 
				
			||||||
 | 
					    inf := TSynHighlighterPasRangeList(CurrentRanges).PasRangeInfo[ALineIndex];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if AFilter.FoldGroup  in [0, FOLDGROUP_PASCAL] then begin
 | 
				
			||||||
 | 
					    // All or Pascal
 | 
				
			||||||
 | 
					    r := CurrentRanges[ALineIndex];
 | 
				
			||||||
 | 
					    if (r <> nil) and (r <> NullRange) then begin
 | 
				
			||||||
 | 
					      r2 := TSynPasSynRange(CurrentRanges[ALineIndex + 1]);
 | 
				
			||||||
 | 
					      if sfbIncludeDisabled in AFilter.Flags then begin
 | 
				
			||||||
 | 
					        Result := TSynPasSynRange(r).CodeFoldStackSize;
 | 
				
			||||||
 | 
					        if (r2 <> nil) and (r2 <> NullRange) then
 | 
				
			||||||
 | 
					          Result := Result + TSynPasSynRange(r2).LastLineCodeFoldLevelFix;
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
 | 
					      else begin
 | 
				
			||||||
 | 
					        Result := TSynPasSynRange(r).PasFoldEndLevel;
 | 
				
			||||||
 | 
					        if (r2 <> nil) and (r2 <> NullRange) then
 | 
				
			||||||
 | 
					          Result := Result + TSynPasSynRange(r2).PasFoldFixLevel;
 | 
				
			||||||
 | 
					      end;
 | 
				
			||||||
 | 
					    end;
 | 
				
			||||||
 | 
					  end;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if AFilter.FoldGroup  in [0, FOLDGROUP_REGION] then begin
 | 
				
			||||||
 | 
					    // All or REGION
 | 
				
			||||||
 | 
					    Result := Result + inf.EndLevelRegion;
 | 
				
			||||||
 | 
					  end;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if AFilter.FoldGroup  in [0, FOLDGROUP_IFDEF] then begin
 | 
				
			||||||
 | 
					    // All or IFDEF
 | 
				
			||||||
 | 
					    Result := Result + inf.EndLevelIfDef;
 | 
				
			||||||
 | 
					  end;
 | 
				
			||||||
 | 
					end;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function TSynPasSyn.FoldBlockMinLevel(ALineIndex: TLineIdx;
 | 
				
			||||||
 | 
					  const AFilter: TSynFoldBlockFilter): integer;
 | 
				
			||||||
 | 
					var
 | 
				
			||||||
 | 
					  inf: TSynPasRangeInfo;
 | 
				
			||||||
 | 
					  r, r2: Pointer;
 | 
				
			||||||
 | 
					begin
 | 
				
			||||||
 | 
					  Assert(CurrentRanges <> nil, 'TSynCustomFoldHighlighter.FoldBlockMinLevel requires CurrentRanges');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  Result := 0;
 | 
				
			||||||
 | 
					  if (ALineIndex < 0) or (ALineIndex >= CurrentLines.Count - 1) then
 | 
				
			||||||
 | 
					    exit;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if AFilter.FoldGroup  in [0, FOLDGROUP_REGION, FOLDGROUP_IFDEF] then
 | 
				
			||||||
 | 
					    inf := TSynHighlighterPasRangeList(CurrentRanges).PasRangeInfo[ALineIndex];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if AFilter.FoldGroup  in [0, FOLDGROUP_PASCAL] then begin
 | 
				
			||||||
 | 
					    // All or Pascal
 | 
				
			||||||
 | 
					    (* Range.EndLevel can be smaller. because it Range.MinLevel does not know the LastLiineFix
 | 
				
			||||||
 | 
					       Using a copy of FoldBlockEndLevel *)
 | 
				
			||||||
 | 
					    r := CurrentRanges[ALineIndex];
 | 
				
			||||||
 | 
					    if (r <> nil) and (r <> NullRange) then begin
 | 
				
			||||||
 | 
					      r2 := TSynPasSynRange(CurrentRanges[ALineIndex + 1]);
 | 
				
			||||||
 | 
					      if sfbIncludeDisabled in AFilter.Flags then begin
 | 
				
			||||||
 | 
					        Result := TSynPasSynRange(r).CodeFoldStackSize;
 | 
				
			||||||
 | 
					        if (r2 <> nil) and (r2 <> NullRange) then
 | 
				
			||||||
 | 
					          Result := Result + TSynPasSynRange(r2).LastLineCodeFoldLevelFix;
 | 
				
			||||||
 | 
					        // now Result = FoldBlockEndLevel
 | 
				
			||||||
 | 
					        Result := Min(Result, TSynPasSynRange(r).MinimumCodeFoldBlockLevel);
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
 | 
					      else begin
 | 
				
			||||||
 | 
					        Result := TSynPasSynRange(r).PasFoldEndLevel;
 | 
				
			||||||
 | 
					        if (r2 <> nil) and (r2 <> NullRange) then
 | 
				
			||||||
 | 
					          Result := Result + TSynPasSynRange(r2).PasFoldFixLevel;
 | 
				
			||||||
 | 
					        // now Result = FoldBlockEndLevel
 | 
				
			||||||
 | 
					        Result := Min(Result, TSynPasSynRange(r).PasFoldMinLevel);
 | 
				
			||||||
 | 
					      end;
 | 
				
			||||||
 | 
					    end;
 | 
				
			||||||
 | 
					  end;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if AFilter.FoldGroup  in [0, FOLDGROUP_REGION] then begin
 | 
				
			||||||
 | 
					    // All or REGION
 | 
				
			||||||
 | 
					    Result := Result + inf.MinLevelRegion;
 | 
				
			||||||
 | 
					  end;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if AFilter.FoldGroup  in [0, FOLDGROUP_IFDEF] then begin
 | 
				
			||||||
 | 
					    // All or IFDEF
 | 
				
			||||||
 | 
					    Result := Result + inf.MinLevelIfDef;
 | 
				
			||||||
 | 
					  end;
 | 
				
			||||||
 | 
					end;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function TSynPasSyn.TopPascalCodeFoldBlockType(DownIndex: Integer = 0): TPascalCodeFoldBlockType;
 | 
					function TSynPasSyn.TopPascalCodeFoldBlockType(DownIndex: Integer = 0): TPascalCodeFoldBlockType;
 | 
				
			||||||
var
 | 
					var
 | 
				
			||||||
  p: Pointer;
 | 
					  p: Pointer;
 | 
				
			||||||
@ -3166,63 +3267,6 @@ begin
 | 
				
			|||||||
  Result := TPascalCodeFoldBlockType(PtrUInt(p));
 | 
					  Result := TPascalCodeFoldBlockType(PtrUInt(p));
 | 
				
			||||||
end;
 | 
					end;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function TSynPasSyn.FoldOpenCount(ALineIndex: Integer; AType: Integer = 0): integer;
 | 
					 | 
				
			||||||
var
 | 
					 | 
				
			||||||
  inf: TSynPasRangeInfo;
 | 
					 | 
				
			||||||
begin
 | 
					 | 
				
			||||||
  Result := 0;
 | 
					 | 
				
			||||||
  if not(AType in [1, 4]) then
 | 
					 | 
				
			||||||
    inf := TSynHighlighterPasRangeList(CurrentRanges).PasRangeInfo[ALineIndex];
 | 
					 | 
				
			||||||
  if (AType = 0) or (AType = 1) then
 | 
					 | 
				
			||||||
    Result := EndPasFoldLevel(ALineIndex) - MinimumPasFoldLevel(ALineIndex);
 | 
					 | 
				
			||||||
  if (AType = 0) or (AType = 2) then
 | 
					 | 
				
			||||||
    Result := Result + inf.EndLevelRegion - inf.MinLevelRegion;
 | 
					 | 
				
			||||||
  if (AType = 0) or (AType = 3) then
 | 
					 | 
				
			||||||
    Result := Result + inf.EndLevelIfDef - inf.MinLevelIfDef;
 | 
					 | 
				
			||||||
  if (AType = 4) then
 | 
					 | 
				
			||||||
    Result := EndPasFoldLevel(ALineIndex, 4) - MinimumPasFoldLevel(ALineIndex, 4);
 | 
					 | 
				
			||||||
  if Result < 0 then
 | 
					 | 
				
			||||||
    Result := 0;
 | 
					 | 
				
			||||||
end;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function TSynPasSyn.FoldCloseCount(ALineIndex: Integer; AType: Integer = 0): integer;
 | 
					 | 
				
			||||||
var
 | 
					 | 
				
			||||||
  inf, inf2: TSynPasRangeInfo;
 | 
					 | 
				
			||||||
begin
 | 
					 | 
				
			||||||
  Result := 0;
 | 
					 | 
				
			||||||
  if not(AType in [1, 4]) then begin
 | 
					 | 
				
			||||||
    inf := TSynHighlighterPasRangeList(CurrentRanges).PasRangeInfo[ALineIndex];
 | 
					 | 
				
			||||||
    inf2 := TSynHighlighterPasRangeList(CurrentRanges).PasRangeInfo[ALineIndex - 1];
 | 
					 | 
				
			||||||
  end;
 | 
					 | 
				
			||||||
  if (AType = 0) or (AType = 1) then
 | 
					 | 
				
			||||||
    Result := EndPasFoldLevel(ALineIndex - 1)
 | 
					 | 
				
			||||||
            - min(MinimumPasFoldLevel(ALineIndex), EndPasFoldLevel(ALineIndex));
 | 
					 | 
				
			||||||
  if (AType = 0) or (AType = 2) then
 | 
					 | 
				
			||||||
    Result := Result + inf2.EndLevelRegion - inf.MinLevelRegion;
 | 
					 | 
				
			||||||
  if (AType = 0) or (AType = 3) then
 | 
					 | 
				
			||||||
    Result := Result + inf2.EndLevelIfDef - inf.MinLevelIfDef;
 | 
					 | 
				
			||||||
  if (AType = 4) then
 | 
					 | 
				
			||||||
    Result := EndPasFoldLevel(ALineIndex - 1, 4)
 | 
					 | 
				
			||||||
            - min(MinimumPasFoldLevel(ALineIndex, 4), EndPasFoldLevel(ALineIndex, 4));
 | 
					 | 
				
			||||||
end;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function TSynPasSyn.FoldNestCount(ALineIndex: Integer; AType: Integer = 0): integer;
 | 
					 | 
				
			||||||
var
 | 
					 | 
				
			||||||
  inf: TSynPasRangeInfo;
 | 
					 | 
				
			||||||
begin
 | 
					 | 
				
			||||||
  Result := 0;
 | 
					 | 
				
			||||||
  if not(AType in [1, 4]) then
 | 
					 | 
				
			||||||
    inf := TSynHighlighterPasRangeList(CurrentRanges).PasRangeInfo[ALineIndex];
 | 
					 | 
				
			||||||
  if (AType = 0) or (AType = 1) then
 | 
					 | 
				
			||||||
    Result := EndPasFoldLevel(ALineIndex);
 | 
					 | 
				
			||||||
  if (AType = 0) or (AType = 2) then
 | 
					 | 
				
			||||||
    Result := Result + inf.EndLevelRegion;
 | 
					 | 
				
			||||||
  if (AType = 0) or (AType = 3) then
 | 
					 | 
				
			||||||
    Result := Result + inf.EndLevelIfDef;
 | 
					 | 
				
			||||||
  if (AType = 4) then
 | 
					 | 
				
			||||||
    Result := EndPasFoldLevel(ALineIndex, 4);
 | 
					 | 
				
			||||||
end;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function TSynPasSyn.FoldTypeCount: integer;
 | 
					function TSynPasSyn.FoldTypeCount: integer;
 | 
				
			||||||
begin
 | 
					begin
 | 
				
			||||||
  Result := 3;
 | 
					  Result := 3;
 | 
				
			||||||
@ -3264,7 +3308,7 @@ begin
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  Result := FoldEndLine(ALineIndex, FoldIndex);
 | 
					  Result := FoldEndLine(ALineIndex, FoldIndex);
 | 
				
			||||||
  // check if fold last line of block (not mixed "end begin")
 | 
					  // check if fold last line of block (not mixed "end begin")
 | 
				
			||||||
  if (EndPasFoldLevel(Result, atype) > MinimumPasFoldLevel(Result, atype)) then
 | 
					  if (FoldBlockEndLevel(Result, atype) > FoldBlockMinLevel(Result, atype)) then
 | 
				
			||||||
    dec(Result);
 | 
					    dec(Result);
 | 
				
			||||||
  // Amount of lines, that will become invisible (excludes the cfCollapsed line)
 | 
					  // Amount of lines, that will become invisible (excludes the cfCollapsed line)
 | 
				
			||||||
  Result := Result - ALineIndex;
 | 
					  Result := Result - ALineIndex;
 | 
				
			||||||
@ -3292,81 +3336,13 @@ begin
 | 
				
			|||||||
  lvl := node.FoldLvlEnd;
 | 
					  lvl := node.FoldLvlEnd;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  Result := ALineIndex + 1;
 | 
					  Result := ALineIndex + 1;
 | 
				
			||||||
  while (Result < cnt) and (MinimumPasFoldLevel(Result, atype) >= lvl) do inc(Result);
 | 
					  while (Result < cnt) and (FoldBlockMinLevel(Result, atype) >= lvl) do inc(Result);
 | 
				
			||||||
  // check if fold last line of block (not mixed "end begin")
 | 
					  // check if fold last line of block (not mixed "end begin")
 | 
				
			||||||
  // and not lastlinefix
 | 
					  // and not lastlinefix
 | 
				
			||||||
  if (Result = cnt) then
 | 
					  if (Result = cnt) then
 | 
				
			||||||
    dec(Result);
 | 
					    dec(Result);
 | 
				
			||||||
end;
 | 
					end;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function TSynPasSyn.MinimumPasFoldLevel(Index: Integer; AType: Integer = 1): integer;
 | 
					 | 
				
			||||||
var
 | 
					 | 
				
			||||||
  r: TSynPasSynRange;
 | 
					 | 
				
			||||||
begin
 | 
					 | 
				
			||||||
  case AType of
 | 
					 | 
				
			||||||
    2:
 | 
					 | 
				
			||||||
      Result := TSynHighlighterPasRangeList(CurrentRanges).
 | 
					 | 
				
			||||||
                  PasRangeInfo[Index].MinLevelRegion;
 | 
					 | 
				
			||||||
    3:
 | 
					 | 
				
			||||||
      Result := TSynHighlighterPasRangeList(CurrentRanges).
 | 
					 | 
				
			||||||
                  PasRangeInfo[Index].MinLevelIfDef;
 | 
					 | 
				
			||||||
    4:  // all pascal nodes (incl. not folded)
 | 
					 | 
				
			||||||
      begin
 | 
					 | 
				
			||||||
        if (Index < 0) or (Index >= CurrentLines.Count) then
 | 
					 | 
				
			||||||
          exit(0);
 | 
					 | 
				
			||||||
        r := TSynPasSynRange(CurrentRanges[Index]);
 | 
					 | 
				
			||||||
        if (r <> nil) and (Pointer(r) <> NullRange) then begin
 | 
					 | 
				
			||||||
          Result := Min(r.CodeFoldStackSize + LastLinePasFoldLevelFix(Index + 1, 4),
 | 
					 | 
				
			||||||
                        r.MinimumCodeFoldBlockLevel);
 | 
					 | 
				
			||||||
        end else
 | 
					 | 
				
			||||||
          Result := 0;
 | 
					 | 
				
			||||||
      end;
 | 
					 | 
				
			||||||
    else
 | 
					 | 
				
			||||||
      begin
 | 
					 | 
				
			||||||
        if (Index < 0) or (Index >= CurrentLines.Count) then
 | 
					 | 
				
			||||||
          exit(0);
 | 
					 | 
				
			||||||
        r := TSynPasSynRange(CurrentRanges[Index]);
 | 
					 | 
				
			||||||
        if (r <> nil) and (Pointer(r) <> NullRange) then begin
 | 
					 | 
				
			||||||
          Result := Min(r.PasFoldEndLevel + LastLinePasFoldLevelFix(Index + 1),
 | 
					 | 
				
			||||||
                        r.PasFoldMinLevel)
 | 
					 | 
				
			||||||
        end else
 | 
					 | 
				
			||||||
          Result := 0;
 | 
					 | 
				
			||||||
      end;
 | 
					 | 
				
			||||||
  end;
 | 
					 | 
				
			||||||
end;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function TSynPasSyn.EndPasFoldLevel(Index: Integer; AType: Integer = 1): integer;
 | 
					 | 
				
			||||||
var
 | 
					 | 
				
			||||||
  r: TSynPasSynRange;
 | 
					 | 
				
			||||||
begin
 | 
					 | 
				
			||||||
  if (Index < 0) or (Index >= CurrentLines.Count - 1) then
 | 
					 | 
				
			||||||
    exit(0);
 | 
					 | 
				
			||||||
  case AType of
 | 
					 | 
				
			||||||
    2:
 | 
					 | 
				
			||||||
      Result := TSynHighlighterPasRangeList(CurrentRanges).
 | 
					 | 
				
			||||||
                  PasRangeInfo[Index].EndLevelRegion;
 | 
					 | 
				
			||||||
    3:
 | 
					 | 
				
			||||||
      Result := TSynHighlighterPasRangeList(CurrentRanges).
 | 
					 | 
				
			||||||
                  PasRangeInfo[Index].EndLevelIfDef;
 | 
					 | 
				
			||||||
    4:  // all pascal nodes (incl. not folded)
 | 
					 | 
				
			||||||
      begin
 | 
					 | 
				
			||||||
        r := TSynPasSynRange(CurrentRanges[Index]);
 | 
					 | 
				
			||||||
        if (r <> nil) and (Pointer(r) <> NullRange) then
 | 
					 | 
				
			||||||
          Result := r.CodeFoldStackSize
 | 
					 | 
				
			||||||
        else
 | 
					 | 
				
			||||||
          Result := 0;
 | 
					 | 
				
			||||||
      end;
 | 
					 | 
				
			||||||
    else
 | 
					 | 
				
			||||||
      begin
 | 
					 | 
				
			||||||
        r := TSynPasSynRange(CurrentRanges[Index]);
 | 
					 | 
				
			||||||
        if (r <> nil) and (Pointer(r) <> NullRange) then
 | 
					 | 
				
			||||||
          Result := r.PasFoldEndLevel + LastLinePasFoldLevelFix(Index + 1)
 | 
					 | 
				
			||||||
        else
 | 
					 | 
				
			||||||
          Result := 0;
 | 
					 | 
				
			||||||
      end;
 | 
					 | 
				
			||||||
  end;
 | 
					 | 
				
			||||||
end;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function TSynPasSyn.LastLinePasFoldLevelFix(Index: Integer; AType: Integer = 1): integer;
 | 
					function TSynPasSyn.LastLinePasFoldLevelFix(Index: Integer; AType: Integer = 1): integer;
 | 
				
			||||||
var
 | 
					var
 | 
				
			||||||
  r: TSynPasSynRange;
 | 
					  r: TSynPasSynRange;
 | 
				
			||||||
@ -3397,49 +3373,7 @@ begin
 | 
				
			|||||||
  end;
 | 
					  end;
 | 
				
			||||||
end;
 | 
					end;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					procedure TSynPasSyn.InitNode(out Node: TSynFoldNodeInfo; EndOffs: Integer;
 | 
				
			||||||
function TSynPasSyn.MinimumFoldLevel(Index: Integer): integer;
 | 
					 | 
				
			||||||
var
 | 
					 | 
				
			||||||
  r: TSynPasSynRange;
 | 
					 | 
				
			||||||
begin
 | 
					 | 
				
			||||||
  if (Index < 0) or (Index >= CurrentLines.Count) then
 | 
					 | 
				
			||||||
    exit(0);
 | 
					 | 
				
			||||||
  r := TSynPasSynRange(CurrentRanges[Index]);
 | 
					 | 
				
			||||||
  if (r <> nil) and (Pointer(r) <> NullRange) then
 | 
					 | 
				
			||||||
    Result := Min(r.CodeFoldStackSize + LastLineFoldLevelFix(Index + 1),
 | 
					 | 
				
			||||||
                  r.MinimumCodeFoldBlockLevel)
 | 
					 | 
				
			||||||
  else
 | 
					 | 
				
			||||||
    Result := 0;
 | 
					 | 
				
			||||||
end;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function TSynPasSyn.EndFoldLevel(Index: Integer): integer;
 | 
					 | 
				
			||||||
var
 | 
					 | 
				
			||||||
  r: TSynPasSynRange;
 | 
					 | 
				
			||||||
begin
 | 
					 | 
				
			||||||
  if (Index < 0) or (Index >= CurrentLines.Count) then
 | 
					 | 
				
			||||||
    exit(0);
 | 
					 | 
				
			||||||
  r := TSynPasSynRange(CurrentRanges[Index]);
 | 
					 | 
				
			||||||
  if (r <> nil) and (Pointer(r) <> NullRange) then
 | 
					 | 
				
			||||||
    Result := r.CodeFoldStackSize + LastLineFoldLevelFix(Index + 1)
 | 
					 | 
				
			||||||
  else
 | 
					 | 
				
			||||||
    Result := 0;
 | 
					 | 
				
			||||||
end;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function TSynPasSyn.LastLineFoldLevelFix(Index: Integer): integer;
 | 
					 | 
				
			||||||
var
 | 
					 | 
				
			||||||
  r: TSynPasSynRange;
 | 
					 | 
				
			||||||
begin
 | 
					 | 
				
			||||||
  if (Index < 0) or (Index >= CurrentLines.Count) then
 | 
					 | 
				
			||||||
    exit(0);
 | 
					 | 
				
			||||||
  r := TSynPasSynRange(CurrentRanges[Index]);
 | 
					 | 
				
			||||||
  if (r <> nil) and (Pointer(r) <> NullRange) then
 | 
					 | 
				
			||||||
    Result := r.LastLineCodeFoldLevelFix
 | 
					 | 
				
			||||||
  else
 | 
					 | 
				
			||||||
    Result := 0;
 | 
					 | 
				
			||||||
end;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
procedure TSynPasSyn.InitNode(var Node: TSynFoldNodeInfo; EndOffs: Integer;
 | 
					 | 
				
			||||||
  ABlockType: TPascalCodeFoldBlockType; aActions: TSynFoldActions; AIsFold: Boolean);
 | 
					  ABlockType: TPascalCodeFoldBlockType; aActions: TSynFoldActions; AIsFold: Boolean);
 | 
				
			||||||
var
 | 
					var
 | 
				
			||||||
  OneLine: Boolean;
 | 
					  OneLine: Boolean;
 | 
				
			||||||
@ -3455,30 +3389,29 @@ begin
 | 
				
			|||||||
  case ABlockType of
 | 
					  case ABlockType of
 | 
				
			||||||
    cfbtRegion:
 | 
					    cfbtRegion:
 | 
				
			||||||
      begin
 | 
					      begin
 | 
				
			||||||
        node.FoldGroup := 2;
 | 
					        node.FoldGroup := FOLDGROUP_REGION;
 | 
				
			||||||
        Node.FoldLvlStart := FSynPasRangeInfo.EndLevelRegion;
 | 
					        Node.FoldLvlStart := FSynPasRangeInfo.EndLevelRegion;
 | 
				
			||||||
        Node.NestLvlStart := FSynPasRangeInfo.EndLevelRegion;
 | 
					        Node.NestLvlStart := FSynPasRangeInfo.EndLevelRegion;
 | 
				
			||||||
        OneLine := (EndOffs < 0) and (Node.FoldLvlStart > FSynPasRangeInfo.MinLevelRegion);
 | 
					        OneLine := (EndOffs < 0) and (Node.FoldLvlStart > FSynPasRangeInfo.MinLevelRegion);
 | 
				
			||||||
      end;
 | 
					      end;
 | 
				
			||||||
    cfbtIfDef:
 | 
					    cfbtIfDef:
 | 
				
			||||||
      begin
 | 
					      begin
 | 
				
			||||||
        node.FoldGroup := 3;
 | 
					        node.FoldGroup := FOLDGROUP_IFDEF;
 | 
				
			||||||
        Node.FoldLvlStart := FSynPasRangeInfo.EndLevelIfDef;
 | 
					        Node.FoldLvlStart := FSynPasRangeInfo.EndLevelIfDef;
 | 
				
			||||||
        Node.NestLvlStart := FSynPasRangeInfo.EndLevelIfDef;
 | 
					        Node.NestLvlStart := FSynPasRangeInfo.EndLevelIfDef;
 | 
				
			||||||
        OneLine := (EndOffs < 0) and (Node.FoldLvlStart > FSynPasRangeInfo.MinLevelIfDef);
 | 
					        OneLine := (EndOffs < 0) and (Node.FoldLvlStart > FSynPasRangeInfo.MinLevelIfDef);
 | 
				
			||||||
      end;
 | 
					      end;
 | 
				
			||||||
    else
 | 
					    else
 | 
				
			||||||
      begin
 | 
					      begin
 | 
				
			||||||
 | 
					        node.FoldGroup := FOLDGROUP_PASCAL;
 | 
				
			||||||
        if AIsFold then begin
 | 
					        if AIsFold then begin
 | 
				
			||||||
          node.FoldGroup := 1;
 | 
					 | 
				
			||||||
          Node.FoldLvlStart := PasCodeFoldRange.PasFoldEndLevel;
 | 
					          Node.FoldLvlStart := PasCodeFoldRange.PasFoldEndLevel;
 | 
				
			||||||
          Node.NestLvlStart := CurrentCodeFoldBlockLevel;
 | 
					          Node.NestLvlStart := PasCodeFoldRange.CodeFoldStackSize;
 | 
				
			||||||
          OneLine := (EndOffs < 0) and (Node.FoldLvlStart > PasCodeFoldRange.PasFoldMinLevel); // MinimumCodeFoldBlockLevel);
 | 
					          OneLine := (EndOffs < 0) and (Node.FoldLvlStart > PasCodeFoldRange.PasFoldMinLevel); // MinimumCodeFoldBlockLevel);
 | 
				
			||||||
        end else begin
 | 
					        end else begin
 | 
				
			||||||
          node.FoldGroup := 4;
 | 
					 | 
				
			||||||
          Node.FoldLvlStart := PasCodeFoldRange.CodeFoldStackSize;
 | 
					          Node.FoldLvlStart := PasCodeFoldRange.CodeFoldStackSize;
 | 
				
			||||||
          Node.NestLvlStart := CurrentCodeFoldBlockLevel;
 | 
					          Node.NestLvlStart := PasCodeFoldRange.CodeFoldStackSize;
 | 
				
			||||||
          OneLine := (EndOffs < 0) and (Node.FoldLvlStart > PasCodeFoldRange.MinimumCodeFoldBlockLevel); // MinimumCodeFoldBlockLevel);
 | 
					          OneLine := (EndOffs < 0) and (Node.FoldLvlStart > PasCodeFoldRange.MinimumCodeFoldBlockLevel);
 | 
				
			||||||
        end;
 | 
					        end;
 | 
				
			||||||
      end;
 | 
					      end;
 | 
				
			||||||
  end;
 | 
					  end;
 | 
				
			||||||
@ -3584,7 +3517,7 @@ begin
 | 
				
			|||||||
  NextToEol;
 | 
					  NextToEol;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  fStringLen := 0;
 | 
					  fStringLen := 0;
 | 
				
			||||||
  i := LastLineFoldLevelFix(Line+1);
 | 
					  i := LastLinePasFoldLevelFix(Line+1, 4);
 | 
				
			||||||
  while i < 0 do begin
 | 
					  while i < 0 do begin
 | 
				
			||||||
    EndPascalCodeFoldBlock;
 | 
					    EndPascalCodeFoldBlock;
 | 
				
			||||||
    inc(i);
 | 
					    inc(i);
 | 
				
			||||||
@ -3706,7 +3639,7 @@ begin
 | 
				
			|||||||
  EndPascalCodeFoldBlock;
 | 
					  EndPascalCodeFoldBlock;
 | 
				
			||||||
  if FAtLineStart then begin
 | 
					  if FAtLineStart then begin
 | 
				
			||||||
    // If we are not at linestart, new folds could have been opened => handle as normal close
 | 
					    // If we are not at linestart, new folds could have been opened => handle as normal close
 | 
				
			||||||
    if (CurrentCodeFoldBlockLevel < FStartCodeFoldBlockLevel) and
 | 
					    if (PasCodeFoldRange.CodeFoldStackSize < FStartCodeFoldBlockLevel) and
 | 
				
			||||||
      (FStartCodeFoldBlockLevel > 0)
 | 
					      (FStartCodeFoldBlockLevel > 0)
 | 
				
			||||||
    then begin
 | 
					    then begin
 | 
				
			||||||
      PasCodeFoldRange.DecLastLineCodeFoldLevelFix;
 | 
					      PasCodeFoldRange.DecLastLineCodeFoldLevelFix;
 | 
				
			||||||
@ -3738,7 +3671,7 @@ function TSynPasSyn.GetDrawDivider(Index: integer): TSynDividerDrawConfigSetting
 | 
				
			|||||||
  begin
 | 
					  begin
 | 
				
			||||||
    i := 0;
 | 
					    i := 0;
 | 
				
			||||||
    j := StartLvl;
 | 
					    j := StartLvl;
 | 
				
			||||||
    m := CurrentCodeFoldBlockLevel;
 | 
					    m := PasCodeFoldRange.CodeFoldStackSize;;
 | 
				
			||||||
    t := TopPascalCodeFoldBlockType(j);
 | 
					    t := TopPascalCodeFoldBlockType(j);
 | 
				
			||||||
    while (i <= MaxDepth) and (j < m) and
 | 
					    while (i <= MaxDepth) and (j < m) and
 | 
				
			||||||
          ((t in CountTypes) or (t in SkipTypes)) do begin
 | 
					          ((t in CountTypes) or (t in SkipTypes)) do begin
 | 
				
			||||||
@ -3759,17 +3692,20 @@ var
 | 
				
			|||||||
begin
 | 
					begin
 | 
				
			||||||
  Result := inherited;
 | 
					  Result := inherited;
 | 
				
			||||||
  if (index = 0) then exit;
 | 
					  if (index = 0) then exit;
 | 
				
			||||||
  CloseCnt :=  EndFoldLevel(Index - 1) - MinimumFoldLevel(Index);
 | 
					  CloseCnt :=  FoldBlockClosingCount(Index, FOLDGROUP_PASCAL, [sfbIncludeDisabled]);
 | 
				
			||||||
  if (CloseCnt = 0) or (MinimumFoldLevel(Index) <> EndFoldLevel(Index)) then // not a mixed line
 | 
					  if (CloseCnt = 0) or
 | 
				
			||||||
 | 
					     (FoldBlockMinLevel(Index, FOLDGROUP_PASCAL, [sfbIncludeDisabled])
 | 
				
			||||||
 | 
					      <> FoldBlockEndLevel(Index, FOLDGROUP_PASCAL, [sfbIncludeDisabled]))
 | 
				
			||||||
 | 
					  then // not a mixed line
 | 
				
			||||||
    exit;
 | 
					    exit;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // SetRange[Index] has the folds at the start of this line
 | 
					  // SetRange[Index] has the folds at the start of this line
 | 
				
			||||||
  // ClosedByNextLine: Folds closed by the next lines LastLineFix
 | 
					  // ClosedByNextLine: Folds closed by the next lines LastLineFix
 | 
				
			||||||
  //                   must be taken from SetRange[Index+1] (end of this line)
 | 
					  //                   must be taken from SetRange[Index+1] (end of this line)
 | 
				
			||||||
  ClosedByNextLine := -LastLineFoldLevelFix(Index + 1);
 | 
					  ClosedByNextLine := -LastLinePasFoldLevelFix(Index + 1, 4);
 | 
				
			||||||
  // ClosedInLastLine: Folds Closed by this lines LastLineFix
 | 
					  // ClosedInLastLine: Folds Closed by this lines LastLineFix
 | 
				
			||||||
  //                   must be ignored. (They are part of SetRange[Index] / this line)
 | 
					  //                   must be ignored. (They are part of SetRange[Index] / this line)
 | 
				
			||||||
  ClosedInLastLine := -LastLineFoldLevelFix(Index);
 | 
					  ClosedInLastLine := -LastLinePasFoldLevelFix(Index, 4);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Get the highest close-offset
 | 
					  // Get the highest close-offset
 | 
				
			||||||
  i := ClosedByNextLine - 1;
 | 
					  i := ClosedByNextLine - 1;
 | 
				
			||||||
 | 
				
			|||||||
@ -56,7 +56,7 @@ interface
 | 
				
			|||||||
{$I SynEdit.inc}
 | 
					{$I SynEdit.inc}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
uses
 | 
					uses
 | 
				
			||||||
  Classes, math, Graphics, SynEditTypes, SynEditHighlighter,
 | 
					  Classes, Graphics, SynEditTypes, SynEditHighlighter,
 | 
				
			||||||
  SynEditHighlighterFoldBase, SynEditHighlighterXMLBase;
 | 
					  SynEditHighlighterFoldBase, SynEditHighlighterXMLBase;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type
 | 
					type
 | 
				
			||||||
@ -98,22 +98,6 @@ type
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
type
 | 
					type
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  { TSynHighlighterXmlRangeList }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  TSynHighlighterXmlRangeList = class(TSynHighlighterRangeList)
 | 
					 | 
				
			||||||
  private
 | 
					 | 
				
			||||||
    FItemOffset: Integer;
 | 
					 | 
				
			||||||
    function GetXmlRangeInfo(Index: Integer): TSynXmlRangeInfo;
 | 
					 | 
				
			||||||
    procedure SetXmlRangeInfo(Index: Integer; const AValue: TSynXmlRangeInfo);
 | 
					 | 
				
			||||||
  protected
 | 
					 | 
				
			||||||
    procedure SetCapacity(const AValue: Integer); override;
 | 
					 | 
				
			||||||
  public
 | 
					 | 
				
			||||||
    constructor Create;
 | 
					 | 
				
			||||||
    procedure Move(AFrom, ATo, ALen: Integer); override;
 | 
					 | 
				
			||||||
    property XmlRangeInfo[Index: Integer]: TSynXmlRangeInfo
 | 
					 | 
				
			||||||
      read GetXmlRangeInfo write SetXmlRangeInfo;
 | 
					 | 
				
			||||||
  end;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  TProcTableProc = procedure of object;
 | 
					  TProcTableProc = procedure of object;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  { TSynXMLSyn }
 | 
					  { TSynXMLSyn }
 | 
				
			||||||
@ -1010,65 +994,8 @@ begin
 | 
				
			|||||||
  Result := ord(high(TXmlCodeFoldBlockType)) - ord(low(TXmlCodeFoldBlockType)) + 1;
 | 
					  Result := ord(high(TXmlCodeFoldBlockType)) - ord(low(TXmlCodeFoldBlockType)) + 1;
 | 
				
			||||||
end;
 | 
					end;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
{ TSynHighlighterXmlRangeList }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function TSynHighlighterXmlRangeList.GetXmlRangeInfo(Index: Integer): TSynXmlRangeInfo;
 | 
					 | 
				
			||||||
begin
 | 
					 | 
				
			||||||
  if (Index < 0) or (Index >= Count) then begin
 | 
					 | 
				
			||||||
    Result.ElementOpenList := nil;
 | 
					 | 
				
			||||||
    exit;
 | 
					 | 
				
			||||||
  end;
 | 
					 | 
				
			||||||
  Result := TSynXmlRangeInfo((ItemPointer[Index] + FItemOffset)^);
 | 
					 | 
				
			||||||
end;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
procedure TSynHighlighterXmlRangeList.SetXmlRangeInfo(Index: Integer;
 | 
					 | 
				
			||||||
  const AValue: TSynXmlRangeInfo);
 | 
					 | 
				
			||||||
begin
 | 
					 | 
				
			||||||
  TSynXmlRangeInfo((ItemPointer[Index] + FItemOffset)^) := AValue;
 | 
					 | 
				
			||||||
end;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
procedure TSynHighlighterXmlRangeList.SetCapacity(const AValue: Integer);
 | 
					 | 
				
			||||||
var
 | 
					 | 
				
			||||||
  i: LongInt;
 | 
					 | 
				
			||||||
begin
 | 
					 | 
				
			||||||
  for i := AValue to Capacity-1 do
 | 
					 | 
				
			||||||
    with TSynXmlRangeInfo((ItemPointer[i] + FItemOffset)^) do begin
 | 
					 | 
				
			||||||
      ElementOpenList := nil;
 | 
					 | 
				
			||||||
      ElementCloseList := nil;
 | 
					 | 
				
			||||||
    end;
 | 
					 | 
				
			||||||
  inherited SetCapacity(AValue);
 | 
					 | 
				
			||||||
end;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
constructor TSynHighlighterXmlRangeList.Create;
 | 
					 | 
				
			||||||
begin
 | 
					 | 
				
			||||||
  inherited;
 | 
					 | 
				
			||||||
  FItemOffset := ItemSize;
 | 
					 | 
				
			||||||
  ItemSize := FItemOffset + SizeOf(TSynXmlRangeInfo);
 | 
					 | 
				
			||||||
end;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
procedure TSynHighlighterXmlRangeList.Move(AFrom, ATo, ALen: Integer);
 | 
					 | 
				
			||||||
var
 | 
					 | 
				
			||||||
  i: LongInt;
 | 
					 | 
				
			||||||
begin
 | 
					 | 
				
			||||||
  if ATo > AFrom then
 | 
					 | 
				
			||||||
    for i:= Max(AFrom + ALen, ATo) to ATo + ALen - 1 do // move forward
 | 
					 | 
				
			||||||
      with TSynXmlRangeInfo((ItemPointer[i] + FItemOffset)^) do begin
 | 
					 | 
				
			||||||
        ElementOpenList := nil;
 | 
					 | 
				
			||||||
        ElementCloseList := nil;
 | 
					 | 
				
			||||||
      end
 | 
					 | 
				
			||||||
  else
 | 
					 | 
				
			||||||
    for i:= ATo to Min(ATo + ALen , AFrom) - 1 do // move backward
 | 
					 | 
				
			||||||
      with TSynXmlRangeInfo((ItemPointer[i] + FItemOffset)^) do begin
 | 
					 | 
				
			||||||
        ElementOpenList := nil;
 | 
					 | 
				
			||||||
        ElementCloseList := nil;
 | 
					 | 
				
			||||||
      end;
 | 
					 | 
				
			||||||
  inherited Move(AFrom, ATo, ALen);
 | 
					 | 
				
			||||||
end;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
initialization
 | 
					initialization
 | 
				
			||||||
  RegisterPlaceableHighlighter(TSynXMLSyn);
 | 
					  RegisterPlaceableHighlighter(TSynXMLSyn);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
end.
 | 
					end.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
				
			|||||||
@ -39,13 +39,14 @@ type
 | 
				
			|||||||
    function TestText5: TStringArray;
 | 
					    function TestText5: TStringArray;
 | 
				
			||||||
    function TestText6: TStringArray;
 | 
					    function TestText6: TStringArray;
 | 
				
			||||||
    function TestText7: TStringArray;
 | 
					    function TestText7: TStringArray;
 | 
				
			||||||
 | 
					    function TestText8: TStringArray;
 | 
				
			||||||
    function TestTextHide(ALen: Integer): TStringArray;
 | 
					    function TestTextHide(ALen: Integer): TStringArray;
 | 
				
			||||||
    function TestTextHide2(ALen: Integer): TStringArray;
 | 
					    function TestTextHide2(ALen: Integer): TStringArray;
 | 
				
			||||||
    function TestTextHide3: TStringArray;
 | 
					    function TestTextHide3: TStringArray;
 | 
				
			||||||
    function TestTextHide4: TStringArray;
 | 
					    function TestTextHide4: TStringArray;
 | 
				
			||||||
    function TestTextPlain: TStringArray;
 | 
					    function TestTextPlain: TStringArray;
 | 
				
			||||||
  protected
 | 
					  protected
 | 
				
			||||||
    procedure TstSetText(AName: String; AText: TStringArray);
 | 
					    procedure TstSetText(AName: String; AText: Array of String);
 | 
				
			||||||
    procedure TstFold(AName: String; AFoldAtIndex: integer; AExpectedLines: Array of Integer);
 | 
					    procedure TstFold(AName: String; AFoldAtIndex: integer; AExpectedLines: Array of Integer);
 | 
				
			||||||
    procedure TstFold(AName: String; AFoldAtIndex, AFoldAtColum: integer; AExpectedLines: Array of Integer);
 | 
					    procedure TstFold(AName: String; AFoldAtIndex, AFoldAtColum: integer; AExpectedLines: Array of Integer);
 | 
				
			||||||
    procedure TstFold(AName: String; AFoldAtIndex, AFoldAtColum, AFoldAtColCnt: integer;
 | 
					    procedure TstFold(AName: String; AFoldAtIndex, AFoldAtColum, AFoldAtColCnt: integer;
 | 
				
			||||||
@ -66,6 +67,7 @@ type
 | 
				
			|||||||
    procedure TestFoldEdit;
 | 
					    procedure TestFoldEdit;
 | 
				
			||||||
    procedure TestFoldStateFromText;
 | 
					    procedure TestFoldStateFromText;
 | 
				
			||||||
    procedure TestFoldStateDesc;
 | 
					    procedure TestFoldStateDesc;
 | 
				
			||||||
 | 
					    procedure TestFoldProvider;
 | 
				
			||||||
  end;
 | 
					  end;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
implementation
 | 
					implementation
 | 
				
			||||||
@ -73,7 +75,7 @@ implementation
 | 
				
			|||||||
type
 | 
					type
 | 
				
			||||||
  TSynEditFoldedViewHack = class(TSynEditFoldedView) end;
 | 
					  TSynEditFoldedViewHack = class(TSynEditFoldedView) end;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
procedure TTestFoldedView.TstSetText(AName: String; AText: TStringArray);
 | 
					procedure TTestFoldedView.TstSetText(AName: String; AText: array of String);
 | 
				
			||||||
begin
 | 
					begin
 | 
				
			||||||
  PopBaseName;
 | 
					  PopBaseName;
 | 
				
			||||||
  ReCreateEdit;
 | 
					  ReCreateEdit;
 | 
				
			||||||
@ -406,6 +408,32 @@ begin
 | 
				
			|||||||
  Result[26] := '';
 | 
					  Result[26] := '';
 | 
				
			||||||
end;
 | 
					end;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function TTestFoldedView.TestText8: TStringArray;
 | 
				
			||||||
 | 
					begin
 | 
				
			||||||
 | 
					  // end begin lines, with mixed type
 | 
				
			||||||
 | 
					  SetLength(Result, 20);
 | 
				
			||||||
 | 
					  Result[0]  := 'program Foo;';
 | 
				
			||||||
 | 
					  Result[1]  := 'procedure a;';
 | 
				
			||||||
 | 
					  Result[2]  := 'begin';
 | 
				
			||||||
 | 
					  Result[3]  := '{%region}';
 | 
				
			||||||
 | 
					  Result[4]  := '{%endregion} {$ifdef x}';
 | 
				
			||||||
 | 
					  Result[5]  := '             {$endif} if a then begin';
 | 
				
			||||||
 | 
					  Result[6]  := '                      end;             {%region}';
 | 
				
			||||||
 | 
					  Result[7]  := '{%endregion} {$ifdef x}';
 | 
				
			||||||
 | 
					  Result[8]  := '             {$endif} if a then begin';
 | 
				
			||||||
 | 
					  Result[9]  := '                        writeln(1);';
 | 
				
			||||||
 | 
					  Result[10] := '{%region}             end;';
 | 
				
			||||||
 | 
					  Result[11] := '  writeln(1);';
 | 
				
			||||||
 | 
					  Result[12] := '{%endregion}  if a then begin';
 | 
				
			||||||
 | 
					  Result[13] := '                        writeln(1);';
 | 
				
			||||||
 | 
					  Result[14] := '{$ifdef x}    end;';
 | 
				
			||||||
 | 
					  Result[15] := '  writeln(1);';
 | 
				
			||||||
 | 
					  Result[16] := '{$endif}';
 | 
				
			||||||
 | 
					  Result[17] := '  writeln(1);';
 | 
				
			||||||
 | 
					  Result[18] := 'end';
 | 
				
			||||||
 | 
					  Result[19] := '';
 | 
				
			||||||
 | 
					end;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function TTestFoldedView.TestTextHide(ALen: Integer): TStringArray;
 | 
					function TTestFoldedView.TestTextHide(ALen: Integer): TStringArray;
 | 
				
			||||||
begin
 | 
					begin
 | 
				
			||||||
  SetLength(Result, 3+ALen);
 | 
					  SetLength(Result, 3+ALen);
 | 
				
			||||||
@ -1457,6 +1485,161 @@ begin
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
end;
 | 
					end;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					procedure TTestFoldedView.TestFoldProvider;
 | 
				
			||||||
 | 
					  procedure DoTestOpenCounts(AName: string; AType: Integer; AExp: Array of Integer);
 | 
				
			||||||
 | 
					  var
 | 
				
			||||||
 | 
					    i: Integer;
 | 
				
			||||||
 | 
					  begin
 | 
				
			||||||
 | 
					    AName := AName + ' (type=' + IntToStr(AType)+') ';
 | 
				
			||||||
 | 
					    for i := low(AExp) to high(AExp) do
 | 
				
			||||||
 | 
					      DebugLn([BaseTestName+AName+ ' line=' + IntToStr(i)+ ' exp=', AExp[i],'   Got=', FoldedView.FoldProvider.FoldOpenCount(i, AType)]);
 | 
				
			||||||
 | 
					    for i := low(AExp) to high(AExp) do
 | 
				
			||||||
 | 
					      AssertEquals(BaseTestName+AName+ ' line=' + IntToStr(i),
 | 
				
			||||||
 | 
					                   AExp[i], FoldedView.FoldProvider.FoldOpenCount(i, AType));
 | 
				
			||||||
 | 
					  end;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var
 | 
				
			||||||
 | 
					  i: Integer;
 | 
				
			||||||
 | 
					begin
 | 
				
			||||||
 | 
					  // TSynEditFoldProvider.FoldOpenCount(ALineIdx: Integer; AType: Integer = 0): Integer;
 | 
				
			||||||
 | 
					  PushBaseName('');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  TstSetText('TestText1', TestText);
 | 
				
			||||||
 | 
					  EnableFolds([cfbtBeginEnd..cfbtNone]);
 | 
				
			||||||
 | 
					  //                       p  P  B  ~  -
 | 
				
			||||||
 | 
					  DoTestOpenCounts('', 0, [1, 1, 1, 0, 0]); // all (fold conf)
 | 
				
			||||||
 | 
					  DoTestOpenCounts('', 1, [1, 1, 1, 0, 0]); // pas
 | 
				
			||||||
 | 
					  //DoTestOpenCounts('', 4, [1, 1, 1, 0, 0]); // pas (incl unfolded)
 | 
				
			||||||
 | 
					  DoTestOpenCounts('', 2, [0, 0, 0, 0, 0]); // %region
 | 
				
			||||||
 | 
					  DoTestOpenCounts('', 3, [0, 0, 0, 0, 0]); // $if
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  TstSetText('TestText1 (2)', TestText);
 | 
				
			||||||
 | 
					  EnableFolds([cfbtTopBeginEnd]);
 | 
				
			||||||
 | 
					  //                       p  P  B  ~  -
 | 
				
			||||||
 | 
					  DoTestOpenCounts('', 0, [0, 0, 1, 0, 0]); // all (fold conf)
 | 
				
			||||||
 | 
					  DoTestOpenCounts('', 1, [0, 0, 1, 0, 0]); // pas
 | 
				
			||||||
 | 
					  //DoTestOpenCounts('', 4, [1, 1, 1, 0, 0]); // pas (incl unfolded)
 | 
				
			||||||
 | 
					  DoTestOpenCounts('', 2, [0, 0, 0, 0, 0]); // %region
 | 
				
			||||||
 | 
					  DoTestOpenCounts('', 3, [0, 0, 0, 0, 0]); // $if
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  TstSetText('TestText1 (3)', TestText);
 | 
				
			||||||
 | 
					  EnableFolds([cfbtProcedure, cfbtBeginEnd]);
 | 
				
			||||||
 | 
					  //                       p  P  B  ~  -
 | 
				
			||||||
 | 
					  DoTestOpenCounts('', 0, [0, 1, 0, 0, 0]); // all (fold conf)
 | 
				
			||||||
 | 
					  DoTestOpenCounts('', 1, [0, 1, 0, 0, 0]); // pas
 | 
				
			||||||
 | 
					  //DoTestOpenCounts('', 4, [1, 1, 1, 0, 0]); // pas (incl unfolded)
 | 
				
			||||||
 | 
					  DoTestOpenCounts('', 2, [0, 0, 0, 0, 0]); // %region
 | 
				
			||||||
 | 
					  DoTestOpenCounts('', 3, [0, 0, 0, 0, 0]); // $if
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  TstSetText('TestText2', TestText2);
 | 
				
			||||||
 | 
					  EnableFolds([cfbtBeginEnd..cfbtNone]);
 | 
				
			||||||
 | 
					  //                                      if    else
 | 
				
			||||||
 | 
					  //                       p  PP B  -  B  B  ~  -B ~  -  -  ~
 | 
				
			||||||
 | 
					  DoTestOpenCounts('', 0, [1, 2, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0]);
 | 
				
			||||||
 | 
					  DoTestOpenCounts('', 1, [1, 2, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0]);
 | 
				
			||||||
 | 
					  //DoTestOpenCounts('', 4, [1, 2, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0]);
 | 
				
			||||||
 | 
					  DoTestOpenCounts('', 2, [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]);
 | 
				
			||||||
 | 
					  DoTestOpenCounts('', 3, [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  TstSetText('TestText2 (2)', TestText2);
 | 
				
			||||||
 | 
					  EnableFolds([cfbtBeginEnd..cfbtNone]-[cfbtProgram, cfbtRegion]);
 | 
				
			||||||
 | 
					  //                       p  PP B  -  B  B  ~  -B ~  -  -  ~
 | 
				
			||||||
 | 
					  DoTestOpenCounts('', 0, [0, 2, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0]);
 | 
				
			||||||
 | 
					  DoTestOpenCounts('', 1, [0, 2, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0]);
 | 
				
			||||||
 | 
					  //DoTestOpenCounts('', 4, [1, 2, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0]);
 | 
				
			||||||
 | 
					  DoTestOpenCounts('', 2, [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]);
 | 
				
			||||||
 | 
					  DoTestOpenCounts('', 3, [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  TstSetText('TestText3', TestText3);
 | 
				
			||||||
 | 
					  EnableFolds([cfbtBeginEnd..cfbtNone],  [cfbtSlashComment]);
 | 
				
			||||||
 | 
					  //                                      if    else        // one-line-comment
 | 
				
			||||||
 | 
					  //                       p  $  P  -  B  %B ~  --B~  -  -  /
 | 
				
			||||||
 | 
					  DoTestOpenCounts('', 0, [1, 1, 1, 0, 1, 2, 0, 1, 0, 0, 0, 1]);
 | 
				
			||||||
 | 
					  DoTestOpenCounts('', 1, [1, 0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 1]);
 | 
				
			||||||
 | 
					  //DoTestOpenCounts('', 4, [1, 0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 1]);
 | 
				
			||||||
 | 
					  DoTestOpenCounts('', 2, [0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0]); // %region
 | 
				
			||||||
 | 
					  DoTestOpenCounts('', 3, [0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]); // %if
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  TstSetText('TestText3 (2)', TestText3);
 | 
				
			||||||
 | 
					  EnableFolds([cfbtBeginEnd..cfbtNone]-[cfbtProgram, cfbtRegion],  [cfbtSlashComment]);
 | 
				
			||||||
 | 
					  //                       p  $  P  -  B  %B ~  --B~  -  -  /
 | 
				
			||||||
 | 
					  DoTestOpenCounts('', 0, [0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 1]);
 | 
				
			||||||
 | 
					  DoTestOpenCounts('', 1, [0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 1]);
 | 
				
			||||||
 | 
					  //DoTestOpenCounts('', 4, [1, 0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 1]);
 | 
				
			||||||
 | 
					  DoTestOpenCounts('', 2, [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]); // %region
 | 
				
			||||||
 | 
					  DoTestOpenCounts('', 3, [0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]); // %if
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  TstSetText('TestText3 (3)', TestText3);
 | 
				
			||||||
 | 
					  EnableFolds([cfbtBeginEnd..cfbtNone]-[cfbtProgram, cfbtIfDef], []);
 | 
				
			||||||
 | 
					  //                       p  $  P  -  B  %B ~  --B~  -  -  /
 | 
				
			||||||
 | 
					  DoTestOpenCounts('', 0, [0, 0, 1, 0, 1, 2, 0, 1, 0, 0, 0, 0]);
 | 
				
			||||||
 | 
					  DoTestOpenCounts('', 1, [0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0]);
 | 
				
			||||||
 | 
					  //DoTestOpenCounts('', 4, [1, 0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 1]);
 | 
				
			||||||
 | 
					  DoTestOpenCounts('', 2, [0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0]); // %region
 | 
				
			||||||
 | 
					  DoTestOpenCounts('', 3, [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]); // %if
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  for i := 0 to 2 do begin // pos of $IFDEF does not matter
 | 
				
			||||||
 | 
					    TstSetText('TestTextPasHl-'+IntToStr(i)+'', TestTextPasHl(i));
 | 
				
			||||||
 | 
					    EnableFolds([cfbtBeginEnd..cfbtNone],  [cfbtSlashComment]);
 | 
				
			||||||
 | 
					    //                             if       $E // one-line-comment
 | 
				
			||||||
 | 
					    //                       p  P  $bb-  -  -  /
 | 
				
			||||||
 | 
					    DoTestOpenCounts('', 0, [1, 1, 3, 0, 0, 0, 1]);
 | 
				
			||||||
 | 
					    DoTestOpenCounts('', 1, [1, 1, 2, 0, 0, 0, 1]);
 | 
				
			||||||
 | 
					    //DoTestOpenCounts('', 4, [1, 1, 2, 0, 0, 0, 1]);
 | 
				
			||||||
 | 
					    DoTestOpenCounts('', 2, [0, 0, 0, 0, 0, 0, 0]); // %region
 | 
				
			||||||
 | 
					    DoTestOpenCounts('', 3, [0, 0, 1, 0, 0, 0, 0]); // %if
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    TstSetText('TestTextPasHl-'+IntToStr(i)+'', TestTextPasHl(i));
 | 
				
			||||||
 | 
					    EnableFolds([cfbtBeginEnd..cfbtNone]-[cfbtBeginEnd],  [cfbtSlashComment]);
 | 
				
			||||||
 | 
					    //                             if       $E // one-line-comment
 | 
				
			||||||
 | 
					    //                       p  P  $bb-  -  -  /
 | 
				
			||||||
 | 
					    DoTestOpenCounts('', 0, [1, 1, 2, 0, 0, 0, 1]);
 | 
				
			||||||
 | 
					    DoTestOpenCounts('', 1, [1, 1, 1, 0, 0, 0, 1]);
 | 
				
			||||||
 | 
					    //DoTestOpenCounts('', 4, [1, 1, 1, 0, 0, 0, 1]);
 | 
				
			||||||
 | 
					    DoTestOpenCounts('', 2, [0, 0, 0, 0, 0, 0, 0]); // %region
 | 
				
			||||||
 | 
					    DoTestOpenCounts('', 3, [0, 0, 1, 0, 0, 0, 0]); // %if
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    TstSetText('TestTextPasHl-'+IntToStr(i)+'', TestTextPasHl(i));
 | 
				
			||||||
 | 
					    EnableFolds([cfbtBeginEnd..cfbtNone]-[cfbtIfDef],  [cfbtSlashComment]);
 | 
				
			||||||
 | 
					    //                             if       $E // one-line-comment
 | 
				
			||||||
 | 
					    //                       p  P  $bb-  -  -  /
 | 
				
			||||||
 | 
					    DoTestOpenCounts('', 0, [1, 1, 2, 0, 0, 0, 1]);
 | 
				
			||||||
 | 
					    DoTestOpenCounts('', 1, [1, 1, 2, 0, 0, 0, 1]);
 | 
				
			||||||
 | 
					    //DoTestOpenCounts('', 4, [1, 1, 2, 0, 0, 0, 1]);
 | 
				
			||||||
 | 
					    DoTestOpenCounts('', 2, [0, 0, 0, 0, 0, 0, 0]); // %region
 | 
				
			||||||
 | 
					    DoTestOpenCounts('', 3, [0, 0, 0, 0, 0, 0, 0]); // %if
 | 
				
			||||||
 | 
					  end;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  TstSetText('TestText4', TestText4);
 | 
				
			||||||
 | 
					  EnableFolds([cfbtBeginEnd..cfbtNone],  [cfbtSlashComment]);
 | 
				
			||||||
 | 
					  //                       pPBB  -  B  -  B  -
 | 
				
			||||||
 | 
					  DoTestOpenCounts('', 0, [3, 1, 0, 1, 0, 1]);
 | 
				
			||||||
 | 
					  DoTestOpenCounts('', 1, [3, 1, 0, 1, 0, 1]);
 | 
				
			||||||
 | 
					  //DoTestOpenCounts('', 4, [3, 1, 0, 1, 0, 1]);
 | 
				
			||||||
 | 
					  DoTestOpenCounts('', 2, [0, 0, 0, 0, 0, 0]);
 | 
				
			||||||
 | 
					  DoTestOpenCounts('', 3, [0, 0, 0, 0, 0, 0]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  TstSetText('TestText8', TestText8);
 | 
				
			||||||
 | 
					  EnableFolds([cfbtBeginEnd..cfbtNone],  [cfbtSlashComment]);
 | 
				
			||||||
 | 
					  //                       p  P  B  %  $  B  %  $  B  ~  %  ~  B  ~  $  ~  -  ~  -
 | 
				
			||||||
 | 
					  DoTestOpenCounts('', 0, [1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0]);
 | 
				
			||||||
 | 
					  DoTestOpenCounts('', 1, [1, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0]);
 | 
				
			||||||
 | 
					//DoTestOpenCounts('', 4, [1, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0]);
 | 
				
			||||||
 | 
					  DoTestOpenCounts('', 2, [0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0]);
 | 
				
			||||||
 | 
					  DoTestOpenCounts('', 3, [0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					end;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
initialization
 | 
					initialization
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  RegisterTest(TTestFoldedView); 
 | 
					  RegisterTest(TTestFoldedView); 
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										136
									
								
								components/synedit/test/testhighlighterlfm.pas
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										136
									
								
								components/synedit/test/testhighlighterlfm.pas
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,136 @@
 | 
				
			|||||||
 | 
					unit TestHighlighterLfm;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					{$mode objfpc}{$H+}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					interface
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					uses
 | 
				
			||||||
 | 
					  Classes, SysUtils, testregistry, TestBase, Forms, LCLProc, TestHighlightFoldBase,
 | 
				
			||||||
 | 
					  SynEdit, SynEditTypes, SynHighlighterLFM, SynEditHighlighterFoldBase;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  { TTestBaseHighlighterLem }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  TTestBaseHighlighterLem = class(TTestBaseHighlighterFoldBase)
 | 
				
			||||||
 | 
					  protected
 | 
				
			||||||
 | 
					    function LfmHighLighter: TSynLFMSyn;
 | 
				
			||||||
 | 
					    function CreateTheHighLighter: TSynCustomFoldHighlighter; override;
 | 
				
			||||||
 | 
					    procedure EnableFolds(AEnbledTypes: TLfmCodeFoldBlockTypes;
 | 
				
			||||||
 | 
					                          AHideTypes: TLfmCodeFoldBlockTypes = [];
 | 
				
			||||||
 | 
					                          ANoFoldTypes: TLfmCodeFoldBlockTypes = []
 | 
				
			||||||
 | 
					                         );
 | 
				
			||||||
 | 
					    //procedure DebugFoldInfo(ALineIdx: Integer; AFilter: TSynFoldActions; Group: Integer=0);
 | 
				
			||||||
 | 
					    //procedure DebugFoldInfo(AFilter: TSynFoldActions; Group: Integer=0);
 | 
				
			||||||
 | 
					    //function FoldActionsToString(AFoldActions: TSynFoldActions): String;
 | 
				
			||||||
 | 
					  end;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  { TTestHighlighterLfm }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  TTestHighlighterLfm = class(TTestBaseHighlighterLem)
 | 
				
			||||||
 | 
					  protected
 | 
				
			||||||
 | 
					    function TestTextFoldInfo1: TStringArray;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    procedure CheckTokensForLine(Name: String; LineIdx: Integer; ExpTokens: Array of TtkTokenKind);
 | 
				
			||||||
 | 
					  published
 | 
				
			||||||
 | 
					    procedure TestFoldInfo;
 | 
				
			||||||
 | 
					  end;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					implementation
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					{ TTestBaseHighlighterLem }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function TTestBaseHighlighterLem.LfmHighLighter: TSynLFMSyn;
 | 
				
			||||||
 | 
					begin
 | 
				
			||||||
 | 
					  Result := TSynLFMSyn(FTheHighLighter);
 | 
				
			||||||
 | 
					end;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function TTestBaseHighlighterLem.CreateTheHighLighter: TSynCustomFoldHighlighter;
 | 
				
			||||||
 | 
					begin
 | 
				
			||||||
 | 
					  Result := TSynLFMSyn.Create(nil);
 | 
				
			||||||
 | 
					end;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					procedure TTestBaseHighlighterLem.EnableFolds(AEnbledTypes: TLfmCodeFoldBlockTypes;
 | 
				
			||||||
 | 
					  AHideTypes: TLfmCodeFoldBlockTypes; ANoFoldTypes: TLfmCodeFoldBlockTypes);
 | 
				
			||||||
 | 
					var
 | 
				
			||||||
 | 
					  i: TLfmCodeFoldBlockType;
 | 
				
			||||||
 | 
					begin
 | 
				
			||||||
 | 
					  for i := low(TLfmCodeFoldBlockType) to high(TLfmCodeFoldBlockType) do begin
 | 
				
			||||||
 | 
					    LfmHighLighter.FoldConfig[ord(i)].Enabled := i in AEnbledTypes;
 | 
				
			||||||
 | 
					    if (i in ANoFoldTypes) then
 | 
				
			||||||
 | 
					      LfmHighLighter.FoldConfig[ord(i)].Modes := []
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					      LfmHighLighter.FoldConfig[ord(i)].Modes := [fmFold];
 | 
				
			||||||
 | 
					    if i in AHideTypes then
 | 
				
			||||||
 | 
					      LfmHighLighter.FoldConfig[ord(i)].Modes := LfmHighLighter.FoldConfig[ord(i)].Modes + [fmHide]
 | 
				
			||||||
 | 
					  end;
 | 
				
			||||||
 | 
					end;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function TTestHighlighterLfm.TestTextFoldInfo1: TStringArray;
 | 
				
			||||||
 | 
					begin
 | 
				
			||||||
 | 
					  SetLength(Result, 11);
 | 
				
			||||||
 | 
					  Result[0] := 'object BreakPointGroupDlg: TBreakPointGroupDlg';
 | 
				
			||||||
 | 
					  Result[1] := '  Left = 431';
 | 
				
			||||||
 | 
					  Result[2] := '  Height = 225';
 | 
				
			||||||
 | 
					  Result[3] := '  object ButtonPanel1: TButtonPanel';
 | 
				
			||||||
 | 
					  Result[4] := '    Left = 6';
 | 
				
			||||||
 | 
					  Result[5] := '  end';
 | 
				
			||||||
 | 
					  Result[6] := '  object Label1: TLabel';
 | 
				
			||||||
 | 
					  Result[7] := '    Left = 0';
 | 
				
			||||||
 | 
					  Result[8] := '  end';
 | 
				
			||||||
 | 
					  Result[9] := 'end';
 | 
				
			||||||
 | 
					  Result[10] := '';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					end;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					procedure TTestHighlighterLfm.CheckTokensForLine(Name: String; LineIdx: Integer;
 | 
				
			||||||
 | 
					  ExpTokens: array of TtkTokenKind);
 | 
				
			||||||
 | 
					var
 | 
				
			||||||
 | 
					  c: Integer;
 | 
				
			||||||
 | 
					begin
 | 
				
			||||||
 | 
					  LfmHighLighter.StartAtLineIndex(LineIdx);
 | 
				
			||||||
 | 
					  c := 0;
 | 
				
			||||||
 | 
					  while not LfmHighLighter.GetEol do begin
 | 
				
			||||||
 | 
					    //DebugLn([LfmHighLighter.GetToken,' (',PasHighLighter.GetTokenID ,') at ', PasHighLighter.GetTokenPos]);
 | 
				
			||||||
 | 
					    AssertEquals(Name + 'TokenId Line='+IntToStr(LineIdx)+' pos='+IntToStr(c),  ord(ExpTokens[c]), ord(LfmHighLighter.GetTokenID));
 | 
				
			||||||
 | 
					    LfmHighLighter.Next;
 | 
				
			||||||
 | 
					    inc(c);
 | 
				
			||||||
 | 
					    if c >= length(ExpTokens) then
 | 
				
			||||||
 | 
					      break;
 | 
				
			||||||
 | 
					  end;
 | 
				
			||||||
 | 
					  AssertEquals(Name+ 'TokenId Line='+IntToStr(LineIdx)+'  amount of tokens', length(ExpTokens), c );
 | 
				
			||||||
 | 
					end;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					procedure TTestHighlighterLfm.TestFoldInfo;
 | 
				
			||||||
 | 
					begin
 | 
				
			||||||
 | 
					  ReCreateEdit;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  //  DebugFoldInfo([]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  {%region}
 | 
				
			||||||
 | 
					  SetLines(TestTextFoldInfo1);
 | 
				
			||||||
 | 
					  EnableFolds([cfbtLfmObject..cfbtLfmNone]);
 | 
				
			||||||
 | 
					  PushBaseName('Text 1 all folds');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  EnableFolds([cfbtLfmObject..cfbtLfmNone], [cfbtLfmNone]);
 | 
				
			||||||
 | 
					  AssertEquals('Len 0', 9, LfmHighLighter.FoldLineLength(0,0));
 | 
				
			||||||
 | 
					  //AssertEquals('Len 1', 0, LfmHighLighter.FoldLineLength(1,0));
 | 
				
			||||||
 | 
					  AssertEquals('Len 3', 2, LfmHighLighter.FoldLineLength(3,0));
 | 
				
			||||||
 | 
					  //AssertEquals('Len 4', 0, LfmHighLighter.FoldLineLength(4,0));
 | 
				
			||||||
 | 
					  //AssertEquals('Len 5', 0, LfmHighLighter.FoldLineLength(5,0));
 | 
				
			||||||
 | 
					  AssertEquals('Len 6', 2, LfmHighLighter.FoldLineLength(6,0));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  CheckFoldOpenCounts('', [1, 0, 0, 1, 0, 0, 1, 0, 0, 0]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  {%endregion}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					end;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					initialization
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  RegisterTest(TTestHighlighterLfm);
 | 
				
			||||||
 | 
					end.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										116
									
								
								components/synedit/test/testhighlightfoldbase.pas
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										116
									
								
								components/synedit/test/testhighlightfoldbase.pas
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,116 @@
 | 
				
			|||||||
 | 
					unit TestHighlightFoldBase;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					{$mode objfpc}{$H+}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					interface
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					uses
 | 
				
			||||||
 | 
					  Classes, SysUtils, testregistry, TestBase, Forms, LCLProc,
 | 
				
			||||||
 | 
					  SynEdit, SynEditTypes, SynEditHighlighterFoldBase;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // used by Fold / MarkupWord
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  { TTestBaseHighlighterPas }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  { TTestBaseHighlighterFoldBase }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  TTestBaseHighlighterFoldBase = class(TTestBase)
 | 
				
			||||||
 | 
					  protected
 | 
				
			||||||
 | 
					    FTheHighLighter: TSynCustomFoldHighlighter;
 | 
				
			||||||
 | 
					    function CreateTheHighLighter: TSynCustomFoldHighlighter; virtual; abstract;
 | 
				
			||||||
 | 
					    procedure SetUp; override;
 | 
				
			||||||
 | 
					    procedure TearDown; override;
 | 
				
			||||||
 | 
					    procedure ReCreateEdit; reintroduce;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    procedure CheckFoldOpenCounts(Name: String; Expected: Array of Integer);
 | 
				
			||||||
 | 
					    procedure CheckFoldInfoCounts(Name: String; Filter: TSynFoldActions; Expected: Array of Integer);
 | 
				
			||||||
 | 
					    procedure CheckFoldInfoCounts(Name: String; Filter: TSynFoldActions; Group: Integer; Expected: Array of Integer);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    function FoldActionsToString(AFoldActions: TSynFoldActions): String;
 | 
				
			||||||
 | 
					  end;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					implementation
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					{ TTestBaseHighlighterFoldBase }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					procedure TTestBaseHighlighterFoldBase.SetUp;
 | 
				
			||||||
 | 
					begin
 | 
				
			||||||
 | 
					  FTheHighLighter := nil;
 | 
				
			||||||
 | 
					  inherited SetUp;
 | 
				
			||||||
 | 
					end;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					procedure TTestBaseHighlighterFoldBase.TearDown;
 | 
				
			||||||
 | 
					begin
 | 
				
			||||||
 | 
					  if Assigned(SynEdit) then
 | 
				
			||||||
 | 
					    SynEdit.Highlighter := nil;
 | 
				
			||||||
 | 
					  FreeAndNil(FTheHighLighter);
 | 
				
			||||||
 | 
					  inherited TearDown;
 | 
				
			||||||
 | 
					end;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					procedure TTestBaseHighlighterFoldBase.ReCreateEdit;
 | 
				
			||||||
 | 
					begin
 | 
				
			||||||
 | 
					  if Assigned(SynEdit) then
 | 
				
			||||||
 | 
					    SynEdit.Highlighter := nil;
 | 
				
			||||||
 | 
					  FreeAndNil(FTheHighLighter);
 | 
				
			||||||
 | 
					  inherited ReCreateEdit;
 | 
				
			||||||
 | 
					  FTheHighLighter := CreateTheHighLighter;
 | 
				
			||||||
 | 
					  SynEdit.Highlighter := FTheHighLighter;
 | 
				
			||||||
 | 
					end;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					procedure TTestBaseHighlighterFoldBase.CheckFoldOpenCounts(Name: String;
 | 
				
			||||||
 | 
					  Expected: array of Integer);
 | 
				
			||||||
 | 
					var
 | 
				
			||||||
 | 
					  i: Integer;
 | 
				
			||||||
 | 
					begin
 | 
				
			||||||
 | 
					  for i := 0 to high(Expected) do
 | 
				
			||||||
 | 
					    AssertEquals(Name + 'OpenCount Line OLD='+IntToStr(i),  Expected[i], FTheHighLighter.FoldOpenCount(i));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  for i := 0 to high(Expected) do
 | 
				
			||||||
 | 
					    AssertEquals(Name + 'OpenCount Line='+IntToStr(i),  Expected[i], FTheHighLighter.FoldBlockOpeningCount(i));
 | 
				
			||||||
 | 
					end;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					procedure TTestBaseHighlighterFoldBase.CheckFoldInfoCounts(Name: String;
 | 
				
			||||||
 | 
					  Filter: TSynFoldActions; Expected: array of Integer);
 | 
				
			||||||
 | 
					begin
 | 
				
			||||||
 | 
					  CheckFoldInfoCounts(Name, Filter, 0, Expected);
 | 
				
			||||||
 | 
					end;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					procedure TTestBaseHighlighterFoldBase.CheckFoldInfoCounts(Name: String;
 | 
				
			||||||
 | 
					  Filter: TSynFoldActions; Group: Integer; Expected: array of Integer);
 | 
				
			||||||
 | 
					var
 | 
				
			||||||
 | 
					  i: Integer;
 | 
				
			||||||
 | 
					  l: TLazSynFoldNodeInfoList;
 | 
				
			||||||
 | 
					begin
 | 
				
			||||||
 | 
					  for i := 0 to high(Expected) do begin
 | 
				
			||||||
 | 
					    l := FTheHighLighter.FoldNodeInfo[i];
 | 
				
			||||||
 | 
					    AssertEquals(Name + 'InfoCount(Ex) Line='+IntToStr(i),
 | 
				
			||||||
 | 
					                 Expected[i],
 | 
				
			||||||
 | 
					                 l.CountEx(Filter, Group));
 | 
				
			||||||
 | 
					    l.ClearFilter;
 | 
				
			||||||
 | 
					    l.ActionFilter := Filter;
 | 
				
			||||||
 | 
					    l.GroupFilter := Group;
 | 
				
			||||||
 | 
					    AssertEquals(Name + 'InfoCount Line='+IntToStr(i),
 | 
				
			||||||
 | 
					                 Expected[i],
 | 
				
			||||||
 | 
					                 FTheHighLighter.FoldNodeInfo[i].Count);
 | 
				
			||||||
 | 
					  end;
 | 
				
			||||||
 | 
					end;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function TTestBaseHighlighterFoldBase.FoldActionsToString(AFoldActions: TSynFoldActions): String;
 | 
				
			||||||
 | 
					var
 | 
				
			||||||
 | 
					  s: string;
 | 
				
			||||||
 | 
					  i: TSynFoldAction;
 | 
				
			||||||
 | 
					begin
 | 
				
			||||||
 | 
					  Result:='';
 | 
				
			||||||
 | 
					  for i := low(TSynFoldAction) to high(TSynFoldAction) do
 | 
				
			||||||
 | 
					    if i in AFoldActions then begin
 | 
				
			||||||
 | 
					      WriteStr(s, i);
 | 
				
			||||||
 | 
					      Result := Result + s + ',';
 | 
				
			||||||
 | 
					    end;
 | 
				
			||||||
 | 
					  if Result <> '' then SetLength(Result, Length(Result)-1);
 | 
				
			||||||
 | 
					end;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					end.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -5,7 +5,7 @@ unit TestHighlightPas;
 | 
				
			|||||||
interface
 | 
					interface
 | 
				
			||||||
 | 
					
 | 
				
			||||||
uses
 | 
					uses
 | 
				
			||||||
  Classes, SysUtils, testregistry, TestBase, Forms, LCLProc,
 | 
					  Classes, SysUtils, testregistry, TestBase, Forms, LCLProc, TestHighlightFoldBase,
 | 
				
			||||||
  SynEdit, SynEditTypes, SynHighlighterPas, SynEditHighlighterFoldBase;
 | 
					  SynEdit, SynEditTypes, SynHighlighterPas, SynEditHighlighterFoldBase;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type
 | 
					type
 | 
				
			||||||
@ -14,12 +14,10 @@ type
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  { TTestBaseHighlighterPas }
 | 
					  { TTestBaseHighlighterPas }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  TTestBaseHighlighterPas = class(TTestBase)
 | 
					  TTestBaseHighlighterPas = class(TTestBaseHighlighterFoldBase)
 | 
				
			||||||
  protected
 | 
					  protected
 | 
				
			||||||
    PasHighLighter: TSynPasSyn;
 | 
					    function PasHighLighter: TSynPasSyn;
 | 
				
			||||||
    procedure SetUp; override;
 | 
					    function CreateTheHighLighter: TSynCustomFoldHighlighter; override;
 | 
				
			||||||
    procedure TearDown; override;
 | 
					 | 
				
			||||||
    procedure ReCreateEdit; reintroduce;
 | 
					 | 
				
			||||||
    procedure EnableFolds(AEnbledTypes: TPascalCodeFoldBlockTypes;
 | 
					    procedure EnableFolds(AEnbledTypes: TPascalCodeFoldBlockTypes;
 | 
				
			||||||
                          AHideTypes: TPascalCodeFoldBlockTypes = [];
 | 
					                          AHideTypes: TPascalCodeFoldBlockTypes = [];
 | 
				
			||||||
                          ANoFoldTypes: TPascalCodeFoldBlockTypes = []
 | 
					                          ANoFoldTypes: TPascalCodeFoldBlockTypes = []
 | 
				
			||||||
@ -38,12 +36,8 @@ type
 | 
				
			|||||||
    function TestTextFoldInfo3: TStringArray;
 | 
					    function TestTextFoldInfo3: TStringArray;
 | 
				
			||||||
    function TestTextFoldInfo4(AIfCol: Integer): TStringArray;
 | 
					    function TestTextFoldInfo4(AIfCol: Integer): TStringArray;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    procedure CheckFoldOpenCounts(Name: String; Expected: Array of Integer);
 | 
					 | 
				
			||||||
    procedure CheckFoldInfoCounts(Name: String; Filter: TSynFoldActions; Expected: Array of Integer);
 | 
					 | 
				
			||||||
    procedure CheckFoldInfoCounts(Name: String; Filter: TSynFoldActions; Group: Integer; Expected: Array of Integer);
 | 
					 | 
				
			||||||
    procedure CheckTokensForLine(Name: String; LineIdx: Integer; ExpTokens: Array of TtkTokenKind);
 | 
					    procedure CheckTokensForLine(Name: String; LineIdx: Integer; ExpTokens: Array of TtkTokenKind);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    function FoldActionsToString(AFoldActions: TSynFoldActions): String;
 | 
					 | 
				
			||||||
  published
 | 
					  published
 | 
				
			||||||
    procedure TestFoldInfo;
 | 
					    procedure TestFoldInfo;
 | 
				
			||||||
    procedure TestExtendedKeywordsAndStrings;
 | 
					    procedure TestExtendedKeywordsAndStrings;
 | 
				
			||||||
@ -60,28 +54,14 @@ implementation
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
{ TTestBaseHighlighterPas }
 | 
					{ TTestBaseHighlighterPas }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
procedure TTestBaseHighlighterPas.SetUp;
 | 
					function TTestBaseHighlighterPas.PasHighLighter: TSynPasSyn;
 | 
				
			||||||
begin
 | 
					begin
 | 
				
			||||||
  PasHighLighter := nil;
 | 
					  Result := TSynPasSyn(FTheHighLighter);
 | 
				
			||||||
  inherited SetUp;
 | 
					 | 
				
			||||||
end;
 | 
					end;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
procedure TTestBaseHighlighterPas.TearDown;
 | 
					function TTestBaseHighlighterPas.CreateTheHighLighter: TSynCustomFoldHighlighter;
 | 
				
			||||||
begin
 | 
					begin
 | 
				
			||||||
  if Assigned(SynEdit) then
 | 
					  Result := TSynPasSyn.Create(nil);
 | 
				
			||||||
    SynEdit.Highlighter := nil;
 | 
					 | 
				
			||||||
  FreeAndNil(PasHighLighter);
 | 
					 | 
				
			||||||
  inherited TearDown;
 | 
					 | 
				
			||||||
end;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
procedure TTestBaseHighlighterPas.ReCreateEdit;
 | 
					 | 
				
			||||||
begin
 | 
					 | 
				
			||||||
  if Assigned(SynEdit) then
 | 
					 | 
				
			||||||
    SynEdit.Highlighter := nil;
 | 
					 | 
				
			||||||
  FreeAndNil(PasHighLighter);
 | 
					 | 
				
			||||||
  inherited ReCreateEdit;
 | 
					 | 
				
			||||||
  PasHighLighter := TSynPasSyn.Create(nil);
 | 
					 | 
				
			||||||
  SynEdit.Highlighter := PasHighLighter;
 | 
					 | 
				
			||||||
end;
 | 
					end;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
procedure TTestBaseHighlighterPas.EnableFolds(AEnbledTypes: TPascalCodeFoldBlockTypes;
 | 
					procedure TTestBaseHighlighterPas.EnableFolds(AEnbledTypes: TPascalCodeFoldBlockTypes;
 | 
				
			||||||
@ -114,8 +94,8 @@ begin
 | 
				
			|||||||
  l.GroupFilter := Group;
 | 
					  l.GroupFilter := Group;
 | 
				
			||||||
  debugln(['### Foldinfo Line: ', ALineIdx,
 | 
					  debugln(['### Foldinfo Line: ', ALineIdx,
 | 
				
			||||||
           ' Cnt=', l.Count, ' CntEx=', c,
 | 
					           ' Cnt=', l.Count, ' CntEx=', c,
 | 
				
			||||||
           '   PasMinLvl=',PasHighLighter.MinimumPasFoldLevel(ALineIdx,1),
 | 
					           '   PasMinLvl=', PasHighLighter.FoldBlockMinLevel(ALineIdx,1),
 | 
				
			||||||
           ' EndLvl=',PasHighLighter.EndPasFoldLevel(ALineIdx,1),
 | 
					           ' EndLvl=',PasHighLighter.FoldBlockEndLevel(ALineIdx,1),
 | 
				
			||||||
           //' Nestcnt=',PasHighLighter.FoldNestCount(ALineIdx,1),
 | 
					           //' Nestcnt=',PasHighLighter.FoldNestCount(ALineIdx,1),
 | 
				
			||||||
            ' : ', copy(SynEdit.Lines[ALineIdx],1,40)]);
 | 
					            ' : ', copy(SynEdit.Lines[ALineIdx],1,40)]);
 | 
				
			||||||
  debugln('Idx: LogXStart End  FldLvlStart End  NestLvlStart End  FldType FldTypeCompat FldGroup FldAction');
 | 
					  debugln('Idx: LogXStart End  FldLvlStart End  NestLvlStart End  FldType FldTypeCompat FldGroup FldAction');
 | 
				
			||||||
@ -231,40 +211,6 @@ begin
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
end;
 | 
					end;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
procedure TTestHighlighterPas.CheckFoldOpenCounts(Name: String; Expected: array of Integer);
 | 
					 | 
				
			||||||
var
 | 
					 | 
				
			||||||
  i: Integer;
 | 
					 | 
				
			||||||
begin
 | 
					 | 
				
			||||||
  for i := 0 to high(Expected) do
 | 
					 | 
				
			||||||
    AssertEquals(Name + 'OpenCount Line='+IntToStr(i),  Expected[i], PasHighLighter.FoldOpenCount(i));
 | 
					 | 
				
			||||||
end;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
procedure TTestHighlighterPas.CheckFoldInfoCounts(Name: String; Filter: TSynFoldActions;
 | 
					 | 
				
			||||||
  Expected: array of Integer);
 | 
					 | 
				
			||||||
begin
 | 
					 | 
				
			||||||
  CheckFoldInfoCounts(Name, Filter, 0, Expected);
 | 
					 | 
				
			||||||
end;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
procedure TTestHighlighterPas.CheckFoldInfoCounts(Name: String;
 | 
					 | 
				
			||||||
  Filter: TSynFoldActions; Group: Integer; Expected: array of Integer);
 | 
					 | 
				
			||||||
var
 | 
					 | 
				
			||||||
  i: Integer;
 | 
					 | 
				
			||||||
  l: TLazSynFoldNodeInfoList;
 | 
					 | 
				
			||||||
begin
 | 
					 | 
				
			||||||
  for i := 0 to high(Expected) do begin
 | 
					 | 
				
			||||||
    l := PasHighLighter.FoldNodeInfo[i];
 | 
					 | 
				
			||||||
    AssertEquals(Name + 'InfoCount(Ex) Line='+IntToStr(i),
 | 
					 | 
				
			||||||
                 Expected[i],
 | 
					 | 
				
			||||||
                 l.CountEx(Filter, Group));
 | 
					 | 
				
			||||||
    l.ClearFilter;
 | 
					 | 
				
			||||||
    l.ActionFilter := Filter;
 | 
					 | 
				
			||||||
    l.GroupFilter := Group;
 | 
					 | 
				
			||||||
    AssertEquals(Name + 'InfoCount Line='+IntToStr(i),
 | 
					 | 
				
			||||||
                 Expected[i],
 | 
					 | 
				
			||||||
                 PasHighLighter.FoldNodeInfo[i].Count);
 | 
					 | 
				
			||||||
  end;
 | 
					 | 
				
			||||||
end;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
procedure TTestHighlighterPas.CheckTokensForLine(Name: String; LineIdx: Integer;
 | 
					procedure TTestHighlighterPas.CheckTokensForLine(Name: String; LineIdx: Integer;
 | 
				
			||||||
  ExpTokens: array of TtkTokenKind);
 | 
					  ExpTokens: array of TtkTokenKind);
 | 
				
			||||||
var
 | 
					var
 | 
				
			||||||
@ -283,21 +229,6 @@ begin
 | 
				
			|||||||
  AssertEquals(Name+ 'TokenId Line='+IntToStr(LineIdx)+'  amount of tokens', length(ExpTokens), c );
 | 
					  AssertEquals(Name+ 'TokenId Line='+IntToStr(LineIdx)+'  amount of tokens', length(ExpTokens), c );
 | 
				
			||||||
end;
 | 
					end;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function TTestHighlighterPas.FoldActionsToString(AFoldActions: TSynFoldActions
 | 
					 | 
				
			||||||
  ): String;
 | 
					 | 
				
			||||||
var
 | 
					 | 
				
			||||||
  s: string;
 | 
					 | 
				
			||||||
  i: TSynFoldAction;
 | 
					 | 
				
			||||||
begin
 | 
					 | 
				
			||||||
  Result:='';
 | 
					 | 
				
			||||||
  for i := low(TSynFoldAction) to high(TSynFoldAction) do
 | 
					 | 
				
			||||||
    if i in AFoldActions then begin
 | 
					 | 
				
			||||||
      WriteStr(s, i);
 | 
					 | 
				
			||||||
      Result := Result + s + ',';
 | 
					 | 
				
			||||||
    end;
 | 
					 | 
				
			||||||
  if Result <> '' then SetLength(Result, Length(Result)-1);
 | 
					 | 
				
			||||||
end;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
procedure TTestHighlighterPas.TestFoldInfo;
 | 
					procedure TTestHighlighterPas.TestFoldInfo;
 | 
				
			||||||
begin
 | 
					begin
 | 
				
			||||||
  ReCreateEdit;
 | 
					  ReCreateEdit;
 | 
				
			||||||
@ -1013,12 +944,12 @@ begin
 | 
				
			|||||||
      CheckFoldInfoCounts('', [], 4, [1, 1, 0, 1, 0, 1, 0, 1, 2, 1, 2, 2]);
 | 
					      CheckFoldInfoCounts('', [], 4, [1, 1, 0, 1, 0, 1, 0, 1, 2, 1, 2, 2]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      //### Foldinfo Line: 0   PasMinLvl=0 EndLvl=0 : program Foo;
 | 
					      //### Foldinfo Line: 0   PasMinLvl=0 EndLvl=0 : program Foo;
 | 
				
			||||||
      CheckNode( 0, [], 4,   0,   0, 7,   0, 0,   0, 1,   10, 10,  4, [sfaOpen,sfaMarkup]);   // program
 | 
					      CheckNode( 0, [], 4,   0,   0, 7,   0, 0,   0, 1,   10, 10,  1, [sfaOpen,sfaMarkup]);   // program
 | 
				
			||||||
      //### Foldinfo Line: 1   PasMinLvl=0 EndLvl=0 : procedure a;
 | 
					      //### Foldinfo Line: 1   PasMinLvl=0 EndLvl=0 : procedure a;
 | 
				
			||||||
      CheckNode( 1, [], 4,   0,   0, 9,   1, 1,   1, 2,   3, 3,  4, [sfaOpen,sfaMarkup]);   // procedure
 | 
					      CheckNode( 1, [], 4,   0,   0, 9,   1, 1,   1, 2,   3, 3,  1, [sfaOpen,sfaMarkup]);   // procedure
 | 
				
			||||||
      //### Foldinfo Line: 2   PasMinLvl=0 EndLvl=0 : {$IFDEF A}
 | 
					      //### Foldinfo Line: 2   PasMinLvl=0 EndLvl=0 : {$IFDEF A}
 | 
				
			||||||
      //### Foldinfo Line: 3   PasMinLvl=0 EndLvl=0 : begin
 | 
					      //### Foldinfo Line: 3   PasMinLvl=0 EndLvl=0 : begin
 | 
				
			||||||
      CheckNode( 3, [], 4,   0,   0, 5,   2, 2,   2, 3,   1, 0,  4, [sfaOpen,sfaMarkup]);   // begin
 | 
					      CheckNode( 3, [], 4,   0,   0, 5,   2, 2,   2, 3,   1, 0,  1, [sfaOpen,sfaMarkup]);   // begin
 | 
				
			||||||
      //### Foldinfo Line: 4   PasMinLvl=0 EndLvl=0 : {$ENDIF}
 | 
					      //### Foldinfo Line: 4   PasMinLvl=0 EndLvl=0 : {$ENDIF}
 | 
				
			||||||
      //### Foldinfo Line: 5   PasMinLvl=0 EndLvl=1 :   {$IFDEF B} if a then begin {$ENDIF}
 | 
					      //### Foldinfo Line: 5   PasMinLvl=0 EndLvl=1 :   {$IFDEF B} if a then begin {$ENDIF}
 | 
				
			||||||
      CheckNode( 5, [], 4,   0,   23, 28,   0, 1,   3, 4,   0, 0,  1, [sfaOpen,sfaMarkup,sfaFold,sfaFoldFold]);   //  begin
 | 
					      CheckNode( 5, [], 4,   0,   23, 28,   0, 1,   3, 4,   0, 0,  1, [sfaOpen,sfaMarkup,sfaFold,sfaFoldFold]);   //  begin
 | 
				
			||||||
@ -1026,16 +957,16 @@ begin
 | 
				
			|||||||
      //### Foldinfo Line: 7   PasMinLvl=0 EndLvl=0 :   end;
 | 
					      //### Foldinfo Line: 7   PasMinLvl=0 EndLvl=0 :   end;
 | 
				
			||||||
      CheckNode( 7, [], 4,   0,   2, 5,   1, 0,   4, 3,   0, 0,  1, [sfaClose,sfaMarkup,sfaFold]);   //  end
 | 
					      CheckNode( 7, [], 4,   0,   2, 5,   1, 0,   4, 3,   0, 0,  1, [sfaClose,sfaMarkup,sfaFold]);   //  end
 | 
				
			||||||
      //### Foldinfo Line: 8   PasMinLvl=0 EndLvl=0 : end;
 | 
					      //### Foldinfo Line: 8   PasMinLvl=0 EndLvl=0 : end;
 | 
				
			||||||
      CheckNode( 8, [], 4,   0,   0, 3,   3, 3,   3, 2,   1, 0,  4, [sfaClose,sfaMarkup]);   // end;
 | 
					      CheckNode( 8, [], 4,   0,   0, 3,   3, 3,   3, 2,   1, 0,  1, [sfaClose,sfaMarkup]);   // end;
 | 
				
			||||||
      CheckNode( 8, [], 4,   1,   0, 3,   2, 2,   2, 1,   3, 3,  4, [sfaClose,sfaMarkup]);   // end;
 | 
					      CheckNode( 8, [], 4,   1,   0, 3,   2, 2,   2, 1,   3, 3,  1, [sfaClose,sfaMarkup]);   // end;
 | 
				
			||||||
      //### Foldinfo Line: 9   PasMinLvl=0 EndLvl=1 : begin
 | 
					      //### Foldinfo Line: 9   PasMinLvl=0 EndLvl=1 : begin
 | 
				
			||||||
      CheckNode( 9, [], 4,   0,   0, 5,   0, 1,   1, 2,   0, 0,  1, [sfaOpen,sfaMarkup,sfaFold,sfaFoldFold]);   // begin
 | 
					      CheckNode( 9, [], 4,   0,   0, 5,   0, 1,   1, 2,   0, 0,  1, [sfaOpen,sfaMarkup,sfaFold,sfaFoldFold]);   // begin
 | 
				
			||||||
      //### Foldinfo Line: 10   PasMinLvl=0 EndLvl=0 : end.
 | 
					      //### Foldinfo Line: 10   PasMinLvl=0 EndLvl=0 : end.
 | 
				
			||||||
      CheckNode(10, [], 4,   0,   0, 3,   1, 0,   2, 1,   0, 0,  1, [sfaClose,sfaMarkup,sfaFold]);   // end.
 | 
					      CheckNode(10, [], 4,   0,   0, 3,   1, 0,   2, 1,   0, 0,  1, [sfaClose,sfaMarkup,sfaFold]);   // end.
 | 
				
			||||||
      CheckNode(10, [], 4,   1,   0, 3,   1, 1,   1, 0,   10, 10,  4, [sfaClose,sfaMarkup]);   // end.
 | 
					      CheckNode(10, [], 4,   1,   0, 3,   1, 1,   1, 0,   10, 10,  1, [sfaClose,sfaMarkup]);   // end.
 | 
				
			||||||
      //### Foldinfo Line: 11   PasMinLvl=0 EndLvl=0 : //
 | 
					      //### Foldinfo Line: 11   PasMinLvl=0 EndLvl=0 : //
 | 
				
			||||||
      CheckNode(11, [], 4,   0,   0, 2,   0, 0,   0, 1,   22, 22,  4, [sfaOpen]);   // //
 | 
					      CheckNode(11, [], 4,   0,   0, 2,   0, 0,   0, 1,   22, 22,  1, [sfaOpen]);   // //
 | 
				
			||||||
      CheckNode(11, [], 4,   1,   2, 2,   1, 1,   1, 0,   22, 22,  4, [sfaClose,sfaLastLineClose]);   // /
 | 
					      CheckNode(11, [], 4,   1,   2, 2,   1, 1,   1, 0,   22, 22,  1, [sfaClose,sfaLastLineClose]);   // /
 | 
				
			||||||
    {%endregion TEXT 1 -- [cfbtBeginEnd..cfbtNone], [] grp=4}
 | 
					    {%endregion TEXT 1 -- [cfbtBeginEnd..cfbtNone], [] grp=4}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    {%region TEXT 1 -- [cfbtBeginEnd..cfbtNone], [sfaFold]}
 | 
					    {%region TEXT 1 -- [cfbtBeginEnd..cfbtNone], [sfaFold]}
 | 
				
			||||||
@ -1116,7 +1047,7 @@ begin
 | 
				
			|||||||
      //### Foldinfo Line: 0   PasMinLvl=0 EndLvl=1 : program Foo;
 | 
					      //### Foldinfo Line: 0   PasMinLvl=0 EndLvl=1 : program Foo;
 | 
				
			||||||
      CheckNode( 0, [], 0,   0,   0, 7,   0, 1,   0, 1,   10, 10,  1, [sfaOpen,sfaMarkup,sfaFold,sfaFoldFold]);
 | 
					      CheckNode( 0, [], 0,   0,   0, 7,   0, 1,   0, 1,   10, 10,  1, [sfaOpen,sfaMarkup,sfaFold,sfaFoldFold]);
 | 
				
			||||||
      //### Foldinfo Line: 1   PasMinLvl=1 EndLvl=1 : procedure a;
 | 
					      //### Foldinfo Line: 1   PasMinLvl=1 EndLvl=1 : procedure a;
 | 
				
			||||||
      CheckNode( 1, [], 0,   0,   0, 9,   1, 1,   1, 2,   3, 3,  4, [sfaOpen,sfaMarkup]);
 | 
					      CheckNode( 1, [], 0,   0,   0, 9,   1, 1,   1, 2,   3, 3,  1, [sfaOpen,sfaMarkup]);
 | 
				
			||||||
      //### Foldinfo Line: 2   PasMinLvl=1 EndLvl=1 : {$IFDEF A}
 | 
					      //### Foldinfo Line: 2   PasMinLvl=1 EndLvl=1 : {$IFDEF A}
 | 
				
			||||||
      CheckNode( 2, [], 0,   0,   2, 7,   0, 1,   0, 1,   18, 18,  3, [sfaOpen,sfaFold,sfaFoldFold]);
 | 
					      CheckNode( 2, [], 0,   0,   2, 7,   0, 1,   0, 1,   18, 18,  3, [sfaOpen,sfaFold,sfaFoldFold]);
 | 
				
			||||||
      //### Foldinfo Line: 3   PasMinLvl=1 EndLvl=2 : begin
 | 
					      //### Foldinfo Line: 3   PasMinLvl=1 EndLvl=2 : begin
 | 
				
			||||||
@ -1132,7 +1063,7 @@ begin
 | 
				
			|||||||
      CheckNode( 7, [], 0,   0,   2, 5,   3, 2,   4, 3,   0, 0,  1, [sfaClose,sfaMarkup,sfaFold]);
 | 
					      CheckNode( 7, [], 0,   0,   2, 5,   3, 2,   4, 3,   0, 0,  1, [sfaClose,sfaMarkup,sfaFold]);
 | 
				
			||||||
      //### Foldinfo Line: 8   PasMinLvl=1 EndLvl=1 : end;
 | 
					      //### Foldinfo Line: 8   PasMinLvl=1 EndLvl=1 : end;
 | 
				
			||||||
      CheckNode( 8, [], 0,   0,   0, 3,   2, 1,   3, 2,   1, 0,  1, [sfaClose,sfaMarkup,sfaFold]);
 | 
					      CheckNode( 8, [], 0,   0,   0, 3,   2, 1,   3, 2,   1, 0,  1, [sfaClose,sfaMarkup,sfaFold]);
 | 
				
			||||||
      CheckNode( 8, [], 0,   1,   0, 3,   2, 2,   2, 1,   3, 3,  4, [sfaClose,sfaMarkup]);
 | 
					      CheckNode( 8, [], 0,   1,   0, 3,   2, 2,   2, 1,   3, 3,  1, [sfaClose,sfaMarkup]);
 | 
				
			||||||
      //### Foldinfo Line: 9   PasMinLvl=1 EndLvl=2 : begin
 | 
					      //### Foldinfo Line: 9   PasMinLvl=1 EndLvl=2 : begin
 | 
				
			||||||
      CheckNode( 9, [], 0,   0,   0, 5,   1, 2,   1, 2,   0, 0,  1, [sfaOpen,sfaMarkup,sfaFold,sfaFoldFold]);
 | 
					      CheckNode( 9, [], 0,   0,   0, 5,   1, 2,   1, 2,   0, 0,  1, [sfaOpen,sfaMarkup,sfaFold,sfaFoldFold]);
 | 
				
			||||||
      //### Foldinfo Line: 10   PasMinLvl=0 EndLvl=0 : end.
 | 
					      //### Foldinfo Line: 10   PasMinLvl=0 EndLvl=0 : end.
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user