SynEdit: Rewritten Multi Highlighter

git-svn-id: trunk@25056 -
This commit is contained in:
martin 2010-04-29 02:17:30 +00:00
parent 9fde93411b
commit 686f8c56be
6 changed files with 1570 additions and 504 deletions

View File

@ -69,7 +69,7 @@ type
protected
function ItemSize: Integer; override;
protected
procedure LineTextChanged(AIndex: Integer); override;
procedure LineTextChanged(AIndex: Integer; ACount: Integer = 1); override;
procedure InsertedLines(AIndex, ACount: Integer); override;
procedure DeletedLines(AIndex, ACount: Integer); override;
public
@ -209,6 +209,17 @@ type
property OnChange: TNotifyEvent read fOnChange write fOnChange;
end;
{ TSynEditLinesList }
TSynEditLinesList=class(TFPList)
private
function GetSynString(Index: Integer): TSynEditStringsBase;
procedure PutSynStrings(Index: Integer; const AValue: TSynEditStringsBase);
public
property Items[Index: Integer]: TSynEditStringsBase
read GetSynString write PutSynStrings; default;
end;
{ TSynCustomHighlighter }
TSynCustomHighlighter = class(TComponent)
@ -216,6 +227,7 @@ type
fAttributes: TStringList;
fAttrChangeHooks: TMethodList;
FCapabilities: TSynHighlighterCapabilities;
FKnownLines: TSynEditLinesList;
FCurrentLines: TSynEditStringsBase;
FCurrentRanges: TSynHighlighterRangeList;
FDrawDividerLevel: Integer;
@ -225,7 +237,7 @@ type
fEnabled: Boolean;
fWordBreakChars: TSynIdentChars;
FIsScanning: Boolean;
procedure SetCurrentLines(const AValue: TSynEditStringsBase);
function GetKnownRanges(Index: Integer): TSynHighlighterRangeList;
procedure SetDrawDividerLevel(const AValue: Integer);
procedure SetEnabled(const Value: boolean); //DDH 2001-10-23
protected
@ -247,15 +259,22 @@ type
procedure SetAttributesOnChange(AEvent: TNotifyEvent);
procedure SetDefaultFilter(Value: string); virtual;
procedure SetSampleSource(Value: string); virtual;
function CreateRangeList: TSynHighlighterRangeList; virtual;
function GetRangeIdentifier: Pointer; virtual;
function CreateRangeList(ALines: TSynEditStringsBase): TSynHighlighterRangeList; virtual;
procedure AfterAttachedToRangeList(ARangeList: TSynHighlighterRangeList); virtual;
procedure BeforeDetachedFromRangeList(ARangeList: TSynHighlighterRangeList); virtual;
function UpdateRangeInfoAtLine(Index: Integer): Boolean; virtual; // Returns true if range changed
// code fold - only valid if hcCodeFolding in Capabilities
procedure SetCurrentLines(const AValue: TSynEditStringsBase); virtual;
property LineIndex: Integer read FLineIndex;
property CurrentRanges: TSynHighlighterRangeList read FCurrentRanges;
function GetDrawDivider(Index: integer): TSynDividerDrawConfigSetting; virtual;
function GetDividerDrawConfig(Index: Integer): TSynDividerDrawConfig; virtual;
function GetDividerDrawConfigCount: Integer; virtual;
function PerformScan(StartIndex, EndIndex: Integer): Integer; virtual;
property IsScanning: Boolean read FIsScanning;
property KnownRanges[Index: Integer]: TSynHighlighterRangeList read GetKnownRanges;
property KnownLines: TSynEditLinesList read FKnownLines;
public
procedure DefHighlightChange(Sender: TObject);
property AttributeChangeNeedScan: Boolean read FAttributeChangeNeedScan;
@ -283,7 +302,7 @@ type
function GetEndOfLineAttribute: TSynHighlighterAttributes; virtual;
function GetTokenAttribute: TSynHighlighterAttributes; virtual; abstract;
function GetTokenKind: integer; virtual; abstract;
function GetTokenPos: Integer; virtual; abstract;
function GetTokenPos: Integer; virtual; abstract; // 0-based
function IsKeyword(const AKeyword: string): boolean; virtual; // DJLP 2000-08-09
procedure Next; virtual; abstract;
procedure NextToEol;
@ -886,6 +905,18 @@ begin
end;
{$ENDIF}
{ TSynEditLinesList }
function TSynEditLinesList.GetSynString(Index: Integer): TSynEditStringsBase;
begin
Result := TSynEditStringsBase(inherited Items[Index]);
end;
procedure TSynEditLinesList.PutSynStrings(Index: Integer; const AValue: TSynEditStringsBase);
begin
inherited Items[Index] := AValue;
end;
{ TSynCustomHighlighter }
constructor TSynCustomHighlighter.Create(AOwner: TComponent);
@ -893,6 +924,7 @@ begin
{$IFDEF SYN_LAZARUS}
FCapabilities:=GetCapabilities;
{$ENDIF}
FKnownLines := TSynEditLinesList.Create;
inherited Create(AOwner);
fWordBreakChars := TSynWordBreakChars;
fAttributes := TStringList.Create;
@ -908,6 +940,7 @@ begin
fAttributes.Free;
fAttrChangeHooks.Free;
inherited Destroy;
FreeAndNil(FKnownLines);
end;
procedure TSynCustomHighlighter.BeginUpdate;
@ -1215,11 +1248,24 @@ procedure TSynCustomHighlighter.SetSampleSource(Value: string);
begin
end;
function TSynCustomHighlighter.CreateRangeList: TSynHighlighterRangeList;
function TSynCustomHighlighter.GetRangeIdentifier: Pointer;
begin
Result := self;
end;
function TSynCustomHighlighter.CreateRangeList(ALines: TSynEditStringsBase): TSynHighlighterRangeList;
begin
Result := TSynHighlighterRangeList.Create;
end;
procedure TSynCustomHighlighter.AfterAttachedToRangeList(ARangeList: TSynHighlighterRangeList);
begin // empty base
end;
procedure TSynCustomHighlighter.BeforeDetachedFromRangeList(ARangeList: TSynHighlighterRangeList);
begin // empty base
end;
procedure TSynCustomHighlighter.UnhookAttrChangeEvent(ANotifyEvent: TNotifyEvent);
begin
fAttrChangeHooks.Remove(TMethod(ANotifyEvent));
@ -1237,31 +1283,36 @@ end;
procedure TSynCustomHighlighter.ScanRanges;
var
StartIndex, EndIndex, CurrentIndex, c: Integer;
StartIndex, EndIndex: Integer;
begin
StartIndex := CurrentRanges.NeedsReScanStartIndex;
if (StartIndex < 0) or (StartIndex >= CurrentRanges.Count) then exit;
EndIndex := CurrentRanges.NeedsReScanEndIndex + 1;
CurrentIndex := StartIndex;
c := CurrentLines.Count;
FIsScanning := True;
try
StartAtLineIndex(CurrentIndex);
NextToEol;
while UpdateRangeInfoAtLine(CurrentIndex) or
(CurrentIndex <= EndIndex)
do begin
inc(CurrentIndex);
if CurrentIndex = c then
break;
ContinueNextLine;
NextToEol;
end;
EndIndex := PerformScan(StartIndex, EndIndex);
finally
FIsScanning := False;
end;
CurrentRanges.ClearReScanNeeded;
CurrentLines.SendHighlightChanged(StartIndex, CurrentIndex - StartIndex + 1);
CurrentLines.SendHighlightChanged(StartIndex, EndIndex - StartIndex + 1);
end;
function TSynCustomHighlighter.PerformScan(StartIndex, EndIndex: Integer): Integer;
var
c: Integer;
begin
Result := StartIndex;
c := CurrentLines.Count;
StartAtLineIndex(Result);
NextToEol;
while UpdateRangeInfoAtLine(Result) or (Result <= EndIndex) do begin
inc(Result);
if Result = c then
break;
ContinueNextLine;
NextToEol;
end;
end;
procedure TSynCustomHighlighter.ScanAllRanges;
@ -1287,21 +1338,23 @@ begin
if AValue = FCurrentLines then
exit;
FCurrentLines := AValue;
FCurrentRanges := TSynHighlighterRangeList(AValue.Ranges[ClassType]);
FCurrentRanges := TSynHighlighterRangeList(AValue.Ranges[GetRangeIdentifier]);
end;
procedure TSynCustomHighlighter.AttachToLines(Lines: TSynEditStringsBase);
var
r: TSynHighlighterRangeList;
begin
r := TSynHighlighterRangeList(Lines.Ranges[ClassType]);
r := TSynHighlighterRangeList(Lines.Ranges[GetRangeIdentifier]);
if assigned(r) then
r.IncRefCount
else begin
r := CreateRangeList;
Lines.Ranges[ClassType] := r;
FKnownLines.Add(Lines);
r := CreateRangeList(Lines);
Lines.Ranges[GetRangeIdentifier] := r;
r.InvalidateAll;
end;
AfterAttachedToRangeList(r); // RefCount already increased
FCurrentLines := nil;
end;
@ -1309,13 +1362,15 @@ procedure TSynCustomHighlighter.DetachFromLines(Lines: TSynEditStringsBase);
var
r: TSynHighlighterRangeList;
begin
r := TSynHighlighterRangeList(Lines.Ranges[ClassType]);
r := TSynHighlighterRangeList(Lines.Ranges[GetRangeIdentifier]);
if not assigned(r) then exit;
r.DecRefCount;
BeforeDetachedFromRangeList(r); // RefCount already decreased
if r.RefCount = 0 then begin
Lines.Ranges[ClassType] := nil;
Lines.Ranges[GetRangeIdentifier] := nil;
r.Free;
end;
FKnownLines.Remove(Lines);
end;
procedure TSynCustomHighlighter.SetDrawDividerLevel(const AValue: Integer);
@ -1325,6 +1380,11 @@ begin
//DefHighlightChange(Self);
end;
function TSynCustomHighlighter.GetKnownRanges(Index: Integer): TSynHighlighterRangeList;
begin
Result := TSynHighlighterRangeList(KnownLines[Index].Ranges[GetRangeIdentifier]);
end;
function TSynCustomHighlighter.GetDrawDivider(Index: integer): TSynDividerDrawConfigSetting;
begin
result := SynEmptyDividerDrawConfigSetting;
@ -1357,16 +1417,16 @@ begin
Result := SizeOf(Pointer);
end;
procedure TSynHighlighterRangeList.LineTextChanged(AIndex: Integer);
procedure TSynHighlighterRangeList.LineTextChanged(AIndex: Integer; ACount: Integer = 1);
begin
if FNeedsReScanStartIndex < 0 then begin
FNeedsReScanStartIndex := AIndex;
FNeedsReScanEndIndex := AIndex;
FNeedsReScanEndIndex := AIndex + ACount - 1;
end
else if AIndex < FNeedsReScanStartIndex then
FNeedsReScanStartIndex := AIndex
else if AIndex > FNeedsReScanEndIndex then
FNeedsReScanEndIndex := AIndex;
else if AIndex + ACount - 1 > FNeedsReScanEndIndex then
FNeedsReScanEndIndex := AIndex + ACount - 1;
end;
procedure TSynHighlighterRangeList.InsertedLines(AIndex, ACount: Integer);

