SynEdit/SourceEdit(TopHint): Improve TLazSynEditNestedFoldsList / less scanning

git-svn-id: trunk@37946 -
This commit is contained in:
martin 2012-07-14 22:39:15 +00:00
parent 74f97a8872
commit 512178a9f7
3 changed files with 323 additions and 219 deletions

View File

@ -299,12 +299,12 @@ type
*) *)
TLazSynEditNestedFoldsListEntry = record TLazSynEditNestedFoldsListEntry = record
FFLags: set of (nfeHasHNode);
FGroupEndLevels: Array of Integer;
//OpenCount: Integer;
LineIdx: TLineIdx;
HNode: TSynFoldNodeInfo; // Highlighter Node HNode: TSynFoldNodeInfo; // Highlighter Node
//FNode: TSynTextFoldAVLNode; // AvlFoldNode //FNode: TSynTextFoldAVLNode; // AvlFoldNode
//Text, Keyword: String;
LineIdx: TLineIdx;
//ColIndex: Integer;
//OpenCount: Integer;
end; end;
TLazSynEditNestedFoldsList = class TLazSynEditNestedFoldsList = class
@ -314,7 +314,7 @@ type
FFoldGroup: Integer; FFoldGroup: Integer;
FLine: TLineIdx; FLine: TLineIdx;
procedure SetFoldGroup(AValue: Integer); procedure SetFoldGroup(AValue: Integer);
procedure SetLines(AValue: TLineIdx); procedure SetLine(AValue: TLineIdx);
private private
FFoldFlags: TSynFoldBlockFilterFlags; FFoldFlags: TSynFoldBlockFilterFlags;
FGroupCount: Integer; FGroupCount: Integer;
@ -322,22 +322,26 @@ type
FCount, FOpeningOnLineCount: Integer; FCount, FOpeningOnLineCount: Integer;
FOpeningLineEndIndex: Integer; FOpeningLineEndIndex: Integer;
FIncludeOpeningOnLine: Boolean; FIncludeOpeningOnLine: Boolean;
FNestInfo: Array of TLazSynEditNestedFoldsListEntry; FNestInfo, FOnLineNestInfo: Array of TLazSynEditNestedFoldsListEntry;
FEvaluationIndex: Integer; FEvaluationIndex: Integer;
FFoldNodeInfoList: TLazSynFoldNodeInfoList; FFoldNodeInfoList: TLazSynFoldNodeInfoList;
FFoldNodeInfoListHoldCnt: integer; FFoldNodeInfoListHoldCnt: integer;
function GetHLNode(Index: Integer): TSynFoldNodeInfo; function GetHLNode(Index: Integer): TSynFoldNodeInfo;
function GetNodeFoldGroup(Index: Integer): Integer; function GetNodeFoldGroup(Index: Integer): Integer;
function GetNodeLine(Index: Integer): Integer;
function GetNodeFoldType(Index: Integer): Pointer; function GetNodeFoldType(Index: Integer): Pointer;
procedure InitSubGroupEndLevels(const AHighlighter: TSynCustomFoldHighlighter); procedure InitSubGroupEndLevels(const AHighlighter: TSynCustomFoldHighlighter);
procedure InitNestInfoForIndex(AnIndex: Integer); procedure InitNestInfoForIndex(AnIndex: Integer);
procedure InitLineInfoForIndex(AnIndex: Integer);
procedure InitCount(const AHighlighter: TSynCustomFoldHighlighter);
procedure InitOpeningOnLine(const AHighlighter: TSynCustomFoldHighlighter); procedure InitOpeningOnLine(const AHighlighter: TSynCustomFoldHighlighter);
procedure SetFoldFlags(AValue: TSynFoldBlockFilterFlags); procedure SetFoldFlags(AValue: TSynFoldBlockFilterFlags);
procedure SetIncludeOpeningOnLine(AValue: Boolean); procedure SetIncludeOpeningOnLine(AValue: Boolean);
procedure AquireFoldNodeInfoList(const AHighlighter: TSynCustomFoldHighlighter; const ALine: Integer = -1); procedure AquireFoldNodeInfoList(const AHighlighter: TSynCustomFoldHighlighter; const ALine: Integer = -1);
procedure ReleaseFoldNodeInfoList; procedure ReleaseFoldNodeInfoList;
procedure SetOpeningLineEndIndex(AValue: Integer); procedure SetOpeningLineEndIndex(AValue: Integer);
function HasCount: Boolean;
public public
constructor Create(aFoldProvider: TSynEditFoldProvider); constructor Create(aFoldProvider: TSynEditFoldProvider);
procedure Clear; procedure Clear;
@ -345,7 +349,7 @@ type
function Count: Integer; function Count: Integer;
function OpeningOnLineCount: Integer; // ignores FFoldFlags function OpeningOnLineCount: Integer; // ignores FFoldFlags
procedure Debug; procedure Debug;
property Line: TLineIdx read FLine write SetLines; property Line: TLineIdx read FLine write SetLine;
property FoldGroup: Integer read FFoldGroup write SetFoldGroup; property FoldGroup: Integer read FFoldGroup write SetFoldGroup;
property FoldFlags: TSynFoldBlockFilterFlags read FFoldFlags write SetFoldFlags; property FoldFlags: TSynFoldBlockFilterFlags read FFoldFlags write SetFoldFlags;
property IncludeOpeningOnLine: Boolean read FIncludeOpeningOnLine write SetIncludeOpeningOnLine; property IncludeOpeningOnLine: Boolean read FIncludeOpeningOnLine write SetIncludeOpeningOnLine;
@ -357,6 +361,7 @@ type
property HLNode[Index: Integer]: TSynFoldNodeInfo read GetHLNode; property HLNode[Index: Integer]: TSynFoldNodeInfo read GetHLNode;
property NodeFoldType[Index: Integer]: Pointer read GetNodeFoldType; // e.g.cfbtBeginEnd, cfbtcfbtProcedure ... property NodeFoldType[Index: Integer]: Pointer read GetNodeFoldType; // e.g.cfbtBeginEnd, cfbtcfbtProcedure ...
property NodeFoldGroup[Index: Integer]: Integer read GetNodeFoldGroup; // independend/overlapping folds, e.g begin/end; ifdef, region property NodeFoldGroup[Index: Integer]: Integer read GetNodeFoldGroup; // independend/overlapping folds, e.g begin/end; ifdef, region
property NodeLine[Index: Integer]: Integer read GetNodeLine; // Index
end; end;
@ -2848,12 +2853,16 @@ end;
{ TLazSynEditNestedFoldsList } { TLazSynEditNestedFoldsList }
procedure TLazSynEditNestedFoldsList.SetLines(AValue: TLineIdx); procedure TLazSynEditNestedFoldsList.SetLine(AValue: TLineIdx);
begin begin
if FLine = AValue then Exit; if FLine = AValue then Exit;
FLine := AValue; FLine := AValue;
// Todo: might be able to re-use old data // Todo: might be able to re-use old data
Clear; FCount := -1; // will trigger InitCount
//FEvaluationIndex := -1;
FOpeningOnLineCount := -1;
SetLength(FGroupEndLevelsAtEval, 0); // will trigger InitSubGroupEndLevels
FGroupCount := -1;
end; end;
procedure TLazSynEditNestedFoldsList.Clear; procedure TLazSynEditNestedFoldsList.Clear;
@ -2863,15 +2872,20 @@ begin
FCount := -1; FCount := -1;
FOpeningOnLineCount := -1; FOpeningOnLineCount := -1;
FEvaluationIndex := -1; FEvaluationIndex := -1;
FOpeningLineEndIndex := -1;
SetLength(FNestInfo, 0); SetLength(FNestInfo, 0);
SetLength(FOnLineNestInfo, 0);
end; end;
procedure TLazSynEditNestedFoldsList.ResetFilter; procedure TLazSynEditNestedFoldsList.ResetFilter;
begin begin
if FIncludeOpeningOnLine and (FFoldFlags = []) and (FFoldGroup = 0) and
(FOpeningLineEndIndex = -1)
then
exit;
FIncludeOpeningOnLine := True; FIncludeOpeningOnLine := True;
FFoldFlags := []; FFoldFlags := [];
FFoldGroup := 0; FFoldGroup := 0;
FOpeningLineEndIndex := -1;
Clear; Clear;
end; end;
@ -2903,8 +2917,12 @@ begin
Result.FoldAction := [sfaInvalid]; Result.FoldAction := [sfaInvalid];
exit; exit;
end; end;
if Index >= FCount then
Result := FOnLineNestInfo[Index - FCount].HNode
else begin
InitNestInfoForIndex(Index); InitNestInfoForIndex(Index);
Result := FNestInfo[Index].HNode; Result := FNestInfo[Index].HNode;
end;
end; end;
function TLazSynEditNestedFoldsList.GetNodeFoldGroup(Index: Integer): Integer; function TLazSynEditNestedFoldsList.GetNodeFoldGroup(Index: Integer): Integer;
@ -2915,6 +2933,12 @@ begin
Result := HLNode[Index].FoldGroup; Result := HLNode[Index].FoldGroup;
end; end;
function TLazSynEditNestedFoldsList.GetNodeLine(Index: Integer): Integer;
begin
InitLineInfoForIndex(Index);
Result := FNestInfo[Index].LineIdx
end;
function TLazSynEditNestedFoldsList.GetNodeFoldType(Index: Integer): Pointer; function TLazSynEditNestedFoldsList.GetNodeFoldType(Index: Integer): Pointer;
var var
hl: TSynCustomFoldHighlighter; hl: TSynCustomFoldHighlighter;
@ -2933,24 +2957,100 @@ procedure TLazSynEditNestedFoldsList.InitNestInfoForIndex(AnIndex: Integer);
var var
CurLine: TLineIdx; CurLine: TLineIdx;
hl: TSynCustomFoldHighlighter; hl: TSynCustomFoldHighlighter;
i, c, t, l: Integer; i, EvalIdx, c, t, l: Integer;
NFilter: TSynFoldActions; NFilter: TSynFoldActions;
nd: TSynFoldNodeInfo; nd: TSynFoldNodeInfo;
GrpCnt: Array of integer;
begin begin
if HasCount and
( (AnIndex >= Count - OpeningOnLineCount) or
( (AnIndex >= FEvaluationIndex) and (nfeHasHNode in FNestInfo[AnIndex].FFLags) )
)
then exit;
hl := FFoldProvider.HighLighterWithLines; hl := FFoldProvider.HighLighterWithLines;
if hl = nil then exit; if hl = nil then exit;
AquireFoldNodeInfoList(hl); AquireFoldNodeInfoList(hl);
try try
if (AnIndex >= Count) or (AnIndex >= FEvaluationIndex) then exit; InitLineInfoForIndex(AnIndex);
if (AnIndex >= Count - OpeningOnLineCount) or
( (AnIndex >= FEvaluationIndex) and (nfeHasHNode in FNestInfo[AnIndex].FFLags) )
then exit;
EvalIdx := AnIndex;
CurLine := FNestInfo[EvalIdx].LineIdx;
while (EvalIdx < FCount-1) and (FNestInfo[EvalIdx+1].LineIdx = CurLine) do inc(EvalIdx);
assert(Length(FNestInfo[EvalIdx].FGroupEndLevels) > 0, 'Length(FNestInfo[EvalIdx].FGroupEndLevels)');
GrpCnt := FNestInfo[EvalIdx].FGroupEndLevels;
NFilter := [sfaOpenFold];
if not(sfbIncludeDisabled in FFoldFlags) then Include(NFilter, sfaFold);
FFoldNodeInfoList.Line := CurLine;
FFoldNodeInfoList.ActionFilter := NFilter;
FFoldNodeInfoList.GroupFilter := FFoldGroup;
c := FFoldNodeInfoList.Count - 1;
//debugln(['TLazSynEditNestedFoldsList.InitNestInfoForIndex CurLine=',CurLine, ' c=',c, ' EvalIdx=',EvalIdx]);
assert(c >= 0, 'InitNestInfoForIndex: FFoldNodeInfoList.Count');
for i := c downto 0 do begin
nd := FFoldNodeInfoList[i];
if FFoldGroup = 0
then t := nd.FoldGroup
else t := 0;
if (sfbIncludeDisabled in FFoldFlags)
then l := nd.NestLvlStart
else l := nd.FoldLvlStart;
if l >= GrpCnt[t] then continue;
dec(GrpCnt[t]);
assert(GrpCnt[t] >= 0, 'TLazSynEditNestedFoldsList.InitNestInfoForIndex GroupEndLevel < 0');
assert(EvalIdx >= 0, 'TLazSynEditNestedFoldsList.InitNestInfoForIndex FEvaluationIndex < 0');
assert(FNestInfo[EvalIdx].LineIdx = CurLine, 'TLazSynEditNestedFoldsList.InitNestInfoForIndex FNestInfo[EvalIdx].LineIdx = CurLine');
//FNestInfo[EvalIdx].LineIdx := CurLine;
include(FNestInfo[EvalIdx].FFLags, nfeHasHNode);
FNestInfo[EvalIdx].HNode := nd;
dec(EvalIdx);
end;
finally
ReleaseFoldNodeInfoList;
end;
//for i := FCount-1 downto 0 do DbgOut([', ',dbgs(nfeHasHNode in FNestInfo[i].FFLags)]); DebugLn();
assert(nfeHasHNode in FNestInfo[AnIndex].FFLags, 'nfeHasHNode in FNestInfo[AnIndex].FFLags');
assert(AnIndex >= FEvaluationIndex, 'TLazSynEditNestedFoldsList.InitNestInfoForIndex Index not found');
end;
procedure TLazSynEditNestedFoldsList.InitLineInfoForIndex(AnIndex: Integer);
var
CurLine: TLineIdx;
hl: TSynCustomFoldHighlighter;
i, c, c1, l: Integer;
NFilter: TSynFoldActions;
nd: TSynFoldNodeInfo;
begin
if HasCount and ((AnIndex >= Count - OpeningOnLineCount) or (AnIndex >= FEvaluationIndex)) then exit;
assert(FEvaluationIndex > 0, 'TLazSynEditNestedFoldsList.InitLineInfoForIndex already finilhed');
hl := FFoldProvider.HighLighterWithLines;
if hl = nil then exit;
AquireFoldNodeInfoList(hl);
try
if (AnIndex >= Count - OpeningOnLineCount) or (AnIndex >= FEvaluationIndex) then exit;
InitSubGroupEndLevels(hl); InitSubGroupEndLevels(hl);
if (FEvaluationIndex = Count) then begin
if (OpeningOnLineCount > 0) then FNestInfo[FEvaluationIndex-1].FGroupEndLevels := copy(FGroupEndLevelsAtEval,0, length(FGroupEndLevelsAtEval));
CurLine := Line
else if (FEvaluationIndex = FCount) then
CurLine := Line - 1 CurLine := Line - 1
end
else else
CurLine := FNestInfo[FEvaluationIndex].LineIdx - 1; CurLine := FNestInfo[FEvaluationIndex].LineIdx - 1;
@ -2958,58 +3058,56 @@ begin
while CurLine > 0 do begin while CurLine > 0 do begin
dec(CurLine); dec(CurLine);
c := 0;
if FFoldGroup = 0 then begin if FFoldGroup = 0 then begin
i := FGroupCount; i := FGroupCount;
while (i > 0) and while (i > 0) do begin
(hl.FoldBlockMinLevel(CurLine, i, FFoldFlags) >= FGroupEndLevelsAtEval[i]) l := hl.FoldBlockMinLevel(CurLine, i, FFoldFlags);
do if (l < FGroupEndLevelsAtEval[i]) then begin
c1 := FGroupEndLevelsAtEval[i] - l;
FGroupEndLevelsAtEval[i] := FGroupEndLevelsAtEval[i] - c1;
c := c + c1;
end;
dec(i); dec(i);
if i <= 0 then continue; end;
end end
else begin else begin
if hl.FoldBlockMinLevel(CurLine, FFoldGroup, FFoldFlags) >= FGroupEndLevelsAtEval[0] then l := hl.FoldBlockMinLevel(CurLine, FFoldGroup, FFoldFlags);
continue; if l < FGroupEndLevelsAtEval[0] then begin
c := FGroupEndLevelsAtEval[0] - l;
FGroupEndLevelsAtEval[0] := FGroupEndLevelsAtEval[0] - c;
end; end;
end;
if c = 0 then continue;
// something of interest opened on this line while c > 0 do begin
NFilter := [sfaOpenFold];
if not(sfbIncludeDisabled in FFoldFlags) then Include(NFilter, sfaFold);
FFoldNodeInfoList.Line := CurLine;
FFoldNodeInfoList.ActionFilter := NFilter;
FFoldNodeInfoList.GroupFilter := FFoldGroup;
c := FFoldNodeInfoList.Count - 1;
//c := hl.FoldNodeInfo[CurLine].CountEx(NFilter, FFoldGroup) - 1;
for i := c downto 0 do begin
nd := FFoldNodeInfoList[i];
//nd := hl.FoldNodeInfo[CurLine].NodeInfoEx(i, NFilter, FFoldGroup);
if FFoldGroup = 0 then
t := nd.FoldGroup
else
t := 0;
if (sfbIncludeDisabled in FFoldFlags)
then l := nd.NestLvlStart
else l := nd.FoldLvlStart;
if l >= FGroupEndLevelsAtEval[t] then continue;
dec(FGroupEndLevelsAtEval[t]);
dec(FEvaluationIndex); dec(FEvaluationIndex);
assert(FGroupEndLevelsAtEval[t] >= 0, 'TLazSynEditNestedFoldsList.InitNestInfoForIndex GroupEndLevel < 0');
assert(FEvaluationIndex >= 0, 'TLazSynEditNestedFoldsList.InitNestInfoForIndex FEvaluationIndex < 0');
FNestInfo[FEvaluationIndex].LineIdx := CurLine; FNestInfo[FEvaluationIndex].LineIdx := CurLine;
FNestInfo[FEvaluationIndex].HNode := nd; FNestInfo[FEvaluationIndex].FFLags:= [];
dec(c);
end; end;
if (AnIndex >= FEvaluationIndex) then Break; if (AnIndex >= FEvaluationIndex) then Break;
FNestInfo[FEvaluationIndex-1].FGroupEndLevels := copy(FGroupEndLevelsAtEval,0, length(FGroupEndLevelsAtEval));
end; end;
finally finally
ReleaseFoldNodeInfoList; ReleaseFoldNodeInfoList;
end; end;
assert(AnIndex >= FEvaluationIndex, 'TLazSynEditNestedFoldsList.InitNestInfoForIndex Index not found'); //debugln(['TLazSynEditNestedFoldsList.InitLineInfoForIndex FEvaluationIndex=', FEvaluationIndex, ' AnIndex=',AnIndex]);
//for i := FCount-1 downto 0 do begin DbgOut([', ',FNestInfo[i].LineIdx]); if length(FNestInfo[i].FGroupEndLevels) > 0 then begin DbgOut(' ('); for c := 0 to length(FNestInfo[i].FGroupEndLevels)-1 do DbgOut([',',FNestInfo[i].FGroupEndLevels[c]]); DbgOut(') '); end; end; DebugLn();
assert(CurLine >= 0, 'TLazSynEditNestedFoldsList.InitLineInfoForIndex Curline < 0');
assert(AnIndex >= FEvaluationIndex, 'TLazSynEditNestedFoldsList.InitLineInfoForIndex Index not found');
end;
procedure TLazSynEditNestedFoldsList.InitCount(const AHighlighter: TSynCustomFoldHighlighter);
var
i, j: Integer;
begin
FCount := AHighlighter.FoldBlockEndLevel(FLine - 1, FFoldGroup, FFoldFlags);
FEvaluationIndex := FCount;
SetLength(FNestInfo, FCount);
end; end;
procedure TLazSynEditNestedFoldsList.InitOpeningOnLine(const AHighlighter: TSynCustomFoldHighlighter); procedure TLazSynEditNestedFoldsList.InitOpeningOnLine(const AHighlighter: TSynCustomFoldHighlighter);
@ -3022,13 +3120,13 @@ var
begin begin
Assert((FOpeningLineEndIndex < 0) or (sfbIncludeDisabled in FoldFlags), 'OpeningLineEndIndex only implemented for sfbIncludeDisabled'); Assert((FOpeningLineEndIndex < 0) or (sfbIncludeDisabled in FoldFlags), 'OpeningLineEndIndex only implemented for sfbIncludeDisabled');
FCount := AHighlighter.FoldBlockEndLevel(FLine - 1, FFoldGroup, FFoldFlags); FOpeningOnLineCount := 0;
FEvaluationIndex := FCount; if FCount < 0 then
InitCount(AHighlighter);
if not FIncludeOpeningOnLine then begin if not FIncludeOpeningOnLine then
SetLength(FNestInfo, FCount); // Capacity for max opening nodes
exit; exit;
end; // FOnLineNestInfo
AquireFoldNodeInfoList(AHighlighter, FLine); AquireFoldNodeInfoList(AHighlighter, FLine);
try try
@ -3050,7 +3148,6 @@ begin
end; end;
SetLength(OpenIdx, FGroupCount, FFoldNodeInfoList.Count); SetLength(OpenIdx, FGroupCount, FFoldNodeInfoList.Count);
SetLength(OpenCnt, FGroupCount); SetLength(OpenCnt, FGroupCount);
FOpeningOnLineCount := 0;
for Grp := 0 to FGroupCount - 1 do for Grp := 0 to FGroupCount - 1 do
OpenCnt[Grp] := 0; OpenCnt[Grp] := 0;
@ -3078,9 +3175,7 @@ begin
end; end;
end; end;
SetLength(FNestInfo, FCount + FOpeningOnLineCount); SetLength(FOnLineNestInfo, FOpeningOnLineCount);
// TODO: skip if FOpeningOnLineCount = 0
//FFoldNodeInfoList.ActionFilter := []; //FFoldNodeInfoList.ActionFilter := [];
//FFoldNodeInfoList.GroupFilter := 0; //FFoldNodeInfoList.GroupFilter := 0;
@ -3100,13 +3195,12 @@ begin
if (oc > 0) and (OpenIdx[Grp - GrpLow, oc-1] = i) then begin if (oc > 0) and (OpenIdx[Grp - GrpLow, oc-1] = i) then begin
dec(OpenCnt[Grp - GrpLow]); dec(OpenCnt[Grp - GrpLow]);
dec(j); dec(j);
FNestInfo[FCount + j].LineIdx := FLine; FOnLineNestInfo[j].LineIdx := FLine;
FNestInfo[FCount + j].HNode := nd; FOnLineNestInfo[j].HNode := nd;
FNestInfo[FCount + j].HNode.NodeIndex := j; FOnLineNestInfo[j].HNode.NodeIndex := j;
end; end;
end; end;
FCount := FCount + FOpeningOnLineCount;
Assert(j=0, 'TLazSynEditNestedFoldsList.InitOpeningOnLine did not fill all nodes '+IntToStr(j)); Assert(j=0, 'TLazSynEditNestedFoldsList.InitOpeningOnLine did not fill all nodes '+IntToStr(j));
finally finally
ReleaseFoldNodeInfoList; ReleaseFoldNodeInfoList;
@ -3124,7 +3218,7 @@ procedure TLazSynEditNestedFoldsList.SetIncludeOpeningOnLine(AValue: Boolean);
begin begin
if FIncludeOpeningOnLine = AValue then Exit; if FIncludeOpeningOnLine = AValue then Exit;
FIncludeOpeningOnLine := AValue; FIncludeOpeningOnLine := AValue;
Clear; //Clear; // Do not Clear, keep the data, can be re-enabled
end; end;
procedure TLazSynEditNestedFoldsList.AquireFoldNodeInfoList(const AHighlighter: TSynCustomFoldHighlighter; procedure TLazSynEditNestedFoldsList.AquireFoldNodeInfoList(const AHighlighter: TSynCustomFoldHighlighter;
@ -3152,6 +3246,11 @@ begin
Clear; // TODO only clear current line, the rest will still be valid Clear; // TODO only clear current line, the rest will still be valid
end; end;
function TLazSynEditNestedFoldsList.HasCount: Boolean;
begin
Result := (FCount >= 0) and ( (not FIncludeOpeningOnLine) or (FOpeningOnLineCount >= 0) );
end;
procedure TLazSynEditNestedFoldsList.SetFoldGroup(AValue: Integer); procedure TLazSynEditNestedFoldsList.SetFoldGroup(AValue: Integer);
begin begin
if FFoldGroup = AValue then Exit; if FFoldGroup = AValue then Exit;
@ -3172,13 +3271,18 @@ function TLazSynEditNestedFoldsList.Count: Integer;
var var
hl: TSynCustomFoldHighlighter; hl: TSynCustomFoldHighlighter;
begin begin
Result := FCount; if (FCount < 0) then begin
if Result >= 0 then exit;
hl := FFoldProvider.HighLighterWithLines; hl := FFoldProvider.HighLighterWithLines;
if hl = nil then exit(-1); if hl = nil then exit(0);
InitCount(hl);
end;
if FIncludeOpeningOnLine and (FOpeningOnLineCount < 0) then begin
hl := FFoldProvider.HighLighterWithLines;
if hl = nil then exit(0);
InitOpeningOnLine(hl); InitOpeningOnLine(hl);
Result := FCount; end;
Result := FCount + OpeningOnLineCount;
end; end;
function TLazSynEditNestedFoldsList.OpeningOnLineCount: Integer; function TLazSynEditNestedFoldsList.OpeningOnLineCount: Integer;
@ -3187,14 +3291,13 @@ var
begin begin
if (not FIncludeOpeningOnLine) or (FLine < 0) then if (not FIncludeOpeningOnLine) or (FLine < 0) then
exit(0); exit(0);
if (FOpeningOnLineCount < 0) then begin
hl := FFoldProvider.HighLighterWithLines; hl := FFoldProvider.HighLighterWithLines;
if hl = nil then if hl = nil then exit(0);
exit(0);
Result := FOpeningOnLineCount;
if Result >= 0 then exit;
InitOpeningOnLine(hl); InitOpeningOnLine(hl);
end;
Result := FOpeningOnLineCount; Result := FOpeningOnLineCount;
end; end;

View File

@ -1813,6 +1813,19 @@ procedure TTestFoldedView.TestNestedFoldsList;
TPascalCodeFoldBlockType(FoldType), TPascalCodeFoldBlockType(FoldTypeCompatible), TPascalCodeFoldBlockType(FoldType), TPascalCodeFoldBlockType(FoldTypeCompatible),
FoldGroup, FoldAction); FoldGroup, FoldAction);
end; end;
procedure InitList(const AName: String; AList: TLazSynEditNestedFoldsList;
ALine, AGroup: Integer; AFlags: TSynFoldBlockFilterFlags;
AInclOpening: Boolean; AClear: Boolean = True);
begin
PopPushBaseName(Format('%s (Line=%d / Grp=%d / FLG=%s / IncOpen=%s)', [AName, ALine, AGroup, dbgs(AFlags), dbgs(AInclOpening)]));
AList.ResetFilter;
if AClear then AList.Clear;
AList.Line := ALine;
AList.FoldGroup := AGroup;
AList.FoldFlags := AFlags;
AList.IncludeOpeningOnLine := AInclOpening;
end;
var var
TheList: TLazSynEditNestedFoldsList; TheList: TLazSynEditNestedFoldsList;
i1, i2, i3, i: Integer; i1, i2, i3, i: Integer;
@ -1826,107 +1839,93 @@ begin
TstSetText('TestText1', TestText); TstSetText('TestText1', TestText);
TheList := FoldedView.FoldProvider.NestedFoldsList; TheList := FoldedView.FoldProvider.NestedFoldsList;
EnableFolds([cfbtBeginEnd..cfbtNone]); EnableFolds([cfbtBeginEnd..cfbtNone]);
PushBaseName('');
PushBaseName('All Enabled - group 0'); InitList('All Enabled ', TheList, 2, 0, [], True);
TheList.ResetFilter; AssertEquals(BaseTestName + 'Cnt', 3, TheList.Count);
TheList.Line := 2; CheckNode(TheList.HLNode[2], 2, 0, 0, 5, 2, 3, 2, 3, 1, 0, 1, [sfaOpen, sfaOpenFold,sfaMarkup,sfaFold,sfaFoldFold, sfaMultiLine]);
TheList.FoldGroup := 0; CheckNode(TheList.HLNode[1], 1, 0, 0, 9, 1, 2, 1, 2, 3, 3, 1, [sfaOpen, sfaOpenFold,sfaMarkup,sfaFold,sfaFoldFold, sfaMultiLine]);
TheList.FoldFlags := []; CheckNode(TheList.HLNode[0], 0, 0, 0, 7, 0, 1, 0, 1, 10, 10, 1, [sfaOpen, sfaOpenFold,sfaMarkup,sfaFold,sfaFoldFold, sfaMultiLine]);
InitList('All Enabled Reverse order', TheList, 2, 0, [], True);
AssertEquals(BaseTestName + 'Cnt', 3, TheList.Count);
CheckNode(TheList.HLNode[0], 0, 0, 0, 7, 0, 1, 0, 1, 10, 10, 1, [sfaOpen, sfaOpenFold,sfaMarkup,sfaFold,sfaFoldFold, sfaMultiLine]);
CheckNode(TheList.HLNode[1], 1, 0, 0, 9, 1, 2, 1, 2, 3, 3, 1, [sfaOpen, sfaOpenFold,sfaMarkup,sfaFold,sfaFoldFold, sfaMultiLine]);
CheckNode(TheList.HLNode[2], 2, 0, 0, 5, 2, 3, 2, 3, 1, 0, 1, [sfaOpen, sfaOpenFold,sfaMarkup,sfaFold,sfaFoldFold, sfaMultiLine]);
InitList('All Enabled', TheList, 2, FOLDGROUP_PASCAL, [], True);
AssertEquals(BaseTestName + 'Cnt', 3, TheList.Count); AssertEquals(BaseTestName + 'Cnt', 3, TheList.Count);
CheckNode(TheList.HLNode[2], 2, 0, 0, 5, 2, 3, 2, 3, 1, 0, 1, [sfaOpen, sfaOpenFold,sfaMarkup,sfaFold,sfaFoldFold, sfaMultiLine]); CheckNode(TheList.HLNode[2], 2, 0, 0, 5, 2, 3, 2, 3, 1, 0, 1, [sfaOpen, sfaOpenFold,sfaMarkup,sfaFold,sfaFoldFold, sfaMultiLine]);
CheckNode(TheList.HLNode[1], 1, 0, 0, 9, 1, 2, 1, 2, 3, 3, 1, [sfaOpen, sfaOpenFold,sfaMarkup,sfaFold,sfaFoldFold, sfaMultiLine]); CheckNode(TheList.HLNode[1], 1, 0, 0, 9, 1, 2, 1, 2, 3, 3, 1, [sfaOpen, sfaOpenFold,sfaMarkup,sfaFold,sfaFoldFold, sfaMultiLine]);
CheckNode(TheList.HLNode[0], 0, 0, 0, 7, 0, 1, 0, 1, 10, 10, 1, [sfaOpen, sfaOpenFold,sfaMarkup,sfaFold,sfaFoldFold, sfaMultiLine]); CheckNode(TheList.HLNode[0], 0, 0, 0, 7, 0, 1, 0, 1, 10, 10, 1, [sfaOpen, sfaOpenFold,sfaMarkup,sfaFold,sfaFoldFold, sfaMultiLine]);
PopPushBaseName('All Enabled - group 1'); InitList('All Enabled', TheList, 2, FOLDGROUP_REGION, [], True);
TheList.ResetFilter;
TheList.Line := 2;
TheList.FoldGroup := 1;
TheList.FoldFlags := [];
AssertEquals(BaseTestName + 'Cnt', 3, TheList.Count);
CheckNode(TheList.HLNode[2], 2, 0, 0, 5, 2, 3, 2, 3, 1, 0, 1, [sfaOpen, sfaOpenFold,sfaMarkup,sfaFold,sfaFoldFold, sfaMultiLine]);
CheckNode(TheList.HLNode[1], 1, 0, 0, 9, 1, 2, 1, 2, 3, 3, 1, [sfaOpen, sfaOpenFold,sfaMarkup,sfaFold,sfaFoldFold, sfaMultiLine]);
CheckNode(TheList.HLNode[0], 0, 0, 0, 7, 0, 1, 0, 1, 10, 10, 1, [sfaOpen, sfaOpenFold,sfaMarkup,sfaFold,sfaFoldFold, sfaMultiLine]);
PopPushBaseName('All Enabled - group 2');
TheList.ResetFilter;
TheList.Line := 2;
TheList.FoldGroup := 2;
TheList.FoldFlags := [];
AssertEquals(BaseTestName + 'Cnt', 0, TheList.Count); AssertEquals(BaseTestName + 'Cnt', 0, TheList.Count);
PopPushBaseName('All Enabled - group 0 - NoCurrentLine'); InitList('All Enabled', TheList, 2, 0, [], False);
TheList.ResetFilter;
TheList.Line := 2;
TheList.FoldGroup := 0;
TheList.FoldFlags := [];
TheList.IncludeOpeningOnLine := False;
AssertEquals(BaseTestName + 'Cnt', 2, TheList.Count); AssertEquals(BaseTestName + 'Cnt', 2, TheList.Count);
CheckNode(TheList.HLNode[1], 1, 0, 0, 9, 1, 2, 1, 2, 3, 3, 1, [sfaOpen, sfaOpenFold,sfaMarkup,sfaFold,sfaFoldFold, sfaMultiLine]); CheckNode(TheList.HLNode[1], 1, 0, 0, 9, 1, 2, 1, 2, 3, 3, 1, [sfaOpen, sfaOpenFold,sfaMarkup,sfaFold,sfaFoldFold, sfaMultiLine]);
CheckNode(TheList.HLNode[0], 0, 0, 0, 7, 0, 1, 0, 1, 10, 10, 1, [sfaOpen, sfaOpenFold,sfaMarkup,sfaFold,sfaFoldFold, sfaMultiLine]); CheckNode(TheList.HLNode[0], 0, 0, 0, 7, 0, 1, 0, 1, 10, 10, 1, [sfaOpen, sfaOpenFold,sfaMarkup,sfaFold,sfaFoldFold, sfaMultiLine]);
PopPushBaseName('All Enabled - group 0 - NoCurrentLine - line 3'); InitList('All Enabled', TheList, 3, 0, [], False);
TheList.ResetFilter;
TheList.Line := 3;
TheList.FoldGroup := 0;
TheList.FoldFlags := [];
TheList.IncludeOpeningOnLine := False;
AssertEquals(BaseTestName + 'Cnt', 3, TheList.Count); AssertEquals(BaseTestName + 'Cnt', 3, TheList.Count);
CheckNode(TheList.HLNode[2], 2, 0, 0, 5, 2, 3, 2, 3, 1, 0, 1, [sfaOpen, sfaOpenFold,sfaMarkup,sfaFold,sfaFoldFold, sfaMultiLine]); CheckNode(TheList.HLNode[2], 2, 0, 0, 5, 2, 3, 2, 3, 1, 0, 1, [sfaOpen, sfaOpenFold,sfaMarkup,sfaFold,sfaFoldFold, sfaMultiLine]);
CheckNode(TheList.HLNode[1], 1, 0, 0, 9, 1, 2, 1, 2, 3, 3, 1, [sfaOpen, sfaOpenFold,sfaMarkup,sfaFold,sfaFoldFold, sfaMultiLine]); CheckNode(TheList.HLNode[1], 1, 0, 0, 9, 1, 2, 1, 2, 3, 3, 1, [sfaOpen, sfaOpenFold,sfaMarkup,sfaFold,sfaFoldFold, sfaMultiLine]);
CheckNode(TheList.HLNode[0], 0, 0, 0, 7, 0, 1, 0, 1, 10, 10, 1, [sfaOpen, sfaOpenFold,sfaMarkup,sfaFold,sfaFoldFold, sfaMultiLine]); CheckNode(TheList.HLNode[0], 0, 0, 0, 7, 0, 1, 0, 1, 10, 10, 1, [sfaOpen, sfaOpenFold,sfaMarkup,sfaFold,sfaFoldFold, sfaMultiLine]);
InitList('All Enabled Reverse Order', TheList, 3, 0, [], False);
AssertEquals(BaseTestName + 'Cnt', 3, TheList.Count);
CheckNode(TheList.HLNode[0], 0, 0, 0, 7, 0, 1, 0, 1, 10, 10, 1, [sfaOpen, sfaOpenFold,sfaMarkup,sfaFold,sfaFoldFold, sfaMultiLine]);
CheckNode(TheList.HLNode[1], 1, 0, 0, 9, 1, 2, 1, 2, 3, 3, 1, [sfaOpen, sfaOpenFold,sfaMarkup,sfaFold,sfaFoldFold, sfaMultiLine]);
CheckNode(TheList.HLNode[2], 2, 0, 0, 5, 2, 3, 2, 3, 1, 0, 1, [sfaOpen, sfaOpenFold,sfaMarkup,sfaFold,sfaFoldFold, sfaMultiLine]);
InitList('All Enabled Mixed Order', TheList, 3, 0, [], False);
AssertEquals(BaseTestName + 'Cnt', 3, TheList.Count);
CheckNode(TheList.HLNode[1], 1, 0, 0, 9, 1, 2, 1, 2, 3, 3, 1, [sfaOpen, sfaOpenFold,sfaMarkup,sfaFold,sfaFoldFold, sfaMultiLine]);
CheckNode(TheList.HLNode[2], 2, 0, 0, 5, 2, 3, 2, 3, 1, 0, 1, [sfaOpen, sfaOpenFold,sfaMarkup,sfaFold,sfaFoldFold, sfaMultiLine]);
CheckNode(TheList.HLNode[0], 0, 0, 0, 7, 0, 1, 0, 1, 10, 10, 1, [sfaOpen, sfaOpenFold,sfaMarkup,sfaFold,sfaFoldFold, sfaMultiLine]);
InitList('All Enabled Mixed Order 2', TheList, 3, 0, [], False);
AssertEquals(BaseTestName + 'Cnt', 3, TheList.Count);
CheckNode(TheList.HLNode[1], 1, 0, 0, 9, 1, 2, 1, 2, 3, 3, 1, [sfaOpen, sfaOpenFold,sfaMarkup,sfaFold,sfaFoldFold, sfaMultiLine]);
CheckNode(TheList.HLNode[0], 0, 0, 0, 7, 0, 1, 0, 1, 10, 10, 1, [sfaOpen, sfaOpenFold,sfaMarkup,sfaFold,sfaFoldFold, sfaMultiLine]);
CheckNode(TheList.HLNode[2], 2, 0, 0, 5, 2, 3, 2, 3, 1, 0, 1, [sfaOpen, sfaOpenFold,sfaMarkup,sfaFold,sfaFoldFold, sfaMultiLine]);
InitList('All Enabled Mixed Order 3', TheList, 3, 0, [], False);
AssertEquals(BaseTestName + 'Cnt', 3, TheList.Count);
CheckNode(TheList.HLNode[0], 0, 0, 0, 7, 0, 1, 0, 1, 10, 10, 1, [sfaOpen, sfaOpenFold,sfaMarkup,sfaFold,sfaFoldFold, sfaMultiLine]);
CheckNode(TheList.HLNode[2], 2, 0, 0, 5, 2, 3, 2, 3, 1, 0, 1, [sfaOpen, sfaOpenFold,sfaMarkup,sfaFold,sfaFoldFold, sfaMultiLine]);
CheckNode(TheList.HLNode[1], 1, 0, 0, 9, 1, 2, 1, 2, 3, 3, 1, [sfaOpen, sfaOpenFold,sfaMarkup,sfaFold,sfaFoldFold, sfaMultiLine]);
EnableFolds([cfbtTopBeginEnd]); EnableFolds([cfbtTopBeginEnd]);
PopPushBaseName('cfbtTopBeginEnd Enabled - group 0'); InitList('cfbtTopBeginEnd Enabled', TheList, 2, 0, [], True);
TheList.ResetFilter;
TheList.Line := 2;
TheList.FoldGroup := 0;
TheList.FoldFlags := [];
AssertEquals(BaseTestName + 'Cnt', 1, TheList.Count); AssertEquals(BaseTestName + 'Cnt', 1, TheList.Count);
CheckNode(TheList.HLNode[0], 2, 0, 0, 5, 0, 1, 2, 3, 1, 0, 1, [sfaOpen, sfaOpenFold,sfaMarkup,sfaFold,sfaFoldFold, sfaMultiLine]); CheckNode(TheList.HLNode[0], 2, 0, 0, 5, 0, 1, 2, 3, 1, 0, 1, [sfaOpen, sfaOpenFold,sfaMarkup,sfaFold,sfaFoldFold, sfaMultiLine]);
EnableFolds([cfbtTopBeginEnd]); EnableFolds([cfbtTopBeginEnd]);
PopPushBaseName('cfbtTopBeginEnd Enabled - group 1'); InitList('cfbtTopBeginEnd Enabled', TheList, 2, FOLDGROUP_PASCAL, [], True);
TheList.ResetFilter;
TheList.Line := 2;
TheList.FoldGroup := 1;
TheList.FoldFlags := [];
AssertEquals(BaseTestName + 'Cnt', 1, TheList.Count); AssertEquals(BaseTestName + 'Cnt', 1, TheList.Count);
CheckNode(TheList.HLNode[0], 2, 0, 0, 5, 0, 1, 2, 3, 1, 0, 1, [sfaOpen, sfaOpenFold,sfaMarkup,sfaFold,sfaFoldFold, sfaMultiLine]); CheckNode(TheList.HLNode[0], 2, 0, 0, 5, 0, 1, 2, 3, 1, 0, 1, [sfaOpen, sfaOpenFold,sfaMarkup,sfaFold,sfaFoldFold, sfaMultiLine]);
EnableFolds([cfbtTopBeginEnd]); EnableFolds([cfbtTopBeginEnd]);
PopPushBaseName('cfbtTopBeginEnd Enabled - group 0 - NoCurrentLine'); InitList('cfbtTopBeginEnd Enabled', TheList, 2, 0, [], False);
TheList.ResetFilter;
TheList.Line := 2;
TheList.FoldGroup := 0;
TheList.FoldFlags := [];
TheList.IncludeOpeningOnLine := False;
AssertEquals(BaseTestName + 'Cnt', 0, TheList.Count); AssertEquals(BaseTestName + 'Cnt', 0, TheList.Count);
EnableFolds([cfbtTopBeginEnd]); EnableFolds([cfbtTopBeginEnd]);
PopPushBaseName('cfbtTopBeginEnd Enabled - group 0 - NoCurrentLine line 3'); InitList('cfbtTopBeginEnd Enabled', TheList, 3, 0, [], False);
TheList.ResetFilter;
TheList.Line := 3;
TheList.FoldGroup := 0;
TheList.FoldFlags := [];
TheList.IncludeOpeningOnLine := False;
AssertEquals(BaseTestName + 'Cnt', 1, TheList.Count); AssertEquals(BaseTestName + 'Cnt', 1, TheList.Count);
CheckNode(TheList.HLNode[0], 2, 0, 0, 5, 0, 1, 2, 3, 1, 0, 1, [sfaOpen, sfaOpenFold,sfaMarkup,sfaFold,sfaFoldFold, sfaMultiLine]); CheckNode(TheList.HLNode[0], 2, 0, 0, 5, 0, 1, 2, 3, 1, 0, 1, [sfaOpen, sfaOpenFold,sfaMarkup,sfaFold,sfaFoldFold, sfaMultiLine]);
InitList('cfbtTopBeginEnd Enabled', TheList, 2, 0, [sfbIncludeDisabled], True);
PopPushBaseName('cfbtTopBeginEnd Enabled - group 0 - sfbIncludeDisabled');
TheList.ResetFilter;
TheList.Line := 2;
TheList.FoldGroup := 0;
TheList.FoldFlags := [sfbIncludeDisabled];
AssertEquals(BaseTestName + 'Cnt', 3, TheList.Count); AssertEquals(BaseTestName + 'Cnt', 3, TheList.Count);
CheckNode(TheList.HLNode[2], 2, 0, 0, 5, 0, 1, 2, 3, 1, 0, 1, [sfaOpen, sfaOpenFold,sfaMarkup,sfaFold,sfaFoldFold, sfaMultiLine]); CheckNode(TheList.HLNode[2], 2, 0, 0, 5, 0, 1, 2, 3, 1, 0, 1, [sfaOpen, sfaOpenFold,sfaMarkup,sfaFold,sfaFoldFold, sfaMultiLine]);
CheckNode(TheList.HLNode[1], 1, 0, 0, 9, -1,-1, 1, 2, 3, 3, 1, [sfaOpen, sfaOpenFold,sfaMarkup, sfaMultiLine]); CheckNode(TheList.HLNode[1], 1, 0, 0, 9, -1,-1, 1, 2, 3, 3, 1, [sfaOpen, sfaOpenFold,sfaMarkup, sfaMultiLine]);
@ -1934,11 +1933,7 @@ begin
EnableFolds([cfbtTopBeginEnd]); EnableFolds([cfbtTopBeginEnd]);
PopPushBaseName('cfbtTopBeginEnd Enabled - group 1 - sfbIncludeDisabled'); InitList('cfbtTopBeginEnd Enabled', TheList, 2, FOLDGROUP_PASCAL, [sfbIncludeDisabled], True);
TheList.ResetFilter;
TheList.Line := 2;
TheList.FoldGroup := 1;
TheList.FoldFlags := [sfbIncludeDisabled];
AssertEquals(BaseTestName + 'Cnt', 3, TheList.Count); AssertEquals(BaseTestName + 'Cnt', 3, TheList.Count);
CheckNode(TheList.HLNode[2], 2, 0, 0, 5, 0, 1, 2, 3, 1, 0, 1, [sfaOpen, sfaOpenFold,sfaMarkup,sfaFold,sfaFoldFold, sfaMultiLine]); CheckNode(TheList.HLNode[2], 2, 0, 0, 5, 0, 1, 2, 3, 1, 0, 1, [sfaOpen, sfaOpenFold,sfaMarkup,sfaFold,sfaFoldFold, sfaMultiLine]);
CheckNode(TheList.HLNode[1], 1, 0, 0, 9, -1,-1, 1, 2, 3, 3, 1, [sfaOpen, sfaOpenFold,sfaMarkup, sfaMultiLine]); CheckNode(TheList.HLNode[1], 1, 0, 0, 9, -1,-1, 1, 2, 3, 3, 1, [sfaOpen, sfaOpenFold,sfaMarkup, sfaMultiLine]);
@ -1947,7 +1942,7 @@ begin
EnableFolds([cfbtTopBeginEnd]); EnableFolds([cfbtTopBeginEnd]);
PopPushBaseName('cfbtTopBeginEnd Enabled - group 2 - sfbIncludeDisabled'); PopPushBaseName('cfbtTopBeginEnd Enabled - group 2 - sfbIncludeDisabled');
TheList.ResetFilter; TheList.ResetFilter; TheList.Clear;
TheList.Line := 2; TheList.Line := 2;
TheList.FoldGroup := 2; TheList.FoldGroup := 2;
TheList.FoldFlags := [sfbIncludeDisabled]; TheList.FoldFlags := [sfbIncludeDisabled];
@ -1956,7 +1951,7 @@ begin
EnableFolds([cfbtTopBeginEnd]); EnableFolds([cfbtTopBeginEnd]);
PopPushBaseName('cfbtTopBeginEnd Enabled - group 0 - NoCurrentLine - sfbIncludeDisabled'); PopPushBaseName('cfbtTopBeginEnd Enabled - group 0 - NoCurrentLine - sfbIncludeDisabled');
TheList.ResetFilter; TheList.ResetFilter; TheList.Clear;
TheList.Line := 2; TheList.Line := 2;
TheList.FoldGroup := 0; TheList.FoldGroup := 0;
TheList.FoldFlags := [sfbIncludeDisabled]; TheList.FoldFlags := [sfbIncludeDisabled];
@ -1968,7 +1963,7 @@ begin
EnableFolds([cfbtTopBeginEnd]); EnableFolds([cfbtTopBeginEnd]);
PopPushBaseName('cfbtTopBeginEnd Enabled - group 0 - NoCurrentLine line 3 - sfbIncludeDisabled'); PopPushBaseName('cfbtTopBeginEnd Enabled - group 0 - NoCurrentLine line 3 - sfbIncludeDisabled');
TheList.ResetFilter; TheList.ResetFilter; TheList.Clear;
TheList.Line := 3; TheList.Line := 3;
TheList.FoldGroup := 0; TheList.FoldGroup := 0;
TheList.FoldFlags := [sfbIncludeDisabled]; TheList.FoldFlags := [sfbIncludeDisabled];
@ -1982,7 +1977,7 @@ begin
// TODO line, currently ignores the opening "begin" on current line // TODO line, currently ignores the opening "begin" on current line
EnableFolds([]); EnableFolds([]);
PopPushBaseName('None Enabled - group 0 - sfbIncludeDisabled - line 3'); PopPushBaseName('None Enabled - group 0 - sfbIncludeDisabled - line 3');
TheList.ResetFilter; TheList.ResetFilter; TheList.Clear;
TheList.Line := 3; TheList.Line := 3;
TheList.FoldGroup := 0; TheList.FoldGroup := 0;
TheList.FoldFlags := [sfbIncludeDisabled]; TheList.FoldFlags := [sfbIncludeDisabled];
@ -1992,10 +1987,6 @@ begin
CheckNode(TheList.HLNode[0], 0, 0, 0, 7, -1,-1, 0, 1, 10, 10, 1, [sfaOpen, sfaOpenFold,sfaMarkup, sfaMultiLine]); CheckNode(TheList.HLNode[0], 0, 0, 0, 7, -1,-1, 0, 1, 10, 10, 1, [sfaOpen, sfaOpenFold,sfaMarkup, sfaMultiLine]);
PopPushBaseName('group 0 - line 4 (with "end"'); PopPushBaseName('group 0 - line 4 (with "end"');
for i1 := 0 to 1 do begin // IncludeOpeningOnLine
if i1 = 0
then PushBaseName('IncludeOpeningOnLine')
else PushBaseName('NOT IncludeOpeningOnLine');
for i2 := 0 to 1 do begin // sfbIncludeDisabled for i2 := 0 to 1 do begin // sfbIncludeDisabled
if i2 = 0 if i2 = 0
then PushBaseName('sfbIncludeDisabled') then PushBaseName('sfbIncludeDisabled')
@ -2020,13 +2011,20 @@ begin
end; end;
if i2 = 0 then i := 3; if i2 = 0 then i := 3;
TheList.Clear;
TheList.ResetFilter; TheList.ResetFilter;
TheList.Line := 4; TheList.Line := 4;
TheList.FoldGroup := 0; TheList.FoldGroup := 0;
if i2 = 0 if i2 = 0
then TheList.FoldFlags := [sfbIncludeDisabled] then TheList.FoldFlags := [sfbIncludeDisabled]
else TheList.FoldFlags := []; else TheList.FoldFlags := [];
TheList.IncludeOpeningOnLine := i1 = 0;
for i1 := 0 to 3 do begin // IncludeOpeningOnLine (switch on<>off<>on without clear)
if i1 in [0,2]
then PushBaseName('IncludeOpeningOnLine')
else PushBaseName('NOT IncludeOpeningOnLine');
TheList.IncludeOpeningOnLine := i1 in [0,2];
AssertEquals(BaseTestName + 'Cnt', i, TheList.Count); AssertEquals(BaseTestName + 'Cnt', i, TheList.Count);
if i3 in [0] then if i3 in [0] then
CheckNode(TheList.HLNode[2], 2, 0, 0, 5, 2, 3, 2, 3, 1, 0, 1, [sfaOpen, sfaOpenFold,sfaMarkup,sfaFold,sfaFoldFold, sfaMultiLine]) CheckNode(TheList.HLNode[2], 2, 0, 0, 5, 2, 3, 2, 3, 1, 0, 1, [sfaOpen, sfaOpenFold,sfaMarkup,sfaFold,sfaFoldFold, sfaMultiLine])
@ -2037,6 +2035,7 @@ begin
else if i2 = 0 then else if i2 = 0 then
CheckNode(TheList.HLNode[1], 1, 0, 0, 9, -1, -1, 1, 2, 3, 3, 1, [sfaOpen, sfaOpenFold,sfaMarkup, sfaMultiLine]); CheckNode(TheList.HLNode[1], 1, 0, 0, 9, -1, -1, 1, 2, 3, 3, 1, [sfaOpen, sfaOpenFold,sfaMarkup, sfaMultiLine]);
CheckNode(TheList.HLNode[0], 0, 0, 0, 7, 0, 1, 0, 1, 10, 10, 1, [sfaOpen, sfaOpenFold,sfaMarkup,sfaFold,sfaFoldFold, sfaMultiLine]); CheckNode(TheList.HLNode[0], 0, 0, 0, 7, 0, 1, 0, 1, 10, 10, 1, [sfaOpen, sfaOpenFold,sfaMarkup,sfaFold,sfaFoldFold, sfaMultiLine]);
PopBaseName; PopBaseName;
end; end;
PopBaseName; PopBaseName;
@ -2054,7 +2053,7 @@ begin
EnableFolds([cfbtBeginEnd..cfbtNone]); EnableFolds([cfbtBeginEnd..cfbtNone]);
PushBaseName('All Enabled - group 0 - line 1'); PushBaseName('All Enabled - group 0 - line 1');
TheList.ResetFilter; TheList.ResetFilter; TheList.Clear;
TheList.Line := 1; TheList.Line := 1;
TheList.FoldGroup := 0; TheList.FoldGroup := 0;
TheList.FoldFlags := []; TheList.FoldFlags := [];
@ -2065,7 +2064,7 @@ begin
PopPushBaseName('All Enabled - group 0 - line 1 - no current'); PopPushBaseName('All Enabled - group 0 - line 1 - no current');
TheList.ResetFilter; TheList.ResetFilter; TheList.Clear;
TheList.Line := 1; TheList.Line := 1;
TheList.FoldGroup := 0; TheList.FoldGroup := 0;
TheList.FoldFlags := []; TheList.FoldFlags := [];
@ -2075,7 +2074,7 @@ begin
PopPushBaseName('All Enabled - group 0 - line 3'); PopPushBaseName('All Enabled - group 0 - line 3');
TheList.ResetFilter; TheList.ResetFilter; TheList.Clear;
TheList.Line := 3; TheList.Line := 3;
TheList.FoldGroup := 0; TheList.FoldGroup := 0;
TheList.FoldFlags := []; TheList.FoldFlags := [];
@ -2087,7 +2086,7 @@ begin
PopPushBaseName('All Enabled - group 0 - line 4'); PopPushBaseName('All Enabled - group 0 - line 4');
TheList.ResetFilter; TheList.ResetFilter; TheList.Clear;
TheList.Line := 4; TheList.Line := 4;
TheList.FoldGroup := 0; TheList.FoldGroup := 0;
TheList.FoldFlags := []; TheList.FoldFlags := [];
@ -2098,7 +2097,7 @@ begin
PopPushBaseName('All Enabled - group 0 - line 4 - NO IncludeOpeningOnLine'); PopPushBaseName('All Enabled - group 0 - line 4 - NO IncludeOpeningOnLine');
TheList.ResetFilter; TheList.ResetFilter; TheList.Clear;
TheList.Line := 4; TheList.Line := 4;
TheList.FoldGroup := 0; TheList.FoldGroup := 0;
TheList.FoldFlags := []; TheList.FoldFlags := [];
@ -2109,7 +2108,7 @@ begin
PopPushBaseName('All Enabled - group 0 - line 5'); PopPushBaseName('All Enabled - group 0 - line 5');
TheList.ResetFilter; TheList.ResetFilter; TheList.Clear;
TheList.Line := 5; TheList.Line := 5;
TheList.FoldGroup := 0; TheList.FoldGroup := 0;
TheList.FoldFlags := []; TheList.FoldFlags := [];
@ -2120,7 +2119,7 @@ begin
CheckNode(TheList.HLNode[0], 0, 0, 0, 7, 0, 1, 0, 1, 10, 10, 1, [sfaOpen, sfaOpenFold,sfaMarkup,sfaFold,sfaFoldFold, sfaMultiLine]); CheckNode(TheList.HLNode[0], 0, 0, 0, 7, 0, 1, 0, 1, 10, 10, 1, [sfaOpen, sfaOpenFold,sfaMarkup,sfaFold,sfaFoldFold, sfaMultiLine]);
PopPushBaseName('All Enabled - group 0 - line 7 mixed'); PopPushBaseName('All Enabled - group 0 - line 7 mixed');
TheList.ResetFilter; TheList.ResetFilter; TheList.Clear;
TheList.Line := 7; TheList.Line := 7;
TheList.FoldGroup := 0; TheList.FoldGroup := 0;
TheList.FoldFlags := []; TheList.FoldFlags := [];
@ -2133,7 +2132,7 @@ begin
CheckNode(TheList.HLNode[0], 0, 0, 0, 7, 0, 1, 0, 1, 10, 10, 1, [sfaOpen, sfaOpenFold,sfaMarkup,sfaFold,sfaFoldFold, sfaMultiLine]); CheckNode(TheList.HLNode[0], 0, 0, 0, 7, 0, 1, 0, 1, 10, 10, 1, [sfaOpen, sfaOpenFold,sfaMarkup,sfaFold,sfaFoldFold, sfaMultiLine]);
PopPushBaseName('All Enabled - group 0 - line 7 mixed // NOT IncludeOpeningOnLine'); PopPushBaseName('All Enabled - group 0 - line 7 mixed // NOT IncludeOpeningOnLine');
TheList.ResetFilter; TheList.ResetFilter; TheList.Clear;
TheList.Line := 7; TheList.Line := 7;
TheList.FoldGroup := 0; TheList.FoldGroup := 0;
TheList.FoldFlags := []; TheList.FoldFlags := [];
@ -2155,7 +2154,7 @@ begin
EnableFolds([cfbtBeginEnd..cfbtNone]); EnableFolds([cfbtBeginEnd..cfbtNone]);
PushBaseName('All Enabled - group 0 - line 3'); PushBaseName('All Enabled - group 0 - line 3');
TheList.ResetFilter; TheList.ResetFilter; TheList.Clear;
TheList.Line := 3; TheList.Line := 3;
TheList.FoldGroup := 0; TheList.FoldGroup := 0;
TheList.FoldFlags := []; TheList.FoldFlags := [];
@ -2166,7 +2165,7 @@ begin
PushBaseName('All Enabled - group 1 - line 3'); PushBaseName('All Enabled - group 1 - line 3');
TheList.ResetFilter; TheList.ResetFilter; TheList.Clear;
TheList.Line := 3; TheList.Line := 3;
TheList.FoldGroup := 1; TheList.FoldGroup := 1;
TheList.FoldFlags := []; TheList.FoldFlags := [];
@ -2176,7 +2175,7 @@ begin
PushBaseName('All Enabled - group 3 - line 3'); PushBaseName('All Enabled - group 3 - line 3');
TheList.ResetFilter; TheList.ResetFilter; TheList.Clear;
TheList.Line := 3; TheList.Line := 3;
TheList.FoldGroup := 3; TheList.FoldGroup := 3;
TheList.FoldFlags := []; TheList.FoldFlags := [];
@ -2185,7 +2184,7 @@ begin
PopPushBaseName('All Enabled - group 0 - line 3'); PopPushBaseName('All Enabled - group 0 - line 3');
TheList.ResetFilter; TheList.ResetFilter; TheList.Clear;
TheList.Line := 4; TheList.Line := 4;
TheList.FoldGroup := 0; TheList.FoldGroup := 0;
TheList.FoldFlags := []; TheList.FoldFlags := [];
@ -2203,7 +2202,7 @@ begin
EnableFolds([cfbtBeginEnd..cfbtNone]); EnableFolds([cfbtBeginEnd..cfbtNone]);
PushBaseName('All Enabled - group 0 - incl line 4'); PushBaseName('All Enabled - group 0 - incl line 4');
TheList.ResetFilter; TheList.ResetFilter; TheList.Clear;
TheList.Line := 4; TheList.Line := 4;
TheList.IncludeOpeningOnLine := True; TheList.IncludeOpeningOnLine := True;
TheList.FoldGroup := 0; TheList.FoldGroup := 0;
@ -2214,7 +2213,7 @@ begin
CheckNode(TheList.HLNode[0], 0, 0, 0, 7, 0, 1, 0, 1, 10, 10, FOLDGROUP_PASCAL, [sfaOpen, sfaOpenFold,sfaMarkup,sfaFold,sfaFoldFold, sfaMultiLine]); CheckNode(TheList.HLNode[0], 0, 0, 0, 7, 0, 1, 0, 1, 10, 10, FOLDGROUP_PASCAL, [sfaOpen, sfaOpenFold,sfaMarkup,sfaFold,sfaFoldFold, sfaMultiLine]);
PopPushBaseName('All Enabled - group 0 - excl line 4'); PopPushBaseName('All Enabled - group 0 - excl line 4');
TheList.ResetFilter; TheList.ResetFilter; TheList.Clear;
TheList.Line := 4; TheList.Line := 4;
TheList.IncludeOpeningOnLine := False; TheList.IncludeOpeningOnLine := False;
TheList.FoldGroup := 0; TheList.FoldGroup := 0;
@ -2225,7 +2224,7 @@ begin
PushBaseName('All Enabled - group IF - incl line 4'); PushBaseName('All Enabled - group IF - incl line 4');
TheList.ResetFilter; TheList.ResetFilter; TheList.Clear;
TheList.Line := 4; TheList.Line := 4;
TheList.IncludeOpeningOnLine := True; TheList.IncludeOpeningOnLine := True;
TheList.FoldGroup := FOLDGROUP_IFDEF; TheList.FoldGroup := FOLDGROUP_IFDEF;
@ -2235,7 +2234,7 @@ begin
CheckNode(TheList.HLNode[0], 3, 0, 1, 7, 0, 1, 0, 1, 18, 18, FOLDGROUP_IFDEF, [sfaOpen, sfaOpenFold,sfaMarkup,sfaFold,sfaFoldFold, sfaMultiLine]); CheckNode(TheList.HLNode[0], 3, 0, 1, 7, 0, 1, 0, 1, 18, 18, FOLDGROUP_IFDEF, [sfaOpen, sfaOpenFold,sfaMarkup,sfaFold,sfaFoldFold, sfaMultiLine]);
PopPushBaseName('All Enabled - group IF - excl line 4'); PopPushBaseName('All Enabled - group IF - excl line 4');
TheList.ResetFilter; TheList.ResetFilter; TheList.Clear;
TheList.Line := 4; TheList.Line := 4;
TheList.IncludeOpeningOnLine := False; TheList.IncludeOpeningOnLine := False;
TheList.FoldGroup := FOLDGROUP_IFDEF; TheList.FoldGroup := FOLDGROUP_IFDEF;
@ -2256,7 +2255,7 @@ begin
EnableFolds([cfbtBeginEnd..cfbtNone]); EnableFolds([cfbtBeginEnd..cfbtNone]);
PushBaseName('All Enabled - group 0 - line 3'); PushBaseName('All Enabled - group 0 - line 3');
TheList.ResetFilter; TheList.ResetFilter; TheList.Clear;
TheList.Line := 5; TheList.Line := 5;
TheList.FoldGroup := 0; TheList.FoldGroup := 0;
TheList.FoldFlags := []; TheList.FoldFlags := [];

