procedure TSynEditMarkupFoldColors.DoTextChanged(StartLine, EndLine,
ACountDiff: Integer);
var
y,i,LCnt : integer;
function GetPairCloseFold(aRow, X : integer ): Integer;
var
y,i,LCnt : integer;
HL: TSynCustomFoldHighlighter;
NodeList: TLazSynFoldNodeInfoList;
TmpNode, CloseNode: TSynFoldNodeInfo;
function FindEndNode(StartNode: TSynFoldNodeInfo;
{var} YIndex, NIndex: Integer): TSynFoldNodeInfo;
function SearchLine(ALineIdx: Integer; var ANodeIdx: Integer): TSynFoldNodeInfo;
begin
NodeList.Line := ALineIdx;
repeat
inc(ANodeIdx);
Result := NodeList[ANodeIdx];
until (sfaInvalid in Result.FoldAction)
or (Result.NestLvlEnd <= StartNode.NestLvlStart);
end;
begin
Result := SearchLine(YIndex, NIndex);
if not (sfaInvalid in Result.FoldAction) then
exit;
inc(YIndex);
while (YIndex < LCnt) and
(HL.FoldBlockMinLevel(YIndex, StartNode.FoldGroup, [sfbIncludeDisabled])
> StartNode.NestLvlStart)
do
inc(YIndex);
if YIndex = LCnt then
exit;
NIndex := -1;
Result := SearchLine(YIndex, NIndex);
if (Result.LogXEnd = 0) or (sfaLastLineClose in Result.FoldAction) then
Result.FoldAction := [sfaInvalid]; // LastLine closed Node(maybe force-closed?)
end;
var y2,i2 : integer;
begin
Result := -1;
y := aRow -1;
HL := TCustomSynEdit(self.SynEdit).Highlighter as TSynCustomFoldHighlighter;
HL.CurrentLines := Lines;
LCnt := Lines.Count;
HL.FoldNodeInfo[y].ClearFilter; // only needed once, in case the line was already used
NodeList := HL.FoldNodeInfo[y];
NodeList.AddReference;
try
NodeList.ActionFilter := [sfaOpen];
i := 0;
repeat
TmpNode := NodeList[i];
if TmpNode.LogXStart < X-1 then
begin
inc(i);
continue;
end;
//find till valid
while (sfaInvalid in TmpNode.FoldAction) and (i < NodeList.Count) do
begin
inc(i);
TmpNode := NodeList[i];
end;
if not (sfaInvalid in TmpNode.FoldAction) then
begin
CloseNode := FindEndNode(TmpNode, y, i);
//AddHighlight(TmpNode);
Result := CloseNode.LineIndex;
exit;
end;
inc(i);
until i >= NodeList.Count;
finally
NodeList.ReleaseReference;
end;
end;
function IsFoldMoved( aRow: Integer ): integer;
var S : string;
i,n : integer;
begin
Result := -1;
n := -1;
S := Caret.LineText;
for i := 1 to Min(Length(S), Length(FPrevCaretText)) do
begin
if S[i] <> FPrevCaretText[i] then
begin
n := i;
break;
end;
end;
if n < 0 then exit;
Result := GetPairCloseFold(aRow, n);
if Result > 0 then
begin
with TCustomSynEdit(SynEdit) do
Result := min(Result, TopLine +LinesInWindow);// . .RowToScreenRow(i);
end;
end;
var
EndFoldLine,LineEnd,y : integer;
begin
if EndLine < 0 then exit; //already refreshed by syn
y := Caret.LineBytePos.y;
EndFoldLine := IsFoldMoved(y);
if EndFoldLine > 0 then
begin
InvalidateSynLines(y+1, EndFoldLine);
end;
FPrevCaretText := Caret.LineText;
// I found that almost anything has been repaint by the SynEdit,
// except the trailing space editing: we should repaint them here.
end;