View File

@ -31,7 +31,8 @@ interface
uses
SysUtils, Classes, math, LCLType,
SynEditTypes, SynEditTextBuffer, SynEditHighlighter, SynEditHighlighterFoldBase;
SynEditTypes, SynEditTextBase, SynEditTextBuffer,
SynEditHighlighter, SynEditHighlighterFoldBase;
type
@ -63,7 +64,7 @@ type
FXmlRangeInfoOpenPos: integer;
FXmlRangeInfoClosePos: integer;
protected
function CreateRangeList: TSynHighlighterRangeList; override;
function CreateRangeList(ALines: TSynEditStringsBase): TSynHighlighterRangeList; override;
function UpdateRangeInfoAtLine(Index: Integer): Boolean; override; // Returns true if range changed
function StartXmlCodeFoldBlock(ABlockType: Integer): TSynCustomCodeFoldBlock;
@ -87,7 +88,7 @@ implementation
const
MaxFoldNestDeep = 500;
function TSynCustomXmlHighlighter.CreateRangeList: TSynHighlighterRangeList;
function TSynCustomXmlHighlighter.CreateRangeList(ALines: TSynEditStringsBase): TSynHighlighterRangeList;
begin
Result := TSynHighlighterXmlRangeList.Create;
end;

View File

@ -78,7 +78,7 @@ type
procedure InsertRows(AIndex, ACount: Integer); virtual;
procedure DeleteRows(AIndex, ACount: Integer); virtual;
property Capacity: Integer read FCapacity write SetCapacity;
// Count must be maintained by owner
// Capacity must be maintained by owner (Shrink)
property Count: Integer read FCount write SetCount;
end;
@ -87,7 +87,7 @@ type
TSynManagedStorageMem = class(TSynEditStorageMem)
protected
// Todo: Add Flags,which updates are required
procedure LineTextChanged(AIndex: Integer); virtual;
procedure LineTextChanged(AIndex: Integer; ACount: Integer = 1); virtual;
procedure InsertedLines(AIndex, ACount: Integer); virtual;
procedure DeletedLines(AIndex, ACount: Integer); virtual;
end;
@ -98,19 +98,21 @@ type
TSynManagedStorageMemList = class
private
FStorageMemList: Array of TSynManagedStorageMem;
FClassList: Array of TClass;
function GetStorageMems(Index: TClass): TSynManagedStorageMem;
procedure SetStorageMems(Index: TClass; const AValue: TSynManagedStorageMem);
FClassList: Array of Pointer;
function GetStorageMems(Index: Pointer): TSynManagedStorageMem;
procedure SetStorageMems(Index: Pointer; const AValue: TSynManagedStorageMem);
procedure SetChildCapacities(const AValue: Integer);
procedure SetChildCounts(const AValue: Integer);
public
procedure ChildInsertRows(AIndex, ACount: Integer);
procedure ChildDeleteRows(AIndex, ACount: Integer);
procedure CallMove(AFrom, ATo, ALen: Integer);
procedure CallLineTextChanged(AIndex: Integer);
procedure CallLineTextChanged(AIndex: Integer; ACount: Integer = 1);
procedure CallInsertedLines(AIndex, ACount: Integer);
procedure CallDeletedLines(AIndex, ACount: Integer);
property ChildCapacities: Integer write SetChildCapacities;
property ChildCounts: Integer write SetChildCounts;
property StorageMems[Index: TClass]: TSynManagedStorageMem
property StorageMems[Index: Pointer]: TSynManagedStorageMem
read GetStorageMems write SetStorageMems; default;
end;
@ -118,11 +120,11 @@ type
TSynEditStringsBase = class(TStrings)
protected
function GetRange(Index: TClass): TSynEditStorageMem; virtual; abstract;
procedure PutRange(Index: TClass; const ARange: TSynEditStorageMem); virtual; abstract;
function GetRange(Index: Pointer): TSynManagedStorageMem; virtual; abstract;
procedure PutRange(Index: Pointer; const ARange: TSynManagedStorageMem); virtual; abstract;
public
procedure SendHighlightChanged(aIndex, aCount: Integer); virtual; abstract;
property Ranges[Index: TClass]: TSynEditStorageMem read GetRange write PutRange;
property Ranges[Index: Pointer]: TSynManagedStorageMem read GetRange write PutRange;
end;
{ TSynEditStrings }
@ -219,8 +221,8 @@ type
function GetIsUtf8 : Boolean; override;
procedure SetIsUtf8(const AValue : Boolean); override;
function GetRange(Index: TClass): TSynEditStorageMem; override;
procedure PutRange(Index: TClass; const ARange: TSynEditStorageMem); override;
function GetRange(Index: Pointer): TSynManagedStorageMem; override;
procedure PutRange(Index: Pointer; const ARange: TSynManagedStorageMem); override;
function GetAttribute(const Owner: TClass; const Index: Integer): Pointer; override;
procedure SetAttribute(const Owner: TClass; const Index: Integer; const AValue: Pointer); override;
@ -650,12 +652,12 @@ begin
end;
//Ranges
function TSynEditStringsLinked.GetRange(Index: TClass): TSynEditStorageMem;
function TSynEditStringsLinked.GetRange(Index: Pointer): TSynManagedStorageMem;
begin
Result:= fSynStrings.Ranges[Index];
end;
procedure TSynEditStringsLinked.PutRange(Index: TClass; const ARange: TSynEditStorageMem);
procedure TSynEditStringsLinked.PutRange(Index: Pointer; const ARange: TSynManagedStorageMem);
begin
fSynStrings.Ranges[Index] := ARange;
end;
@ -1248,7 +1250,7 @@ begin
if (AIndex < 0) or (AIndex > Count) then
ListIndexOutOfBounds(AIndex);
if Capacity < Count + ACount then
SetCapacity(Count + ACount);
SetCapacity(Count + ACount + 8);
if AIndex < Count then
Move(AIndex, AIndex + ACount, Count - AIndex);
Count := Count + ACount;
@ -1264,6 +1266,8 @@ begin
if LinesAfter > 0 then
Move(AIndex + ACount, AIndex, LinesAfter);
Count := Count - ACount;
if (Capacity > 16) and (Capacity > Count * 2) then
Capacity := Capacity - (Count div 2);
end;
procedure TSynEditStorageMem.Move(AFrom, ATo, ALen: Integer);
@ -1283,7 +1287,7 @@ end;
{ TSynManagedStorageMem }
procedure TSynManagedStorageMem.LineTextChanged(AIndex: Integer);
procedure TSynManagedStorageMem.LineTextChanged(AIndex: Integer; ACount: Integer = 1);
begin // empty base class
end;
@ -1297,7 +1301,7 @@ end;
{ TSynManagedStorageMemList }
function TSynManagedStorageMemList.GetStorageMems(Index: TClass): TSynManagedStorageMem;
function TSynManagedStorageMemList.GetStorageMems(Index: Pointer): TSynManagedStorageMem;
var
i: Integer;
begin
@ -1310,7 +1314,7 @@ begin
end;
end;
procedure TSynManagedStorageMemList.SetStorageMems(Index: TClass;
procedure TSynManagedStorageMemList.SetStorageMems(Index: Pointer;
const AValue: TSynManagedStorageMem);
var
i, j: Integer;
@ -1361,6 +1365,22 @@ begin
FStorageMemList[i].Count := AValue;
end;
procedure TSynManagedStorageMemList.ChildInsertRows(AIndex, ACount: Integer);
var
i: Integer;
begin
for i := 0 to high(FStorageMemList) do
FStorageMemList[i].InsertRows(AIndex, ACount);
end;
procedure TSynManagedStorageMemList.ChildDeleteRows(AIndex, ACount: Integer);
var
i: Integer;
begin
for i := 0 to high(FStorageMemList) do
FStorageMemList[i].DeleteRows(AIndex, ACount);
end;
procedure TSynManagedStorageMemList.CallMove(AFrom, ATo, ALen: Integer);
var
i: Integer;
@ -1369,12 +1389,12 @@ begin
FStorageMemList[i].Move(AFrom, ATo, ALen);
end;
procedure TSynManagedStorageMemList.CallLineTextChanged(AIndex: Integer);
procedure TSynManagedStorageMemList.CallLineTextChanged(AIndex: Integer; ACount: Integer = 1);
var
i: Integer;
begin
for i := 0 to high(FStorageMemList) do
FStorageMemList[i].LineTextChanged(AIndex);
FStorageMemList[i].LineTextChanged(AIndex, ACount);
end;
procedure TSynManagedStorageMemList.CallInsertedLines(AIndex, ACount: Integer);

View File

@ -90,12 +90,12 @@ type
function GetAttribute(Index: Integer; Pos: Integer; Size: Word): Pointer;
function GetAttributeSize: Integer;
function GetObject(Index: Integer): TObject;
function GetRange(Index: TClass): TSynManagedStorageMem;
function GetRange(Index: Pointer): TSynManagedStorageMem;
function GetString(Index: Integer): String;
procedure SetAttribute(Index: Integer; Pos: Integer; Size: Word; const AValue: Pointer);
procedure SetAttributeSize(const AValue: Integer);
procedure SetObject(Index: Integer; const AValue: TObject);
procedure SetRange(Index: TClass; const AValue: TSynManagedStorageMem);
procedure SetRange(Index: Pointer; const AValue: TSynManagedStorageMem);
procedure SetString(Index: Integer; const AValue: String);
protected
procedure Move(AFrom, ATo, ALen: Integer); override;
@ -114,7 +114,7 @@ type
read GetAttribute write SetAttribute;
property AttributeSize: Integer read GetAttributeSize write SetAttributeSize;
property RangeList[Index: TClass]: TSynManagedStorageMem read GetRange write SetRange;
property RangeList[Index: Pointer]: TSynManagedStorageMem read GetRange write SetRange;
end;
{ TSynEditStringList }
@ -163,8 +163,8 @@ type
procedure IgnoreSendNotification(AReason: TSynEditNotifyReason;
IncIgnore: Boolean); override;
function GetRange(Index: TClass): TSynEditStorageMem; override;
procedure PutRange(Index: TClass; const ARange: TSynEditStorageMem); override;
function GetRange(Index: Pointer): TSynManagedStorageMem; override;
procedure PutRange(Index: Pointer; const ARange: TSynManagedStorageMem); override;
function GetAttribute(const Owner: TClass; const Index: Integer): Pointer; override;
procedure SetAttribute(const Owner: TClass; const Index: Integer; const AValue: Pointer); override;
function Get(Index: integer): string; override;
@ -709,7 +709,7 @@ begin
Result := nil;
end;
function TSynEditStringList.GetRange(Index: TClass): TSynEditStorageMem;
function TSynEditStringList.GetRange(Index: Pointer): TSynManagedStorageMem;
begin
Result := FList.RangeList[Index];
end;
@ -820,9 +820,9 @@ begin
EndUpdate;
end;
procedure TSynEditStringList.PutRange(Index: TClass; const ARange: TSynEditStorageMem);
procedure TSynEditStringList.PutRange(Index: Pointer; const ARange: TSynManagedStorageMem);
begin
FList.RangeList[Index] := ARange as TSynManagedStorageMem;
FList.RangeList[Index] := ARange;
end;
function TSynEditStringList.GetAttribute(const Owner: TClass; const Index: Integer): Pointer;
@ -1213,7 +1213,7 @@ begin
Result := (PObject(Mem + Index * FAttributeSize + SizeOf(String)))^;
end;
function TSynEditStringMemory.GetRange(Index: TClass): TSynManagedStorageMem;
function TSynEditStringMemory.GetRange(Index: Pointer): TSynManagedStorageMem;
begin
Result := FRangeList[Index];
end;
@ -1223,7 +1223,7 @@ begin
(PObject(Mem + Index * FAttributeSize + SizeOf(String)))^ := AValue;
end;
procedure TSynEditStringMemory.SetRange(Index: TClass; const AValue: TSynManagedStorageMem);
procedure TSynEditStringMemory.SetRange(Index: Pointer; const AValue: TSynManagedStorageMem);
begin
FRangeList[Index] := AValue;

File diff suppressed because it is too large Load Diff

View File

@ -58,7 +58,7 @@ uses
Windows, Messages,
{$ENDIF}
Classes, Registry, Graphics, SynEditHighlighterFoldBase, SynEditMiscProcs,
SynEditTypes, SynEditHighlighter, SynEditTextBuffer,
SynEditTypes, SynEditHighlighter, SynEditTextBase, SynEditTextBuffer,
SynEditStrConst;
type
@ -414,7 +414,7 @@ type
protected
function GetRangeClass: TSynCustomHighlighterRangeClass; override;
procedure CreateRootCodeFoldBlock; override;
function CreateRangeList: TSynHighlighterRangeList; override;
function CreateRangeList(ALines: TSynEditStringsBase): TSynHighlighterRangeList; override;
function UpdateRangeInfoAtLine(Index: Integer): Boolean; override; // Returns true if range changed
function StartPascalCodeFoldBlock
@ -3366,7 +3366,7 @@ begin
cfbtAsm, cfbtRegion];
end;
function TSynPasSyn.CreateRangeList: TSynHighlighterRangeList;
function TSynPasSyn.CreateRangeList(ALines: TSynEditStringsBase): TSynHighlighterRangeList;
begin
Result := TSynHighlighterPasRangeList.Create;
end;