mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-11-13 13:59:53 +01:00
SynEdit: Current word markup: reduce search overhead
git-svn-id: trunk@39846 -
This commit is contained in:
parent
ade191f786
commit
abd47577bd
@ -77,7 +77,7 @@ type
|
|||||||
procedure DoCaretChanged(Sender: TObject); virtual;
|
procedure DoCaretChanged(Sender: TObject); virtual;
|
||||||
procedure DoTopLineChanged(OldTopLine : Integer); virtual;
|
procedure DoTopLineChanged(OldTopLine : Integer); virtual;
|
||||||
procedure DoLinesInWindoChanged(OldLinesInWindow : Integer); virtual;
|
procedure DoLinesInWindoChanged(OldLinesInWindow : Integer); virtual;
|
||||||
procedure DoTextChanged(StartLine, EndLine : Integer); virtual;
|
procedure DoTextChanged(StartLine, EndLine : Integer); virtual; // 1 based
|
||||||
procedure DoMarkupChanged(AMarkup: TSynSelectedColor); virtual;
|
procedure DoMarkupChanged(AMarkup: TSynSelectedColor); virtual;
|
||||||
|
|
||||||
procedure InvalidateSynLines(FirstLine, LastLine: integer); // Call Synedt to invalidate lines
|
procedure InvalidateSynLines(FirstLine, LastLine: integer); // Call Synedt to invalidate lines
|
||||||
@ -108,7 +108,7 @@ type
|
|||||||
AMarkup: TSynSelectedColor); virtual;
|
AMarkup: TSynSelectedColor); virtual;
|
||||||
|
|
||||||
// Notifications about Changes to the text
|
// Notifications about Changes to the text
|
||||||
Procedure TextChanged(aFirstCodeLine, aLastCodeLine: Integer); virtual;
|
Procedure TextChanged(aFirstCodeLine, aLastCodeLine: Integer); virtual; // 1 based
|
||||||
Procedure TempDisable;
|
Procedure TempDisable;
|
||||||
Procedure TempEnable;
|
Procedure TempEnable;
|
||||||
procedure IncPaintLock; virtual;
|
procedure IncPaintLock; virtual;
|
||||||
|
|||||||
@ -32,31 +32,6 @@ uses
|
|||||||
|
|
||||||
type
|
type
|
||||||
|
|
||||||
(*
|
|
||||||
TSynMarkupHighAllLineState = (hlsValid, hlsInvalid);
|
|
||||||
|
|
||||||
TSynMarkupHighAllLine = Record
|
|
||||||
MatchIndex : Integer;
|
|
||||||
State : TSynMarkupHighAllLineState;
|
|
||||||
end;
|
|
||||||
|
|
||||||
{ TSynMarkupHighAllLines }
|
|
||||||
|
|
||||||
TSynMarkupHighAllLines = class(TObject)
|
|
||||||
private
|
|
||||||
FCount, FCapacity : Integer;
|
|
||||||
FLines : Array of TSynMarkupHighAllLine;
|
|
||||||
function GetLine(const Index : Integer) : TSynMarkupHighAllLine;
|
|
||||||
procedure SetCount(const AValue : Integer);
|
|
||||||
procedure SetLine(const Index : Integer; const AValue : TSynMarkupHighAllLine);
|
|
||||||
public
|
|
||||||
constructor Create;
|
|
||||||
Function MaybeReduceCapacity : Boolean;
|
|
||||||
property Count : Integer read FCount write SetCount;
|
|
||||||
property Line [const Index : Integer] : TSynMarkupHighAllLine read GetLine write SetLine; default;
|
|
||||||
end;
|
|
||||||
*)
|
|
||||||
|
|
||||||
{ TSynMarkupHighAllMatch }
|
{ TSynMarkupHighAllMatch }
|
||||||
TSynMarkupHighAllMatch = Record
|
TSynMarkupHighAllMatch = Record
|
||||||
StartPoint, EndPoint : TPoint;
|
StartPoint, EndPoint : TPoint;
|
||||||
@ -80,6 +55,11 @@ type
|
|||||||
public
|
public
|
||||||
constructor Create;
|
constructor Create;
|
||||||
Function MaybeReduceCapacity : Boolean;
|
Function MaybeReduceCapacity : Boolean;
|
||||||
|
function IndexOfFirstMatchForLine(ALine: Integer): Integer;
|
||||||
|
function IndexOfLastMatchForLine(ALine: Integer): Integer;
|
||||||
|
procedure Delete(AIndex: Integer; ACount: Integer = 1);
|
||||||
|
procedure Insert(AIndex: Integer; ACount: Integer = 1);
|
||||||
|
procedure Insert(AIndex: Integer; AStartPoint, AEndPoint: TPoint);
|
||||||
property Count : Integer read FCount write SetCount;
|
property Count : Integer read FCount write SetCount;
|
||||||
property Match [const Index : Integer] : TSynMarkupHighAllMatch read GetMatch write SetMatch; default;
|
property Match [const Index : Integer] : TSynMarkupHighAllMatch read GetMatch write SetMatch; default;
|
||||||
property StartPoint [const Index : Integer] : TPoint read GetStartPoint write SetStartPoint;
|
property StartPoint [const Index : Integer] : TPoint read GetStartPoint write SetStartPoint;
|
||||||
@ -94,20 +74,28 @@ type
|
|||||||
TSynEditMarkupHighlightAll = class(TSynEditMarkup)
|
TSynEditMarkupHighlightAll = class(TSynEditMarkup)
|
||||||
private
|
private
|
||||||
FFoldView: TSynEditFoldedView;
|
FFoldView: TSynEditFoldedView;
|
||||||
fSearchString : string; // for highlighting all occurences of a word/term
|
FSearchString : string; // for highlighting all occurences of a word/term
|
||||||
fSearchOptions: TSynSearchOptions;
|
FSearchOptions: TSynSearchOptions;
|
||||||
fSearch: TSynEditSearch;
|
FSearchStringMaxLines: Integer;
|
||||||
|
FSearch: TSynEditSearch;
|
||||||
|
FNextPosIdx, FNextPosRow: Integer;
|
||||||
|
|
||||||
fStartPoint : TPoint; // First found position, before TopLine of visible area
|
FStartPoint : TPoint; // First found position, before TopLine of visible area
|
||||||
fMatches : TSynMarkupHighAllMatchList;
|
FMatches : TSynMarkupHighAllMatchList;
|
||||||
fHasInvalidLines : Boolean;
|
FFirstInvalidLine, FLastInvalidLine: Integer;
|
||||||
FHideSingleMatch: Boolean;
|
FHideSingleMatch: Boolean;
|
||||||
|
|
||||||
Procedure FindStartPoint;
|
function SearchStringMaxLines: Integer;
|
||||||
Procedure FindInitialize(Backward: Boolean);
|
Procedure FindInitialize;
|
||||||
function GetMatchCount: Integer;
|
function GetMatchCount: Integer;
|
||||||
procedure SetFoldView(AValue: TSynEditFoldedView);
|
procedure SetFoldView(AValue: TSynEditFoldedView);
|
||||||
Procedure ValidateMatches(RePaint: Boolean = True; KeepStartPoint: Boolean = False);
|
Procedure FindMatches(AStartPoint, AEndPoint: TPoint;
|
||||||
|
var AIndex: Integer;
|
||||||
|
AStopAfterLine: Integer = -1; // AEndPoint may be set further down, for multi-line matches
|
||||||
|
ABackward : Boolean = False
|
||||||
|
);
|
||||||
|
procedure SetHideSingleMatch(AValue: Boolean);
|
||||||
|
Procedure ValidateMatches(SkipPaint: Boolean = False);
|
||||||
procedure SetSearchOptions(const AValue : TSynSearchOptions);
|
procedure SetSearchOptions(const AValue : TSynSearchOptions);
|
||||||
procedure DoFoldChanged(aLine: Integer);
|
procedure DoFoldChanged(aLine: Integer);
|
||||||
protected
|
protected
|
||||||
@ -115,13 +103,14 @@ type
|
|||||||
procedure DoTopLineChanged(OldTopLine : Integer); override;
|
procedure DoTopLineChanged(OldTopLine : Integer); override;
|
||||||
procedure DoLinesInWindoChanged(OldLinesInWindow : Integer); override;
|
procedure DoLinesInWindoChanged(OldLinesInWindow : Integer); override;
|
||||||
procedure DoMarkupChanged(AMarkup: TSynSelectedColor); override;
|
procedure DoMarkupChanged(AMarkup: TSynSelectedColor); override;
|
||||||
procedure DoTextChanged(StartLine, EndLine: Integer); override;
|
procedure DoTextChanged(StartLine, EndLine: Integer); override; // 1 based
|
||||||
property HideSingleMatch: Boolean read FHideSingleMatch write FHideSingleMatch;
|
property HideSingleMatch: Boolean read FHideSingleMatch write SetHideSingleMatch;
|
||||||
property MatchCount: Integer read GetMatchCount;
|
property MatchCount: Integer read GetMatchCount;
|
||||||
public
|
public
|
||||||
constructor Create(ASynEdit : TSynEditBase);
|
constructor Create(ASynEdit : TSynEditBase);
|
||||||
destructor Destroy; override;
|
destructor Destroy; override;
|
||||||
|
|
||||||
|
procedure PrepareMarkupForRow(aRow: Integer); override;
|
||||||
function GetMarkupAttributeAtRowCol(const aRow: Integer;
|
function GetMarkupAttributeAtRowCol(const aRow: Integer;
|
||||||
const aStartCol: TLazSynDisplayTokenBound;
|
const aStartCol: TLazSynDisplayTokenBound;
|
||||||
const AnRtlInfo: TLazSynDisplayRtlInfo): TSynSelectedColor; override;
|
const AnRtlInfo: TLazSynDisplayRtlInfo): TSynSelectedColor; override;
|
||||||
@ -130,8 +119,10 @@ type
|
|||||||
const AnRtlInfo: TLazSynDisplayRtlInfo;
|
const AnRtlInfo: TLazSynDisplayRtlInfo;
|
||||||
out ANextPhys, ANextLog: Integer); override;
|
out ANextPhys, ANextLog: Integer); override;
|
||||||
|
|
||||||
Procedure Invalidate(RePaint: Boolean = True);
|
// AFirst/ ALast are 1 based
|
||||||
Procedure SendLineInvalidation;
|
Procedure Invalidate(SkipPaint: Boolean = False);
|
||||||
|
Procedure InvalidateLines(AFirstLine: Integer = 0; ALastLine: Integer = 0; SkipPaint: Boolean = False);
|
||||||
|
Procedure SendLineInvalidation(AFirstIndex: Integer = -1;ALastIndex: Integer = -1);
|
||||||
|
|
||||||
property FoldView: TSynEditFoldedView read FFoldView write SetFoldView;
|
property FoldView: TSynEditFoldedView read FFoldView write SetFoldView;
|
||||||
|
|
||||||
@ -190,6 +181,12 @@ type
|
|||||||
implementation
|
implementation
|
||||||
uses SynEdit;
|
uses SynEdit;
|
||||||
|
|
||||||
|
const
|
||||||
|
SEARCH_START_OFFS = 100; // Search n lises before/after visible area. (Before applies only, if no exact offset can not be calculated from searchtext)
|
||||||
|
MATCHES_CLEAN_CNT_THRESHOLD = 2500; // Remove matches out of range, only if more Matches are present
|
||||||
|
MATCHES_CLEAN_LINE_THRESHOLD = 300; // Remove matches out of range, only if they are at least n lines from visible area.
|
||||||
|
MATCHES_CLEAN_LINE_KEEP = 200; // LinesKept, if cleaning. MUST be LESS than MATCHES_CLEAN_LINE_THRESHOLD
|
||||||
|
|
||||||
{ TSynMarkupHighAllLines }
|
{ TSynMarkupHighAllLines }
|
||||||
|
|
||||||
(*
|
(*
|
||||||
@ -255,6 +252,74 @@ begin
|
|||||||
result := true;
|
result := true;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function TSynMarkupHighAllMatchList.IndexOfFirstMatchForLine(ALine: Integer): Integer;
|
||||||
|
var
|
||||||
|
l, h: Integer;
|
||||||
|
begin
|
||||||
|
if FCount = 0 then
|
||||||
|
exit(-1);
|
||||||
|
l := 0;
|
||||||
|
h := FCount -1;
|
||||||
|
Result := (l+h) div 2;
|
||||||
|
while (h > l) do begin
|
||||||
|
if FMatches[Result].EndPoint.y >= ALine then
|
||||||
|
h := Result
|
||||||
|
else
|
||||||
|
l := Result + 1;
|
||||||
|
Result := (l+h) div 2;
|
||||||
|
end;
|
||||||
|
if (FMatches[Result].EndPoint.y < ALine) then
|
||||||
|
Result := -1;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TSynMarkupHighAllMatchList.IndexOfLastMatchForLine(ALine: Integer): Integer;
|
||||||
|
var
|
||||||
|
l, h: Integer;
|
||||||
|
begin
|
||||||
|
if FCount = 0 then
|
||||||
|
exit(-1);
|
||||||
|
l := 0;
|
||||||
|
h := FCount -1;
|
||||||
|
Result := (l+h) div 2;
|
||||||
|
while (h > l) do begin
|
||||||
|
if FMatches[Result].StartPoint.y <= ALine then
|
||||||
|
l := Result + 1
|
||||||
|
else
|
||||||
|
h := Result;
|
||||||
|
Result := (l+h) div 2;
|
||||||
|
end;
|
||||||
|
if (FMatches[Result].StartPoint.y > ALine) then
|
||||||
|
Result := -1;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TSynMarkupHighAllMatchList.Delete(AIndex: Integer; ACount: Integer);
|
||||||
|
begin
|
||||||
|
if AIndex >= FCount then
|
||||||
|
exit;
|
||||||
|
if AIndex + ACount > FCount then
|
||||||
|
ACount := FCount - AIndex
|
||||||
|
else
|
||||||
|
if AIndex + ACount < FCount then
|
||||||
|
System.Move(FMatches[AIndex+ACount], FMatches[AIndex], (FCount-AIndex-ACount)*SizeOf(TSynMarkupHighAllMatch));
|
||||||
|
Count := Count - ACount;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TSynMarkupHighAllMatchList.Insert(AIndex: Integer; ACount: Integer);
|
||||||
|
begin
|
||||||
|
if AIndex > FCount then
|
||||||
|
exit;
|
||||||
|
Count := FCount + ACount;
|
||||||
|
if AIndex < FCount then
|
||||||
|
System.Move(FMatches[AIndex], FMatches[AIndex+ACount], (FCount-AIndex-ACount)*SizeOf(TSynMarkupHighAllMatch));
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TSynMarkupHighAllMatchList.Insert(AIndex: Integer; AStartPoint, AEndPoint: TPoint);
|
||||||
|
begin
|
||||||
|
Insert(AIndex);
|
||||||
|
FMatches[AIndex].StartPoint := AStartPoint;
|
||||||
|
FMatches[AIndex].EndPoint := AEndPoint;
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TSynMarkupHighAllMatchList.SetCount(const AValue : Integer);
|
procedure TSynMarkupHighAllMatchList.SetCount(const AValue : Integer);
|
||||||
begin
|
begin
|
||||||
if FCount=AValue then exit;
|
if FCount=AValue then exit;
|
||||||
@ -270,7 +335,7 @@ end;
|
|||||||
|
|
||||||
function TSynMarkupHighAllMatchList.GetPointCount : Integer;
|
function TSynMarkupHighAllMatchList.GetPointCount : Integer;
|
||||||
begin
|
begin
|
||||||
result := Count << 1;
|
result := Count * 2;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TSynMarkupHighAllMatchList.GetPoint(const Index : Integer) : TPoint;
|
function TSynMarkupHighAllMatchList.GetPoint(const Index : Integer) : TPoint;
|
||||||
@ -326,7 +391,8 @@ begin
|
|||||||
fSearch := TSynEditSearch.Create;
|
fSearch := TSynEditSearch.Create;
|
||||||
fMatches := TSynMarkupHighAllMatchList.Create;
|
fMatches := TSynMarkupHighAllMatchList.Create;
|
||||||
fSearchString:='';
|
fSearchString:='';
|
||||||
fHasInvalidLines:=True;
|
FFirstInvalidLine := 1;
|
||||||
|
FLastInvalidLine := MaxInt;
|
||||||
FHideSingleMatch := False;
|
FHideSingleMatch := False;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -342,46 +408,49 @@ procedure TSynEditMarkupHighlightAll.SetSearchOptions(const AValue : TSynSearchO
|
|||||||
begin
|
begin
|
||||||
if fSearchOptions = AValue then exit;
|
if fSearchOptions = AValue then exit;
|
||||||
fSearchOptions := AValue;
|
fSearchOptions := AValue;
|
||||||
|
FSearchStringMaxLines := -1;
|
||||||
Invalidate;
|
Invalidate;
|
||||||
ValidateMatches;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TSynEditMarkupHighlightAll.SetSearchString(const AValue : String);
|
procedure TSynEditMarkupHighlightAll.SetSearchString(const AValue : String);
|
||||||
begin
|
begin
|
||||||
if fSearchString = AValue then exit;
|
if fSearchString = AValue then exit;
|
||||||
fSearchString := AValue;
|
fSearchString := AValue;
|
||||||
Invalidate;
|
FSearchStringMaxLines := -1;
|
||||||
ValidateMatches; // bad if options and string search at the same time *and* string is <> ''
|
//DebugLnEnter(['TSynEditMarkupHighlightAll.SetSearchString ', fSearchString]);
|
||||||
|
Invalidate; // bad if options and string search at the same time *and* string is <> ''
|
||||||
|
//DebugLnExit(['TSynEditMarkupHighlightAll.SetSearchString ']);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TSynEditMarkupHighlightAll.DoTopLineChanged(OldTopLine : Integer);
|
procedure TSynEditMarkupHighlightAll.DoTopLineChanged(OldTopLine : Integer);
|
||||||
begin
|
begin
|
||||||
// {TODO: Only do a partial search on the new area}
|
// {TODO: Only do a partial search on the new area}
|
||||||
Invalidate(False);
|
//DebugLnEnter(['TSynEditMarkupHighlightAll.DoTopLineChanged ',FSearchString]);
|
||||||
ValidateMatches(False, (fStartPoint.y < TopLine) and (fStartPoint.y >= 0));
|
ValidateMatches(True);
|
||||||
|
//DebugLnExit(['TSynEditMarkupHighlightAll.DoTopLineChanged ']);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TSynEditMarkupHighlightAll.DoLinesInWindoChanged(OldLinesInWindow : Integer);
|
procedure TSynEditMarkupHighlightAll.DoLinesInWindoChanged(OldLinesInWindow : Integer);
|
||||||
begin
|
begin
|
||||||
// {TODO: Only do a partial search on the new area}
|
// {TODO: Only do a partial search on the new area}
|
||||||
Invalidate(False);;
|
//DebugLnEnter(['TSynEditMarkupHighlightAll.DoLinesInWindoChanged ',FSearchString]);
|
||||||
ValidateMatches(False, True);
|
ValidateMatches(True);
|
||||||
|
//DebugLnExit(['TSynEditMarkupHighlightAll.DoLinesInWindoChanged ']);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TSynEditMarkupHighlightAll.DoMarkupChanged(AMarkup : TSynSelectedColor);
|
procedure TSynEditMarkupHighlightAll.DoMarkupChanged(AMarkup : TSynSelectedColor);
|
||||||
begin
|
begin
|
||||||
Invalidate; {TODO: only redraw, no search}
|
SendLineInvalidation;
|
||||||
ValidateMatches;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TSynEditMarkupHighlightAll.FindInitialize(Backward : Boolean);
|
procedure TSynEditMarkupHighlightAll.FindInitialize;
|
||||||
begin
|
begin
|
||||||
fSearch.Pattern := fSearchString;
|
fSearch.Pattern := fSearchString;
|
||||||
fSearch.Sensitive := ssoMatchCase in fSearchOptions;
|
fSearch.Sensitive := ssoMatchCase in fSearchOptions;
|
||||||
fSearch.Whole := ssoWholeWord in fSearchOptions;
|
fSearch.Whole := ssoWholeWord in fSearchOptions;
|
||||||
fSearch.RegularExpressions := ssoRegExpr in fSearchOptions;
|
fSearch.RegularExpressions := ssoRegExpr in fSearchOptions;
|
||||||
fSearch.RegExprMultiLine := ssoRegExprMultiLine in fSearchOptions;
|
fSearch.RegExprMultiLine := ssoRegExprMultiLine in fSearchOptions;
|
||||||
fSearch.Backwards := Backward;
|
fSearch.Backwards := False;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TSynEditMarkupHighlightAll.GetMatchCount: Integer;
|
function TSynEditMarkupHighlightAll.GetMatchCount: Integer;
|
||||||
@ -402,30 +471,56 @@ begin
|
|||||||
FFoldView.AddFoldChangedHandler(@DoFoldChanged);
|
FFoldView.AddFoldChangedHandler(@DoFoldChanged);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TSynEditMarkupHighlightAll.DoFoldChanged(aLine: Integer);
|
procedure TSynEditMarkupHighlightAll.FindMatches(AStartPoint, AEndPoint: TPoint;
|
||||||
|
var AIndex: Integer; AStopAfterLine: Integer; ABackward: Boolean);
|
||||||
|
var
|
||||||
|
ptFoundStart, ptFoundEnd: TPoint;
|
||||||
begin
|
begin
|
||||||
Invalidate(False);
|
//debugln(['FindMatches IDX=', AIndex,' # ',dbgs(AStartPoint),' - ',dbgs(AEndPoint), 'AStopAfterLine=',AStopAfterLine, ' cnt=',FMatches.Count]);
|
||||||
ValidateMatches(False, (fStartPoint.y < TopLine) and (fStartPoint.y >= 0));
|
fSearch.Backwards := ABackward;
|
||||||
|
While (true) do begin
|
||||||
|
if not fSearch.FindNextOne(Lines, AStartPoint, AEndPoint, ptFoundStart, ptFoundEnd)
|
||||||
|
then break;
|
||||||
|
AStartPoint := ptFoundEnd;
|
||||||
|
|
||||||
|
FMatches.Insert(AIndex, ptFoundStart, ptFoundEnd);
|
||||||
|
inc(AIndex); // BAckward learch needs final index to point to last inserted (currently support only find ONE)
|
||||||
|
|
||||||
|
if (AStopAfterLine >= 0) and (ptFoundStart.Y > AStopAfterLine) then
|
||||||
|
break;
|
||||||
|
end;
|
||||||
|
//debugln(['FindMatches IDX=', AIndex]);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TSynEditMarkupHighlightAll.FindStartPoint;
|
procedure TSynEditMarkupHighlightAll.SetHideSingleMatch(AValue: Boolean);
|
||||||
|
begin
|
||||||
|
if FHideSingleMatch = AValue then Exit;
|
||||||
|
FHideSingleMatch := AValue;
|
||||||
|
if FMatches.Count = 1 then
|
||||||
|
if FHideSingleMatch then
|
||||||
|
Invalidate // TODO only need extend search
|
||||||
|
//ValidateMatches() // May find a 2nd, by extending startpos
|
||||||
|
else
|
||||||
|
SendLineInvalidation; // Show the existing match
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TSynEditMarkupHighlightAll.DoFoldChanged(aLine: Integer);
|
||||||
|
begin
|
||||||
|
InvalidateLines(aLine+1, MaxInt, True);
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TSynEditMarkupHighlightAll.SearchStringMaxLines: Integer;
|
||||||
var
|
var
|
||||||
ptStart, ptEnd, ptFoundStart, ptFoundEnd: TPoint;
|
|
||||||
i, j: Integer;
|
i, j: Integer;
|
||||||
begin
|
begin
|
||||||
if fSearchString = '' then exit;
|
Result := FSearchStringMaxLines;
|
||||||
|
if Result > 0 then
|
||||||
if (ssoWholeWord in fSearchOptions) and (not HideSingleMatch) then begin
|
|
||||||
// can not wrap around lines
|
|
||||||
fStartPoint := Point(1, TopLine);
|
|
||||||
exit;
|
exit;
|
||||||
end;
|
|
||||||
|
|
||||||
if (fSearchOptions * [ssoRegExpr, ssoRegExprMultiLine] = []) and
|
if (fSearchOptions * [ssoRegExpr, ssoRegExprMultiLine] = [])
|
||||||
(not HideSingleMatch)
|
|
||||||
then begin
|
then begin
|
||||||
// can not wrap around lines
|
// can not wrap around lines
|
||||||
j := 0;
|
j := 1;
|
||||||
i := Length(fSearchString);
|
i := Length(fSearchString);
|
||||||
while i > 0 do begin
|
while i > 0 do begin
|
||||||
if fSearchString[i] = #13 then begin
|
if fSearchString[i] = #13 then begin
|
||||||
@ -439,165 +534,352 @@ begin
|
|||||||
end;
|
end;
|
||||||
dec(i);
|
dec(i);
|
||||||
end;
|
end;
|
||||||
fStartPoint := Point(1, Max(1, TopLine - j));
|
FSearchStringMaxLines := j;
|
||||||
exit;
|
end
|
||||||
|
else begin
|
||||||
|
if (fSearchOptions * [ssoRegExpr, ssoRegExprMultiLine] = [ssoRegExpr]) then
|
||||||
|
FSearchStringMaxLines := 1 // Only ssoRegExprMultiLine can expand accross lines (actually \n\r should anymay...)
|
||||||
|
else
|
||||||
|
FSearchStringMaxLines := 0; // Unknown
|
||||||
end;
|
end;
|
||||||
|
|
||||||
FindInitialize(true);
|
Result := FSearchStringMaxLines;
|
||||||
ptStart := Point(1, Max(1, TopLine-100));
|
|
||||||
ptEnd.Y := TopLine;
|
|
||||||
ptEnd.X := 1;
|
|
||||||
if fSearch.FindNextOne(Lines, ptStart, ptEnd, ptFoundStart, ptFoundEnd)
|
|
||||||
then fStartPoint := ptFoundStart
|
|
||||||
else fStartPoint := ptEnd;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TSynEditMarkupHighlightAll.ValidateMatches(RePaint: Boolean = True;
|
procedure TSynEditMarkupHighlightAll.ValidateMatches(SkipPaint: Boolean);
|
||||||
KeepStartPoint: Boolean = False);
|
|
||||||
|
function IsStartPosValid: Boolean;
|
||||||
|
begin
|
||||||
|
Result := (FStartPoint.y > 0) and
|
||||||
|
(FStartPoint.y < TopLine) and
|
||||||
|
( (FFirstInvalidLine < 1) or (FStartPoint.y < FFirstInvalidLine) or
|
||||||
|
( (FLastInvalidLine > 0) and (FStartPoint.y > FLastInvalidLine) )
|
||||||
|
);
|
||||||
|
// or to far back
|
||||||
|
end;
|
||||||
|
|
||||||
var
|
var
|
||||||
LastLine : Integer;
|
LastLine : Integer; // Last visible
|
||||||
Pos : Integer;
|
EndOffsLine : Integer; // Stop search (LastLine + Offs)
|
||||||
ptStart, ptEnd, ptFoundStart, ptFoundEnd: TPoint;
|
Idx, Idx2 : Integer;
|
||||||
|
FirstInvalIdx, LastInvalIdx: Integer;
|
||||||
begin
|
begin
|
||||||
if (fSearchString = '') or (not MarkupInfo.IsEnabled) then begin
|
if (fSearchString = '') or (not MarkupInfo.IsEnabled) then begin
|
||||||
fMatches.Count := 0;
|
fMatches.Count := 0;
|
||||||
exit;
|
exit;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
if not fHasInvalidLines
|
|
||||||
then exit;
|
|
||||||
fHasInvalidLines := false;
|
|
||||||
|
|
||||||
LastLine := ScreenRowToRow(LinesInWindow);
|
LastLine := ScreenRowToRow(LinesInWindow);
|
||||||
|
|
||||||
{ TODO: need a list of invalidated lines, so we can keep valid matches }
|
// remove matches, that are too far off the current visible area
|
||||||
if not KeepStartPoint then
|
if FMatches.Count > MATCHES_CLEAN_CNT_THRESHOLD then begin
|
||||||
FindStartPoint;
|
if TopLine - FMatches.EndPoint[0].y > MATCHES_CLEAN_LINE_THRESHOLD then begin
|
||||||
ptStart := fStartPoint;
|
Idx := FMatches.IndexOfFirstMatchForLine(TopLine - MATCHES_CLEAN_LINE_KEEP) - 1;
|
||||||
Pos := 0;
|
FMatches.Delete(0, Idx);
|
||||||
|
end;
|
||||||
FindInitialize(false);
|
if FMatches.StartPoint[FMatches.Count-1].y - LastLine > MATCHES_CLEAN_LINE_THRESHOLD then begin
|
||||||
ptEnd.Y:= min(ScreenRowToRow(LinesInWindow)+100, Lines.Count);
|
Idx := FMatches.IndexOfLastMatchForLine(LastLine + MATCHES_CLEAN_LINE_KEEP) + 1;
|
||||||
ptEnd.X:= Length(Lines[ptEnd.y - 1]);
|
FMatches.Delete(Idx, FMatches.Count - Idx);
|
||||||
|
end;
|
||||||
While (true) do begin
|
|
||||||
if not fSearch.FindNextOne(Lines, ptStart, ptEnd, ptFoundStart, ptFoundEnd)
|
|
||||||
then break;
|
|
||||||
ptStart := ptFoundEnd;
|
|
||||||
|
|
||||||
fMatches.StartPoint[Pos] := ptFoundStart;
|
|
||||||
fMatches.EndPoint[Pos] := ptFoundEnd;
|
|
||||||
|
|
||||||
if ptFoundStart.Y > LastLine
|
|
||||||
then break;
|
|
||||||
inc(Pos);
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
fMatches.Count := Pos;
|
FirstInvalIdx := -1;
|
||||||
fMatches.MaybeReduceCapacity;
|
LastInvalIdx := -1;
|
||||||
if RePaint and ( not(HideSingleMatch) or (fMatches.Count > 1) ) then
|
if (FFirstInvalidLine > 0) or (FLastInvalidLine > 0) then begin
|
||||||
SendLineInvalidation;
|
FirstInvalIdx := FMatches.IndexOfFirstMatchForLine(FFirstInvalidLine);
|
||||||
|
LastInvalIdx := FMatches.IndexOfLastMatchForLine(FLastInvalidLine);
|
||||||
|
if (FirstInvalIdx >= 0) xor (LastInvalIdx >= 0) then begin
|
||||||
|
if FirstInvalIdx < 0 then
|
||||||
|
FirstInvalIdx := 0;
|
||||||
|
if LastInvalIdx < 0 then
|
||||||
|
LastInvalIdx := FMatches.Count - 1;
|
||||||
|
end;
|
||||||
|
if FirstInvalIdx >= 0 then begin
|
||||||
|
if (not SkipPaint) then
|
||||||
|
SendLineInvalidation(FirstInvalIdx, LastInvalIdx);
|
||||||
|
FMatches.Delete(FirstInvalIdx, LastInvalIdx-FirstInvalIdx+1);
|
||||||
|
if FirstInvalIdx >= FMatches.Count then
|
||||||
|
FirstInvalIdx := -1;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
//DebugLnEnter(['>>> ValidateMatches ', FFirstInvalidLine, ' - ',FLastInvalidLine, ' Cnt=',FMatches.Count, ' Idx: ', FirstInvalIdx, ' - ',LastInvalIdx, ' ',SynEdit.Name]);
|
||||||
|
|
||||||
|
FindInitialize;
|
||||||
|
|
||||||
|
if not IsStartPosValid then begin
|
||||||
|
|
||||||
|
if (FMatches.Count > 0) and (FMatches.StartPoint[0].y < TopLine) then begin
|
||||||
|
// New StartPoint from existing matches
|
||||||
|
FStartPoint := FMatches.StartPoint[0];
|
||||||
|
if FirstInvalIdx = 0 then
|
||||||
|
FirstInvalIdx := -1;
|
||||||
|
end
|
||||||
|
|
||||||
|
else begin
|
||||||
|
// New StartPoint
|
||||||
|
Idx := 0;
|
||||||
|
if SearchStringMaxLines > 0 then
|
||||||
|
FStartPoint := Point(1, TopLine - (SearchStringMaxLines - 1))
|
||||||
|
else begin // Search backward
|
||||||
|
FindMatches(Point(1, Max(1, TopLine-SEARCH_START_OFFS)), Point(1, TopLine), Idx, 0, True); // stopAfterline=0, do only ONE find
|
||||||
|
if Idx = 0
|
||||||
|
then FStartPoint := Point(1, TopLine) // no previous match found
|
||||||
|
else FStartPoint := FMatches.EndPoint[0];
|
||||||
|
end;
|
||||||
|
//debugln(['ValidateMatches: startpoint ', dbgs(FStartPoint)]);
|
||||||
|
if FMatches.Count > Idx then begin
|
||||||
|
// Fill at start
|
||||||
|
Idx2 := Idx;
|
||||||
|
FindMatches(FStartPoint, FMatches.StartPoint[Idx], Idx);
|
||||||
|
if (not SkipPaint) and (Idx > Idx2) and
|
||||||
|
( (not HideSingleMatch) or (FMatches.Count > 1) or
|
||||||
|
// Might still get more matches.
|
||||||
|
(FirstInvalIdx > 0) or (FMatches.EndPoint[FMatches.Count - 1].y <= LastLine)
|
||||||
|
)
|
||||||
|
then
|
||||||
|
SendLineInvalidation(Idx2, Idx-1);
|
||||||
|
if FirstInvalIdx = 0 then
|
||||||
|
FirstInvalIdx := -1;
|
||||||
|
end;
|
||||||
|
if (FirstInvalIdx >= 0) and (Idx > 0) then begin
|
||||||
|
inc(FirstInvalIdx, Idx);
|
||||||
|
inc(LastInvalIdx, Idx);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
end; // StartPoint
|
||||||
|
|
||||||
|
if FMatches.Count = 0 then begin
|
||||||
|
//debugln(['ValidateMatches cnt was 0']);
|
||||||
|
Idx := 0;
|
||||||
|
EndOffsLine := min(LastLine+SEARCH_START_OFFS, Lines.Count);
|
||||||
|
FindMatches(FStartPoint, Point(Length(Lines[EndOffsLine - 1]), EndOffsLine), Idx, LastLine);
|
||||||
|
if (not SkipPaint) and (Idx > 0) and
|
||||||
|
( (not HideSingleMatch) or (FMatches.Count > 1) )
|
||||||
|
then
|
||||||
|
SendLineInvalidation(0, Idx-1);
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
|
||||||
|
if (FirstInvalIdx >= 0) then begin
|
||||||
|
//debugln(['ValidateMatches REPLACE']);
|
||||||
|
// Replace invalidated
|
||||||
|
Idx := FirstInvalIdx; // actually first valid now
|
||||||
|
if Idx > 0 then begin
|
||||||
|
FindMatches(FMatches.EndPoint[Idx-1], FMatches.StartPoint[Idx], Idx);
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
FindMatches(FStartPoint, FMatches.StartPoint[Idx], Idx);
|
||||||
|
end;
|
||||||
|
if (not SkipPaint) and (Idx > FirstInvalIdx) and
|
||||||
|
( (not HideSingleMatch) or (FMatches.Count > 1) or
|
||||||
|
// Might still get more matches.
|
||||||
|
(FMatches.EndPoint[FMatches.Count - 1].y <= LastLine)
|
||||||
|
)
|
||||||
|
then
|
||||||
|
SendLineInvalidation(FirstInvalIdx, Idx-1);
|
||||||
|
end;
|
||||||
|
|
||||||
|
// TODO: store a searched until position
|
||||||
|
if FMatches.EndPoint[FMatches.Count - 1].y <= LastLine then begin
|
||||||
|
//debugln(['ValidateMatches AT END']);
|
||||||
|
// extend at end
|
||||||
|
Idx := FMatches.Count;
|
||||||
|
Idx2 := Idx;
|
||||||
|
EndOffsLine := min(LastLine+SEARCH_START_OFFS, Lines.Count);
|
||||||
|
FindMatches(FMatches.EndPoint[Idx-1], Point(Length(Lines[EndOffsLine - 1]), EndOffsLine), Idx, LastLine);
|
||||||
|
if (not SkipPaint) and (Idx > Idx2) and
|
||||||
|
( (not HideSingleMatch) or (FMatches.Count > 1) )
|
||||||
|
then
|
||||||
|
SendLineInvalidation(Idx2, Idx-1);
|
||||||
|
end;
|
||||||
|
|
||||||
|
end;
|
||||||
|
|
||||||
|
//DebugLnExit(['<<< ValidateMatches Cnt=',FMatches.Count]);
|
||||||
|
FFirstInvalidLine := 0;
|
||||||
|
FLastInvalidLine := 0;
|
||||||
|
FNextPosRow := -1;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TSynEditMarkupHighlightAll.DoTextChanged(StartLine, EndLine: Integer);
|
procedure TSynEditMarkupHighlightAll.DoTextChanged(StartLine, EndLine: Integer);
|
||||||
begin
|
begin
|
||||||
if (fSearchString = '') then exit;
|
if (fSearchString = '') then exit;
|
||||||
Invalidate;
|
InvalidateLines(StartLine, MaxInt); // EndLine); // Might be LineCount changed
|
||||||
ValidateMatches;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TSynEditMarkupHighlightAll.Invalidate(RePaint: Boolean = True);
|
procedure TSynEditMarkupHighlightAll.InvalidateLines(AFirstLine: Integer; ALastLine: Integer;
|
||||||
|
SkipPaint: Boolean);
|
||||||
begin
|
begin
|
||||||
if RePaint then
|
if AFirstLine < 1 then
|
||||||
SendLineInvalidation;
|
AFirstLine := 1;
|
||||||
fHasInvalidLines := True;
|
if (ALastLine < 1) then
|
||||||
fMatches.Count := 0;
|
ALastLine := MaxInt
|
||||||
if SearchString = '' then fMatches.MaybeReduceCapacity;
|
else
|
||||||
|
if ALastLine < AFirstLine then
|
||||||
|
ALastLine := AFirstLine;
|
||||||
|
|
||||||
|
//if (FMatches.Count > 0) and
|
||||||
|
// (ALastLine < FMatches.StartPoint[0].y) or
|
||||||
|
// (AFirstLine > FMatches.EndPoint[FMatches.Count-1].y)
|
||||||
|
//then
|
||||||
|
// exit;
|
||||||
|
|
||||||
|
if (FStartPoint.y < 0) or (ALastLine >= FStartPoint.y) then begin
|
||||||
|
|
||||||
|
if (AFirstLine < FFirstInvalidLine) or (FFirstInvalidLine <= 0) then
|
||||||
|
FFirstInvalidLine := AFirstLine;
|
||||||
|
if (ALastLine > FLastInvalidLine) then
|
||||||
|
FLastInvalidLine := ALastLine;
|
||||||
|
end;
|
||||||
|
|
||||||
|
ValidateMatches(SkipPaint);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TSynEditMarkupHighlightAll.SendLineInvalidation;
|
procedure TSynEditMarkupHighlightAll.SendLineInvalidation(AFirstIndex: Integer;
|
||||||
|
ALastIndex: Integer);
|
||||||
var
|
var
|
||||||
Pos: Integer;
|
Pos: Integer;
|
||||||
|
Line1, Line2: Integer;
|
||||||
begin
|
begin
|
||||||
// Inform SynEdit which lines need repainting
|
// Inform SynEdit which lines need repainting
|
||||||
Pos := 0;
|
if fMatches.Count = 0 then
|
||||||
while (Pos < fMatches.PointCount)
|
exit;
|
||||||
|
|
||||||
|
if AFirstIndex < 0 then
|
||||||
|
AFirstIndex := 0;
|
||||||
|
if (ALastIndex < 0) or (ALastIndex > FMatches.Count - 1) then
|
||||||
|
ALastIndex := FMatches.Count - 1;
|
||||||
|
|
||||||
|
Line1 := fMatches.StartPoint[AFirstIndex].y;
|
||||||
|
Line2 := fMatches.EndPoint[AFirstIndex].y;
|
||||||
|
Pos := AFirstIndex;
|
||||||
|
while (Pos < ALastIndex)
|
||||||
do begin
|
do begin
|
||||||
// first block, or new-end bigger last-end
|
inc(Pos);
|
||||||
if ( (Pos = 0) or (fMatches.Point[Pos+1].y > fMatches.Point[Pos-1].y) )
|
if fMatches.EndPoint[Pos].y <= Line2 then
|
||||||
then
|
Continue;
|
||||||
InvalidateSynLines(fMatches.Point[Pos].y, fMatches.Point[Pos+1].y);
|
if fMatches.StartPoint[Pos].y <= Line2 + 1 then begin
|
||||||
inc(pos,2);
|
Line2 := fMatches.EndPoint[Pos].y;
|
||||||
|
Continue;
|
||||||
|
end;
|
||||||
|
|
||||||
|
InvalidateSynLines(Line1, Line2);
|
||||||
|
Line1 := fMatches.StartPoint[Pos].y;
|
||||||
|
Line2 := fMatches.EndPoint[Pos].y;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
InvalidateSynLines(Line1, Line2);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TSynEditMarkupHighlightAll.PrepareMarkupForRow(aRow: Integer);
|
||||||
|
begin
|
||||||
|
if (FNextPosRow > 0) and (aRow > FNextPosRow) and
|
||||||
|
( (FNextPosIdx = -2) or // No match after FNextPosRow
|
||||||
|
( (FNextPosIdx >= 0) and (FNextPosIdx < FMatches.PointCount) and (aRow <= FMatches.Point[FNextPosIdx].y) )
|
||||||
|
)
|
||||||
|
then begin
|
||||||
|
if (FNextPosIdx >= 0) and
|
||||||
|
( (aRow = FMatches.Point[FNextPosIdx].y) or (FNextPosIdx and 1 = 1) )
|
||||||
|
then
|
||||||
|
FNextPosRow := aRow;
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
|
||||||
|
FNextPosRow := aRow;
|
||||||
|
FNextPosIdx := FMatches.IndexOfFirstMatchForLine(aRow) * 2;
|
||||||
|
if FNextPosIdx < 0 then
|
||||||
|
exit;
|
||||||
|
if (FMatches.Point[FNextPosIdx].y < aRow) then
|
||||||
|
inc(FNextPosIdx); // Use EndPoint
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TSynEditMarkupHighlightAll.GetMarkupAttributeAtRowCol(const aRow: Integer;
|
function TSynEditMarkupHighlightAll.GetMarkupAttributeAtRowCol(const aRow: Integer;
|
||||||
const aStartCol: TLazSynDisplayTokenBound; const AnRtlInfo: TLazSynDisplayRtlInfo): TSynSelectedColor;
|
const aStartCol: TLazSynDisplayTokenBound; const AnRtlInfo: TLazSynDisplayRtlInfo): TSynSelectedColor;
|
||||||
var
|
var
|
||||||
Pos, s, e: Integer;
|
pos, s, e: Integer;
|
||||||
begin
|
begin
|
||||||
result := nil;
|
result := nil;
|
||||||
if (fSearchString = '') then
|
if (fSearchString = '') then
|
||||||
exit;
|
exit;
|
||||||
|
|
||||||
if HideSingleMatch and (fMatches.Count <= 1) then exit;
|
if (HideSingleMatch and (fMatches.Count <= 1)) or (aRow <> FNextPosRow) or (FNextPosIdx < 0)
|
||||||
|
then
|
||||||
|
exit;
|
||||||
|
|
||||||
Pos:= 0;
|
while (FNextPosIdx < fMatches.PointCount) and
|
||||||
while (Pos < fMatches.PointCount)
|
(fMatches.Point[FNextPosIdx].y = aRow) and
|
||||||
and ( (fMatches.Point[Pos].y < aRow)
|
(fMatches.Point[FNextPosIdx].x <= aStartCol.Logical)
|
||||||
or ((fMatches.Point[Pos].y = aRow) and (fMatches.Point[Pos].x <= aStartCol.Logical)) )
|
do
|
||||||
do inc(Pos);
|
inc(FNextPosIdx);
|
||||||
|
|
||||||
if Pos = fMatches.PointCount // last point was EndPoint => no markup
|
if FNextPosIdx = fMatches.PointCount // last point was EndPoint => no markup
|
||||||
then exit;
|
then exit;
|
||||||
|
|
||||||
if (Pos and 1)=0 // the next Point is a StartPoint => Outside Match
|
pos := FNextPosIdx - 1;
|
||||||
|
while (pos >= 0) and (fMatches.Point[pos].y = aRow) and
|
||||||
|
(fMatches.Point[pos].x > aStartCol.Logical)
|
||||||
|
do
|
||||||
|
dec(pos);
|
||||||
|
|
||||||
|
if pos < 0 then
|
||||||
|
exit;
|
||||||
|
|
||||||
|
//pos is the point at or before LogPos
|
||||||
|
if (pos and 1)= 1 // the Point is a EndPoint => Outside Match
|
||||||
then exit;
|
then exit;
|
||||||
|
|
||||||
//debugLN('+++>MARUP *ON* ',dbgs(@result),' / ',dbgs(ARow), ' at index ', dbgs(Pos));
|
//debugLN('+++>MARUP *ON* ',dbgs(@result),' / ',dbgs(ARow), ' at index ', dbgs(FNextPosIdx));
|
||||||
if fMatches.Point[Pos-1].y < aRow then
|
if fMatches.Point[pos].y < aRow then
|
||||||
s := -1
|
s := -1
|
||||||
else
|
else
|
||||||
s := fMatches.Point[Pos-1].x;
|
s := fMatches.Point[pos].x;
|
||||||
if fMatches.Point[Pos].y > aRow then
|
if (pos = FMatches.PointCount) or (fMatches.Point[pos+1].y > aRow) then
|
||||||
e := -1
|
e := -1
|
||||||
else
|
else
|
||||||
e := fMatches.Point[Pos].x;
|
e := fMatches.Point[pos+1].x;
|
||||||
MarkupInfo.SetFrameBoundsLog(s, e);
|
MarkupInfo.SetFrameBoundsLog(s, e);
|
||||||
result := MarkupInfo;
|
Result := MarkupInfo;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TSynEditMarkupHighlightAll.GetNextMarkupColAfterRowCol(const aRow: Integer;
|
procedure TSynEditMarkupHighlightAll.GetNextMarkupColAfterRowCol(const aRow: Integer;
|
||||||
const aStartCol: TLazSynDisplayTokenBound; const AnRtlInfo: TLazSynDisplayRtlInfo; out ANextPhys,
|
const aStartCol: TLazSynDisplayTokenBound; const AnRtlInfo: TLazSynDisplayRtlInfo; out ANextPhys,
|
||||||
ANextLog: Integer);
|
ANextLog: Integer);
|
||||||
var
|
|
||||||
Pos: Integer;
|
|
||||||
begin
|
begin
|
||||||
ANextLog := -1;
|
ANextLog := -1;
|
||||||
ANextPhys := -1;
|
ANextPhys := -1;
|
||||||
if (fSearchString = '') then
|
if (fSearchString = '') then
|
||||||
exit;
|
exit;
|
||||||
|
if (HideSingleMatch and (fMatches.Count <= 1)) or
|
||||||
|
(aRow <> FNextPosRow) or (FNextPosIdx < 0) or
|
||||||
|
(FNextPosIdx >= fMatches.PointCount) or (FMatches.Point[FNextPosIdx].y > aRow)
|
||||||
|
then
|
||||||
|
exit;
|
||||||
|
|
||||||
if HideSingleMatch and (fMatches.Count <= 1) then exit;
|
while (FNextPosIdx < fMatches.PointCount) and
|
||||||
|
(fMatches.Point[FNextPosIdx].y = aRow) and
|
||||||
|
(fMatches.Point[FNextPosIdx].x <= aStartCol.Logical)
|
||||||
|
do
|
||||||
|
inc(FNextPosIdx);
|
||||||
|
|
||||||
Pos:= 0;
|
if FNextPosIdx = fMatches.PointCount
|
||||||
while (Pos < fMatches.PointCount)
|
then exit;
|
||||||
and ( (fMatches.Point[Pos].y < aRow)
|
if fMatches.Point[FNextPosIdx].y <> aRow
|
||||||
or ((fMatches.Point[Pos].y = aRow) and (fMatches.Point[Pos].x <= aStartCol.Logical)) )
|
|
||||||
do inc(Pos);
|
|
||||||
|
|
||||||
// what is ifthe next is an END, with a start at the same pos?
|
|
||||||
|
|
||||||
if Pos = fMatches.PointCount
|
|
||||||
then exit;
|
then exit;
|
||||||
|
|
||||||
if fMatches.Point[Pos].y <> aRow
|
ANextLog := fMatches.Point[FNextPosIdx].x;
|
||||||
then exit;
|
|
||||||
|
|
||||||
ANextLog := fMatches.Point[Pos].x;
|
|
||||||
//debugLN('--->NEXT POS ',dbgs(ANextLog),' / ',dbgs(ARow), ' at index ', dbgs(Pos));
|
//debugLN('--->NEXT POS ',dbgs(ANextLog),' / ',dbgs(ARow), ' at index ', dbgs(Pos));
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TSynEditMarkupHighlightAll.Invalidate(SkipPaint: Boolean);
|
||||||
|
begin
|
||||||
|
if not SkipPaint then
|
||||||
|
SendLineInvalidation;
|
||||||
|
FStartPoint.y := -1;
|
||||||
|
FMatches.Count := 0;
|
||||||
|
ValidateMatches(SkipPaint);
|
||||||
|
end;
|
||||||
|
|
||||||
{ TSynEditMarkupHighlightAllCaret }
|
{ TSynEditMarkupHighlightAllCaret }
|
||||||
|
|
||||||
procedure TSynEditMarkupHighlightAllCaret.SetWaitTime(const AValue: Integer);
|
procedure TSynEditMarkupHighlightAllCaret.SetWaitTime(const AValue: Integer);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user