IDE: More textmate Highlighting

This commit is contained in:
Martin 2023-09-20 16:50:53 +02:00
parent 9d18db68aa
commit 13516416e2
3 changed files with 149 additions and 30 deletions

View File

@ -413,6 +413,10 @@ type
FSampleTextFile: String; FSampleTextFile: String;
FLangName: string; FLangName: string;
FRegExMatchFoldBegin, FRegExMatchFoldEnd: TRegExpr;
MatchFoldBegin, MatchFoldEnd: String;
FMainPatternCount: integer; FMainPatternCount: integer;
FMainPatternList: TTextMatePatternList; FMainPatternList: TTextMatePatternList;
FPatternRepo: TTextMatePatternMap; FPatternRepo: TTextMatePatternMap;
@ -463,6 +467,8 @@ type
procedure Next; procedure Next;
function IsAtEol: boolean; function IsAtEol: boolean;
procedure NextToEol; procedure NextToEol;
function IsFoldBegin: boolean;
function IsFoldEnd: boolean;
property CurrentTokenPos: integer read FCurrentTokenPos; property CurrentTokenPos: integer read FCurrentTokenPos;
property NextTokenPos: integer read FNextTokenPos; property NextTokenPos: integer read FNextTokenPos;
@ -2339,6 +2345,8 @@ begin
FPatternRepo.Free; FPatternRepo.Free;
FTheEmptyPattern.Free; FTheEmptyPattern.Free;
FOtherGrammars.Free; FOtherGrammars.Free;
FRegExMatchFoldBegin.Free;
FRegExMatchFoldEnd.Free;
end; end;
procedure TTextMateGrammar.ParseGrammar(AGrammarDef: String); procedure TTextMateGrammar.ParseGrammar(AGrammarDef: String);
@ -2369,6 +2377,14 @@ begin
FRootPattern.FName := jsKeyAsString(JSonDef, 'name'); FRootPattern.FName := jsKeyAsString(JSonDef, 'name');
FRootPattern.ScopeName := jsKeyAsString(JSonDef, 'scopeName'); FRootPattern.ScopeName := jsKeyAsString(JSonDef, 'scopeName');
MatchFoldBegin := jsKeyAsString(JSonDef, 'foldingStartMarker');
MatchFoldEnd := jsKeyAsString(JSonDef, 'foldingStopMarker');
if MatchFoldBegin <> '' then
FRootPattern.DoInitRegex(FRegExMatchFoldBegin, MatchFoldBegin, 'foldingStartMarker');
if MatchFoldEnd <> '' then
FRootPattern.DoInitRegex(FRegExMatchFoldEnd, MatchFoldEnd, 'foldingStopMarker');
// language file? // language file?
if JSonDef.IndexOfName('contributes') >= 0 then begin if JSonDef.IndexOfName('contributes') >= 0 then begin
try try
@ -2625,5 +2641,29 @@ begin
FCurrentTokenPos := Length(FLineText) + 1; FCurrentTokenPos := Length(FLineText) + 1;
end; end;
function TTextMateGrammar.IsFoldBegin: boolean;
begin
if MatchFoldBegin = '' then
exit(false);
try
FRegExMatchFoldBegin.InputString := FLineText;
Result := FRegExMatchFoldBegin.Exec;
except
Result := False;
end;
end;
function TTextMateGrammar.IsFoldEnd: boolean;
begin
if MatchFoldEnd = '' then
exit(false);
try
FRegExMatchFoldEnd.InputString := FLineText;
Result := FRegExMatchFoldEnd.Exec;
except
Result := False;
end;
end;
end. end.

View File

