SynEdit: Refactor ScanRanges / Fix changed lines for ScanRanges (when outside PaintLock)

(cherry picked from commit 439768951a)
This commit is contained in:
Martin 2025-06-24 15:43:21 +02:00
parent d3d4138e1c
commit d8fc020d66

View File

@ -688,7 +688,8 @@ type
procedure MoveCaretVert(DY: integer; UseScreenLine: Boolean = False);
procedure PrimarySelectionRequest(const RequestedFormatID: TClipboardFormat;
Data: TStream);
procedure ScanRanges(ATextChanged: Boolean = True);
procedure ScanRanges;
procedure ScanChangedLines(AChangedLinesStart, AChangedLinesEnd, AChangedLinesDiff: Integer; ATextChanged: Boolean);
procedure IdleScanRanges(Sender: TObject; var Done: Boolean);
procedure DoBlockSelectionChanged(Sender: TObject);
procedure SetBlockIndent(const AValue: integer);
@ -2590,7 +2591,7 @@ begin
FMarkupManager.IncPaintLock;
end;
inc(FPaintLock);
FFoldedLinesView.Lock; //DecPaintLock triggers ScanRanges, and folds must wait
FFoldedLinesView.Lock; //DecPaintLock triggers ScanChangedLines, and folds must wait
FTrimmedLinesView.Lock; // Lock before caret
FBlockSelection.Lock;
FCaret.Lock;
@ -2611,11 +2612,12 @@ begin
FCaret.Unlock; // Maybe after FFoldedLinesView
FBlockSelection.Unlock;
// FTrimmedLinesView sets the highlighter to modified. Until fixed, must be done before ScanRanges
// FTrimmedLinesView sets the highlighter to modified. Until fixed, must be done before ScanRanges;
FTrimmedLinesView.UnLock; // Must be unlocked after caret // May Change lines
if (FPaintLock=1) and (not WaitingForInitialSize) then begin
ScanRanges(FLastTextChangeStamp <> TSynEditStringList(FLines).TextChangeStamp);
ScanChangedLines(FChangedLinesStart, FChangedLinesEnd, FChangedLinesDiff,
FLastTextChangeStamp <> TSynEditStringList(FLines).TextChangeStamp);
if sfAfterLoadFromFileNeeded in fStateFlags then
AfterLoadFromFile;
if FChangedLinesStart > 0 then begin
@ -4701,7 +4703,7 @@ begin
if eoFoldedCopyPaste in fOptions2 then begin
PTxt := ClipHelper.GetTagPointer(synClipTagFold);
if PTxt <> nil then begin
ScanRanges;
ScanRanges; // Only update HL. Need HL to provide fold info
FFoldedLinesView.ApplyFoldDescription(InsStart.Y -1, InsStart.X,
FInternalBlockSelection.StartLinePos-1, FInternalBlockSelection.StartBytePos,
PTxt, ClipHelper.GetTagLen(synClipTagFold));
@ -5575,7 +5577,16 @@ begin
end;
end;
procedure TCustomSynEdit.ScanRanges(ATextChanged: Boolean = True);
procedure TCustomSynEdit.ScanRanges;
begin
if fHighlighter = nil then
exit;
FHighlighter.CurrentLines := FLines; // Trailing spaces are not needed
FHighlighter.ScanRanges;
end;
procedure TCustomSynEdit.ScanChangedLines(AChangedLinesStart, AChangedLinesEnd,
AChangedLinesDiff: Integer; ATextChanged: Boolean);
begin
if WaitingForInitialSize then begin
Application.RemoveOnIdleHandler(@IdleScanRanges); // avoid duplicate add
@ -5593,8 +5604,7 @@ begin
TopView := TopView;
exit;
end;
FHighlighter.CurrentLines := FLines; // Trailing spaces are not needed
FHighlighter.ScanRanges;
ScanRanges;
// Todo: text may not have changed
if ATextChanged then
@ -5637,13 +5647,14 @@ begin
end;
if PaintLock>0 then begin
// FChangedLinesStart is also given to Markup.TextChanged; but it is not used there
// FChangedLinesStart is also given to Markup.TextChanged
if (FChangedLinesStart<1) or (FChangedLinesStart>AIndex+1) then
FChangedLinesStart:=AIndex+1;
FChangedLinesEnd := -1; // Invalidate the rest of lines
// TODO: review FChangedLinesDiff // Do not allow to reset (accumulate) to zero / just an indicator that theline count changed
FChangedLinesDiff := FChangedLinesDiff + ACount;
end else begin
ScanRanges;
ScanChangedLines(ToPos(AIndex), -1, ACount, True);
InvalidateLines(AIndex + 1, -1);
InvalidateGutterLines(AIndex + 1, -1);
if FCaret.LinePos > FLines.Count then FCaret.LinePos := FLines.Count;
@ -5671,7 +5682,7 @@ begin
if (FChangedLinesEnd >= 0) and (FChangedLinesEnd<AIndex+1) then
FChangedLinesEnd:=AIndex + 1 + MaX(ACount, 0); // TODO: why 2 (TWO) extra lines?
end else begin
ScanRanges;
ScanChangedLines(ToPos(AIndex), ToPos(AIndex) + max(ACount-1, 0), 0, True);
InvalidateLines(AIndex + 1, AIndex + ACount);
InvalidateGutterLines(AIndex + 1, AIndex + ACount);
end;
@ -5743,7 +5754,7 @@ begin
(* ToDo: FFoldedLinesView.TopLine := AValue;
Required, if "TopView := TopView" or "TopLine := TopLine" is called,
after ScanRanges (used to be: LineCountChanged / LineTextChanged)
after ScanChangedLines/ScanRanges (used to be: LineCountChanged / LineTextChanged)
*)
FFoldedLinesView.TopLine := AValue;
@ -6655,7 +6666,7 @@ begin
else
SetTextBetweenPoints(NewCaret, NewCaret, DragDropText, [setSelect], scamEnd, smaMoveUp, sm);
if (FoldInfo <> '') and (sm <> smColumn) then begin
ScanRanges;
ScanRanges; // Only update HL. Need HL to provide fold info
FFoldedLinesView.ApplyFoldDescription(NewCaret.Y -1, NewCaret.X,
FBlockSelection.EndLinePos-1, FBlockSelection.EndBytePos,
PChar(FoldInfo), length(FoldInfo));
@ -6777,7 +6788,7 @@ begin
fTSearch.ResetIdentChars;
end;
RecalcCharExtent;
ScanRanges; // Todo: Skip if paintlocked
ScanChangedLines(0,0,0, False); // Todo: Skip if paintlocked
// There may not have been a scan
if fHighlighter <> nil then
FHighlighter.CurrentLines := FLines;
@ -7898,7 +7909,7 @@ begin
end;
Exclude(fStateFlags, sfAfterLoadFromFileNeeded);
if assigned(FFoldedLinesView) then begin
ScanRanges;
ScanRanges; // Only update HL. Need HL to provide fold info
FFoldedLinesView.UnfoldAll;
FFoldedLinesView.CollapseDefaultFolds;
if FPendingFoldState <> '' then