View File

@ -125,8 +125,6 @@ type
property TopLineCount: Integer read FTopLineCount write SetTopLineCount; property TopLineCount: Integer read FTopLineCount write SetTopLineCount;
end; end;
{ TIDESynEditor } { TIDESynEditor }
TIDESynEditor = class(TSynEdit) TIDESynEditor = class(TSynEdit)
@ -628,10 +626,13 @@ end;
procedure TIDESynEditor.SrcSynCaretChanged(Sender: TObject); procedure TIDESynEditor.SrcSynCaretChanged(Sender: TObject);
var var
InfCnt, i, t, ListCnt: Integer; InfCnt, i, t, ListCnt: Integer;
InfList: array [0..1] of TSynFoldNodeInfo; InfList: array [0..1] of
record
LineIndex: Integer;
FoldType: TPascalCodeFoldBlockType;
end;
NodeFoldType: TPascalCodeFoldBlockType; NodeFoldType: TPascalCodeFoldBlockType;
List: TLazSynEditNestedFoldsList; List: TLazSynEditNestedFoldsList;
Inf: TSynFoldNodeInfo;
begin begin
if (not FShowTopInfo) or (not HandleAllocated) then exit; if (not FShowTopInfo) or (not HandleAllocated) then exit;
if FSrcSynCaretChangedLock or not(TextView.HighLighter is TSynPasSyn) then exit; if FSrcSynCaretChangedLock or not(TextView.HighLighter is TSynPasSyn) then exit;
@ -643,6 +644,7 @@ begin
if CaretY >= TopLine then begin if CaretY >= TopLine then begin
List := TextView.FoldProvider.NestedFoldsList; List := TextView.FoldProvider.NestedFoldsList;
List.ResetFilter; List.ResetFilter;
List.Clear;
List.Line := CaretY-1; List.Line := CaretY-1;
List.FoldGroup := FOLDGROUP_PASCAL; List.FoldGroup := FOLDGROUP_PASCAL;
List.FoldFlags := [sfbIncludeDisabled]; List.FoldFlags := [sfbIncludeDisabled];
@ -650,34 +652,34 @@ begin
InfCnt := List.Count; InfCnt := List.Count;
for i := InfCnt-1 downto 0 do begin for i := InfCnt-1 downto 0 do begin
if not(TPascalCodeFoldBlockType({%H-}PtrUInt(List.NodeFoldType[i])) in NodeFoldType := TPascalCodeFoldBlockType({%H-}PtrUInt(List.NodeFoldType[i]));
if not(NodeFoldType in
[cfbtClass, cfbtClassSection, cfbtProcedure]) [cfbtClass, cfbtClassSection, cfbtProcedure])
then then
continue; continue;
Inf := List.HLNode[i];
if sfaInvalid in Inf.FoldAction then
continue;
NodeFoldType:=TPascalCodeFoldBlockType({%H-}PtrUInt(Inf.FoldType));
if (NodeFoldType in [cfbtClassSection]) and (ListCnt = 0) then begin if (NodeFoldType in [cfbtClassSection]) and (ListCnt = 0) then begin
InfList[ListCnt] := Inf; InfList[ListCnt].LineIndex := List.NodeLine[i];
InfList[ListCnt].FoldType := NodeFoldType;
inc(ListCnt); inc(ListCnt);
end; end;
if (NodeFoldType in [cfbtClass]) and (ListCnt < 2) then begin if (NodeFoldType in [cfbtClass]) and (ListCnt < 2) then begin
InfList[ListCnt] := Inf; InfList[ListCnt].LineIndex := List.NodeLine[i];
InfList[ListCnt].FoldType := NodeFoldType;
inc(ListCnt); inc(ListCnt);
end; end;
if (NodeFoldType in [cfbtProcedure]) and (ListCnt < 2) then begin if (NodeFoldType in [cfbtProcedure]) and (ListCnt < 2) then begin
InfList[ListCnt] := Inf; InfList[ListCnt].LineIndex := List.NodeLine[i];
InfList[ListCnt].FoldType := NodeFoldType;
inc(ListCnt); inc(ListCnt);
end; end;
if (NodeFoldType in [cfbtProcedure]) and (ListCnt = 2) and if (NodeFoldType in [cfbtProcedure]) and (ListCnt = 2) and
(TPascalCodeFoldBlockType({%H-}PtrUInt(InfList[ListCnt-1].FoldType)) = cfbtProcedure) (InfList[ListCnt-1].FoldType = cfbtProcedure)
then begin then begin
InfList[ListCnt-1] := Inf; InfList[ListCnt-1].LineIndex := List.NodeLine[i];
InfList[ListCnt-1].FoldType := NodeFoldType;
end; end;
end; end;
end; end;