@ -13,13 +13,29 @@ uses
// LazEdit // LazEdit
TextMateGrammar, TextMateGrammar,
// SynEdit // SynEdit
SynEditHighlighter, SynEditHighlighterFoldBase, SynEditTypes; SynEditHighlighter, SynEditHighlighterFoldBase, SynEditTypes, SynEditTextBase;
type type
TNameAttributesMap = specialize TFPGMapObject<string, TSynHighlighterAttributes>; TNameAttributesMap = specialize TFPGMapObject<string, TSynHighlighterAttributes>;
TGrammarLoadEvent = procedure(AGrammarFile, AGrammarPath: String; out AGrammarDef: String); TGrammarLoadEvent = procedure(AGrammarFile, AGrammarPath: String; out AGrammarDef: String);
TSynTextMateRangeInfo = record
FoldLevel: Smallint;
end;
{ TSynHighlighterTextMateRangeList }
TSynHighlighterTextMateRangeList = class(TSynHighlighterRangeList)
private
FItemOffset: integer;
function GetRangeInfo(Index: Integer): TSynTextMateRangeInfo;
procedure SetRangeInfo(Index: Integer; AValue: TSynTextMateRangeInfo);
public
constructor Create;
property RangeInfo[Index: Integer]: TSynTextMateRangeInfo read GetRangeInfo write SetRangeInfo;
end;
{ TSynTextMateSyn } { TSynTextMateSyn }
TSynTextMateSyn = class(TSynCustomFoldHighlighter) TSynTextMateSyn = class(TSynCustomFoldHighlighter)
@ -41,6 +57,7 @@ type
const AnAttribInfo: TSynAttributeInfo; out AnUseId, AnUseObject: Boolean); const AnAttribInfo: TSynAttributeInfo; out AnUseId, AnUseObject: Boolean);
private private
FCurrentRange: Integer; FCurrentRange: Integer;
FRangeInfo: TSynTextMateRangeInfo;
FCurrentTokenPos, FCurrentTokenLen: Integer; FCurrentTokenPos, FCurrentTokenLen: Integer;
FCurrentTokenKind: integer; FCurrentTokenKind: integer;
FCurrentAttrib: TSynHighlighterAttributes; FCurrentAttrib: TSynHighlighterAttributes;
@ -48,6 +65,8 @@ type
protected protected
function GetInstanceLanguageName: string; override; function GetInstanceLanguageName: string; override;
function CreateRangeList(ALines: TSynEditStringsBase): TSynHighlighterRangeList; override;
function UpdateRangeInfoAtLine(Index: Integer): Boolean; override;
public public
constructor Create(AOwner: TComponent); override; constructor Create(AOwner: TComponent); override;
destructor Destroy; override; destructor Destroy; override;
@ -70,13 +89,8 @@ type
procedure ResetRange; override; procedure ResetRange; override;
function GetRange: Pointer; override; function GetRange: Pointer; override;
function FoldBlockOpeningCount(ALineIndex: TLineIdx; const AFilter: TSynFoldBlockFilter): integer; override; overload;
function FoldBlockClosingCount(ALineIndex: TLineIdx; const AFilter: TSynFoldBlockFilter): integer; override; overload;
function FoldBlockEndLevel(ALineIndex: TLineIdx; const AFilter: TSynFoldBlockFilter): integer; override; overload; function FoldBlockEndLevel(ALineIndex: TLineIdx; const AFilter: TSynFoldBlockFilter): integer; override; overload;
function FoldBlockMinLevel(ALineIndex: TLineIdx; const AFilter: TSynFoldBlockFilter): integer; override; overload; function FoldBlockMinLevel(ALineIndex: TLineIdx; const AFilter: TSynFoldBlockFilter): integer; override; overload;
function FoldBlockNestedTypes(ALineIndex: TLineIdx; ANestIndex: Integer;
out AType: Pointer; const AFilter: TSynFoldBlockFilter): boolean; override; overload;
property OnLoadGrammarFile: TGrammarLoadEvent read FOnLoadGrammarFile write FOnLoadGrammarFile; property OnLoadGrammarFile: TGrammarLoadEvent read FOnLoadGrammarFile write FOnLoadGrammarFile;
property GrammarPath: String read FGrammarPath write SetGrammarPath; property GrammarPath: String read FGrammarPath write SetGrammarPath;
@ -86,6 +100,30 @@ type
implementation implementation
{ TSynHighlighterTextMateRangeList }
function TSynHighlighterTextMateRangeList.GetRangeInfo(Index: Integer
): TSynTextMateRangeInfo;
begin
if (Index < 0) or (Index >= Count) then
Result := Default(TSynTextMateRangeInfo)
else
Result := TSynTextMateRangeInfo((ItemPointer[Index] + FItemOffset)^);
end;
procedure TSynHighlighterTextMateRangeList.SetRangeInfo(Index: Integer;
AValue: TSynTextMateRangeInfo);
begin
TSynTextMateRangeInfo((ItemPointer[Index] + FItemOffset)^) := AValue;
end;
constructor TSynHighlighterTextMateRangeList.Create;
begin
inherited;
FItemOffset := ItemSize;
ItemSize := FItemOffset + SizeOf(TSynTextMateRangeInfo);
end;
{ TSynTextMateSyn } { TSynTextMateSyn }
function TSynTextMateSyn.LoadFile(AGrammarFile: String): String; function TSynTextMateSyn.LoadFile(AGrammarFile: String): String;
@ -133,6 +171,23 @@ begin
Result := FTextMateGrammar.LanguageName; Result := FTextMateGrammar.LanguageName;
end; end;
function TSynTextMateSyn.CreateRangeList(ALines: TSynEditStringsBase
): TSynHighlighterRangeList;
begin
Result := TSynHighlighterTextMateRangeList.Create;
end;
function TSynTextMateSyn.UpdateRangeInfoAtLine(Index: Integer): Boolean;
var
r: TSynTextMateRangeInfo;
begin
Result := inherited;
r := TSynHighlighterTextMateRangeList(CurrentRanges).RangeInfo[Index];
Result := Result
or (FRangeInfo.FoldLevel <> r.FoldLevel);
TSynHighlighterTextMateRangeList(CurrentRanges).RangeInfo[Index] := FRangeInfo;
end;
procedure TSynTextMateSyn.DoPopulateAttributeInfo( procedure TSynTextMateSyn.DoPopulateAttributeInfo(
Sender: TTextMateGrammar; APattern: TTextMatePattern; Sender: TTextMateGrammar; APattern: TTextMatePattern;
AContextName: String; var AnAttribInfo: TSynAttributeInfo); AContextName: String; var AnAttribInfo: TSynAttributeInfo);
@ -191,6 +246,8 @@ end;
procedure TSynTextMateSyn.SetLine(const NewValue: String; procedure TSynTextMateSyn.SetLine(const NewValue: String;
LineNumber: Integer); LineNumber: Integer);
var
nd: TSynFoldNodeInfo;
begin begin
inherited SetLine(NewValue, LineNumber); inherited SetLine(NewValue, LineNumber);
@ -201,6 +258,38 @@ begin
FTextMateGrammar.SetLine(CurrentLineText, FCurrentRange); FTextMateGrammar.SetLine(CurrentLineText, FCurrentRange);
FCurrentRange := -2; FCurrentRange := -2;
if FTextMateGrammar.IsFoldBegin then begin
if not FTextMateGrammar.IsFoldEnd then begin
inc(FRangeInfo.FoldLevel);
if IsCollectingNodeInfo then begin
nd := Default(TSynFoldNodeInfo);
nd.LineIndex := LineIndex;
nd.FoldGroup := 1;
nd.FoldLvlStart := FRangeInfo.FoldLevel - 1;
nd.FoldLvlEnd := FRangeInfo.FoldLevel;
nd.NestLvlStart := FRangeInfo.FoldLevel - 1;
nd.NestLvlEnd := FRangeInfo.FoldLevel;
nd.FoldAction := [sfaFold, sfaFoldFold, sfaOpen, sfaOpenFold];
CollectingNodeInfoList.Add(nd);
end;
end;
end
else
if FTextMateGrammar.IsFoldEnd and (FRangeInfo.FoldLevel > 0) then begin
dec(FRangeInfo.FoldLevel);
if IsCollectingNodeInfo then begin
nd := Default(TSynFoldNodeInfo);
nd.LineIndex := LineIndex;
nd.FoldGroup := 1;
nd.FoldLvlStart := FRangeInfo.FoldLevel + 1;
nd.FoldLvlEnd := FRangeInfo.FoldLevel;
nd.NestLvlStart := FRangeInfo.FoldLevel + 1;
nd.NestLvlEnd := FRangeInfo.FoldLevel;
nd.FoldAction := [sfaFold, sfaFoldFold, sfaClose, sfaCloseFold];
CollectingNodeInfoList.Add(nd);
end;
end;
if IsScanning then begin if IsScanning then begin
FTextMateGrammar.NextToEol; FTextMateGrammar.NextToEol;
end end
@ -266,11 +355,13 @@ end;
procedure TSynTextMateSyn.SetRange(Value: Pointer); procedure TSynTextMateSyn.SetRange(Value: Pointer);
begin begin
FCurrentRange := PtrUInt(Value); FCurrentRange := PtrUInt(Value);
FRangeInfo := TSynHighlighterTextMateRangeList(CurrentRanges).RangeInfo[LineIndex-1];
end; end;
procedure TSynTextMateSyn.ResetRange; procedure TSynTextMateSyn.ResetRange;
begin begin
FCurrentRange := -1; FCurrentRange := -1;
FRangeInfo := Default(TSynTextMateRangeInfo);
end; end;
function TSynTextMateSyn.GetRange: Pointer; function TSynTextMateSyn.GetRange: Pointer;
@ -279,35 +370,25 @@ begin
Result := Pointer(PtrUInt(FCurrentRange)); Result := Pointer(PtrUInt(FCurrentRange));
end; end;
function TSynTextMateSyn.FoldBlockOpeningCount(ALineIndex: TLineIdx;
const AFilter: TSynFoldBlockFilter): integer;
begin
Result := 0;
end;
function TSynTextMateSyn.FoldBlockClosingCount(ALineIndex: TLineIdx;
const AFilter: TSynFoldBlockFilter): integer;
begin
Result := 0;
end;
function TSynTextMateSyn.FoldBlockEndLevel(ALineIndex: TLineIdx; function TSynTextMateSyn.FoldBlockEndLevel(ALineIndex: TLineIdx;
const AFilter: TSynFoldBlockFilter): integer; const AFilter: TSynFoldBlockFilter): integer;
var
RangeInfo: TSynTextMateRangeInfo;
begin begin
Result := 0; RangeInfo := TSynHighlighterTextMateRangeList(CurrentRanges).RangeInfo[ALineIndex];
Result := RangeInfo.FoldLevel;
end; end;
function TSynTextMateSyn.FoldBlockMinLevel(ALineIndex: TLineIdx; function TSynTextMateSyn.FoldBlockMinLevel(ALineIndex: TLineIdx;
const AFilter: TSynFoldBlockFilter): integer; const AFilter: TSynFoldBlockFilter): integer;
var
RangeInfo: TSynTextMateRangeInfo;
begin begin
Result := 0; RangeInfo := TSynHighlighterTextMateRangeList(CurrentRanges).RangeInfo[ALineIndex-1];
end; Result := RangeInfo.FoldLevel;
RangeInfo := TSynHighlighterTextMateRangeList(CurrentRanges).RangeInfo[ALineIndex];
function TSynTextMateSyn.FoldBlockNestedTypes(ALineIndex: TLineIdx; if Result > RangeInfo.FoldLevel then
ANestIndex: Integer; out AType: Pointer; const AFilter: TSynFoldBlockFilter Result := RangeInfo.FoldLevel;
): boolean;
begin
Result := False;
end; end;
end. end.

View File

@ -3741,7 +3741,7 @@ begin
CaretXY := Point(1,1); CaretXY := Point(1,1);
MappedAttributes := TStringList.Create; MappedAttributes := TStringList.Create;
for j := 0 to tmlHighlighter.AttrCount - 1 do begin for j := 0 to tmlHighlighter.AttrCount - 1 do begin
n := tmlHighlighter.Attribute[j].StoredName; n := tmlHighlighter.Attribute[j].StoredName+'.';
if strlicomp(pchar(n), pchar('comment.'), 8) = 0 then MappedAttributes.Add(n+'=Comment'); if strlicomp(pchar(n), pchar('comment.'), 8) = 0 then MappedAttributes.Add(n+'=Comment');
if strlicomp(pchar(n), pchar('string.'), 7) = 0 then MappedAttributes.Add(n+'=String'); if strlicomp(pchar(n), pchar('string.'), 7) = 0 then MappedAttributes.Add(n+'=String');
if strlicomp(pchar(n), pchar('constant.numeric.'), 17) = 0 then MappedAttributes.Add(n+'=Number'); if strlicomp(pchar(n), pchar('constant.numeric.'), 17) = 0 then MappedAttributes.Add(n+'=Number');
@ -3750,8 +3750,6 @@ begin
if strlicomp(pchar(n), pchar('key.'), 4) = 0 then MappedAttributes.Add(n+'=Reserved word'); if strlicomp(pchar(n), pchar('key.'), 4) = 0 then MappedAttributes.Add(n+'=Reserved word');
if strlicomp(pchar(n), pchar('entity.name.'), 12) = 0 then MappedAttributes.Add(n+'=Identifier'); if strlicomp(pchar(n), pchar('entity.name.'), 12) = 0 then MappedAttributes.Add(n+'=Identifier');
if strlicomp(pchar(n), pchar('identifier.'), 11) = 0 then MappedAttributes.Add(n+'=Identifier'); if strlicomp(pchar(n), pchar('identifier.'), 11) = 0 then MappedAttributes.Add(n+'=Identifier');
if strlicomp(pchar(n), pchar('comment.'), 8) = 0 then MappedAttributes.Add(n+'=Comment');
end; end;
end; end;
Add(NewInfo); Add(NewInfo);